1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2025, Duje Mihanović <duje@dujemihanovic.xyz> 4 */ 5 6 #include <linux/bits.h> 7 #include <linux/bug.h> 8 #include <linux/delay.h> 9 #include <linux/device.h> 10 #include <linux/err.h> 11 #include <linux/i2c.h> 12 #include <linux/math.h> 13 #include <linux/mod_devicetable.h> 14 #include <linux/module.h> 15 #include <linux/platform_device.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/regmap.h> 18 #include <linux/types.h> 19 #include <linux/units.h> 20 21 #include <asm/byteorder.h> 22 23 #include <linux/iio/iio.h> 24 #include <linux/iio/types.h> 25 26 #include <linux/mfd/88pm886.h> 27 28 struct pm886_gpadc { 29 struct regmap *map; 30 }; 31 32 enum pm886_gpadc_channel { 33 VSC_CHAN, 34 VCHG_PWR_CHAN, 35 VCF_OUT_CHAN, 36 VBAT_CHAN, 37 VBAT_SLP_CHAN, 38 VBUS_CHAN, 39 40 GPADC0_CHAN, 41 GPADC1_CHAN, 42 GPADC2_CHAN, 43 GPADC3_CHAN, 44 45 GND_DET1_CHAN, 46 GND_DET2_CHAN, 47 MIC_DET_CHAN, 48 49 TINT_CHAN, 50 }; 51 52 static const int pm886_gpadc_regs[] = { 53 [VSC_CHAN] = PM886_REG_GPADC_VSC, 54 [VCHG_PWR_CHAN] = PM886_REG_GPADC_VCHG_PWR, 55 [VCF_OUT_CHAN] = PM886_REG_GPADC_VCF_OUT, 56 [VBAT_CHAN] = PM886_REG_GPADC_VBAT, 57 [VBAT_SLP_CHAN] = PM886_REG_GPADC_VBAT_SLP, 58 [VBUS_CHAN] = PM886_REG_GPADC_VBUS, 59 60 [GPADC0_CHAN] = PM886_REG_GPADC_GPADC0, 61 [GPADC1_CHAN] = PM886_REG_GPADC_GPADC1, 62 [GPADC2_CHAN] = PM886_REG_GPADC_GPADC2, 63 [GPADC3_CHAN] = PM886_REG_GPADC_GPADC3, 64 65 [GND_DET1_CHAN] = PM886_REG_GPADC_GND_DET1, 66 [GND_DET2_CHAN] = PM886_REG_GPADC_GND_DET2, 67 [MIC_DET_CHAN] = PM886_REG_GPADC_MIC_DET, 68 69 [TINT_CHAN] = PM886_REG_GPADC_TINT, 70 }; 71 72 #define ADC_CHANNEL_VOLTAGE(index, lsb, name) \ 73 { \ 74 .type = IIO_VOLTAGE, \ 75 .indexed = 1, \ 76 .channel = index, \ 77 .address = lsb, \ 78 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 79 BIT(IIO_CHAN_INFO_SCALE), \ 80 .datasheet_name = name, \ 81 } 82 83 #define ADC_CHANNEL_RESISTANCE(index, lsb, name) \ 84 { \ 85 .type = IIO_RESISTANCE, \ 86 .indexed = 1, \ 87 .channel = index, \ 88 .address = lsb, \ 89 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ 90 .datasheet_name = name, \ 91 } 92 93 #define ADC_CHANNEL_TEMPERATURE(index, lsb, name) \ 94 { \ 95 .type = IIO_TEMP, \ 96 .indexed = 1, \ 97 .channel = index, \ 98 .address = lsb, \ 99 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 100 BIT(IIO_CHAN_INFO_SCALE) | \ 101 BIT(IIO_CHAN_INFO_OFFSET), \ 102 .datasheet_name = name, \ 103 } 104 105 static const struct iio_chan_spec pm886_gpadc_channels[] = { 106 ADC_CHANNEL_VOLTAGE(VSC_CHAN, 1367, "vsc"), 107 ADC_CHANNEL_VOLTAGE(VCHG_PWR_CHAN, 1709, "vchg_pwr"), 108 ADC_CHANNEL_VOLTAGE(VCF_OUT_CHAN, 1367, "vcf_out"), 109 ADC_CHANNEL_VOLTAGE(VBAT_CHAN, 1367, "vbat"), 110 ADC_CHANNEL_VOLTAGE(VBAT_SLP_CHAN, 1367, "vbat_slp"), 111 ADC_CHANNEL_VOLTAGE(VBUS_CHAN, 1709, "vbus"), 112 113 ADC_CHANNEL_RESISTANCE(GPADC0_CHAN, 342, "gpadc0"), 114 ADC_CHANNEL_RESISTANCE(GPADC1_CHAN, 342, "gpadc1"), 115 ADC_CHANNEL_RESISTANCE(GPADC2_CHAN, 342, "gpadc2"), 116 ADC_CHANNEL_RESISTANCE(GPADC3_CHAN, 342, "gpadc3"), 117 118 ADC_CHANNEL_VOLTAGE(GND_DET1_CHAN, 342, "gnddet1"), 119 ADC_CHANNEL_VOLTAGE(GND_DET2_CHAN, 342, "gnddet2"), 120 ADC_CHANNEL_VOLTAGE(MIC_DET_CHAN, 1367, "mic_det"), 121 122 ADC_CHANNEL_TEMPERATURE(TINT_CHAN, 104, "tint"), 123 }; 124 125 static const struct regmap_config pm886_gpadc_regmap_config = { 126 .reg_bits = 8, 127 .val_bits = 8, 128 .max_register = PM886_GPADC_MAX_REGISTER, 129 }; 130 131 static int gpadc_get_raw(struct iio_dev *iio, enum pm886_gpadc_channel chan) 132 { 133 struct pm886_gpadc *gpadc = iio_priv(iio); 134 __be16 buf; 135 int ret; 136 137 ret = regmap_bulk_read(gpadc->map, pm886_gpadc_regs[chan], &buf, sizeof(buf)); 138 if (ret) 139 return ret; 140 141 return be16_to_cpu(buf) >> 4; 142 } 143 144 static int 145 gpadc_set_bias(struct pm886_gpadc *gpadc, enum pm886_gpadc_channel chan, bool on) 146 { 147 unsigned int gpadc_num = chan - GPADC0_CHAN; 148 unsigned int bits = BIT(gpadc_num + 4) | BIT(gpadc_num); 149 150 return regmap_assign_bits(gpadc->map, PM886_REG_GPADC_CONFIG(0x14), bits, on); 151 } 152 153 static int 154 gpadc_find_bias_current(struct iio_dev *iio, struct iio_chan_spec const *chan, 155 unsigned int *raw_uV, unsigned int *raw_uA) 156 { 157 struct pm886_gpadc *gpadc = iio_priv(iio); 158 unsigned int gpadc_num = chan->channel - GPADC0_CHAN; 159 unsigned int reg = PM886_REG_GPADC_CONFIG(0xb + gpadc_num); 160 unsigned long lsb = chan->address; 161 int ret; 162 163 for (unsigned int i = 0; i < PM886_GPADC_BIAS_LEVELS; i++) { 164 ret = regmap_update_bits(gpadc->map, reg, GENMASK(3, 0), i); 165 if (ret) 166 return ret; 167 168 /* Wait for the new bias level to apply. */ 169 fsleep(5 * USEC_PER_MSEC); 170 171 *raw_uA = PM886_GPADC_INDEX_TO_BIAS_uA(i); 172 *raw_uV = gpadc_get_raw(iio, chan->channel) * lsb; 173 174 /* 175 * Vendor kernel errors out above 1.25 V, but testing shows 176 * that the resistance of the battery detection channel (GPADC2 177 * on coreprimevelte) reaches about 1.4 MΩ when the battery is 178 * removed, which can't be measured with such a low upper 179 * limit. Therefore, to be able to detect the battery without 180 * ugly externs as used in the vendor fuel gauge driver, 181 * increase this limit a bit. 182 */ 183 if (WARN_ON(*raw_uV > 1500 * (MICRO / MILLI))) 184 return -EIO; 185 186 /* 187 * Vendor kernel errors out under 300 mV, but for the same 188 * reason as above (except the channel hovers around 3.5 kΩ 189 * with battery present) reduce this limit. 190 */ 191 if (*raw_uV < 200 * (MICRO / MILLI)) { 192 dev_dbg(&iio->dev, "bad bias for chan %d: %d uA @ %d uV\n", 193 chan->channel, *raw_uA, *raw_uV); 194 continue; 195 } 196 197 dev_dbg(&iio->dev, "good bias for chan %d: %d uA @ %d uV\n", 198 chan->channel, *raw_uA, *raw_uV); 199 return 0; 200 } 201 202 dev_err(&iio->dev, "failed to find good bias for chan %d\n", chan->channel); 203 return -EINVAL; 204 } 205 206 static int 207 gpadc_get_resistance_ohm(struct iio_dev *iio, struct iio_chan_spec const *chan) 208 { 209 struct pm886_gpadc *gpadc = iio_priv(iio); 210 unsigned int raw_uV, raw_uA; 211 int ret; 212 213 ret = gpadc_set_bias(gpadc, chan->channel, true); 214 if (ret) 215 goto out; 216 217 ret = gpadc_find_bias_current(iio, chan, &raw_uV, &raw_uA); 218 if (ret) 219 goto out; 220 221 ret = DIV_ROUND_CLOSEST(raw_uV, raw_uA); 222 out: 223 gpadc_set_bias(gpadc, chan->channel, false); 224 return ret; 225 } 226 227 static int 228 __pm886_gpadc_read_raw(struct iio_dev *iio, struct iio_chan_spec const *chan, 229 int *val, int *val2, long mask) 230 { 231 unsigned long lsb = chan->address; 232 233 switch (mask) { 234 case IIO_CHAN_INFO_RAW: 235 *val = gpadc_get_raw(iio, chan->channel); 236 if (*val < 0) 237 return *val; 238 239 return IIO_VAL_INT; 240 case IIO_CHAN_INFO_SCALE: 241 *val = lsb; 242 243 if (chan->type == IIO_VOLTAGE) { 244 *val2 = MILLI; 245 return IIO_VAL_FRACTIONAL; 246 } else { 247 return IIO_VAL_INT; 248 } 249 case IIO_CHAN_INFO_OFFSET: 250 /* Raw value is 104 millikelvin/LSB, convert it to 104 millicelsius/LSB */ 251 *val = ABSOLUTE_ZERO_MILLICELSIUS; 252 *val2 = lsb; 253 return IIO_VAL_FRACTIONAL; 254 case IIO_CHAN_INFO_PROCESSED: 255 *val = gpadc_get_resistance_ohm(iio, chan); 256 if (*val < 0) 257 return *val; 258 259 return IIO_VAL_INT; 260 default: 261 return -EINVAL; 262 } 263 } 264 265 static int pm886_gpadc_read_raw(struct iio_dev *iio, struct iio_chan_spec const *chan, 266 int *val, int *val2, long mask) 267 { 268 struct device *dev = iio->dev.parent; 269 int ret; 270 271 ret = pm_runtime_resume_and_get(dev); 272 if (ret) 273 return ret; 274 275 ret = __pm886_gpadc_read_raw(iio, chan, val, val2, mask); 276 277 pm_runtime_put_autosuspend(dev); 278 return ret; 279 } 280 281 static int pm886_gpadc_hw_enable(struct regmap *map) 282 { 283 const u8 config[] = { 284 PM886_GPADC_CONFIG1_EN_ALL, 285 PM886_GPADC_CONFIG2_EN_ALL, 286 PM886_GPADC_GND_DET2_EN, 287 }; 288 int ret; 289 290 /* Enable the ADC block. */ 291 ret = regmap_set_bits(map, PM886_REG_GPADC_CONFIG(0x6), BIT(0)); 292 if (ret) 293 return ret; 294 295 /* Enable all channels. */ 296 return regmap_bulk_write(map, PM886_REG_GPADC_CONFIG(0x1), config, ARRAY_SIZE(config)); 297 } 298 299 static int pm886_gpadc_hw_disable(struct regmap *map) 300 { 301 return regmap_clear_bits(map, PM886_REG_GPADC_CONFIG(0x6), BIT(0)); 302 } 303 304 static const struct iio_info pm886_gpadc_iio_info = { 305 .read_raw = pm886_gpadc_read_raw, 306 }; 307 308 static int pm886_gpadc_probe(struct platform_device *pdev) 309 { 310 struct device *dev = &pdev->dev; 311 struct pm886_chip *chip = dev_get_drvdata(dev->parent); 312 struct i2c_client *client = chip->client; 313 struct pm886_gpadc *gpadc; 314 struct i2c_client *page; 315 struct iio_dev *iio; 316 int ret; 317 318 iio = devm_iio_device_alloc(dev, sizeof(*gpadc)); 319 if (!iio) 320 return -ENOMEM; 321 322 gpadc = iio_priv(iio); 323 dev_set_drvdata(dev, iio); 324 325 page = devm_i2c_new_dummy_device(dev, client->adapter, 326 client->addr + PM886_PAGE_OFFSET_GPADC); 327 if (IS_ERR(page)) 328 return dev_err_probe(dev, PTR_ERR(page), "Failed to initialize GPADC page\n"); 329 330 gpadc->map = devm_regmap_init_i2c(page, &pm886_gpadc_regmap_config); 331 if (IS_ERR(gpadc->map)) 332 return dev_err_probe(dev, PTR_ERR(gpadc->map), 333 "Failed to initialize GPADC regmap\n"); 334 335 iio->name = "88pm886-gpadc"; 336 iio->modes = INDIO_DIRECT_MODE; 337 iio->info = &pm886_gpadc_iio_info; 338 iio->channels = pm886_gpadc_channels; 339 iio->num_channels = ARRAY_SIZE(pm886_gpadc_channels); 340 device_set_node(&iio->dev, dev_fwnode(dev->parent)); 341 342 ret = devm_pm_runtime_enable(dev); 343 if (ret) 344 return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); 345 346 pm_runtime_set_autosuspend_delay(dev, 50); 347 pm_runtime_use_autosuspend(dev); 348 ret = devm_iio_device_register(dev, iio); 349 if (ret) 350 return dev_err_probe(dev, ret, "Failed to register ADC\n"); 351 352 return 0; 353 } 354 355 static int pm886_gpadc_runtime_resume(struct device *dev) 356 { 357 struct iio_dev *iio = dev_get_drvdata(dev); 358 struct pm886_gpadc *gpadc = iio_priv(iio); 359 360 return pm886_gpadc_hw_enable(gpadc->map); 361 } 362 363 static int pm886_gpadc_runtime_suspend(struct device *dev) 364 { 365 struct iio_dev *iio = dev_get_drvdata(dev); 366 struct pm886_gpadc *gpadc = iio_priv(iio); 367 368 return pm886_gpadc_hw_disable(gpadc->map); 369 } 370 371 static DEFINE_RUNTIME_DEV_PM_OPS(pm886_gpadc_pm_ops, 372 pm886_gpadc_runtime_suspend, 373 pm886_gpadc_runtime_resume, NULL); 374 375 static const struct platform_device_id pm886_gpadc_id[] = { 376 { "88pm886-gpadc" }, 377 { } 378 }; 379 MODULE_DEVICE_TABLE(platform, pm886_gpadc_id); 380 381 static struct platform_driver pm886_gpadc_driver = { 382 .driver = { 383 .name = "88pm886-gpadc", 384 .pm = pm_ptr(&pm886_gpadc_pm_ops), 385 }, 386 .probe = pm886_gpadc_probe, 387 .id_table = pm886_gpadc_id, 388 }; 389 module_platform_driver(pm886_gpadc_driver); 390 391 MODULE_AUTHOR("Duje Mihanović <duje@dujemihanovic.xyz>"); 392 MODULE_DESCRIPTION("Marvell 88PM886 GPADC driver"); 393 MODULE_LICENSE("GPL"); 394