Commit d0136b8a authored by Hans de Goede's avatar Hans de Goede Committed by Greg Kroah-Hartman

iio: adc: Revert "axp288: Drop bogus AXP288_ADC_TS_PIN_CTRL register modifications"

[ Upstream commit 631b010a ]

Inheriting the ADC BIAS current settings from the BIOS instead of
hardcoding then causes the AXP288 to disable charging (I think it
mis-detects an overheated battery) on at least one model tablet.

So lets go back to hard coding the values, this reverts
commit fa2849e9 ("iio: adc: axp288: Drop bogus
AXP288_ADC_TS_PIN_CTRL register modifications"), fixing charging not
working on the model tablet in question.

The exact cause is not fully understood, hence the revert to a known working
state.

Cc: stable@vger.kernel.org
Reported-by: 's avatarUmberto Ixxo <sfumato1977@gmail.com>
Signed-off-by: 's avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: 's avatarJonathan Cameron <jic23@kernel.org>
Signed-off-by: 's avatarSasha Levin <sashal@kernel.org>
parent 271b4a84
......@@ -28,6 +28,8 @@
#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
enum axp288_adc_id {
AXP288_ADC_TS,
......@@ -121,6 +123,16 @@ static int axp288_adc_read_channel(int *val, unsigned long address,
return IIO_VAL_INT;
}
static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode,
unsigned long address)
{
/* channels other than GPADC do not need to switch TS pin */
if (address != AXP288_GP_ADC_H)
return 0;
return regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode);
}
static int axp288_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
......@@ -131,7 +143,16 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC,
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,
chan->address))
dev_err(&indio_dev->dev, "TS pin restore\n");
break;
default:
ret = -EINVAL;
......@@ -141,6 +162,15 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
return ret;
}
static int axp288_adc_set_state(struct regmap *regmap)
{
/* 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;
return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
}
static const struct iio_info axp288_adc_iio_info = {
.read_raw = &axp288_adc_read_raw,
.driver_module = THIS_MODULE,
......@@ -169,7 +199,7 @@ static int axp288_adc_probe(struct platform_device *pdev)
* Set ADC to enabled state at all time, including system suspend.
* otherwise internal fuel gauge functionality may be affected.
*/
ret = regmap_write(info->regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
ret = axp288_adc_set_state(axp20x->regmap);
if (ret) {
dev_err(&pdev->dev, "unable to enable ADC device\n");
return ret;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment