1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Intel Dollar Cove TI PMIC GPADC Driver 4 * 5 * Copyright (C) 2014 Intel Corporation (Ramakrishna Pallala <ramakrishna.pallala@intel.com>) 6 * Copyright (C) 2024 - 2025 Hans de Goede <hansg@kernel.org> 7 */ 8 9 #include <linux/bits.h> 10 #include <linux/bitfield.h> 11 #include <linux/bitops.h> 12 #include <linux/cleanup.h> 13 #include <linux/delay.h> 14 #include <linux/device.h> 15 #include <linux/interrupt.h> 16 #include <linux/mfd/intel_soc_pmic.h> 17 #include <linux/mod_devicetable.h> 18 #include <linux/module.h> 19 #include <linux/mutex.h> 20 #include <linux/platform_device.h> 21 #include <linux/regmap.h> 22 #include <linux/wait.h> 23 24 #include <linux/iio/driver.h> 25 #include <linux/iio/iio.h> 26 #include <linux/iio/machine.h> 27 28 #define DC_TI_ADC_CNTL_REG 0x50 29 #define DC_TI_ADC_START BIT(0) 30 #define DC_TI_ADC_CH_SEL GENMASK(2, 1) 31 #define DC_TI_ADC_EN BIT(5) 32 #define DC_TI_ADC_EN_EXT_BPTH_BIAS BIT(6) 33 34 #define DC_TI_VBAT_ZSE_GE_REG 0x53 35 #define DC_TI_VBAT_GE GENMASK(3, 0) 36 #define DC_TI_VBAT_ZSE GENMASK(7, 4) 37 38 /* VBAT GE gain correction is in 0.0015 increments, ZSE is in 1.0 increments */ 39 #define DC_TI_VBAT_GE_STEP 15 40 #define DC_TI_VBAT_GE_DIV 10000 41 42 #define DC_TI_ADC_DATA_REG_CH(x) (0x54 + 2 * (x)) 43 44 enum dc_ti_adc_id { 45 DC_TI_ADC_VBAT, 46 DC_TI_ADC_PMICTEMP, 47 DC_TI_ADC_BATTEMP, 48 DC_TI_ADC_SYSTEMP0, 49 }; 50 51 struct dc_ti_adc_info { 52 struct mutex lock; /* Protects against concurrent accesses to the ADC */ 53 wait_queue_head_t wait; 54 struct device *dev; 55 struct regmap *regmap; 56 int vbat_zse; 57 int vbat_ge; 58 bool conversion_done; 59 }; 60 61 static const struct iio_chan_spec dc_ti_adc_channels[] = { 62 { 63 .indexed = 1, 64 .type = IIO_VOLTAGE, 65 .channel = DC_TI_ADC_VBAT, 66 .address = DC_TI_ADC_DATA_REG_CH(0), 67 .datasheet_name = "CH0", 68 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 69 BIT(IIO_CHAN_INFO_SCALE) | 70 BIT(IIO_CHAN_INFO_PROCESSED), 71 }, { 72 .indexed = 1, 73 .type = IIO_TEMP, 74 .channel = DC_TI_ADC_PMICTEMP, 75 .address = DC_TI_ADC_DATA_REG_CH(1), 76 .datasheet_name = "CH1", 77 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 78 }, { 79 .indexed = 1, 80 .type = IIO_TEMP, 81 .channel = DC_TI_ADC_BATTEMP, 82 .address = DC_TI_ADC_DATA_REG_CH(2), 83 .datasheet_name = "CH2", 84 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 85 }, { 86 .indexed = 1, 87 .type = IIO_TEMP, 88 .channel = DC_TI_ADC_SYSTEMP0, 89 .address = DC_TI_ADC_DATA_REG_CH(3), 90 .datasheet_name = "CH3", 91 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 92 } 93 }; 94 95 static struct iio_map dc_ti_adc_default_maps[] = { 96 IIO_MAP("CH0", "chtdc_ti_battery", "VBAT"), 97 IIO_MAP("CH1", "chtdc_ti_battery", "PMICTEMP"), 98 IIO_MAP("CH2", "chtdc_ti_battery", "BATTEMP"), 99 IIO_MAP("CH3", "chtdc_ti_battery", "SYSTEMP0"), 100 { } 101 }; 102 103 static irqreturn_t dc_ti_adc_isr(int irq, void *data) 104 { 105 struct dc_ti_adc_info *info = data; 106 107 info->conversion_done = true; 108 wake_up(&info->wait); 109 return IRQ_HANDLED; 110 } 111 112 static int dc_ti_adc_scale(struct dc_ti_adc_info *info, 113 struct iio_chan_spec const *chan, 114 int *val, int *val2) 115 { 116 if (chan->channel != DC_TI_ADC_VBAT) 117 return -EINVAL; 118 119 /* Vbat ADC scale is 4.6875 mV / unit */ 120 *val = 4; 121 *val2 = 687500; 122 123 return IIO_VAL_INT_PLUS_MICRO; 124 } 125 126 static int dc_ti_adc_raw_to_processed(struct dc_ti_adc_info *info, 127 struct iio_chan_spec const *chan, 128 int raw, int *val, int *val2) 129 { 130 if (chan->channel != DC_TI_ADC_VBAT) 131 return -EINVAL; 132 133 /* Apply calibration */ 134 raw -= info->vbat_zse; 135 raw = raw * (DC_TI_VBAT_GE_DIV - info->vbat_ge * DC_TI_VBAT_GE_STEP) / 136 DC_TI_VBAT_GE_DIV; 137 /* Vbat ADC scale is 4.6875 mV / unit */ 138 raw *= 46875; 139 140 /* raw is now in 10000 units / mV, convert to milli + milli/1e6 */ 141 *val = raw / 10000; 142 *val2 = (raw % 10000) * 100; 143 144 return IIO_VAL_INT_PLUS_MICRO; 145 } 146 147 static int dc_ti_adc_sample(struct dc_ti_adc_info *info, 148 struct iio_chan_spec const *chan, int *val) 149 { 150 int ret, ch = chan->channel; 151 __be16 buf; 152 153 info->conversion_done = false; 154 155 /* 156 * As per TI (PMIC Vendor), the ADC enable and ADC start commands should 157 * not be sent together. Hence send the commands separately. 158 */ 159 ret = regmap_set_bits(info->regmap, DC_TI_ADC_CNTL_REG, DC_TI_ADC_EN); 160 if (ret) 161 return ret; 162 163 ret = regmap_update_bits(info->regmap, DC_TI_ADC_CNTL_REG, 164 DC_TI_ADC_CH_SEL, 165 FIELD_PREP(DC_TI_ADC_CH_SEL, ch)); 166 if (ret) 167 return ret; 168 169 /* 170 * As per PMIC Vendor, a minimum of 50 ųs delay is required between ADC 171 * Enable and ADC START commands. This is also recommended by Intel 172 * Hardware team after the timing analysis of GPADC signals. Since the 173 * I2C Write transaction to set the channel number also imparts 25 ųs 174 * delay, we need to wait for another 25 ųs before issuing ADC START. 175 */ 176 fsleep(25); 177 178 ret = regmap_set_bits(info->regmap, DC_TI_ADC_CNTL_REG, 179 DC_TI_ADC_START); 180 if (ret) 181 return ret; 182 183 /* TI (PMIC Vendor) recommends 5 s timeout for conversion */ 184 ret = wait_event_timeout(info->wait, info->conversion_done, 5 * HZ); 185 if (ret == 0) { 186 ret = -ETIMEDOUT; 187 goto disable_adc; 188 } 189 190 ret = regmap_bulk_read(info->regmap, chan->address, &buf, sizeof(buf)); 191 if (ret) 192 goto disable_adc; 193 194 /* The ADC values are 10 bits wide */ 195 *val = be16_to_cpu(buf) & GENMASK(9, 0); 196 197 disable_adc: 198 regmap_clear_bits(info->regmap, DC_TI_ADC_CNTL_REG, 199 DC_TI_ADC_START | DC_TI_ADC_EN); 200 return ret; 201 } 202 203 static int dc_ti_adc_read_raw(struct iio_dev *indio_dev, 204 struct iio_chan_spec const *chan, 205 int *val, int *val2, long mask) 206 { 207 struct dc_ti_adc_info *info = iio_priv(indio_dev); 208 int ret; 209 210 if (mask == IIO_CHAN_INFO_SCALE) 211 return dc_ti_adc_scale(info, chan, val, val2); 212 213 guard(mutex)(&info->lock); 214 215 /* 216 * If channel BPTHERM has been selected, first enable the BPTHERM BIAS 217 * which provides the VREF Voltage reference to convert BPTHERM Input 218 * voltage to temperature. 219 */ 220 if (chan->channel == DC_TI_ADC_BATTEMP) { 221 ret = regmap_set_bits(info->regmap, DC_TI_ADC_CNTL_REG, 222 DC_TI_ADC_EN_EXT_BPTH_BIAS); 223 if (ret) 224 return ret; 225 /* 226 * As per PMIC Vendor specifications, BPTHERM BIAS should be 227 * enabled 35 ms before ADC_EN command. 228 */ 229 msleep(35); 230 } 231 232 ret = dc_ti_adc_sample(info, chan, val); 233 234 if (chan->channel == DC_TI_ADC_BATTEMP) 235 regmap_clear_bits(info->regmap, DC_TI_ADC_CNTL_REG, 236 DC_TI_ADC_EN_EXT_BPTH_BIAS); 237 238 if (ret) 239 return ret; 240 241 switch (mask) { 242 case IIO_CHAN_INFO_RAW: 243 return IIO_VAL_INT; 244 case IIO_CHAN_INFO_PROCESSED: 245 return dc_ti_adc_raw_to_processed(info, chan, *val, val, val2); 246 } 247 248 return -EINVAL; 249 } 250 251 static const struct iio_info dc_ti_adc_iio_info = { 252 .read_raw = dc_ti_adc_read_raw, 253 }; 254 255 static int dc_ti_adc_probe(struct platform_device *pdev) 256 { 257 struct device *dev = &pdev->dev; 258 struct intel_soc_pmic *pmic = dev_get_drvdata(dev->parent); 259 struct dc_ti_adc_info *info; 260 struct iio_dev *indio_dev; 261 unsigned int val; 262 int irq, ret; 263 264 irq = platform_get_irq(pdev, 0); 265 if (irq < 0) 266 return irq; 267 268 indio_dev = devm_iio_device_alloc(dev, sizeof(*info)); 269 if (!indio_dev) 270 return -ENOMEM; 271 272 info = iio_priv(indio_dev); 273 274 ret = devm_mutex_init(dev, &info->lock); 275 if (ret) 276 return ret; 277 278 init_waitqueue_head(&info->wait); 279 280 info->dev = dev; 281 info->regmap = pmic->regmap; 282 283 indio_dev->name = "dc_ti_adc"; 284 indio_dev->channels = dc_ti_adc_channels; 285 indio_dev->num_channels = ARRAY_SIZE(dc_ti_adc_channels); 286 indio_dev->info = &dc_ti_adc_iio_info; 287 indio_dev->modes = INDIO_DIRECT_MODE; 288 289 ret = regmap_read(info->regmap, DC_TI_VBAT_ZSE_GE_REG, &val); 290 if (ret) 291 return ret; 292 293 info->vbat_zse = sign_extend32(FIELD_GET(DC_TI_VBAT_ZSE, val), 3); 294 info->vbat_ge = sign_extend32(FIELD_GET(DC_TI_VBAT_GE, val), 3); 295 296 dev_dbg(dev, "vbat-zse %d vbat-ge %d\n", info->vbat_zse, info->vbat_ge); 297 298 ret = devm_iio_map_array_register(dev, indio_dev, dc_ti_adc_default_maps); 299 if (ret) 300 return ret; 301 302 ret = devm_request_threaded_irq(dev, irq, NULL, dc_ti_adc_isr, 303 IRQF_ONESHOT, indio_dev->name, info); 304 if (ret) 305 return ret; 306 307 return devm_iio_device_register(dev, indio_dev); 308 } 309 310 static const struct platform_device_id dc_ti_adc_ids[] = { 311 { .name = "chtdc_ti_adc" }, 312 { } 313 }; 314 MODULE_DEVICE_TABLE(platform, dc_ti_adc_ids); 315 316 static struct platform_driver dc_ti_adc_driver = { 317 .driver = { 318 .name = "dc_ti_adc", 319 }, 320 .probe = dc_ti_adc_probe, 321 .id_table = dc_ti_adc_ids, 322 }; 323 module_platform_driver(dc_ti_adc_driver); 324 325 MODULE_AUTHOR("Ramakrishna Pallala (Intel)"); 326 MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>"); 327 MODULE_DESCRIPTION("Intel Dollar Cove (TI) GPADC Driver"); 328 MODULE_LICENSE("GPL"); 329