Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: adc: mt6370: Fix ibus and ibat scaling value of some specific vendor ID chips

The scale value of ibus and ibat on the datasheet is incorrect due to the
customer report after the experimentation with some specific vendor ID
chips.

Fixes: c1404d1b659f ("iio: adc: mt6370: Add MediaTek MT6370 support")
Signed-off-by: ChiaEn Wu <chiaen_wu@richtek.com>
Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
Link: https://lore.kernel.org/r/1681122862-1994-1-git-send-email-chiaen_wu@richtek.com
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

ChiaEn Wu and committed by
Jonathan Cameron
00ffdd6f 20f291b8

+51 -2
+51 -2
drivers/iio/adc/mt6370-adc.c
··· 19 19 20 20 #include <dt-bindings/iio/adc/mediatek,mt6370_adc.h> 21 21 22 + #define MT6370_REG_DEV_INFO 0x100 22 23 #define MT6370_REG_CHG_CTRL3 0x113 23 24 #define MT6370_REG_CHG_CTRL7 0x117 24 25 #define MT6370_REG_CHG_ADC 0x121 ··· 28 27 #define MT6370_ADC_START_MASK BIT(0) 29 28 #define MT6370_ADC_IN_SEL_MASK GENMASK(7, 4) 30 29 #define MT6370_AICR_ICHG_MASK GENMASK(7, 2) 30 + #define MT6370_VENID_MASK GENMASK(7, 4) 31 31 32 32 #define MT6370_AICR_100_mA 0x0 33 33 #define MT6370_AICR_150_mA 0x1 ··· 49 47 #define ADC_CONV_TIME_MS 35 50 48 #define ADC_CONV_POLLING_TIME_US 1000 51 49 50 + #define MT6370_VID_RT5081 0x8 51 + #define MT6370_VID_RT5081A 0xA 52 + #define MT6370_VID_MT6370 0xE 53 + 52 54 struct mt6370_adc_data { 53 55 struct device *dev; 54 56 struct regmap *regmap; ··· 61 55 * from being read at the same time. 62 56 */ 63 57 struct mutex adc_lock; 58 + unsigned int vid; 64 59 }; 65 60 66 61 static int mt6370_adc_read_channel(struct mt6370_adc_data *priv, int chan, ··· 105 98 return ret; 106 99 } 107 100 101 + static int mt6370_adc_get_ibus_scale(struct mt6370_adc_data *priv) 102 + { 103 + switch (priv->vid) { 104 + case MT6370_VID_RT5081: 105 + case MT6370_VID_RT5081A: 106 + case MT6370_VID_MT6370: 107 + return 3350; 108 + default: 109 + return 3875; 110 + } 111 + } 112 + 113 + static int mt6370_adc_get_ibat_scale(struct mt6370_adc_data *priv) 114 + { 115 + switch (priv->vid) { 116 + case MT6370_VID_RT5081: 117 + case MT6370_VID_RT5081A: 118 + case MT6370_VID_MT6370: 119 + return 2680; 120 + default: 121 + return 3870; 122 + } 123 + } 124 + 108 125 static int mt6370_adc_read_scale(struct mt6370_adc_data *priv, 109 126 int chan, int *val1, int *val2) 110 127 { ··· 154 123 case MT6370_AICR_250_mA: 155 124 case MT6370_AICR_300_mA: 156 125 case MT6370_AICR_350_mA: 157 - *val1 = 3350; 126 + *val1 = mt6370_adc_get_ibus_scale(priv); 158 127 break; 159 128 default: 160 129 *val1 = 5000; ··· 181 150 case MT6370_ICHG_600_mA: 182 151 case MT6370_ICHG_700_mA: 183 152 case MT6370_ICHG_800_mA: 184 - *val1 = 2680; 153 + *val1 = mt6370_adc_get_ibat_scale(priv); 185 154 break; 186 155 default: 187 156 *val1 = 5000; ··· 282 251 MT6370_ADC_CHAN(TEMP_JC, IIO_TEMP, 12, BIT(IIO_CHAN_INFO_OFFSET)), 283 252 }; 284 253 254 + static int mt6370_get_vendor_info(struct mt6370_adc_data *priv) 255 + { 256 + unsigned int dev_info; 257 + int ret; 258 + 259 + ret = regmap_read(priv->regmap, MT6370_REG_DEV_INFO, &dev_info); 260 + if (ret) 261 + return ret; 262 + 263 + priv->vid = FIELD_GET(MT6370_VENID_MASK, dev_info); 264 + 265 + return 0; 266 + } 267 + 285 268 static int mt6370_adc_probe(struct platform_device *pdev) 286 269 { 287 270 struct device *dev = &pdev->dev; ··· 316 271 priv->dev = dev; 317 272 priv->regmap = regmap; 318 273 mutex_init(&priv->adc_lock); 274 + 275 + ret = mt6370_get_vendor_info(priv); 276 + if (ret) 277 + return dev_err_probe(dev, ret, "Failed to get vid\n"); 319 278 320 279 ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, 0); 321 280 if (ret)