All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Hans de Goede <hdegoede@redhat.com>,
	Stable@vger.kernel.org,
	Jonathan Cameron <Jonathan.Cameron@huawei.com>
Subject: [PATCH 4.14 02/35] iio: adc: axp288: Fix TS-pin handling
Date: Wed, 13 Feb 2019 19:37:57 +0100	[thread overview]
Message-ID: <20190213183706.297155819@linuxfoundation.org> (raw)
In-Reply-To: <20190213183706.176685027@linuxfoundation.org>

4.14-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hans de Goede <hdegoede@redhat.com>

commit 9bcf15f75cac3c6a00d8f8083a635de9c8537799 upstream.

Prior to this commit there were 3 issues with our handling of the TS-pin:

1) There are 2 ways how the firmware can disable monitoring of the TS-pin
for designs which do not have a temperature-sensor for the battery:
a) Clearing bit 0 of the AXP20X_ADC_EN1 register
b) Setting bit 2 of the AXP288_ADC_TS_PIN_CTRL monitoring

Prior to this commit we were unconditionally setting both bits to the
value used on devices with a TS. This causes the temperature protection to
kick in on devices without a TS, such as the Jumper ezbook v2, causing
them to not charge under Linux.

This commit fixes this by using regmap_update_bits when updating these 2
registers, leaving the 2 mentioned bits alone.

The next 2 problems are related to our handling of the current-source
for the TS-pin. The current-source used for the battery temp-sensor (TS)
is shared with the GPADC. For proper fuel-gauge and charger operation the
TS current-source needs to be permanently on. But to read the GPADC we
need to temporary switch the TS current-source to ondemand, so that the
GPADC can use it, otherwise we will always read an all 0 value.

2) Problem 2 is we were writing hardcoded values to the ADC TS pin-ctrl
register, overwriting various other unrelated bits. Specifically we were
overwriting the current-source setting for the TS and GPIO0 pins, forcing
it to 80ųA independent of its original setting. On a Chuwi Vi10 tablet
this was causing us to get a too high adc value (due to a too high
current-source) resulting in the following errors being logged:

ACPI Error: AE_ERROR, Returned by Handler for [UserDefinedRegion]
ACPI Error: Method parse/execution failed \_SB.SXP1._TMP, AE_ERROR

This commit fixes this by using regmap_update_bits to change only the
relevant bits.

3) After reading the GPADC channel we were unconditionally enabling the
TS current-source even on devices where the TS-pin is not used and the
current-source thus was off before axp288_adc_read_raw call.

This commit fixes this by making axp288_adc_set_ts a nop on devices where
the ADC is not enabled for the TS-pin.

BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1610545
Fixes: 3091141d7803 ("iio: adc: axp288: Fix the GPADC pin ...")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/iio/adc/axp288_adc.c |   76 +++++++++++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 16 deletions(-)

--- a/drivers/iio/adc/axp288_adc.c
+++ b/drivers/iio/adc/axp288_adc.c
@@ -27,9 +27,18 @@
 #include <linux/iio/machine.h>
 #include <linux/iio/driver.h>
 
-#define AXP288_ADC_EN_MASK		0xF1
-#define AXP288_ADC_TS_PIN_GPADC		0xF2
-#define AXP288_ADC_TS_PIN_ON		0xF3
+/*
+ * This mask enables all ADCs except for the battery temp-sensor (TS), that is
+ * left as-is to avoid breaking charging on devices without a temp-sensor.
+ */
+#define AXP288_ADC_EN_MASK				0xF0
+#define AXP288_ADC_TS_ENABLE				0x01
+
+#define AXP288_ADC_TS_CURRENT_ON_OFF_MASK		GENMASK(1, 0)
+#define AXP288_ADC_TS_CURRENT_OFF			(0 << 0)
+#define AXP288_ADC_TS_CURRENT_ON_WHEN_CHARGING		(1 << 0)
+#define AXP288_ADC_TS_CURRENT_ON_ONDEMAND		(2 << 0)
+#define AXP288_ADC_TS_CURRENT_ON			(3 << 0)
 
 enum axp288_adc_id {
 	AXP288_ADC_TS,
@@ -44,6 +53,7 @@ enum axp288_adc_id {
 struct axp288_adc_info {
 	int irq;
 	struct regmap *regmap;
+	bool ts_enabled;
 };
 
 static const struct iio_chan_spec axp288_adc_channels[] = {
@@ -123,21 +133,33 @@ static int axp288_adc_read_channel(int *
 	return IIO_VAL_INT;
 }
 
-static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode,
-				unsigned long address)
+/*
+ * The current-source used for the battery temp-sensor (TS) is shared
+ * with the GPADC. For proper fuel-gauge and charger operation the TS
+ * current-source needs to be permanently on. But to read the GPADC we
+ * need to temporary switch the TS current-source to ondemand, so that
+ * the GPADC can use it, otherwise we will always read an all 0 value.
+ */
+static int axp288_adc_set_ts(struct axp288_adc_info *info,
+			     unsigned int mode, unsigned long address)
 {
 	int ret;
 
-	/* channels other than GPADC do not need to switch TS pin */
+	/* No need to switch the current-source if the TS pin is disabled */
+	if (!info->ts_enabled)
+		return 0;
+
+	/* Channels other than GPADC do not need the current source */
 	if (address != AXP288_GP_ADC_H)
 		return 0;
 
-	ret = regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode);
+	ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL,
+				 AXP288_ADC_TS_CURRENT_ON_OFF_MASK, mode);
 	if (ret)
 		return ret;
 
 	/* When switching to the GPADC pin give things some time to settle */
-	if (mode == AXP288_ADC_TS_PIN_GPADC)
+	if (mode == AXP288_ADC_TS_CURRENT_ON_ONDEMAND)
 		usleep_range(6000, 10000);
 
 	return 0;
@@ -153,14 +175,14 @@ static int axp288_adc_read_raw(struct ii
 	mutex_lock(&indio_dev->mlock);
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
-		if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC,
+		if (axp288_adc_set_ts(info, AXP288_ADC_TS_CURRENT_ON_ONDEMAND,
 					chan->address)) {
 			dev_err(&indio_dev->dev, "GPADC mode\n");
 			ret = -EINVAL;
 			break;
 		}
 		ret = axp288_adc_read_channel(val, chan->address, info->regmap);
-		if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON,
+		if (axp288_adc_set_ts(info, AXP288_ADC_TS_CURRENT_ON,
 						chan->address))
 			dev_err(&indio_dev->dev, "TS pin restore\n");
 		break;
@@ -172,13 +194,35 @@ static int axp288_adc_read_raw(struct ii
 	return ret;
 }
 
-static int axp288_adc_set_state(struct regmap *regmap)
+static int axp288_adc_initialize(struct axp288_adc_info *info)
 {
-	/* ADC should be always enabled for internal FG to function */
-	if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON))
-		return -EIO;
+	int ret, adc_enable_val;
+
+	/*
+	 * Determine if the TS pin is enabled and set the TS current-source
+	 * accordingly.
+	 */
+	ret = regmap_read(info->regmap, AXP20X_ADC_EN1, &adc_enable_val);
+	if (ret)
+		return ret;
+
+	if (adc_enable_val & AXP288_ADC_TS_ENABLE) {
+		info->ts_enabled = true;
+		ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL,
+					 AXP288_ADC_TS_CURRENT_ON_OFF_MASK,
+					 AXP288_ADC_TS_CURRENT_ON);
+	} else {
+		info->ts_enabled = false;
+		ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL,
+					 AXP288_ADC_TS_CURRENT_ON_OFF_MASK,
+					 AXP288_ADC_TS_CURRENT_OFF);
+	}
+	if (ret)
+		return ret;
 
-	return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
+	/* Turn on the ADC for all channels except TS, leave TS as is */
+	return regmap_update_bits(info->regmap, AXP20X_ADC_EN1,
+				  AXP288_ADC_EN_MASK, AXP288_ADC_EN_MASK);
 }
 
 static const struct iio_info axp288_adc_iio_info = {
@@ -209,7 +253,7 @@ static int axp288_adc_probe(struct platf
 	 * Set ADC to enabled state at all time, including system suspend.
 	 * otherwise internal fuel gauge functionality may be affected.
 	 */
-	ret = axp288_adc_set_state(axp20x->regmap);
+	ret = axp288_adc_initialize(info);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to enable ADC device\n");
 		return ret;



  parent reply	other threads:[~2019-02-13 18:41 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-13 18:37 [PATCH 4.14 00/35] 4.14.100-stable review Greg Kroah-Hartman
2019-02-13 18:37 ` [PATCH 4.14 01/35] mtd: rawnand: gpmi: fix MX28 bus master lockup problem Greg Kroah-Hartman
2019-02-13 18:37 ` Greg Kroah-Hartman [this message]
2019-02-13 18:37 ` [PATCH 4.14 03/35] iio: chemical: atlas-ph-sensor: correct IIO_TEMP values to millicelsius Greg Kroah-Hartman
2019-02-13 18:37 ` [PATCH 4.14 04/35] signal: Always notice exiting tasks Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 05/35] signal: Better detection of synchronous signals Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 06/35] misc: vexpress: Off by one in vexpress_syscfg_exec() Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 07/35] samples: mei: use /dev/mei0 instead of /dev/mei Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 08/35] debugfs: fix debugfs_rename parameter checking Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 09/35] tracing: uprobes: Fix typo in pr_fmt string Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 10/35] mips: cm: reprime error cause Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 11/35] MIPS: OCTEON: dont set octeon_dma_bar_type if PCI is disabled Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 12/35] MIPS: VDSO: Include $(ccflags-vdso) in o32,n32 .lds builds Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 13/35] ARM: iop32x/n2100: fix PCI IRQ mapping Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 14/35] ARM: tango: Improve ARCH_MULTIPLATFORM compatibility Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 15/35] mac80211: ensure that mgmt tx skbs have tailroom for encryption Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 16/35] drm/modes: Prevent division by zero htotal Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 17/35] drm/vmwgfx: Fix setting of dma masks Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 18/35] drm/vmwgfx: Return error code from vmw_execbuf_copy_fence_user Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 19/35] HID: debug: fix the ring buffer implementation Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 20/35] Revert "ext4: use ext4_write_inode() when fsyncing w/o a journal" Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 21/35] libceph: avoid KEEPALIVE_PENDING races in ceph_con_keepalive() Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 22/35] xfrm: refine validation of template and selector families Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 23/35] batman-adv: Avoid WARN on net_device without parent in netns Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 24/35] batman-adv: Force mac header to start of data on xmit Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 25/35] perf tests attr: Fix task term values Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 26/35] perf tests attr: Fix group stat tests Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 27/35] perf tests attr: Make hw events optional Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 28/35] uio: Reduce return paths from uio_write() Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 29/35] uio: Prevent device destruction while fds are open Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 30/35] uio: use request_threaded_irq instead Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 31/35] uio: change to use the mutex lock instead of the spin lock Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 32/35] uio: fix crash after the device is unregistered Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 33/35] uio: fix wrong return value from uio_mmap() Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 34/35] uio: fix possible circular locking dependency Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.14 35/35] Revert "uio: use request_threaded_irq instead" Greg Kroah-Hartman
2019-02-14 10:06 ` [PATCH 4.14 00/35] 4.14.100-stable review Jon Hunter
2019-02-14 10:06   ` Jon Hunter
2019-02-14 10:11   ` Greg Kroah-Hartman
2019-02-14 16:42 ` Dan Rue
2019-02-14 19:17 ` Guenter Roeck
2019-02-14 22:21 ` shuah

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190213183706.297155819@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=hdegoede@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.