All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/3] Few non-critical cpcap ADC fixes
@ 2017-05-23  0:51 ` Tony Lindgren
  0 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA

Hi all,

Here are few fixes for cpcap ADC mostly to get temperature readings                                  produce sane values. AFAIK no need for urgency with these and they                                   can all wait for v4.13 merge window.

Regards,

Tony

Changes since v1:

- Rename CPCAP_ADC_AD0_BATTDETB to just CPCAP_ADC_AD0 based on
  Matt Ranostay's suggestion as it's the battery temperature

- Add ack from Sebastian Reichel

Tony Lindgren (3):
  iio: adc: cpcap: Fix default register values and battery temperature
  iio: adc: cpcap: Fix die temperature
  iio: adc: cpcap: Remove hung interrupt quirk

 drivers/iio/adc/cpcap-adc.c | 109 +++++++++++++++++++++++++++++++-------------
 1 file changed, 77 insertions(+), 32 deletions(-)

-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCHv2 0/3] Few non-critical cpcap ADC fixes
@ 2017-05-23  0:51 ` Tony Lindgren
  0 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap

Hi all,

Here are few fixes for cpcap ADC mostly to get temperature readings                                  produce sane values. AFAIK no need for urgency with these and they                                   can all wait for v4.13 merge window.

Regards,

Tony

Changes since v1:

- Rename CPCAP_ADC_AD0_BATTDETB to just CPCAP_ADC_AD0 based on
  Matt Ranostay's suggestion as it's the battery temperature

- Add ack from Sebastian Reichel

Tony Lindgren (3):
  iio: adc: cpcap: Fix default register values and battery temperature
  iio: adc: cpcap: Fix die temperature
  iio: adc: cpcap: Remove hung interrupt quirk

 drivers/iio/adc/cpcap-adc.c | 109 +++++++++++++++++++++++++++++++-------------
 1 file changed, 77 insertions(+), 32 deletions(-)

-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
  2017-05-23  0:51 ` Tony Lindgren
@ 2017-05-23  0:51     ` Tony Lindgren
  -1 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

Looking at the register dumps from Android kernel on droid 4, I noticed
the values with the mainline kernel don't match. Let's fix this by
initializing the ADC registers to what Android does.

For getting correct values from the battery thermistor, we need to
toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
to get correct battery temperatures. And looks like we also need to
wait a little bit before reading the battery temperature as otherwise
the results are inaccurate.

Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/iio/adc/cpcap-adc.c | 58 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 50 insertions(+), 8 deletions(-)

diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -52,6 +52,10 @@
 #define CPCAP_BIT_RAND0			BIT(1)	/* Set with CAL_MODE */
 #define CPCAP_BIT_ADEN			BIT(0)	/* Currently unused */
 
+#define CPCAP_REG_ADCC1_DEFAULTS	(CPCAP_BIT_ADEN_AUTO_CLR | \
+					 CPCAP_BIT_ADC_CLK_SEL0 |  \
+					 CPCAP_BIT_RAND1)
+
 /* Register CPCAP_REG_ADCC2 bits */
 #define CPCAP_BIT_CAL_FACTOR_ENABLE	BIT(15)	/* Currently unused */
 #define CPCAP_BIT_BATDETB_EN		BIT(14)	/* Currently unused */
@@ -62,7 +66,7 @@
 #define CPCAP_BIT_ADC_PS_FACTOR0	BIT(9)
 #define CPCAP_BIT_AD4_SELECT		BIT(8)	/* Currently unused */
 #define CPCAP_BIT_ADC_BUSY		BIT(7)	/* Currently unused */
-#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Currently unused */
+#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Bias for AD0_BATTDETB */
 #define CPCAP_BIT_ADTRIG_DIS		BIT(5)	/* Disable interrupt */
 #define CPCAP_BIT_LIADC			BIT(4)	/* Currently unused */
 #define CPCAP_BIT_TS_REFEN		BIT(3)	/* Currently unused */
@@ -70,6 +74,13 @@
 #define CPCAP_BIT_TS_M1			BIT(1)	/* Currently unused */
 #define CPCAP_BIT_TS_M0			BIT(0)	/* Currently unused */
 
+#define CPCAP_REG_ADCC2_DEFAULTS	(CPCAP_BIT_AD4_SELECT | \
+					 CPCAP_BIT_ADTRIG_DIS | \
+					 CPCAP_BIT_ADTRIG_DIS | \
+					 CPCAP_BIT_LIADC | \
+					 CPCAP_BIT_TS_M2 | \
+					 CPCAP_BIT_TS_M1)
+
 #define CPCAP_MAX_TEMP_LVL		27
 #define CPCAP_FOUR_POINT_TWO_ADC	801
 #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD	530
@@ -124,10 +135,10 @@ struct cpcap_adc {
  */
 enum cpcap_adc_channel {
 	/* Bank0 channels */
-	CPCAP_ADC_AD0_BATTDETB,	/* Battery detection */
+	CPCAP_ADC_AD0,		/* Battery temperature */
 	CPCAP_ADC_BATTP,	/* Battery voltage */
 	CPCAP_ADC_VBUS,		/* USB VBUS voltage */
-	CPCAP_ADC_AD3,		/* Battery temperature when charging */
+	CPCAP_ADC_AD3,		/* Die temperature when charging */
 	CPCAP_ADC_BPLUS_AD4,	/* Another battery or system voltage */
 	CPCAP_ADC_CHG_ISENSE,	/* Calibrated charge current */
 	CPCAP_ADC_BATTI,	/* Calibrated system current */
@@ -217,7 +228,7 @@ struct cpcap_adc_request {
 /* Phasing table for channels. Note that channels 16 & 17 use BATTP and BATTI */
 static const struct cpcap_adc_phasing_tbl bank_phasing[] = {
 	/* Bank0 */
-	[CPCAP_ADC_AD0_BATTDETB] = {0, 0x80, 0x80,    0, 1023},
+	[CPCAP_ADC_AD0] =          {0, 0x80, 0x80,    0, 1023},
 	[CPCAP_ADC_BATTP] =        {0, 0x80, 0x80,    0, 1023},
 	[CPCAP_ADC_VBUS] =         {0, 0x80, 0x80,    0, 1023},
 	[CPCAP_ADC_AD3] =          {0, 0x80, 0x80,    0, 1023},
@@ -243,7 +254,7 @@ static const struct cpcap_adc_phasing_tbl bank_phasing[] = {
  */
 static struct cpcap_adc_conversion_tbl bank_conversion[] = {
 	/* Bank0 */
-	[CPCAP_ADC_AD0_BATTDETB] = {
+	[CPCAP_ADC_AD0] = {
 		IIO_CHAN_INFO_PROCESSED,    0,    0, 0,     1,    1,
 	},
 	[CPCAP_ADC_BATTP] = {
@@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 		return;
 
 	switch (req->channel) {
+	case CPCAP_ADC_AD0:
+		value2 |= CPCAP_BIT_THERMBIAS_EN;
+		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
+					   CPCAP_BIT_THERMBIAS_EN,
+					   value2);
+		if (error)
+			return;
+		usleep_range(800, 1000);
+		break;
 	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
 		value1 |= CPCAP_BIT_AD_SEL1;
 		break;
@@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
 				   CPCAP_BIT_ATOX_PS_FACTOR |
 				   CPCAP_BIT_ADC_PS_FACTOR1 |
-				   CPCAP_BIT_ADC_PS_FACTOR0,
+				   CPCAP_BIT_ADC_PS_FACTOR0 |
+				   CPCAP_BIT_THERMBIAS_EN,
 				   value2);
 	if (error)
 		return;
@@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
 	return error;
 }
 
+static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
+{
+	int error;
+
+	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
+				   0xffff,
+				   CPCAP_REG_ADCC1_DEFAULTS);
+	if (error)
+		return error;
+
+	return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
+				  0xffff,
+				  CPCAP_REG_ADCC2_DEFAULTS);
+}
+
 static void cpcap_adc_phase(struct cpcap_adc_request *req)
 {
 	const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
@@ -758,7 +794,7 @@ static void cpcap_adc_convert(struct cpcap_adc_request *req)
 		return;
 
 	/* Temperatures use a lookup table instead of conversion table */
-	if ((req->channel == CPCAP_ADC_AD0_BATTDETB) ||
+	if ((req->channel == CPCAP_ADC_AD0) ||
 	    (req->channel == CPCAP_ADC_AD3)) {
 		req->result =
 			cpcap_adc_table_to_millicelcius(req->result);
@@ -820,7 +856,7 @@ static int cpcap_adc_init_request(struct cpcap_adc_request *req,
 	req->conv_tbl = bank_conversion;
 
 	switch (channel) {
-	case CPCAP_ADC_AD0_BATTDETB ... CPCAP_ADC_USB_ID:
+	case CPCAP_ADC_AD0 ... CPCAP_ADC_USB_ID:
 		req->bank_index = channel;
 		break;
 	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
@@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = regmap_read(ddata->reg, chan->address, val);
 		if (error)
 			goto err_unlock;
+		error = cpcap_adc_stop_bank(ddata);
+		if (error)
+			goto err_unlock;
 		mutex_unlock(&ddata->lock);
 		break;
 	case IIO_CHAN_INFO_PROCESSED:
@@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = cpcap_adc_read_bank_scaled(ddata, &req);
 		if (error)
 			goto err_unlock;
+		error = cpcap_adc_stop_bank(ddata);
+		if (error)
+			goto err_unlock;
 		mutex_unlock(&ddata->lock);
 		*val = req.result;
 		break;
-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
@ 2017-05-23  0:51     ` Tony Lindgren
  0 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap, Marcel Partap, Michael Scott,
	Sebastian Reichel

Looking at the register dumps from Android kernel on droid 4, I noticed
the values with the mainline kernel don't match. Let's fix this by
initializing the ADC registers to what Android does.

For getting correct values from the battery thermistor, we need to
toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
to get correct battery temperatures. And looks like we also need to
wait a little bit before reading the battery temperature as otherwise
the results are inaccurate.

Cc: Marcel Partap <mpartap@gmx.net>
Cc: Michael Scott <michael.scott@linaro.org>
Cc: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/iio/adc/cpcap-adc.c | 58 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 50 insertions(+), 8 deletions(-)

diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -52,6 +52,10 @@
 #define CPCAP_BIT_RAND0			BIT(1)	/* Set with CAL_MODE */
 #define CPCAP_BIT_ADEN			BIT(0)	/* Currently unused */
 
+#define CPCAP_REG_ADCC1_DEFAULTS	(CPCAP_BIT_ADEN_AUTO_CLR | \
+					 CPCAP_BIT_ADC_CLK_SEL0 |  \
+					 CPCAP_BIT_RAND1)
+
 /* Register CPCAP_REG_ADCC2 bits */
 #define CPCAP_BIT_CAL_FACTOR_ENABLE	BIT(15)	/* Currently unused */
 #define CPCAP_BIT_BATDETB_EN		BIT(14)	/* Currently unused */
@@ -62,7 +66,7 @@
 #define CPCAP_BIT_ADC_PS_FACTOR0	BIT(9)
 #define CPCAP_BIT_AD4_SELECT		BIT(8)	/* Currently unused */
 #define CPCAP_BIT_ADC_BUSY		BIT(7)	/* Currently unused */
-#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Currently unused */
+#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Bias for AD0_BATTDETB */
 #define CPCAP_BIT_ADTRIG_DIS		BIT(5)	/* Disable interrupt */
 #define CPCAP_BIT_LIADC			BIT(4)	/* Currently unused */
 #define CPCAP_BIT_TS_REFEN		BIT(3)	/* Currently unused */
@@ -70,6 +74,13 @@
 #define CPCAP_BIT_TS_M1			BIT(1)	/* Currently unused */
 #define CPCAP_BIT_TS_M0			BIT(0)	/* Currently unused */
 
+#define CPCAP_REG_ADCC2_DEFAULTS	(CPCAP_BIT_AD4_SELECT | \
+					 CPCAP_BIT_ADTRIG_DIS | \
+					 CPCAP_BIT_ADTRIG_DIS | \
+					 CPCAP_BIT_LIADC | \
+					 CPCAP_BIT_TS_M2 | \
+					 CPCAP_BIT_TS_M1)
+
 #define CPCAP_MAX_TEMP_LVL		27
 #define CPCAP_FOUR_POINT_TWO_ADC	801
 #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD	530
@@ -124,10 +135,10 @@ struct cpcap_adc {
  */
 enum cpcap_adc_channel {
 	/* Bank0 channels */
-	CPCAP_ADC_AD0_BATTDETB,	/* Battery detection */
+	CPCAP_ADC_AD0,		/* Battery temperature */
 	CPCAP_ADC_BATTP,	/* Battery voltage */
 	CPCAP_ADC_VBUS,		/* USB VBUS voltage */
-	CPCAP_ADC_AD3,		/* Battery temperature when charging */
+	CPCAP_ADC_AD3,		/* Die temperature when charging */
 	CPCAP_ADC_BPLUS_AD4,	/* Another battery or system voltage */
 	CPCAP_ADC_CHG_ISENSE,	/* Calibrated charge current */
 	CPCAP_ADC_BATTI,	/* Calibrated system current */
@@ -217,7 +228,7 @@ struct cpcap_adc_request {
 /* Phasing table for channels. Note that channels 16 & 17 use BATTP and BATTI */
 static const struct cpcap_adc_phasing_tbl bank_phasing[] = {
 	/* Bank0 */
-	[CPCAP_ADC_AD0_BATTDETB] = {0, 0x80, 0x80,    0, 1023},
+	[CPCAP_ADC_AD0] =          {0, 0x80, 0x80,    0, 1023},
 	[CPCAP_ADC_BATTP] =        {0, 0x80, 0x80,    0, 1023},
 	[CPCAP_ADC_VBUS] =         {0, 0x80, 0x80,    0, 1023},
 	[CPCAP_ADC_AD3] =          {0, 0x80, 0x80,    0, 1023},
@@ -243,7 +254,7 @@ static const struct cpcap_adc_phasing_tbl bank_phasing[] = {
  */
 static struct cpcap_adc_conversion_tbl bank_conversion[] = {
 	/* Bank0 */
-	[CPCAP_ADC_AD0_BATTDETB] = {
+	[CPCAP_ADC_AD0] = {
 		IIO_CHAN_INFO_PROCESSED,    0,    0, 0,     1,    1,
 	},
 	[CPCAP_ADC_BATTP] = {
@@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 		return;
 
 	switch (req->channel) {
+	case CPCAP_ADC_AD0:
+		value2 |= CPCAP_BIT_THERMBIAS_EN;
+		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
+					   CPCAP_BIT_THERMBIAS_EN,
+					   value2);
+		if (error)
+			return;
+		usleep_range(800, 1000);
+		break;
 	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
 		value1 |= CPCAP_BIT_AD_SEL1;
 		break;
@@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
 				   CPCAP_BIT_ATOX_PS_FACTOR |
 				   CPCAP_BIT_ADC_PS_FACTOR1 |
-				   CPCAP_BIT_ADC_PS_FACTOR0,
+				   CPCAP_BIT_ADC_PS_FACTOR0 |
+				   CPCAP_BIT_THERMBIAS_EN,
 				   value2);
 	if (error)
 		return;
@@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
 	return error;
 }
 
+static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
+{
+	int error;
+
+	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
+				   0xffff,
+				   CPCAP_REG_ADCC1_DEFAULTS);
+	if (error)
+		return error;
+
+	return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
+				  0xffff,
+				  CPCAP_REG_ADCC2_DEFAULTS);
+}
+
 static void cpcap_adc_phase(struct cpcap_adc_request *req)
 {
 	const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
@@ -758,7 +794,7 @@ static void cpcap_adc_convert(struct cpcap_adc_request *req)
 		return;
 
 	/* Temperatures use a lookup table instead of conversion table */
-	if ((req->channel == CPCAP_ADC_AD0_BATTDETB) ||
+	if ((req->channel == CPCAP_ADC_AD0) ||
 	    (req->channel == CPCAP_ADC_AD3)) {
 		req->result =
 			cpcap_adc_table_to_millicelcius(req->result);
@@ -820,7 +856,7 @@ static int cpcap_adc_init_request(struct cpcap_adc_request *req,
 	req->conv_tbl = bank_conversion;
 
 	switch (channel) {
-	case CPCAP_ADC_AD0_BATTDETB ... CPCAP_ADC_USB_ID:
+	case CPCAP_ADC_AD0 ... CPCAP_ADC_USB_ID:
 		req->bank_index = channel;
 		break;
 	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
@@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = regmap_read(ddata->reg, chan->address, val);
 		if (error)
 			goto err_unlock;
+		error = cpcap_adc_stop_bank(ddata);
+		if (error)
+			goto err_unlock;
 		mutex_unlock(&ddata->lock);
 		break;
 	case IIO_CHAN_INFO_PROCESSED:
@@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = cpcap_adc_read_bank_scaled(ddata, &req);
 		if (error)
 			goto err_unlock;
+		error = cpcap_adc_stop_bank(ddata);
+		if (error)
+			goto err_unlock;
 		mutex_unlock(&ddata->lock);
 		*val = req.result;
 		break;
-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 2/3] iio: adc: cpcap: Fix die temperature
  2017-05-23  0:51 ` Tony Lindgren
@ 2017-05-23  0:51     ` Tony Lindgren
  -1 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

It seems that "MC13783 Power Management and Audio Ciruit User's Guide"
MC1378UG.pdf documents several similar components as in the CPCAP PMIC.

Chapter "9.5.5 Die Temperature and UID" says that the die temperature
value is 282 at 25C with LSB of -1.14C. Converting CPCAP PMIC channel3
values with following seems to produce values that make sense for a
PMIC die:

temperature = 25000 + ((regval - 282) * 114)

As we don't have any other documentation, let's assume the die
temperature is unconfigured in the Motorola mapphone Linux kernel
and the current temperature conversion table should be only used
for the battery thermistor and not for the die temperature.

Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/iio/adc/cpcap-adc.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -875,6 +875,22 @@ static int cpcap_adc_init_request(struct cpcap_adc_request *req,
 	return 0;
 }
 
+static int cpcap_adc_read_st_die_temp(struct cpcap_adc *ddata,
+				      int addr, int *val)
+{
+	int error;
+
+	error = regmap_read(ddata->reg, addr, val);
+	if (error)
+		return error;
+
+	*val -= 282;
+	*val *= 114;
+	*val += 25000;
+
+	return 0;
+}
+
 static int cpcap_adc_read(struct iio_dev *indio_dev,
 			  struct iio_chan_spec const *chan,
 			  int *val, int *val2, long mask)
@@ -906,9 +922,18 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = cpcap_adc_start_bank(ddata, &req);
 		if (error)
 			goto err_unlock;
-		error = cpcap_adc_read_bank_scaled(ddata, &req);
-		if (error)
-			goto err_unlock;
+		if ((ddata->vendor == CPCAP_VENDOR_ST) &&
+		    (chan->channel == CPCAP_ADC_AD3)) {
+			error = cpcap_adc_read_st_die_temp(ddata,
+							   chan->address,
+							   &req.result);
+			if (error)
+				goto err_unlock;
+		} else {
+			error = cpcap_adc_read_bank_scaled(ddata, &req);
+			if (error)
+				goto err_unlock;
+		}
 		error = cpcap_adc_stop_bank(ddata);
 		if (error)
 			goto err_unlock;
-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 2/3] iio: adc: cpcap: Fix die temperature
@ 2017-05-23  0:51     ` Tony Lindgren
  0 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap, Marcel Partap, Michael Scott,
	Sebastian Reichel

It seems that "MC13783 Power Management and Audio Ciruit User's Guide"
MC1378UG.pdf documents several similar components as in the CPCAP PMIC.

Chapter "9.5.5 Die Temperature and UID" says that the die temperature
value is 282 at 25C with LSB of -1.14C. Converting CPCAP PMIC channel3
values with following seems to produce values that make sense for a
PMIC die:

temperature = 25000 + ((regval - 282) * 114)

As we don't have any other documentation, let's assume the die
temperature is unconfigured in the Motorola mapphone Linux kernel
and the current temperature conversion table should be only used
for the battery thermistor and not for the die temperature.

Cc: Marcel Partap <mpartap@gmx.net>
Cc: Michael Scott <michael.scott@linaro.org>
Cc: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/iio/adc/cpcap-adc.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -875,6 +875,22 @@ static int cpcap_adc_init_request(struct cpcap_adc_request *req,
 	return 0;
 }
 
+static int cpcap_adc_read_st_die_temp(struct cpcap_adc *ddata,
+				      int addr, int *val)
+{
+	int error;
+
+	error = regmap_read(ddata->reg, addr, val);
+	if (error)
+		return error;
+
+	*val -= 282;
+	*val *= 114;
+	*val += 25000;
+
+	return 0;
+}
+
 static int cpcap_adc_read(struct iio_dev *indio_dev,
 			  struct iio_chan_spec const *chan,
 			  int *val, int *val2, long mask)
@@ -906,9 +922,18 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = cpcap_adc_start_bank(ddata, &req);
 		if (error)
 			goto err_unlock;
-		error = cpcap_adc_read_bank_scaled(ddata, &req);
-		if (error)
-			goto err_unlock;
+		if ((ddata->vendor == CPCAP_VENDOR_ST) &&
+		    (chan->channel == CPCAP_ADC_AD3)) {
+			error = cpcap_adc_read_st_die_temp(ddata,
+							   chan->address,
+							   &req.result);
+			if (error)
+				goto err_unlock;
+		} else {
+			error = cpcap_adc_read_bank_scaled(ddata, &req);
+			if (error)
+				goto err_unlock;
+		}
 		error = cpcap_adc_stop_bank(ddata);
 		if (error)
 			goto err_unlock;
-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 3/3] iio: adc: cpcap: Remove hung interrupt quirk
  2017-05-23  0:51 ` Tony Lindgren
@ 2017-05-23  0:51     ` Tony Lindgren
  -1 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott

This is no longer needed as the real problem was interrupt flags
not getting passed properly from device tree to the cpcap-core.c
mfd driver. This got fixed with commit ac89473213c6 ("mfd: cpcap:
Fix interrupt to use level interrupt") So let's remove ADC
interrupt specific the quirk.

Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/iio/adc/cpcap-adc.c | 24 +-----------------------
 1 file changed, 1 insertion(+), 23 deletions(-)

diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -89,7 +89,7 @@
 #define ST_ADC_CAL_BATTI_LOW_THRESHOLD	494
 #define ST_ADC_CALIBRATE_DIFF_THRESHOLD	3
 
-#define CPCAP_ADC_MAX_RETRIES		5	/* Calibration and quirk */
+#define CPCAP_ADC_MAX_RETRIES		5	/* Calibration */
 
 /**
  * struct cpcap_adc_ato - timing settings for cpcap adc
@@ -635,27 +635,6 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 	}
 }
 
-/*
- * Occasionally the ADC does not seem to start and there will be no
- * interrupt. Let's re-init interrupt to prevent the ADC from hanging
- * for the next request. It is unclear why this happens, but the next
- * request will usually work after doing this.
- */
-static void cpcap_adc_quirk_reset_lost_irq(struct cpcap_adc *ddata)
-{
-	int error;
-
-	dev_info(ddata->dev, "lost ADC irq, attempting to reinit\n");
-	disable_irq(ddata->irq);
-	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
-				   CPCAP_BIT_ADTRIG_DIS,
-				   CPCAP_BIT_ADTRIG_DIS);
-	if (error)
-		dev_warn(ddata->dev, "%s reset failed: %i\n",
-			 __func__, error);
-	enable_irq(ddata->irq);
-}
-
 static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
 				struct cpcap_adc_request *req)
 {
@@ -673,7 +652,6 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
 			return 0;
 
 		if (error == 0) {
-			cpcap_adc_quirk_reset_lost_irq(ddata);
 			error = -ETIMEDOUT;
 			continue;
 		}
-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 3/3] iio: adc: cpcap: Remove hung interrupt quirk
@ 2017-05-23  0:51     ` Tony Lindgren
  0 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap, Marcel Partap, Michael Scott

This is no longer needed as the real problem was interrupt flags
not getting passed properly from device tree to the cpcap-core.c
mfd driver. This got fixed with commit ac89473213c6 ("mfd: cpcap:
Fix interrupt to use level interrupt") So let's remove ADC
interrupt specific the quirk.

Cc: Marcel Partap <mpartap@gmx.net>
Cc: Michael Scott <michael.scott@linaro.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/iio/adc/cpcap-adc.c | 24 +-----------------------
 1 file changed, 1 insertion(+), 23 deletions(-)

diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -89,7 +89,7 @@
 #define ST_ADC_CAL_BATTI_LOW_THRESHOLD	494
 #define ST_ADC_CALIBRATE_DIFF_THRESHOLD	3
 
-#define CPCAP_ADC_MAX_RETRIES		5	/* Calibration and quirk */
+#define CPCAP_ADC_MAX_RETRIES		5	/* Calibration */
 
 /**
  * struct cpcap_adc_ato - timing settings for cpcap adc
@@ -635,27 +635,6 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 	}
 }
 
-/*
- * Occasionally the ADC does not seem to start and there will be no
- * interrupt. Let's re-init interrupt to prevent the ADC from hanging
- * for the next request. It is unclear why this happens, but the next
- * request will usually work after doing this.
- */
-static void cpcap_adc_quirk_reset_lost_irq(struct cpcap_adc *ddata)
-{
-	int error;
-
-	dev_info(ddata->dev, "lost ADC irq, attempting to reinit\n");
-	disable_irq(ddata->irq);
-	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
-				   CPCAP_BIT_ADTRIG_DIS,
-				   CPCAP_BIT_ADTRIG_DIS);
-	if (error)
-		dev_warn(ddata->dev, "%s reset failed: %i\n",
-			 __func__, error);
-	enable_irq(ddata->irq);
-}
-
 static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
 				struct cpcap_adc_request *req)
 {
@@ -673,7 +652,6 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
 			return 0;
 
 		if (error == 0) {
-			cpcap_adc_quirk_reset_lost_irq(ddata);
 			error = -ETIMEDOUT;
 			continue;
 		}
-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
  2017-05-23  0:51     ` Tony Lindgren
@ 2017-05-24 19:18         ` Jonathan Cameron
  -1 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-05-24 19:18 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

On Mon, 22 May 2017 17:51:44 -0700
Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:

> Looking at the register dumps from Android kernel on droid 4, I noticed
> the values with the mainline kernel don't match. Let's fix this by
> initializing the ADC registers to what Android does.
> 
> For getting correct values from the battery thermistor, we need to
> toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
> to get correct battery temperatures. And looks like we also need to
> wait a little bit before reading the battery temperature as otherwise
> the results are inaccurate.
> 
> Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
> Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
Applied to the togreg branch of iio.git and will be shortly pushed
out as testing for the autobuilders to play with it.

Thanks,

Jonathan
> ---
>  drivers/iio/adc/cpcap-adc.c | 58 ++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 50 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
> --- a/drivers/iio/adc/cpcap-adc.c
> +++ b/drivers/iio/adc/cpcap-adc.c
> @@ -52,6 +52,10 @@
>  #define CPCAP_BIT_RAND0			BIT(1)	/* Set with CAL_MODE */
>  #define CPCAP_BIT_ADEN			BIT(0)	/* Currently unused */
>  
> +#define CPCAP_REG_ADCC1_DEFAULTS	(CPCAP_BIT_ADEN_AUTO_CLR | \
> +					 CPCAP_BIT_ADC_CLK_SEL0 |  \
> +					 CPCAP_BIT_RAND1)
> +
>  /* Register CPCAP_REG_ADCC2 bits */
>  #define CPCAP_BIT_CAL_FACTOR_ENABLE	BIT(15)	/* Currently unused */
>  #define CPCAP_BIT_BATDETB_EN		BIT(14)	/* Currently unused */
> @@ -62,7 +66,7 @@
>  #define CPCAP_BIT_ADC_PS_FACTOR0	BIT(9)
>  #define CPCAP_BIT_AD4_SELECT		BIT(8)	/* Currently unused */
>  #define CPCAP_BIT_ADC_BUSY		BIT(7)	/* Currently unused */
> -#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Currently unused */
> +#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Bias for AD0_BATTDETB */
>  #define CPCAP_BIT_ADTRIG_DIS		BIT(5)	/* Disable interrupt */
>  #define CPCAP_BIT_LIADC			BIT(4)	/* Currently unused */
>  #define CPCAP_BIT_TS_REFEN		BIT(3)	/* Currently unused */
> @@ -70,6 +74,13 @@
>  #define CPCAP_BIT_TS_M1			BIT(1)	/* Currently unused */
>  #define CPCAP_BIT_TS_M0			BIT(0)	/* Currently unused */
>  
> +#define CPCAP_REG_ADCC2_DEFAULTS	(CPCAP_BIT_AD4_SELECT | \
> +					 CPCAP_BIT_ADTRIG_DIS | \
> +					 CPCAP_BIT_ADTRIG_DIS | \
> +					 CPCAP_BIT_LIADC | \
> +					 CPCAP_BIT_TS_M2 | \
> +					 CPCAP_BIT_TS_M1)
> +
>  #define CPCAP_MAX_TEMP_LVL		27
>  #define CPCAP_FOUR_POINT_TWO_ADC	801
>  #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD	530
> @@ -124,10 +135,10 @@ struct cpcap_adc {
>   */
>  enum cpcap_adc_channel {
>  	/* Bank0 channels */
> -	CPCAP_ADC_AD0_BATTDETB,	/* Battery detection */
> +	CPCAP_ADC_AD0,		/* Battery temperature */
>  	CPCAP_ADC_BATTP,	/* Battery voltage */
>  	CPCAP_ADC_VBUS,		/* USB VBUS voltage */
> -	CPCAP_ADC_AD3,		/* Battery temperature when charging */
> +	CPCAP_ADC_AD3,		/* Die temperature when charging */
>  	CPCAP_ADC_BPLUS_AD4,	/* Another battery or system voltage */
>  	CPCAP_ADC_CHG_ISENSE,	/* Calibrated charge current */
>  	CPCAP_ADC_BATTI,	/* Calibrated system current */
> @@ -217,7 +228,7 @@ struct cpcap_adc_request {
>  /* Phasing table for channels. Note that channels 16 & 17 use BATTP and BATTI */
>  static const struct cpcap_adc_phasing_tbl bank_phasing[] = {
>  	/* Bank0 */
> -	[CPCAP_ADC_AD0_BATTDETB] = {0, 0x80, 0x80,    0, 1023},
> +	[CPCAP_ADC_AD0] =          {0, 0x80, 0x80,    0, 1023},
>  	[CPCAP_ADC_BATTP] =        {0, 0x80, 0x80,    0, 1023},
>  	[CPCAP_ADC_VBUS] =         {0, 0x80, 0x80,    0, 1023},
>  	[CPCAP_ADC_AD3] =          {0, 0x80, 0x80,    0, 1023},
> @@ -243,7 +254,7 @@ static const struct cpcap_adc_phasing_tbl bank_phasing[] = {
>   */
>  static struct cpcap_adc_conversion_tbl bank_conversion[] = {
>  	/* Bank0 */
> -	[CPCAP_ADC_AD0_BATTDETB] = {
> +	[CPCAP_ADC_AD0] = {
>  		IIO_CHAN_INFO_PROCESSED,    0,    0, 0,     1,    1,
>  	},
>  	[CPCAP_ADC_BATTP] = {
> @@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>  		return;
>  
>  	switch (req->channel) {
> +	case CPCAP_ADC_AD0:
> +		value2 |= CPCAP_BIT_THERMBIAS_EN;
> +		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> +					   CPCAP_BIT_THERMBIAS_EN,
> +					   value2);
> +		if (error)
> +			return;
> +		usleep_range(800, 1000);
> +		break;
>  	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
>  		value1 |= CPCAP_BIT_AD_SEL1;
>  		break;
> @@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>  	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>  				   CPCAP_BIT_ATOX_PS_FACTOR |
>  				   CPCAP_BIT_ADC_PS_FACTOR1 |
> -				   CPCAP_BIT_ADC_PS_FACTOR0,
> +				   CPCAP_BIT_ADC_PS_FACTOR0 |
> +				   CPCAP_BIT_THERMBIAS_EN,
>  				   value2);
>  	if (error)
>  		return;
> @@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>  	return error;
>  }
>  
> +static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
> +{
> +	int error;
> +
> +	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
> +				   0xffff,
> +				   CPCAP_REG_ADCC1_DEFAULTS);
> +	if (error)
> +		return error;
> +
> +	return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> +				  0xffff,
> +				  CPCAP_REG_ADCC2_DEFAULTS);
> +}
> +
>  static void cpcap_adc_phase(struct cpcap_adc_request *req)
>  {
>  	const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
> @@ -758,7 +794,7 @@ static void cpcap_adc_convert(struct cpcap_adc_request *req)
>  		return;
>  
>  	/* Temperatures use a lookup table instead of conversion table */
> -	if ((req->channel == CPCAP_ADC_AD0_BATTDETB) ||
> +	if ((req->channel == CPCAP_ADC_AD0) ||
>  	    (req->channel == CPCAP_ADC_AD3)) {
>  		req->result =
>  			cpcap_adc_table_to_millicelcius(req->result);
> @@ -820,7 +856,7 @@ static int cpcap_adc_init_request(struct cpcap_adc_request *req,
>  	req->conv_tbl = bank_conversion;
>  
>  	switch (channel) {
> -	case CPCAP_ADC_AD0_BATTDETB ... CPCAP_ADC_USB_ID:
> +	case CPCAP_ADC_AD0 ... CPCAP_ADC_USB_ID:
>  		req->bank_index = channel;
>  		break;
>  	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
> @@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>  		error = regmap_read(ddata->reg, chan->address, val);
>  		if (error)
>  			goto err_unlock;
> +		error = cpcap_adc_stop_bank(ddata);
> +		if (error)
> +			goto err_unlock;
>  		mutex_unlock(&ddata->lock);
>  		break;
>  	case IIO_CHAN_INFO_PROCESSED:
> @@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>  		error = cpcap_adc_read_bank_scaled(ddata, &req);
>  		if (error)
>  			goto err_unlock;
> +		error = cpcap_adc_stop_bank(ddata);
> +		if (error)
> +			goto err_unlock;
>  		mutex_unlock(&ddata->lock);
>  		*val = req.result;
>  		break;

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
@ 2017-05-24 19:18         ` Jonathan Cameron
  0 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-05-24 19:18 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap, Marcel Partap, Michael Scott,
	Sebastian Reichel

On Mon, 22 May 2017 17:51:44 -0700
Tony Lindgren <tony@atomide.com> wrote:

> Looking at the register dumps from Android kernel on droid 4, I noticed
> the values with the mainline kernel don't match. Let's fix this by
> initializing the ADC registers to what Android does.
> 
> For getting correct values from the battery thermistor, we need to
> toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
> to get correct battery temperatures. And looks like we also need to
> wait a little bit before reading the battery temperature as otherwise
> the results are inaccurate.
> 
> Cc: Marcel Partap <mpartap@gmx.net>
> Cc: Michael Scott <michael.scott@linaro.org>
> Cc: Sebastian Reichel <sre@kernel.org>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
Applied to the togreg branch of iio.git and will be shortly pushed
out as testing for the autobuilders to play with it.

Thanks,

Jonathan
> ---
>  drivers/iio/adc/cpcap-adc.c | 58 ++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 50 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
> --- a/drivers/iio/adc/cpcap-adc.c
> +++ b/drivers/iio/adc/cpcap-adc.c
> @@ -52,6 +52,10 @@
>  #define CPCAP_BIT_RAND0			BIT(1)	/* Set with CAL_MODE */
>  #define CPCAP_BIT_ADEN			BIT(0)	/* Currently unused */
>  
> +#define CPCAP_REG_ADCC1_DEFAULTS	(CPCAP_BIT_ADEN_AUTO_CLR | \
> +					 CPCAP_BIT_ADC_CLK_SEL0 |  \
> +					 CPCAP_BIT_RAND1)
> +
>  /* Register CPCAP_REG_ADCC2 bits */
>  #define CPCAP_BIT_CAL_FACTOR_ENABLE	BIT(15)	/* Currently unused */
>  #define CPCAP_BIT_BATDETB_EN		BIT(14)	/* Currently unused */
> @@ -62,7 +66,7 @@
>  #define CPCAP_BIT_ADC_PS_FACTOR0	BIT(9)
>  #define CPCAP_BIT_AD4_SELECT		BIT(8)	/* Currently unused */
>  #define CPCAP_BIT_ADC_BUSY		BIT(7)	/* Currently unused */
> -#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Currently unused */
> +#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Bias for AD0_BATTDETB */
>  #define CPCAP_BIT_ADTRIG_DIS		BIT(5)	/* Disable interrupt */
>  #define CPCAP_BIT_LIADC			BIT(4)	/* Currently unused */
>  #define CPCAP_BIT_TS_REFEN		BIT(3)	/* Currently unused */
> @@ -70,6 +74,13 @@
>  #define CPCAP_BIT_TS_M1			BIT(1)	/* Currently unused */
>  #define CPCAP_BIT_TS_M0			BIT(0)	/* Currently unused */
>  
> +#define CPCAP_REG_ADCC2_DEFAULTS	(CPCAP_BIT_AD4_SELECT | \
> +					 CPCAP_BIT_ADTRIG_DIS | \
> +					 CPCAP_BIT_ADTRIG_DIS | \
> +					 CPCAP_BIT_LIADC | \
> +					 CPCAP_BIT_TS_M2 | \
> +					 CPCAP_BIT_TS_M1)
> +
>  #define CPCAP_MAX_TEMP_LVL		27
>  #define CPCAP_FOUR_POINT_TWO_ADC	801
>  #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD	530
> @@ -124,10 +135,10 @@ struct cpcap_adc {
>   */
>  enum cpcap_adc_channel {
>  	/* Bank0 channels */
> -	CPCAP_ADC_AD0_BATTDETB,	/* Battery detection */
> +	CPCAP_ADC_AD0,		/* Battery temperature */
>  	CPCAP_ADC_BATTP,	/* Battery voltage */
>  	CPCAP_ADC_VBUS,		/* USB VBUS voltage */
> -	CPCAP_ADC_AD3,		/* Battery temperature when charging */
> +	CPCAP_ADC_AD3,		/* Die temperature when charging */
>  	CPCAP_ADC_BPLUS_AD4,	/* Another battery or system voltage */
>  	CPCAP_ADC_CHG_ISENSE,	/* Calibrated charge current */
>  	CPCAP_ADC_BATTI,	/* Calibrated system current */
> @@ -217,7 +228,7 @@ struct cpcap_adc_request {
>  /* Phasing table for channels. Note that channels 16 & 17 use BATTP and BATTI */
>  static const struct cpcap_adc_phasing_tbl bank_phasing[] = {
>  	/* Bank0 */
> -	[CPCAP_ADC_AD0_BATTDETB] = {0, 0x80, 0x80,    0, 1023},
> +	[CPCAP_ADC_AD0] =          {0, 0x80, 0x80,    0, 1023},
>  	[CPCAP_ADC_BATTP] =        {0, 0x80, 0x80,    0, 1023},
>  	[CPCAP_ADC_VBUS] =         {0, 0x80, 0x80,    0, 1023},
>  	[CPCAP_ADC_AD3] =          {0, 0x80, 0x80,    0, 1023},
> @@ -243,7 +254,7 @@ static const struct cpcap_adc_phasing_tbl bank_phasing[] = {
>   */
>  static struct cpcap_adc_conversion_tbl bank_conversion[] = {
>  	/* Bank0 */
> -	[CPCAP_ADC_AD0_BATTDETB] = {
> +	[CPCAP_ADC_AD0] = {
>  		IIO_CHAN_INFO_PROCESSED,    0,    0, 0,     1,    1,
>  	},
>  	[CPCAP_ADC_BATTP] = {
> @@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>  		return;
>  
>  	switch (req->channel) {
> +	case CPCAP_ADC_AD0:
> +		value2 |= CPCAP_BIT_THERMBIAS_EN;
> +		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> +					   CPCAP_BIT_THERMBIAS_EN,
> +					   value2);
> +		if (error)
> +			return;
> +		usleep_range(800, 1000);
> +		break;
>  	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
>  		value1 |= CPCAP_BIT_AD_SEL1;
>  		break;
> @@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>  	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>  				   CPCAP_BIT_ATOX_PS_FACTOR |
>  				   CPCAP_BIT_ADC_PS_FACTOR1 |
> -				   CPCAP_BIT_ADC_PS_FACTOR0,
> +				   CPCAP_BIT_ADC_PS_FACTOR0 |
> +				   CPCAP_BIT_THERMBIAS_EN,
>  				   value2);
>  	if (error)
>  		return;
> @@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>  	return error;
>  }
>  
> +static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
> +{
> +	int error;
> +
> +	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
> +				   0xffff,
> +				   CPCAP_REG_ADCC1_DEFAULTS);
> +	if (error)
> +		return error;
> +
> +	return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> +				  0xffff,
> +				  CPCAP_REG_ADCC2_DEFAULTS);
> +}
> +
>  static void cpcap_adc_phase(struct cpcap_adc_request *req)
>  {
>  	const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
> @@ -758,7 +794,7 @@ static void cpcap_adc_convert(struct cpcap_adc_request *req)
>  		return;
>  
>  	/* Temperatures use a lookup table instead of conversion table */
> -	if ((req->channel == CPCAP_ADC_AD0_BATTDETB) ||
> +	if ((req->channel == CPCAP_ADC_AD0) ||
>  	    (req->channel == CPCAP_ADC_AD3)) {
>  		req->result =
>  			cpcap_adc_table_to_millicelcius(req->result);
> @@ -820,7 +856,7 @@ static int cpcap_adc_init_request(struct cpcap_adc_request *req,
>  	req->conv_tbl = bank_conversion;
>  
>  	switch (channel) {
> -	case CPCAP_ADC_AD0_BATTDETB ... CPCAP_ADC_USB_ID:
> +	case CPCAP_ADC_AD0 ... CPCAP_ADC_USB_ID:
>  		req->bank_index = channel;
>  		break;
>  	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
> @@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>  		error = regmap_read(ddata->reg, chan->address, val);
>  		if (error)
>  			goto err_unlock;
> +		error = cpcap_adc_stop_bank(ddata);
> +		if (error)
> +			goto err_unlock;
>  		mutex_unlock(&ddata->lock);
>  		break;
>  	case IIO_CHAN_INFO_PROCESSED:
> @@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>  		error = cpcap_adc_read_bank_scaled(ddata, &req);
>  		if (error)
>  			goto err_unlock;
> +		error = cpcap_adc_stop_bank(ddata);
> +		if (error)
> +			goto err_unlock;
>  		mutex_unlock(&ddata->lock);
>  		*val = req.result;
>  		break;


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/3] iio: adc: cpcap: Fix die temperature
  2017-05-23  0:51     ` Tony Lindgren
@ 2017-05-24 19:19         ` Jonathan Cameron
  -1 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-05-24 19:19 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

On Mon, 22 May 2017 17:51:45 -0700
Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:

> It seems that "MC13783 Power Management and Audio Ciruit User's Guide"
> MC1378UG.pdf documents several similar components as in the CPCAP PMIC.
> 
> Chapter "9.5.5 Die Temperature and UID" says that the die temperature
> value is 282 at 25C with LSB of -1.14C. Converting CPCAP PMIC channel3
> values with following seems to produce values that make sense for a
> PMIC die:
> 
> temperature = 25000 + ((regval - 282) * 114)
> 
> As we don't have any other documentation, let's assume the die
> temperature is unconfigured in the Motorola mapphone Linux kernel
> and the current temperature conversion table should be only used
> for the battery thermistor and not for the die temperature.
> 
> Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
> Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
Applied to the togreg branch of iio.git which will shortly be
pushed out as testing for the autobuilders to play with it.

Thanks,

Jonathan
> ---
>  drivers/iio/adc/cpcap-adc.c | 31 ++++++++++++++++++++++++++++---
>  1 file changed, 28 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
> --- a/drivers/iio/adc/cpcap-adc.c
> +++ b/drivers/iio/adc/cpcap-adc.c
> @@ -875,6 +875,22 @@ static int cpcap_adc_init_request(struct cpcap_adc_request *req,
>  	return 0;
>  }
>  
> +static int cpcap_adc_read_st_die_temp(struct cpcap_adc *ddata,
> +				      int addr, int *val)
> +{
> +	int error;
> +
> +	error = regmap_read(ddata->reg, addr, val);
> +	if (error)
> +		return error;
> +
> +	*val -= 282;
> +	*val *= 114;
> +	*val += 25000;
> +
> +	return 0;
> +}
> +
>  static int cpcap_adc_read(struct iio_dev *indio_dev,
>  			  struct iio_chan_spec const *chan,
>  			  int *val, int *val2, long mask)
> @@ -906,9 +922,18 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>  		error = cpcap_adc_start_bank(ddata, &req);
>  		if (error)
>  			goto err_unlock;
> -		error = cpcap_adc_read_bank_scaled(ddata, &req);
> -		if (error)
> -			goto err_unlock;
> +		if ((ddata->vendor == CPCAP_VENDOR_ST) &&
> +		    (chan->channel == CPCAP_ADC_AD3)) {
> +			error = cpcap_adc_read_st_die_temp(ddata,
> +							   chan->address,
> +							   &req.result);
> +			if (error)
> +				goto err_unlock;
> +		} else {
> +			error = cpcap_adc_read_bank_scaled(ddata, &req);
> +			if (error)
> +				goto err_unlock;
> +		}
>  		error = cpcap_adc_stop_bank(ddata);
>  		if (error)
>  			goto err_unlock;

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/3] iio: adc: cpcap: Fix die temperature
@ 2017-05-24 19:19         ` Jonathan Cameron
  0 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-05-24 19:19 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap, Marcel Partap, Michael Scott,
	Sebastian Reichel

On Mon, 22 May 2017 17:51:45 -0700
Tony Lindgren <tony@atomide.com> wrote:

> It seems that "MC13783 Power Management and Audio Ciruit User's Guide"
> MC1378UG.pdf documents several similar components as in the CPCAP PMIC.
> 
> Chapter "9.5.5 Die Temperature and UID" says that the die temperature
> value is 282 at 25C with LSB of -1.14C. Converting CPCAP PMIC channel3
> values with following seems to produce values that make sense for a
> PMIC die:
> 
> temperature = 25000 + ((regval - 282) * 114)
> 
> As we don't have any other documentation, let's assume the die
> temperature is unconfigured in the Motorola mapphone Linux kernel
> and the current temperature conversion table should be only used
> for the battery thermistor and not for the die temperature.
> 
> Cc: Marcel Partap <mpartap@gmx.net>
> Cc: Michael Scott <michael.scott@linaro.org>
> Cc: Sebastian Reichel <sre@kernel.org>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
Applied to the togreg branch of iio.git which will shortly be
pushed out as testing for the autobuilders to play with it.

Thanks,

Jonathan
> ---
>  drivers/iio/adc/cpcap-adc.c | 31 ++++++++++++++++++++++++++++---
>  1 file changed, 28 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
> --- a/drivers/iio/adc/cpcap-adc.c
> +++ b/drivers/iio/adc/cpcap-adc.c
> @@ -875,6 +875,22 @@ static int cpcap_adc_init_request(struct cpcap_adc_request *req,
>  	return 0;
>  }
>  
> +static int cpcap_adc_read_st_die_temp(struct cpcap_adc *ddata,
> +				      int addr, int *val)
> +{
> +	int error;
> +
> +	error = regmap_read(ddata->reg, addr, val);
> +	if (error)
> +		return error;
> +
> +	*val -= 282;
> +	*val *= 114;
> +	*val += 25000;
> +
> +	return 0;
> +}
> +
>  static int cpcap_adc_read(struct iio_dev *indio_dev,
>  			  struct iio_chan_spec const *chan,
>  			  int *val, int *val2, long mask)
> @@ -906,9 +922,18 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>  		error = cpcap_adc_start_bank(ddata, &req);
>  		if (error)
>  			goto err_unlock;
> -		error = cpcap_adc_read_bank_scaled(ddata, &req);
> -		if (error)
> -			goto err_unlock;
> +		if ((ddata->vendor == CPCAP_VENDOR_ST) &&
> +		    (chan->channel == CPCAP_ADC_AD3)) {
> +			error = cpcap_adc_read_st_die_temp(ddata,
> +							   chan->address,
> +							   &req.result);
> +			if (error)
> +				goto err_unlock;
> +		} else {
> +			error = cpcap_adc_read_bank_scaled(ddata, &req);
> +			if (error)
> +				goto err_unlock;
> +		}
>  		error = cpcap_adc_stop_bank(ddata);
>  		if (error)
>  			goto err_unlock;


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3] iio: adc: cpcap: Remove hung interrupt quirk
  2017-05-23  0:51     ` Tony Lindgren
@ 2017-05-24 19:24         ` Jonathan Cameron
  -1 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-05-24 19:24 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott

On Mon, 22 May 2017 17:51:46 -0700
Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:

> This is no longer needed as the real problem was interrupt flags
> not getting passed properly from device tree to the cpcap-core.c
> mfd driver. This got fixed with commit ac89473213c6 ("mfd: cpcap:
> Fix interrupt to use level interrupt") So let's remove ADC
> interrupt specific the quirk.
> 
> Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
> Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Reviewed-by: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
Applied to the togreg branch of iio.git and initially pushed out
as testing for the autobuilders to play with it.

Thanks for cleaning this up.

Jonathan
> ---
>  drivers/iio/adc/cpcap-adc.c | 24 +-----------------------
>  1 file changed, 1 insertion(+), 23 deletions(-)
> 
> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
> --- a/drivers/iio/adc/cpcap-adc.c
> +++ b/drivers/iio/adc/cpcap-adc.c
> @@ -89,7 +89,7 @@
>  #define ST_ADC_CAL_BATTI_LOW_THRESHOLD	494
>  #define ST_ADC_CALIBRATE_DIFF_THRESHOLD	3
>  
> -#define CPCAP_ADC_MAX_RETRIES		5	/* Calibration and quirk */
> +#define CPCAP_ADC_MAX_RETRIES		5	/* Calibration */
>  
>  /**
>   * struct cpcap_adc_ato - timing settings for cpcap adc
> @@ -635,27 +635,6 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>  	}
>  }
>  
> -/*
> - * Occasionally the ADC does not seem to start and there will be no
> - * interrupt. Let's re-init interrupt to prevent the ADC from hanging
> - * for the next request. It is unclear why this happens, but the next
> - * request will usually work after doing this.
> - */
> -static void cpcap_adc_quirk_reset_lost_irq(struct cpcap_adc *ddata)
> -{
> -	int error;
> -
> -	dev_info(ddata->dev, "lost ADC irq, attempting to reinit\n");
> -	disable_irq(ddata->irq);
> -	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> -				   CPCAP_BIT_ADTRIG_DIS,
> -				   CPCAP_BIT_ADTRIG_DIS);
> -	if (error)
> -		dev_warn(ddata->dev, "%s reset failed: %i\n",
> -			 __func__, error);
> -	enable_irq(ddata->irq);
> -}
> -
>  static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>  				struct cpcap_adc_request *req)
>  {
> @@ -673,7 +652,6 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>  			return 0;
>  
>  		if (error == 0) {
> -			cpcap_adc_quirk_reset_lost_irq(ddata);
>  			error = -ETIMEDOUT;
>  			continue;
>  		}

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3] iio: adc: cpcap: Remove hung interrupt quirk
@ 2017-05-24 19:24         ` Jonathan Cameron
  0 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-05-24 19:24 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap, Marcel Partap, Michael Scott

On Mon, 22 May 2017 17:51:46 -0700
Tony Lindgren <tony@atomide.com> wrote:

> This is no longer needed as the real problem was interrupt flags
> not getting passed properly from device tree to the cpcap-core.c
> mfd driver. This got fixed with commit ac89473213c6 ("mfd: cpcap:
> Fix interrupt to use level interrupt") So let's remove ADC
> interrupt specific the quirk.
> 
> Cc: Marcel Partap <mpartap@gmx.net>
> Cc: Michael Scott <michael.scott@linaro.org>
> Reviewed-by: Sebastian Reichel <sre@kernel.org>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
Applied to the togreg branch of iio.git and initially pushed out
as testing for the autobuilders to play with it.

Thanks for cleaning this up.

Jonathan
> ---
>  drivers/iio/adc/cpcap-adc.c | 24 +-----------------------
>  1 file changed, 1 insertion(+), 23 deletions(-)
> 
> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
> --- a/drivers/iio/adc/cpcap-adc.c
> +++ b/drivers/iio/adc/cpcap-adc.c
> @@ -89,7 +89,7 @@
>  #define ST_ADC_CAL_BATTI_LOW_THRESHOLD	494
>  #define ST_ADC_CALIBRATE_DIFF_THRESHOLD	3
>  
> -#define CPCAP_ADC_MAX_RETRIES		5	/* Calibration and quirk */
> +#define CPCAP_ADC_MAX_RETRIES		5	/* Calibration */
>  
>  /**
>   * struct cpcap_adc_ato - timing settings for cpcap adc
> @@ -635,27 +635,6 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>  	}
>  }
>  
> -/*
> - * Occasionally the ADC does not seem to start and there will be no
> - * interrupt. Let's re-init interrupt to prevent the ADC from hanging
> - * for the next request. It is unclear why this happens, but the next
> - * request will usually work after doing this.
> - */
> -static void cpcap_adc_quirk_reset_lost_irq(struct cpcap_adc *ddata)
> -{
> -	int error;
> -
> -	dev_info(ddata->dev, "lost ADC irq, attempting to reinit\n");
> -	disable_irq(ddata->irq);
> -	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> -				   CPCAP_BIT_ADTRIG_DIS,
> -				   CPCAP_BIT_ADTRIG_DIS);
> -	if (error)
> -		dev_warn(ddata->dev, "%s reset failed: %i\n",
> -			 __func__, error);
> -	enable_irq(ddata->irq);
> -}
> -
>  static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>  				struct cpcap_adc_request *req)
>  {
> @@ -673,7 +652,6 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>  			return 0;
>  
>  		if (error == 0) {
> -			cpcap_adc_quirk_reset_lost_irq(ddata);
>  			error = -ETIMEDOUT;
>  			continue;
>  		}


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
  2017-05-24 19:18         ` Jonathan Cameron
@ 2017-06-07  6:22             ` Tony Lindgren
  -1 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-06-07  6:22 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

* Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> [170524 12:22]:
> On Mon, 22 May 2017 17:51:44 -0700
> Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> 
> > Looking at the register dumps from Android kernel on droid 4, I noticed
> > the values with the mainline kernel don't match. Let's fix this by
> > initializing the ADC registers to what Android does.
> > 
> > For getting correct values from the battery thermistor, we need to
> > toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
> > to get correct battery temperatures. And looks like we also need to
> > wait a little bit before reading the battery temperature as otherwise
> > the results are inaccurate.
> > 
> > Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
> > Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> Applied to the togreg branch of iio.git and will be shortly pushed
> out as testing for the autobuilders to play with it.

Not seeing these in your togreg brach or in next? The
branch I just checked is the one below, maybe I'm looking
at a wrong branch or something.

Regards,

Tony

https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git/log/?h=togreg

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
@ 2017-06-07  6:22             ` Tony Lindgren
  0 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-06-07  6:22 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap, Marcel Partap, Michael Scott,
	Sebastian Reichel

* Jonathan Cameron <jic23@kernel.org> [170524 12:22]:
> On Mon, 22 May 2017 17:51:44 -0700
> Tony Lindgren <tony@atomide.com> wrote:
> 
> > Looking at the register dumps from Android kernel on droid 4, I noticed
> > the values with the mainline kernel don't match. Let's fix this by
> > initializing the ADC registers to what Android does.
> > 
> > For getting correct values from the battery thermistor, we need to
> > toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
> > to get correct battery temperatures. And looks like we also need to
> > wait a little bit before reading the battery temperature as otherwise
> > the results are inaccurate.
> > 
> > Cc: Marcel Partap <mpartap@gmx.net>
> > Cc: Michael Scott <michael.scott@linaro.org>
> > Cc: Sebastian Reichel <sre@kernel.org>
> > Signed-off-by: Tony Lindgren <tony@atomide.com>
> Applied to the togreg branch of iio.git and will be shortly pushed
> out as testing for the autobuilders to play with it.

Not seeing these in your togreg brach or in next? The
branch I just checked is the one below, maybe I'm looking
at a wrong branch or something.

Regards,

Tony

https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git/log/?h=togreg

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
  2017-06-07  6:22             ` Tony Lindgren
@ 2017-06-11 14:12                 ` Jonathan Cameron
  -1 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-06-11 14:12 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

On Tue, 6 Jun 2017 23:22:00 -0700
Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:

> * Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> [170524 12:22]:
> > On Mon, 22 May 2017 17:51:44 -0700
> > Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> >   
> > > Looking at the register dumps from Android kernel on droid 4, I noticed
> > > the values with the mainline kernel don't match. Let's fix this by
> > > initializing the ADC registers to what Android does.
> > > 
> > > For getting correct values from the battery thermistor, we need to
> > > toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
> > > to get correct battery temperatures. And looks like we also need to
> > > wait a little bit before reading the battery temperature as otherwise
> > > the results are inaccurate.
> > > 
> > > Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
> > > Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > > Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > > Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>  
> > Applied to the togreg branch of iio.git and will be shortly pushed
> > out as testing for the autobuilders to play with it.  
> 
> Not seeing these in your togreg brach or in next? The
> branch I just checked is the one below, maybe I'm looking
> at a wrong branch or something.
I think I was being a muppet last weekend.  Forgot to actually
push out anything much.

Done now, though still as testing as obviously the autobuilders haven't
looked at it yet.
Sorry about that and thanks for point it out!

Jonathan
> 
> Regards,
> 
> Tony
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git/log/?h=togreg

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
@ 2017-06-11 14:12                 ` Jonathan Cameron
  0 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-06-11 14:12 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap, Marcel Partap, Michael Scott,
	Sebastian Reichel

On Tue, 6 Jun 2017 23:22:00 -0700
Tony Lindgren <tony@atomide.com> wrote:

> * Jonathan Cameron <jic23@kernel.org> [170524 12:22]:
> > On Mon, 22 May 2017 17:51:44 -0700
> > Tony Lindgren <tony@atomide.com> wrote:
> >   
> > > Looking at the register dumps from Android kernel on droid 4, I noticed
> > > the values with the mainline kernel don't match. Let's fix this by
> > > initializing the ADC registers to what Android does.
> > > 
> > > For getting correct values from the battery thermistor, we need to
> > > toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
> > > to get correct battery temperatures. And looks like we also need to
> > > wait a little bit before reading the battery temperature as otherwise
> > > the results are inaccurate.
> > > 
> > > Cc: Marcel Partap <mpartap@gmx.net>
> > > Cc: Michael Scott <michael.scott@linaro.org>
> > > Cc: Sebastian Reichel <sre@kernel.org>
> > > Signed-off-by: Tony Lindgren <tony@atomide.com>  
> > Applied to the togreg branch of iio.git and will be shortly pushed
> > out as testing for the autobuilders to play with it.  
> 
> Not seeing these in your togreg brach or in next? The
> branch I just checked is the one below, maybe I'm looking
> at a wrong branch or something.
I think I was being a muppet last weekend.  Forgot to actually
push out anything much.

Done now, though still as testing as obviously the autobuilders haven't
looked at it yet.
Sorry about that and thanks for point it out!

Jonathan
> 
> Regards,
> 
> Tony
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git/log/?h=togreg


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
  2017-05-20  5:52         ` Matt Ranostay
@ 2017-05-20 16:02             ` Tony Lindgren
  -1 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-20 16:02 UTC (permalink / raw)
  To: Matt Ranostay
  Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, open list:IIO SUBSYSTEM AND...,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

* Matt Ranostay <matt.ranostay-OWPKS81ov/FWk0Htik3J/w@public.gmane.org> [170519 22:55]:
> On Thu, May 18, 2017 at 8:40 PM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> >  enum cpcap_adc_channel {
> >         /* Bank0 channels */
> > -       CPCAP_ADC_AD0_BATTDETB, /* Battery detection */
> > +       CPCAP_ADC_AD0_BATTDETB, /* Battery temperature */
> 
> Since this doesn't mean battery detection anymore I'd recommend
> renaming to CPCAP_ADC_AD0_BATTEMP or similar.

OK I'll change it to just CPCAP_ADC_AD0 as it seems it's use has
changed across revisions or products.

Regards,

Tony

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
@ 2017-05-20 16:02             ` Tony Lindgren
  0 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-20 16:02 UTC (permalink / raw)
  To: Matt Ranostay
  Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, open list:IIO SUBSYSTEM AND...,
	linux-omap, Marcel Partap, Michael Scott, Sebastian Reichel

* Matt Ranostay <matt.ranostay@konsulko.com> [170519 22:55]:
> On Thu, May 18, 2017 at 8:40 PM, Tony Lindgren <tony@atomide.com> wrote:
> >  enum cpcap_adc_channel {
> >         /* Bank0 channels */
> > -       CPCAP_ADC_AD0_BATTDETB, /* Battery detection */
> > +       CPCAP_ADC_AD0_BATTDETB, /* Battery temperature */
> 
> Since this doesn't mean battery detection anymore I'd recommend
> renaming to CPCAP_ADC_AD0_BATTEMP or similar.

OK I'll change it to just CPCAP_ADC_AD0 as it seems it's use has
changed across revisions or products.

Regards,

Tony

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
  2017-05-20  5:52         ` Matt Ranostay
@ 2017-05-20 15:51             ` Jonathan Cameron
  -1 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-05-20 15:51 UTC (permalink / raw)
  To: Matt Ranostay, Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	open list:IIO SUBSYSTEM AND...,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

On 20/05/17 06:52, Matt Ranostay wrote:
> On Thu, May 18, 2017 at 8:40 PM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
>> Looking at the register dumps from Android kernel on droid 4, I noticed
>> the values with the mainline kernel don't match. Let's fix this by
>> initializing the ADC registers to what Android does.
>>
>> For getting correct values from the battery thermistor, we need to
>> toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
>> to get correct battery temperatures. And looks like we also need to
>> wait a little bit before reading the battery temperature as otherwise
>> the results are inaccurate.
>>
>> Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
>> Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
Other than Matt's valid point inline, looks sensible to me...

Jonathan
>> ---
>>   drivers/iio/adc/cpcap-adc.c | 50 +++++++++++++++++++++++++++++++++++++++++----
>>   1 file changed, 46 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
>> --- a/drivers/iio/adc/cpcap-adc.c
>> +++ b/drivers/iio/adc/cpcap-adc.c
>> @@ -52,6 +52,10 @@
>>   #define CPCAP_BIT_RAND0                        BIT(1)  /* Set with CAL_MODE */
>>   #define CPCAP_BIT_ADEN                 BIT(0)  /* Currently unused */
>>
>> +#define CPCAP_REG_ADCC1_DEFAULTS       (CPCAP_BIT_ADEN_AUTO_CLR | \
>> +                                        CPCAP_BIT_ADC_CLK_SEL0 |  \
>> +                                        CPCAP_BIT_RAND1)
>> +
>>   /* Register CPCAP_REG_ADCC2 bits */
>>   #define CPCAP_BIT_CAL_FACTOR_ENABLE    BIT(15) /* Currently unused */
>>   #define CPCAP_BIT_BATDETB_EN           BIT(14) /* Currently unused */
>> @@ -62,7 +66,7 @@
>>   #define CPCAP_BIT_ADC_PS_FACTOR0       BIT(9)
>>   #define CPCAP_BIT_AD4_SELECT           BIT(8)  /* Currently unused */
>>   #define CPCAP_BIT_ADC_BUSY             BIT(7)  /* Currently unused */
>> -#define CPCAP_BIT_THERMBIAS_EN         BIT(6)  /* Currently unused */
>> +#define CPCAP_BIT_THERMBIAS_EN         BIT(6)  /* Bias for AD0_BATTDETB */
>>   #define CPCAP_BIT_ADTRIG_DIS           BIT(5)  /* Disable interrupt */
>>   #define CPCAP_BIT_LIADC                        BIT(4)  /* Currently unused */
>>   #define CPCAP_BIT_TS_REFEN             BIT(3)  /* Currently unused */
>> @@ -70,6 +74,13 @@
>>   #define CPCAP_BIT_TS_M1                        BIT(1)  /* Currently unused */
>>   #define CPCAP_BIT_TS_M0                        BIT(0)  /* Currently unused */
>>
>> +#define CPCAP_REG_ADCC2_DEFAULTS       (CPCAP_BIT_AD4_SELECT | \
>> +                                        CPCAP_BIT_ADTRIG_DIS | \
>> +                                        CPCAP_BIT_ADTRIG_DIS | \
>> +                                        CPCAP_BIT_LIADC | \
>> +                                        CPCAP_BIT_TS_M2 | \
>> +                                        CPCAP_BIT_TS_M1)
>> +
>>   #define CPCAP_MAX_TEMP_LVL             27
>>   #define CPCAP_FOUR_POINT_TWO_ADC       801
>>   #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD        530
>> @@ -124,10 +135,10 @@ struct cpcap_adc {
>>    */
>>   enum cpcap_adc_channel {
>>          /* Bank0 channels */
>> -       CPCAP_ADC_AD0_BATTDETB, /* Battery detection */
>> +       CPCAP_ADC_AD0_BATTDETB, /* Battery temperature */
> 
> Since this doesn't mean battery detection anymore I'd recommend
> renaming to CPCAP_ADC_AD0_BATTEMP or similar.
> 
>>          CPCAP_ADC_BATTP,        /* Battery voltage */
>>          CPCAP_ADC_VBUS,         /* USB VBUS voltage */
>> -       CPCAP_ADC_AD3,          /* Battery temperature when charging */
>> +       CPCAP_ADC_AD3,          /* Die temperature when charging */
>>          CPCAP_ADC_BPLUS_AD4,    /* Another battery or system voltage */
>>          CPCAP_ADC_CHG_ISENSE,   /* Calibrated charge current */
>>          CPCAP_ADC_BATTI,        /* Calibrated system current */
>> @@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>>                  return;
>>
>>          switch (req->channel) {
>> +       case CPCAP_ADC_AD0_BATTDETB:
>> +               value2 |= CPCAP_BIT_THERMBIAS_EN;
>> +               error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>> +                                          CPCAP_BIT_THERMBIAS_EN,
>> +                                          value2);
>> +               if (error)
>> +                       return;
>> +               usleep_range(800, 1000);
>> +               break;
>>          case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
>>                  value1 |= CPCAP_BIT_AD_SEL1;
>>                  break;
>> @@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>>          error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>>                                     CPCAP_BIT_ATOX_PS_FACTOR |
>>                                     CPCAP_BIT_ADC_PS_FACTOR1 |
>> -                                  CPCAP_BIT_ADC_PS_FACTOR0,
>> +                                  CPCAP_BIT_ADC_PS_FACTOR0 |
>> +                                  CPCAP_BIT_THERMBIAS_EN,
>>                                     value2);
>>          if (error)
>>                  return;
>> @@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>>          return error;
>>   }
>>
>> +static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
>> +{
>> +       int error;
>> +
>> +       error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
>> +                                  0xffff,
>> +                                  CPCAP_REG_ADCC1_DEFAULTS);
>> +       if (error)
>> +               return error;
>> +
>> +       return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>> +                                 0xffff,
>> +                                 CPCAP_REG_ADCC2_DEFAULTS);
>> +}
>> +
>>   static void cpcap_adc_phase(struct cpcap_adc_request *req)
>>   {
>>          const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
>> @@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>>                  error = regmap_read(ddata->reg, chan->address, val);
>>                  if (error)
>>                          goto err_unlock;
>> +               error = cpcap_adc_stop_bank(ddata);
>> +               if (error)
>> +                       goto err_unlock;
>>                  mutex_unlock(&ddata->lock);
>>                  break;
>>          case IIO_CHAN_INFO_PROCESSED:
>> @@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>>                  error = cpcap_adc_read_bank_scaled(ddata, &req);
>>                  if (error)
>>                          goto err_unlock;
>> +               error = cpcap_adc_stop_bank(ddata);
>> +               if (error)
>> +                       goto err_unlock;
>>                  mutex_unlock(&ddata->lock);
>>                  *val = req.result;
>>                  break;
>> --
>> 2.13.0
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
@ 2017-05-20 15:51             ` Jonathan Cameron
  0 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2017-05-20 15:51 UTC (permalink / raw)
  To: Matt Ranostay, Tony Lindgren
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	open list:IIO SUBSYSTEM AND...,
	linux-omap, Marcel Partap, Michael Scott, Sebastian Reichel

On 20/05/17 06:52, Matt Ranostay wrote:
> On Thu, May 18, 2017 at 8:40 PM, Tony Lindgren <tony@atomide.com> wrote:
>> Looking at the register dumps from Android kernel on droid 4, I noticed
>> the values with the mainline kernel don't match. Let's fix this by
>> initializing the ADC registers to what Android does.
>>
>> For getting correct values from the battery thermistor, we need to
>> toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
>> to get correct battery temperatures. And looks like we also need to
>> wait a little bit before reading the battery temperature as otherwise
>> the results are inaccurate.
>>
>> Cc: Marcel Partap <mpartap@gmx.net>
>> Cc: Michael Scott <michael.scott@linaro.org>
>> Cc: Sebastian Reichel <sre@kernel.org>
>> Signed-off-by: Tony Lindgren <tony@atomide.com>
Other than Matt's valid point inline, looks sensible to me...

Jonathan
>> ---
>>   drivers/iio/adc/cpcap-adc.c | 50 +++++++++++++++++++++++++++++++++++++++++----
>>   1 file changed, 46 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
>> --- a/drivers/iio/adc/cpcap-adc.c
>> +++ b/drivers/iio/adc/cpcap-adc.c
>> @@ -52,6 +52,10 @@
>>   #define CPCAP_BIT_RAND0                        BIT(1)  /* Set with CAL_MODE */
>>   #define CPCAP_BIT_ADEN                 BIT(0)  /* Currently unused */
>>
>> +#define CPCAP_REG_ADCC1_DEFAULTS       (CPCAP_BIT_ADEN_AUTO_CLR | \
>> +                                        CPCAP_BIT_ADC_CLK_SEL0 |  \
>> +                                        CPCAP_BIT_RAND1)
>> +
>>   /* Register CPCAP_REG_ADCC2 bits */
>>   #define CPCAP_BIT_CAL_FACTOR_ENABLE    BIT(15) /* Currently unused */
>>   #define CPCAP_BIT_BATDETB_EN           BIT(14) /* Currently unused */
>> @@ -62,7 +66,7 @@
>>   #define CPCAP_BIT_ADC_PS_FACTOR0       BIT(9)
>>   #define CPCAP_BIT_AD4_SELECT           BIT(8)  /* Currently unused */
>>   #define CPCAP_BIT_ADC_BUSY             BIT(7)  /* Currently unused */
>> -#define CPCAP_BIT_THERMBIAS_EN         BIT(6)  /* Currently unused */
>> +#define CPCAP_BIT_THERMBIAS_EN         BIT(6)  /* Bias for AD0_BATTDETB */
>>   #define CPCAP_BIT_ADTRIG_DIS           BIT(5)  /* Disable interrupt */
>>   #define CPCAP_BIT_LIADC                        BIT(4)  /* Currently unused */
>>   #define CPCAP_BIT_TS_REFEN             BIT(3)  /* Currently unused */
>> @@ -70,6 +74,13 @@
>>   #define CPCAP_BIT_TS_M1                        BIT(1)  /* Currently unused */
>>   #define CPCAP_BIT_TS_M0                        BIT(0)  /* Currently unused */
>>
>> +#define CPCAP_REG_ADCC2_DEFAULTS       (CPCAP_BIT_AD4_SELECT | \
>> +                                        CPCAP_BIT_ADTRIG_DIS | \
>> +                                        CPCAP_BIT_ADTRIG_DIS | \
>> +                                        CPCAP_BIT_LIADC | \
>> +                                        CPCAP_BIT_TS_M2 | \
>> +                                        CPCAP_BIT_TS_M1)
>> +
>>   #define CPCAP_MAX_TEMP_LVL             27
>>   #define CPCAP_FOUR_POINT_TWO_ADC       801
>>   #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD        530
>> @@ -124,10 +135,10 @@ struct cpcap_adc {
>>    */
>>   enum cpcap_adc_channel {
>>          /* Bank0 channels */
>> -       CPCAP_ADC_AD0_BATTDETB, /* Battery detection */
>> +       CPCAP_ADC_AD0_BATTDETB, /* Battery temperature */
> 
> Since this doesn't mean battery detection anymore I'd recommend
> renaming to CPCAP_ADC_AD0_BATTEMP or similar.
> 
>>          CPCAP_ADC_BATTP,        /* Battery voltage */
>>          CPCAP_ADC_VBUS,         /* USB VBUS voltage */
>> -       CPCAP_ADC_AD3,          /* Battery temperature when charging */
>> +       CPCAP_ADC_AD3,          /* Die temperature when charging */
>>          CPCAP_ADC_BPLUS_AD4,    /* Another battery or system voltage */
>>          CPCAP_ADC_CHG_ISENSE,   /* Calibrated charge current */
>>          CPCAP_ADC_BATTI,        /* Calibrated system current */
>> @@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>>                  return;
>>
>>          switch (req->channel) {
>> +       case CPCAP_ADC_AD0_BATTDETB:
>> +               value2 |= CPCAP_BIT_THERMBIAS_EN;
>> +               error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>> +                                          CPCAP_BIT_THERMBIAS_EN,
>> +                                          value2);
>> +               if (error)
>> +                       return;
>> +               usleep_range(800, 1000);
>> +               break;
>>          case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
>>                  value1 |= CPCAP_BIT_AD_SEL1;
>>                  break;
>> @@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>>          error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>>                                     CPCAP_BIT_ATOX_PS_FACTOR |
>>                                     CPCAP_BIT_ADC_PS_FACTOR1 |
>> -                                  CPCAP_BIT_ADC_PS_FACTOR0,
>> +                                  CPCAP_BIT_ADC_PS_FACTOR0 |
>> +                                  CPCAP_BIT_THERMBIAS_EN,
>>                                     value2);
>>          if (error)
>>                  return;
>> @@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>>          return error;
>>   }
>>
>> +static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
>> +{
>> +       int error;
>> +
>> +       error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
>> +                                  0xffff,
>> +                                  CPCAP_REG_ADCC1_DEFAULTS);
>> +       if (error)
>> +               return error;
>> +
>> +       return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>> +                                 0xffff,
>> +                                 CPCAP_REG_ADCC2_DEFAULTS);
>> +}
>> +
>>   static void cpcap_adc_phase(struct cpcap_adc_request *req)
>>   {
>>          const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
>> @@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>>                  error = regmap_read(ddata->reg, chan->address, val);
>>                  if (error)
>>                          goto err_unlock;
>> +               error = cpcap_adc_stop_bank(ddata);
>> +               if (error)
>> +                       goto err_unlock;
>>                  mutex_unlock(&ddata->lock);
>>                  break;
>>          case IIO_CHAN_INFO_PROCESSED:
>> @@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>>                  error = cpcap_adc_read_bank_scaled(ddata, &req);
>>                  if (error)
>>                          goto err_unlock;
>> +               error = cpcap_adc_stop_bank(ddata);
>> +               if (error)
>> +                       goto err_unlock;
>>                  mutex_unlock(&ddata->lock);
>>                  *val = req.result;
>>                  break;
>> --
>> 2.13.0
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
  2017-05-19  3:40     ` Tony Lindgren
@ 2017-05-20  5:52         ` Matt Ranostay
  -1 siblings, 0 replies; 26+ messages in thread
From: Matt Ranostay @ 2017-05-20  5:52 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, open list:IIO SUBSYSTEM AND...,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

On Thu, May 18, 2017 at 8:40 PM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> Looking at the register dumps from Android kernel on droid 4, I noticed
> the values with the mainline kernel don't match. Let's fix this by
> initializing the ADC registers to what Android does.
>
> For getting correct values from the battery thermistor, we need to
> toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
> to get correct battery temperatures. And looks like we also need to
> wait a little bit before reading the battery temperature as otherwise
> the results are inaccurate.
>
> Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
> Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/iio/adc/cpcap-adc.c | 50 +++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 46 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
> --- a/drivers/iio/adc/cpcap-adc.c
> +++ b/drivers/iio/adc/cpcap-adc.c
> @@ -52,6 +52,10 @@
>  #define CPCAP_BIT_RAND0                        BIT(1)  /* Set with CAL_MODE */
>  #define CPCAP_BIT_ADEN                 BIT(0)  /* Currently unused */
>
> +#define CPCAP_REG_ADCC1_DEFAULTS       (CPCAP_BIT_ADEN_AUTO_CLR | \
> +                                        CPCAP_BIT_ADC_CLK_SEL0 |  \
> +                                        CPCAP_BIT_RAND1)
> +
>  /* Register CPCAP_REG_ADCC2 bits */
>  #define CPCAP_BIT_CAL_FACTOR_ENABLE    BIT(15) /* Currently unused */
>  #define CPCAP_BIT_BATDETB_EN           BIT(14) /* Currently unused */
> @@ -62,7 +66,7 @@
>  #define CPCAP_BIT_ADC_PS_FACTOR0       BIT(9)
>  #define CPCAP_BIT_AD4_SELECT           BIT(8)  /* Currently unused */
>  #define CPCAP_BIT_ADC_BUSY             BIT(7)  /* Currently unused */
> -#define CPCAP_BIT_THERMBIAS_EN         BIT(6)  /* Currently unused */
> +#define CPCAP_BIT_THERMBIAS_EN         BIT(6)  /* Bias for AD0_BATTDETB */
>  #define CPCAP_BIT_ADTRIG_DIS           BIT(5)  /* Disable interrupt */
>  #define CPCAP_BIT_LIADC                        BIT(4)  /* Currently unused */
>  #define CPCAP_BIT_TS_REFEN             BIT(3)  /* Currently unused */
> @@ -70,6 +74,13 @@
>  #define CPCAP_BIT_TS_M1                        BIT(1)  /* Currently unused */
>  #define CPCAP_BIT_TS_M0                        BIT(0)  /* Currently unused */
>
> +#define CPCAP_REG_ADCC2_DEFAULTS       (CPCAP_BIT_AD4_SELECT | \
> +                                        CPCAP_BIT_ADTRIG_DIS | \
> +                                        CPCAP_BIT_ADTRIG_DIS | \
> +                                        CPCAP_BIT_LIADC | \
> +                                        CPCAP_BIT_TS_M2 | \
> +                                        CPCAP_BIT_TS_M1)
> +
>  #define CPCAP_MAX_TEMP_LVL             27
>  #define CPCAP_FOUR_POINT_TWO_ADC       801
>  #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD        530
> @@ -124,10 +135,10 @@ struct cpcap_adc {
>   */
>  enum cpcap_adc_channel {
>         /* Bank0 channels */
> -       CPCAP_ADC_AD0_BATTDETB, /* Battery detection */
> +       CPCAP_ADC_AD0_BATTDETB, /* Battery temperature */

Since this doesn't mean battery detection anymore I'd recommend
renaming to CPCAP_ADC_AD0_BATTEMP or similar.

>         CPCAP_ADC_BATTP,        /* Battery voltage */
>         CPCAP_ADC_VBUS,         /* USB VBUS voltage */
> -       CPCAP_ADC_AD3,          /* Battery temperature when charging */
> +       CPCAP_ADC_AD3,          /* Die temperature when charging */
>         CPCAP_ADC_BPLUS_AD4,    /* Another battery or system voltage */
>         CPCAP_ADC_CHG_ISENSE,   /* Calibrated charge current */
>         CPCAP_ADC_BATTI,        /* Calibrated system current */
> @@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>                 return;
>
>         switch (req->channel) {
> +       case CPCAP_ADC_AD0_BATTDETB:
> +               value2 |= CPCAP_BIT_THERMBIAS_EN;
> +               error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> +                                          CPCAP_BIT_THERMBIAS_EN,
> +                                          value2);
> +               if (error)
> +                       return;
> +               usleep_range(800, 1000);
> +               break;
>         case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
>                 value1 |= CPCAP_BIT_AD_SEL1;
>                 break;
> @@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>         error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>                                    CPCAP_BIT_ATOX_PS_FACTOR |
>                                    CPCAP_BIT_ADC_PS_FACTOR1 |
> -                                  CPCAP_BIT_ADC_PS_FACTOR0,
> +                                  CPCAP_BIT_ADC_PS_FACTOR0 |
> +                                  CPCAP_BIT_THERMBIAS_EN,
>                                    value2);
>         if (error)
>                 return;
> @@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>         return error;
>  }
>
> +static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
> +{
> +       int error;
> +
> +       error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
> +                                  0xffff,
> +                                  CPCAP_REG_ADCC1_DEFAULTS);
> +       if (error)
> +               return error;
> +
> +       return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> +                                 0xffff,
> +                                 CPCAP_REG_ADCC2_DEFAULTS);
> +}
> +
>  static void cpcap_adc_phase(struct cpcap_adc_request *req)
>  {
>         const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
> @@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>                 error = regmap_read(ddata->reg, chan->address, val);
>                 if (error)
>                         goto err_unlock;
> +               error = cpcap_adc_stop_bank(ddata);
> +               if (error)
> +                       goto err_unlock;
>                 mutex_unlock(&ddata->lock);
>                 break;
>         case IIO_CHAN_INFO_PROCESSED:
> @@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>                 error = cpcap_adc_read_bank_scaled(ddata, &req);
>                 if (error)
>                         goto err_unlock;
> +               error = cpcap_adc_stop_bank(ddata);
> +               if (error)
> +                       goto err_unlock;
>                 mutex_unlock(&ddata->lock);
>                 *val = req.result;
>                 break;
> --
> 2.13.0
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
@ 2017-05-20  5:52         ` Matt Ranostay
  0 siblings, 0 replies; 26+ messages in thread
From: Matt Ranostay @ 2017-05-20  5:52 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, open list:IIO SUBSYSTEM AND...,
	linux-omap, Marcel Partap, Michael Scott, Sebastian Reichel

On Thu, May 18, 2017 at 8:40 PM, Tony Lindgren <tony@atomide.com> wrote:
> Looking at the register dumps from Android kernel on droid 4, I noticed
> the values with the mainline kernel don't match. Let's fix this by
> initializing the ADC registers to what Android does.
>
> For getting correct values from the battery thermistor, we need to
> toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
> to get correct battery temperatures. And looks like we also need to
> wait a little bit before reading the battery temperature as otherwise
> the results are inaccurate.
>
> Cc: Marcel Partap <mpartap@gmx.net>
> Cc: Michael Scott <michael.scott@linaro.org>
> Cc: Sebastian Reichel <sre@kernel.org>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> ---
>  drivers/iio/adc/cpcap-adc.c | 50 +++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 46 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
> --- a/drivers/iio/adc/cpcap-adc.c
> +++ b/drivers/iio/adc/cpcap-adc.c
> @@ -52,6 +52,10 @@
>  #define CPCAP_BIT_RAND0                        BIT(1)  /* Set with CAL_MODE */
>  #define CPCAP_BIT_ADEN                 BIT(0)  /* Currently unused */
>
> +#define CPCAP_REG_ADCC1_DEFAULTS       (CPCAP_BIT_ADEN_AUTO_CLR | \
> +                                        CPCAP_BIT_ADC_CLK_SEL0 |  \
> +                                        CPCAP_BIT_RAND1)
> +
>  /* Register CPCAP_REG_ADCC2 bits */
>  #define CPCAP_BIT_CAL_FACTOR_ENABLE    BIT(15) /* Currently unused */
>  #define CPCAP_BIT_BATDETB_EN           BIT(14) /* Currently unused */
> @@ -62,7 +66,7 @@
>  #define CPCAP_BIT_ADC_PS_FACTOR0       BIT(9)
>  #define CPCAP_BIT_AD4_SELECT           BIT(8)  /* Currently unused */
>  #define CPCAP_BIT_ADC_BUSY             BIT(7)  /* Currently unused */
> -#define CPCAP_BIT_THERMBIAS_EN         BIT(6)  /* Currently unused */
> +#define CPCAP_BIT_THERMBIAS_EN         BIT(6)  /* Bias for AD0_BATTDETB */
>  #define CPCAP_BIT_ADTRIG_DIS           BIT(5)  /* Disable interrupt */
>  #define CPCAP_BIT_LIADC                        BIT(4)  /* Currently unused */
>  #define CPCAP_BIT_TS_REFEN             BIT(3)  /* Currently unused */
> @@ -70,6 +74,13 @@
>  #define CPCAP_BIT_TS_M1                        BIT(1)  /* Currently unused */
>  #define CPCAP_BIT_TS_M0                        BIT(0)  /* Currently unused */
>
> +#define CPCAP_REG_ADCC2_DEFAULTS       (CPCAP_BIT_AD4_SELECT | \
> +                                        CPCAP_BIT_ADTRIG_DIS | \
> +                                        CPCAP_BIT_ADTRIG_DIS | \
> +                                        CPCAP_BIT_LIADC | \
> +                                        CPCAP_BIT_TS_M2 | \
> +                                        CPCAP_BIT_TS_M1)
> +
>  #define CPCAP_MAX_TEMP_LVL             27
>  #define CPCAP_FOUR_POINT_TWO_ADC       801
>  #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD        530
> @@ -124,10 +135,10 @@ struct cpcap_adc {
>   */
>  enum cpcap_adc_channel {
>         /* Bank0 channels */
> -       CPCAP_ADC_AD0_BATTDETB, /* Battery detection */
> +       CPCAP_ADC_AD0_BATTDETB, /* Battery temperature */

Since this doesn't mean battery detection anymore I'd recommend
renaming to CPCAP_ADC_AD0_BATTEMP or similar.

>         CPCAP_ADC_BATTP,        /* Battery voltage */
>         CPCAP_ADC_VBUS,         /* USB VBUS voltage */
> -       CPCAP_ADC_AD3,          /* Battery temperature when charging */
> +       CPCAP_ADC_AD3,          /* Die temperature when charging */
>         CPCAP_ADC_BPLUS_AD4,    /* Another battery or system voltage */
>         CPCAP_ADC_CHG_ISENSE,   /* Calibrated charge current */
>         CPCAP_ADC_BATTI,        /* Calibrated system current */
> @@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>                 return;
>
>         switch (req->channel) {
> +       case CPCAP_ADC_AD0_BATTDETB:
> +               value2 |= CPCAP_BIT_THERMBIAS_EN;
> +               error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> +                                          CPCAP_BIT_THERMBIAS_EN,
> +                                          value2);
> +               if (error)
> +                       return;
> +               usleep_range(800, 1000);
> +               break;
>         case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
>                 value1 |= CPCAP_BIT_AD_SEL1;
>                 break;
> @@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
>         error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
>                                    CPCAP_BIT_ATOX_PS_FACTOR |
>                                    CPCAP_BIT_ADC_PS_FACTOR1 |
> -                                  CPCAP_BIT_ADC_PS_FACTOR0,
> +                                  CPCAP_BIT_ADC_PS_FACTOR0 |
> +                                  CPCAP_BIT_THERMBIAS_EN,
>                                    value2);
>         if (error)
>                 return;
> @@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
>         return error;
>  }
>
> +static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
> +{
> +       int error;
> +
> +       error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
> +                                  0xffff,
> +                                  CPCAP_REG_ADCC1_DEFAULTS);
> +       if (error)
> +               return error;
> +
> +       return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
> +                                 0xffff,
> +                                 CPCAP_REG_ADCC2_DEFAULTS);
> +}
> +
>  static void cpcap_adc_phase(struct cpcap_adc_request *req)
>  {
>         const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
> @@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>                 error = regmap_read(ddata->reg, chan->address, val);
>                 if (error)
>                         goto err_unlock;
> +               error = cpcap_adc_stop_bank(ddata);
> +               if (error)
> +                       goto err_unlock;
>                 mutex_unlock(&ddata->lock);
>                 break;
>         case IIO_CHAN_INFO_PROCESSED:
> @@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
>                 error = cpcap_adc_read_bank_scaled(ddata, &req);
>                 if (error)
>                         goto err_unlock;
> +               error = cpcap_adc_stop_bank(ddata);
> +               if (error)
> +                       goto err_unlock;
>                 mutex_unlock(&ddata->lock);
>                 *val = req.result;
>                 break;
> --
> 2.13.0
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
  2017-05-19  3:40 [PATCH 0/3] Few non-critical cpcap ADC fixes Tony Lindgren
@ 2017-05-19  3:40     ` Tony Lindgren
  0 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-19  3:40 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott,
	Sebastian Reichel

Looking at the register dumps from Android kernel on droid 4, I noticed
the values with the mainline kernel don't match. Let's fix this by
initializing the ADC registers to what Android does.

For getting correct values from the battery thermistor, we need to
toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
to get correct battery temperatures. And looks like we also need to
wait a little bit before reading the battery temperature as otherwise
the results are inaccurate.

Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/iio/adc/cpcap-adc.c | 50 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -52,6 +52,10 @@
 #define CPCAP_BIT_RAND0			BIT(1)	/* Set with CAL_MODE */
 #define CPCAP_BIT_ADEN			BIT(0)	/* Currently unused */
 
+#define CPCAP_REG_ADCC1_DEFAULTS	(CPCAP_BIT_ADEN_AUTO_CLR | \
+					 CPCAP_BIT_ADC_CLK_SEL0 |  \
+					 CPCAP_BIT_RAND1)
+
 /* Register CPCAP_REG_ADCC2 bits */
 #define CPCAP_BIT_CAL_FACTOR_ENABLE	BIT(15)	/* Currently unused */
 #define CPCAP_BIT_BATDETB_EN		BIT(14)	/* Currently unused */
@@ -62,7 +66,7 @@
 #define CPCAP_BIT_ADC_PS_FACTOR0	BIT(9)
 #define CPCAP_BIT_AD4_SELECT		BIT(8)	/* Currently unused */
 #define CPCAP_BIT_ADC_BUSY		BIT(7)	/* Currently unused */
-#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Currently unused */
+#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Bias for AD0_BATTDETB */
 #define CPCAP_BIT_ADTRIG_DIS		BIT(5)	/* Disable interrupt */
 #define CPCAP_BIT_LIADC			BIT(4)	/* Currently unused */
 #define CPCAP_BIT_TS_REFEN		BIT(3)	/* Currently unused */
@@ -70,6 +74,13 @@
 #define CPCAP_BIT_TS_M1			BIT(1)	/* Currently unused */
 #define CPCAP_BIT_TS_M0			BIT(0)	/* Currently unused */
 
+#define CPCAP_REG_ADCC2_DEFAULTS	(CPCAP_BIT_AD4_SELECT | \
+					 CPCAP_BIT_ADTRIG_DIS | \
+					 CPCAP_BIT_ADTRIG_DIS | \
+					 CPCAP_BIT_LIADC | \
+					 CPCAP_BIT_TS_M2 | \
+					 CPCAP_BIT_TS_M1)
+
 #define CPCAP_MAX_TEMP_LVL		27
 #define CPCAP_FOUR_POINT_TWO_ADC	801
 #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD	530
@@ -124,10 +135,10 @@ struct cpcap_adc {
  */
 enum cpcap_adc_channel {
 	/* Bank0 channels */
-	CPCAP_ADC_AD0_BATTDETB,	/* Battery detection */
+	CPCAP_ADC_AD0_BATTDETB,	/* Battery temperature */
 	CPCAP_ADC_BATTP,	/* Battery voltage */
 	CPCAP_ADC_VBUS,		/* USB VBUS voltage */
-	CPCAP_ADC_AD3,		/* Battery temperature when charging */
+	CPCAP_ADC_AD3,		/* Die temperature when charging */
 	CPCAP_ADC_BPLUS_AD4,	/* Another battery or system voltage */
 	CPCAP_ADC_CHG_ISENSE,	/* Calibrated charge current */
 	CPCAP_ADC_BATTI,	/* Calibrated system current */
@@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 		return;
 
 	switch (req->channel) {
+	case CPCAP_ADC_AD0_BATTDETB:
+		value2 |= CPCAP_BIT_THERMBIAS_EN;
+		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
+					   CPCAP_BIT_THERMBIAS_EN,
+					   value2);
+		if (error)
+			return;
+		usleep_range(800, 1000);
+		break;
 	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
 		value1 |= CPCAP_BIT_AD_SEL1;
 		break;
@@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
 				   CPCAP_BIT_ATOX_PS_FACTOR |
 				   CPCAP_BIT_ADC_PS_FACTOR1 |
-				   CPCAP_BIT_ADC_PS_FACTOR0,
+				   CPCAP_BIT_ADC_PS_FACTOR0 |
+				   CPCAP_BIT_THERMBIAS_EN,
 				   value2);
 	if (error)
 		return;
@@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
 	return error;
 }
 
+static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
+{
+	int error;
+
+	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
+				   0xffff,
+				   CPCAP_REG_ADCC1_DEFAULTS);
+	if (error)
+		return error;
+
+	return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
+				  0xffff,
+				  CPCAP_REG_ADCC2_DEFAULTS);
+}
+
 static void cpcap_adc_phase(struct cpcap_adc_request *req)
 {
 	const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
@@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = regmap_read(ddata->reg, chan->address, val);
 		if (error)
 			goto err_unlock;
+		error = cpcap_adc_stop_bank(ddata);
+		if (error)
+			goto err_unlock;
 		mutex_unlock(&ddata->lock);
 		break;
 	case IIO_CHAN_INFO_PROCESSED:
@@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = cpcap_adc_read_bank_scaled(ddata, &req);
 		if (error)
 			goto err_unlock;
+		error = cpcap_adc_stop_bank(ddata);
+		if (error)
+			goto err_unlock;
 		mutex_unlock(&ddata->lock);
 		*val = req.result;
 		break;
-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature
@ 2017-05-19  3:40     ` Tony Lindgren
  0 siblings, 0 replies; 26+ messages in thread
From: Tony Lindgren @ 2017-05-19  3:40 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-iio, linux-omap, Marcel Partap, Michael Scott,
	Sebastian Reichel

Looking at the register dumps from Android kernel on droid 4, I noticed
the values with the mainline kernel don't match. Let's fix this by
initializing the ADC registers to what Android does.

For getting correct values from the battery thermistor, we need to
toggle the CPCAP_BIT_THERMBIAS_EN when measuring battery temperature
to get correct battery temperatures. And looks like we also need to
wait a little bit before reading the battery temperature as otherwise
the results are inaccurate.

Cc: Marcel Partap <mpartap@gmx.net>
Cc: Michael Scott <michael.scott@linaro.org>
Cc: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/iio/adc/cpcap-adc.c | 50 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -52,6 +52,10 @@
 #define CPCAP_BIT_RAND0			BIT(1)	/* Set with CAL_MODE */
 #define CPCAP_BIT_ADEN			BIT(0)	/* Currently unused */
 
+#define CPCAP_REG_ADCC1_DEFAULTS	(CPCAP_BIT_ADEN_AUTO_CLR | \
+					 CPCAP_BIT_ADC_CLK_SEL0 |  \
+					 CPCAP_BIT_RAND1)
+
 /* Register CPCAP_REG_ADCC2 bits */
 #define CPCAP_BIT_CAL_FACTOR_ENABLE	BIT(15)	/* Currently unused */
 #define CPCAP_BIT_BATDETB_EN		BIT(14)	/* Currently unused */
@@ -62,7 +66,7 @@
 #define CPCAP_BIT_ADC_PS_FACTOR0	BIT(9)
 #define CPCAP_BIT_AD4_SELECT		BIT(8)	/* Currently unused */
 #define CPCAP_BIT_ADC_BUSY		BIT(7)	/* Currently unused */
-#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Currently unused */
+#define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Bias for AD0_BATTDETB */
 #define CPCAP_BIT_ADTRIG_DIS		BIT(5)	/* Disable interrupt */
 #define CPCAP_BIT_LIADC			BIT(4)	/* Currently unused */
 #define CPCAP_BIT_TS_REFEN		BIT(3)	/* Currently unused */
@@ -70,6 +74,13 @@
 #define CPCAP_BIT_TS_M1			BIT(1)	/* Currently unused */
 #define CPCAP_BIT_TS_M0			BIT(0)	/* Currently unused */
 
+#define CPCAP_REG_ADCC2_DEFAULTS	(CPCAP_BIT_AD4_SELECT | \
+					 CPCAP_BIT_ADTRIG_DIS | \
+					 CPCAP_BIT_ADTRIG_DIS | \
+					 CPCAP_BIT_LIADC | \
+					 CPCAP_BIT_TS_M2 | \
+					 CPCAP_BIT_TS_M1)
+
 #define CPCAP_MAX_TEMP_LVL		27
 #define CPCAP_FOUR_POINT_TWO_ADC	801
 #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD	530
@@ -124,10 +135,10 @@ struct cpcap_adc {
  */
 enum cpcap_adc_channel {
 	/* Bank0 channels */
-	CPCAP_ADC_AD0_BATTDETB,	/* Battery detection */
+	CPCAP_ADC_AD0_BATTDETB,	/* Battery temperature */
 	CPCAP_ADC_BATTP,	/* Battery voltage */
 	CPCAP_ADC_VBUS,		/* USB VBUS voltage */
-	CPCAP_ADC_AD3,		/* Battery temperature when charging */
+	CPCAP_ADC_AD3,		/* Die temperature when charging */
 	CPCAP_ADC_BPLUS_AD4,	/* Another battery or system voltage */
 	CPCAP_ADC_CHG_ISENSE,	/* Calibrated charge current */
 	CPCAP_ADC_BATTI,	/* Calibrated system current */
@@ -541,6 +552,15 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 		return;
 
 	switch (req->channel) {
+	case CPCAP_ADC_AD0_BATTDETB:
+		value2 |= CPCAP_BIT_THERMBIAS_EN;
+		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
+					   CPCAP_BIT_THERMBIAS_EN,
+					   value2);
+		if (error)
+			return;
+		usleep_range(800, 1000);
+		break;
 	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
 		value1 |= CPCAP_BIT_AD_SEL1;
 		break;
@@ -583,7 +603,8 @@ static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
 				   CPCAP_BIT_ATOX_PS_FACTOR |
 				   CPCAP_BIT_ADC_PS_FACTOR1 |
-				   CPCAP_BIT_ADC_PS_FACTOR0,
+				   CPCAP_BIT_ADC_PS_FACTOR0 |
+				   CPCAP_BIT_THERMBIAS_EN,
 				   value2);
 	if (error)
 		return;
@@ -664,6 +685,21 @@ static int cpcap_adc_start_bank(struct cpcap_adc *ddata,
 	return error;
 }
 
+static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
+{
+	int error;
+
+	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
+				   0xffff,
+				   CPCAP_REG_ADCC1_DEFAULTS);
+	if (error)
+		return error;
+
+	return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
+				  0xffff,
+				  CPCAP_REG_ADCC2_DEFAULTS);
+}
+
 static void cpcap_adc_phase(struct cpcap_adc_request *req)
 {
 	const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
@@ -860,6 +896,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = regmap_read(ddata->reg, chan->address, val);
 		if (error)
 			goto err_unlock;
+		error = cpcap_adc_stop_bank(ddata);
+		if (error)
+			goto err_unlock;
 		mutex_unlock(&ddata->lock);
 		break;
 	case IIO_CHAN_INFO_PROCESSED:
@@ -870,6 +909,9 @@ static int cpcap_adc_read(struct iio_dev *indio_dev,
 		error = cpcap_adc_read_bank_scaled(ddata, &req);
 		if (error)
 			goto err_unlock;
+		error = cpcap_adc_stop_bank(ddata);
+		if (error)
+			goto err_unlock;
 		mutex_unlock(&ddata->lock);
 		*val = req.result;
 		break;
-- 
2.13.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2017-06-11 14:12 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-23  0:51 [PATCHv2 0/3] Few non-critical cpcap ADC fixes Tony Lindgren
2017-05-23  0:51 ` Tony Lindgren
     [not found] ` <20170523005146.726-1-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2017-05-23  0:51   ` [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature Tony Lindgren
2017-05-23  0:51     ` Tony Lindgren
     [not found]     ` <20170523005146.726-2-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2017-05-24 19:18       ` Jonathan Cameron
2017-05-24 19:18         ` Jonathan Cameron
     [not found]         ` <20170524201831.3504c42d-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-06-07  6:22           ` Tony Lindgren
2017-06-07  6:22             ` Tony Lindgren
     [not found]             ` <20170607062200.GD3730-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2017-06-11 14:12               ` Jonathan Cameron
2017-06-11 14:12                 ` Jonathan Cameron
2017-05-23  0:51   ` [PATCH 2/3] iio: adc: cpcap: Fix die temperature Tony Lindgren
2017-05-23  0:51     ` Tony Lindgren
     [not found]     ` <20170523005146.726-3-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2017-05-24 19:19       ` Jonathan Cameron
2017-05-24 19:19         ` Jonathan Cameron
2017-05-23  0:51   ` [PATCH 3/3] iio: adc: cpcap: Remove hung interrupt quirk Tony Lindgren
2017-05-23  0:51     ` Tony Lindgren
     [not found]     ` <20170523005146.726-4-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2017-05-24 19:24       ` Jonathan Cameron
2017-05-24 19:24         ` Jonathan Cameron
  -- strict thread matches above, loose matches on Subject: below --
2017-05-19  3:40 [PATCH 0/3] Few non-critical cpcap ADC fixes Tony Lindgren
     [not found] ` <20170519034035.16795-1-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2017-05-19  3:40   ` [PATCH 1/3] iio: adc: cpcap: Fix default register values and battery temperature Tony Lindgren
2017-05-19  3:40     ` Tony Lindgren
     [not found]     ` <20170519034035.16795-2-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2017-05-20  5:52       ` Matt Ranostay
2017-05-20  5:52         ` Matt Ranostay
     [not found]         ` <CAJCx=gm7t=2nuHiLCXUohLXR62gZ-ux62tWyEQXyNXMrhTutKg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-05-20 15:51           ` Jonathan Cameron
2017-05-20 15:51             ` Jonathan Cameron
2017-05-20 16:02           ` Tony Lindgren
2017-05-20 16:02             ` Tony Lindgren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.