Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 631b010a authored by Hans de Goede's avatar Hans de Goede Committed by Jonathan Cameron
Browse files

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



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: default avatarUmberto Ixxo <sfumato1977@gmail.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent be2ea533
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -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;