xref: /linux/drivers/iio/adc/intel_dc_ti_adc.c (revision 68a052239fc4b351e961f698b824f7654a346091)
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