1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. |
4 | */ |
5 | |
6 | #include <linux/bitops.h> |
7 | #include <linux/completion.h> |
8 | #include <linux/delay.h> |
9 | #include <linux/err.h> |
10 | #include <linux/iio/adc/qcom-vadc-common.h> |
11 | #include <linux/iio/iio.h> |
12 | #include <linux/interrupt.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/math64.h> |
15 | #include <linux/module.h> |
16 | #include <linux/mod_devicetable.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/property.h> |
19 | #include <linux/regmap.h> |
20 | #include <linux/slab.h> |
21 | #include <linux/log2.h> |
22 | |
23 | #include <dt-bindings/iio/qcom,spmi-vadc.h> |
24 | |
25 | /* VADC register and bit definitions */ |
26 | #define VADC_REVISION2 0x1 |
27 | #define VADC_REVISION2_SUPPORTED_VADC 1 |
28 | |
29 | #define VADC_PERPH_TYPE 0x4 |
30 | #define VADC_PERPH_TYPE_ADC 8 |
31 | |
32 | #define VADC_PERPH_SUBTYPE 0x5 |
33 | #define VADC_PERPH_SUBTYPE_VADC 1 |
34 | |
35 | #define VADC_STATUS1 0x8 |
36 | #define VADC_STATUS1_OP_MODE 4 |
37 | #define VADC_STATUS1_REQ_STS BIT(1) |
38 | #define VADC_STATUS1_EOC BIT(0) |
39 | #define VADC_STATUS1_REQ_STS_EOC_MASK 0x3 |
40 | |
41 | #define VADC_MODE_CTL 0x40 |
42 | #define VADC_OP_MODE_SHIFT 3 |
43 | #define VADC_OP_MODE_NORMAL 0 |
44 | #define VADC_AMUX_TRIM_EN BIT(1) |
45 | #define VADC_ADC_TRIM_EN BIT(0) |
46 | |
47 | #define VADC_EN_CTL1 0x46 |
48 | #define VADC_EN_CTL1_SET BIT(7) |
49 | |
50 | #define VADC_ADC_CH_SEL_CTL 0x48 |
51 | |
52 | #define VADC_ADC_DIG_PARAM 0x50 |
53 | #define VADC_ADC_DIG_DEC_RATIO_SEL_SHIFT 2 |
54 | |
55 | #define VADC_HW_SETTLE_DELAY 0x51 |
56 | |
57 | #define VADC_CONV_REQ 0x52 |
58 | #define VADC_CONV_REQ_SET BIT(7) |
59 | |
60 | #define VADC_FAST_AVG_CTL 0x5a |
61 | #define VADC_FAST_AVG_EN 0x5b |
62 | #define VADC_FAST_AVG_EN_SET BIT(7) |
63 | |
64 | #define VADC_ACCESS 0xd0 |
65 | #define VADC_ACCESS_DATA 0xa5 |
66 | |
67 | #define VADC_PERH_RESET_CTL3 0xda |
68 | #define VADC_FOLLOW_WARM_RB BIT(2) |
69 | |
70 | #define VADC_DATA 0x60 /* 16 bits */ |
71 | |
72 | #define VADC_CHAN_MIN VADC_USBIN |
73 | #define VADC_CHAN_MAX VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM |
74 | |
75 | /** |
76 | * struct vadc_channel_prop - VADC channel property. |
77 | * @channel: channel number, refer to the channel list. |
78 | * @calibration: calibration type. |
79 | * @decimation: sampling rate supported for the channel. |
80 | * @prescale: channel scaling performed on the input signal. |
81 | * @hw_settle_time: the time between AMUX being configured and the |
82 | * start of conversion. |
83 | * @avg_samples: ability to provide single result from the ADC |
84 | * that is an average of multiple measurements. |
85 | * @scale_fn_type: Represents the scaling function to convert voltage |
86 | * physical units desired by the client for the channel. |
87 | * @channel_name: Channel name used in device tree. |
88 | */ |
89 | struct vadc_channel_prop { |
90 | unsigned int channel; |
91 | enum vadc_calibration calibration; |
92 | unsigned int decimation; |
93 | unsigned int prescale; |
94 | unsigned int hw_settle_time; |
95 | unsigned int avg_samples; |
96 | enum vadc_scale_fn_type scale_fn_type; |
97 | const char *channel_name; |
98 | }; |
99 | |
100 | /** |
101 | * struct vadc_priv - VADC private structure. |
102 | * @regmap: pointer to struct regmap. |
103 | * @dev: pointer to struct device. |
104 | * @base: base address for the ADC peripheral. |
105 | * @nchannels: number of VADC channels. |
106 | * @chan_props: array of VADC channel properties. |
107 | * @iio_chans: array of IIO channels specification. |
108 | * @are_ref_measured: are reference points measured. |
109 | * @poll_eoc: use polling instead of interrupt. |
110 | * @complete: VADC result notification after interrupt is received. |
111 | * @graph: store parameters for calibration. |
112 | * @lock: ADC lock for access to the peripheral. |
113 | */ |
114 | struct vadc_priv { |
115 | struct regmap *regmap; |
116 | struct device *dev; |
117 | u16 base; |
118 | unsigned int nchannels; |
119 | struct vadc_channel_prop *chan_props; |
120 | struct iio_chan_spec *iio_chans; |
121 | bool are_ref_measured; |
122 | bool poll_eoc; |
123 | struct completion complete; |
124 | struct vadc_linear_graph graph[2]; |
125 | struct mutex lock; |
126 | }; |
127 | |
128 | static const struct u32_fract vadc_prescale_ratios[] = { |
129 | { .numerator = 1, .denominator = 1 }, |
130 | { .numerator = 1, .denominator = 3 }, |
131 | { .numerator = 1, .denominator = 4 }, |
132 | { .numerator = 1, .denominator = 6 }, |
133 | { .numerator = 1, .denominator = 20 }, |
134 | { .numerator = 1, .denominator = 8 }, |
135 | { .numerator = 10, .denominator = 81 }, |
136 | { .numerator = 1, .denominator = 10 }, |
137 | }; |
138 | |
139 | static int vadc_read(struct vadc_priv *vadc, u16 offset, u8 *data) |
140 | { |
141 | return regmap_bulk_read(map: vadc->regmap, reg: vadc->base + offset, val: data, val_count: 1); |
142 | } |
143 | |
144 | static int vadc_write(struct vadc_priv *vadc, u16 offset, u8 data) |
145 | { |
146 | return regmap_write(map: vadc->regmap, reg: vadc->base + offset, val: data); |
147 | } |
148 | |
149 | static int vadc_reset(struct vadc_priv *vadc) |
150 | { |
151 | u8 data; |
152 | int ret; |
153 | |
154 | ret = vadc_write(vadc, VADC_ACCESS, VADC_ACCESS_DATA); |
155 | if (ret) |
156 | return ret; |
157 | |
158 | ret = vadc_read(vadc, VADC_PERH_RESET_CTL3, data: &data); |
159 | if (ret) |
160 | return ret; |
161 | |
162 | ret = vadc_write(vadc, VADC_ACCESS, VADC_ACCESS_DATA); |
163 | if (ret) |
164 | return ret; |
165 | |
166 | data |= VADC_FOLLOW_WARM_RB; |
167 | |
168 | return vadc_write(vadc, VADC_PERH_RESET_CTL3, data); |
169 | } |
170 | |
171 | static int vadc_set_state(struct vadc_priv *vadc, bool state) |
172 | { |
173 | return vadc_write(vadc, VADC_EN_CTL1, data: state ? VADC_EN_CTL1_SET : 0); |
174 | } |
175 | |
176 | static void vadc_show_status(struct vadc_priv *vadc) |
177 | { |
178 | u8 mode, sta1, chan, dig, en, req; |
179 | int ret; |
180 | |
181 | ret = vadc_read(vadc, VADC_MODE_CTL, data: &mode); |
182 | if (ret) |
183 | return; |
184 | |
185 | ret = vadc_read(vadc, VADC_ADC_DIG_PARAM, data: &dig); |
186 | if (ret) |
187 | return; |
188 | |
189 | ret = vadc_read(vadc, VADC_ADC_CH_SEL_CTL, data: &chan); |
190 | if (ret) |
191 | return; |
192 | |
193 | ret = vadc_read(vadc, VADC_CONV_REQ, data: &req); |
194 | if (ret) |
195 | return; |
196 | |
197 | ret = vadc_read(vadc, VADC_STATUS1, data: &sta1); |
198 | if (ret) |
199 | return; |
200 | |
201 | ret = vadc_read(vadc, VADC_EN_CTL1, data: &en); |
202 | if (ret) |
203 | return; |
204 | |
205 | dev_err(vadc->dev, |
206 | "mode:%02x en:%02x chan:%02x dig:%02x req:%02x sta1:%02x\n" , |
207 | mode, en, chan, dig, req, sta1); |
208 | } |
209 | |
210 | static int vadc_configure(struct vadc_priv *vadc, |
211 | struct vadc_channel_prop *prop) |
212 | { |
213 | u8 decimation, mode_ctrl; |
214 | int ret; |
215 | |
216 | /* Mode selection */ |
217 | mode_ctrl = (VADC_OP_MODE_NORMAL << VADC_OP_MODE_SHIFT) | |
218 | VADC_ADC_TRIM_EN | VADC_AMUX_TRIM_EN; |
219 | ret = vadc_write(vadc, VADC_MODE_CTL, data: mode_ctrl); |
220 | if (ret) |
221 | return ret; |
222 | |
223 | /* Channel selection */ |
224 | ret = vadc_write(vadc, VADC_ADC_CH_SEL_CTL, data: prop->channel); |
225 | if (ret) |
226 | return ret; |
227 | |
228 | /* Digital parameter setup */ |
229 | decimation = prop->decimation << VADC_ADC_DIG_DEC_RATIO_SEL_SHIFT; |
230 | ret = vadc_write(vadc, VADC_ADC_DIG_PARAM, data: decimation); |
231 | if (ret) |
232 | return ret; |
233 | |
234 | /* HW settle time delay */ |
235 | ret = vadc_write(vadc, VADC_HW_SETTLE_DELAY, data: prop->hw_settle_time); |
236 | if (ret) |
237 | return ret; |
238 | |
239 | ret = vadc_write(vadc, VADC_FAST_AVG_CTL, data: prop->avg_samples); |
240 | if (ret) |
241 | return ret; |
242 | |
243 | if (prop->avg_samples) |
244 | ret = vadc_write(vadc, VADC_FAST_AVG_EN, VADC_FAST_AVG_EN_SET); |
245 | else |
246 | ret = vadc_write(vadc, VADC_FAST_AVG_EN, data: 0); |
247 | |
248 | return ret; |
249 | } |
250 | |
251 | static int vadc_poll_wait_eoc(struct vadc_priv *vadc, unsigned int interval_us) |
252 | { |
253 | unsigned int count, retry; |
254 | u8 sta1; |
255 | int ret; |
256 | |
257 | retry = interval_us / VADC_CONV_TIME_MIN_US; |
258 | |
259 | for (count = 0; count < retry; count++) { |
260 | ret = vadc_read(vadc, VADC_STATUS1, data: &sta1); |
261 | if (ret) |
262 | return ret; |
263 | |
264 | sta1 &= VADC_STATUS1_REQ_STS_EOC_MASK; |
265 | if (sta1 == VADC_STATUS1_EOC) |
266 | return 0; |
267 | |
268 | usleep_range(VADC_CONV_TIME_MIN_US, VADC_CONV_TIME_MAX_US); |
269 | } |
270 | |
271 | vadc_show_status(vadc); |
272 | |
273 | return -ETIMEDOUT; |
274 | } |
275 | |
276 | static int vadc_read_result(struct vadc_priv *vadc, u16 *data) |
277 | { |
278 | int ret; |
279 | |
280 | ret = regmap_bulk_read(map: vadc->regmap, reg: vadc->base + VADC_DATA, val: data, val_count: 2); |
281 | if (ret) |
282 | return ret; |
283 | |
284 | *data = clamp_t(u16, *data, VADC_MIN_ADC_CODE, VADC_MAX_ADC_CODE); |
285 | |
286 | return 0; |
287 | } |
288 | |
289 | static struct vadc_channel_prop *vadc_get_channel(struct vadc_priv *vadc, |
290 | unsigned int num) |
291 | { |
292 | unsigned int i; |
293 | |
294 | for (i = 0; i < vadc->nchannels; i++) |
295 | if (vadc->chan_props[i].channel == num) |
296 | return &vadc->chan_props[i]; |
297 | |
298 | dev_dbg(vadc->dev, "no such channel %02x\n" , num); |
299 | |
300 | return NULL; |
301 | } |
302 | |
303 | static int vadc_do_conversion(struct vadc_priv *vadc, |
304 | struct vadc_channel_prop *prop, u16 *data) |
305 | { |
306 | unsigned int timeout; |
307 | int ret; |
308 | |
309 | mutex_lock(&vadc->lock); |
310 | |
311 | ret = vadc_configure(vadc, prop); |
312 | if (ret) |
313 | goto unlock; |
314 | |
315 | if (!vadc->poll_eoc) |
316 | reinit_completion(x: &vadc->complete); |
317 | |
318 | ret = vadc_set_state(vadc, state: true); |
319 | if (ret) |
320 | goto unlock; |
321 | |
322 | ret = vadc_write(vadc, VADC_CONV_REQ, VADC_CONV_REQ_SET); |
323 | if (ret) |
324 | goto err_disable; |
325 | |
326 | timeout = BIT(prop->avg_samples) * VADC_CONV_TIME_MIN_US * 2; |
327 | |
328 | if (vadc->poll_eoc) { |
329 | ret = vadc_poll_wait_eoc(vadc, interval_us: timeout); |
330 | } else { |
331 | ret = wait_for_completion_timeout(x: &vadc->complete, timeout); |
332 | if (!ret) { |
333 | ret = -ETIMEDOUT; |
334 | goto err_disable; |
335 | } |
336 | |
337 | /* Double check conversion status */ |
338 | ret = vadc_poll_wait_eoc(vadc, VADC_CONV_TIME_MIN_US); |
339 | if (ret) |
340 | goto err_disable; |
341 | } |
342 | |
343 | ret = vadc_read_result(vadc, data); |
344 | |
345 | err_disable: |
346 | vadc_set_state(vadc, state: false); |
347 | if (ret) |
348 | dev_err(vadc->dev, "conversion failed\n" ); |
349 | unlock: |
350 | mutex_unlock(lock: &vadc->lock); |
351 | return ret; |
352 | } |
353 | |
354 | static int vadc_measure_ref_points(struct vadc_priv *vadc) |
355 | { |
356 | struct vadc_channel_prop *prop; |
357 | u16 read_1, read_2; |
358 | int ret; |
359 | |
360 | vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE; |
361 | vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV; |
362 | |
363 | prop = vadc_get_channel(vadc, VADC_REF_1250MV); |
364 | ret = vadc_do_conversion(vadc, prop, data: &read_1); |
365 | if (ret) |
366 | goto err; |
367 | |
368 | /* Try with buffered 625mV channel first */ |
369 | prop = vadc_get_channel(vadc, VADC_SPARE1); |
370 | if (!prop) |
371 | prop = vadc_get_channel(vadc, VADC_REF_625MV); |
372 | |
373 | ret = vadc_do_conversion(vadc, prop, data: &read_2); |
374 | if (ret) |
375 | goto err; |
376 | |
377 | if (read_1 == read_2) { |
378 | ret = -EINVAL; |
379 | goto err; |
380 | } |
381 | |
382 | vadc->graph[VADC_CALIB_ABSOLUTE].dy = read_1 - read_2; |
383 | vadc->graph[VADC_CALIB_ABSOLUTE].gnd = read_2; |
384 | |
385 | /* Ratiometric calibration */ |
386 | prop = vadc_get_channel(vadc, VADC_VDD_VADC); |
387 | ret = vadc_do_conversion(vadc, prop, data: &read_1); |
388 | if (ret) |
389 | goto err; |
390 | |
391 | prop = vadc_get_channel(vadc, VADC_GND_REF); |
392 | ret = vadc_do_conversion(vadc, prop, data: &read_2); |
393 | if (ret) |
394 | goto err; |
395 | |
396 | if (read_1 == read_2) { |
397 | ret = -EINVAL; |
398 | goto err; |
399 | } |
400 | |
401 | vadc->graph[VADC_CALIB_RATIOMETRIC].dy = read_1 - read_2; |
402 | vadc->graph[VADC_CALIB_RATIOMETRIC].gnd = read_2; |
403 | err: |
404 | if (ret) |
405 | dev_err(vadc->dev, "measure reference points failed\n" ); |
406 | |
407 | return ret; |
408 | } |
409 | |
410 | static int vadc_prescaling_from_dt(u32 numerator, u32 denominator) |
411 | { |
412 | unsigned int pre; |
413 | |
414 | for (pre = 0; pre < ARRAY_SIZE(vadc_prescale_ratios); pre++) |
415 | if (vadc_prescale_ratios[pre].numerator == numerator && |
416 | vadc_prescale_ratios[pre].denominator == denominator) |
417 | break; |
418 | |
419 | if (pre == ARRAY_SIZE(vadc_prescale_ratios)) |
420 | return -EINVAL; |
421 | |
422 | return pre; |
423 | } |
424 | |
425 | static int vadc_hw_settle_time_from_dt(u32 value) |
426 | { |
427 | if ((value <= 1000 && value % 100) || (value > 1000 && value % 2000)) |
428 | return -EINVAL; |
429 | |
430 | if (value <= 1000) |
431 | value /= 100; |
432 | else |
433 | value = value / 2000 + 10; |
434 | |
435 | return value; |
436 | } |
437 | |
438 | static int vadc_avg_samples_from_dt(u32 value) |
439 | { |
440 | if (!is_power_of_2(n: value) || value > VADC_AVG_SAMPLES_MAX) |
441 | return -EINVAL; |
442 | |
443 | return __ffs64(word: value); |
444 | } |
445 | |
446 | static int vadc_read_raw(struct iio_dev *indio_dev, |
447 | struct iio_chan_spec const *chan, int *val, int *val2, |
448 | long mask) |
449 | { |
450 | struct vadc_priv *vadc = iio_priv(indio_dev); |
451 | struct vadc_channel_prop *prop; |
452 | u16 adc_code; |
453 | int ret; |
454 | |
455 | switch (mask) { |
456 | case IIO_CHAN_INFO_PROCESSED: |
457 | prop = &vadc->chan_props[chan->address]; |
458 | ret = vadc_do_conversion(vadc, prop, data: &adc_code); |
459 | if (ret) |
460 | break; |
461 | |
462 | ret = qcom_vadc_scale(scaletype: prop->scale_fn_type, |
463 | calib_graph: &vadc->graph[prop->calibration], |
464 | prescale: &vadc_prescale_ratios[prop->prescale], |
465 | absolute: (prop->calibration == VADC_CALIB_ABSOLUTE), |
466 | adc_code, result_mdec: val); |
467 | if (ret) |
468 | break; |
469 | |
470 | return IIO_VAL_INT; |
471 | case IIO_CHAN_INFO_RAW: |
472 | prop = &vadc->chan_props[chan->address]; |
473 | ret = vadc_do_conversion(vadc, prop, data: &adc_code); |
474 | if (ret) |
475 | break; |
476 | |
477 | *val = (int)adc_code; |
478 | return IIO_VAL_INT; |
479 | default: |
480 | ret = -EINVAL; |
481 | break; |
482 | } |
483 | |
484 | return ret; |
485 | } |
486 | |
487 | static int vadc_fwnode_xlate(struct iio_dev *indio_dev, |
488 | const struct fwnode_reference_args *iiospec) |
489 | { |
490 | struct vadc_priv *vadc = iio_priv(indio_dev); |
491 | unsigned int i; |
492 | |
493 | for (i = 0; i < vadc->nchannels; i++) |
494 | if (vadc->iio_chans[i].channel == iiospec->args[0]) |
495 | return i; |
496 | |
497 | return -EINVAL; |
498 | } |
499 | |
500 | static int vadc_read_label(struct iio_dev *indio_dev, |
501 | struct iio_chan_spec const *chan, char *label) |
502 | { |
503 | struct vadc_priv *vadc = iio_priv(indio_dev); |
504 | const char *name = vadc->chan_props[chan->address].channel_name; |
505 | |
506 | return sysfs_emit(buf: label, fmt: "%s\n" , name); |
507 | } |
508 | |
509 | static const struct iio_info vadc_info = { |
510 | .read_raw = vadc_read_raw, |
511 | .read_label = vadc_read_label, |
512 | .fwnode_xlate = vadc_fwnode_xlate, |
513 | }; |
514 | |
515 | struct vadc_channels { |
516 | const char *datasheet_name; |
517 | unsigned int prescale_index; |
518 | enum iio_chan_type type; |
519 | long info_mask; |
520 | enum vadc_scale_fn_type scale_fn_type; |
521 | }; |
522 | |
523 | #define VADC_CHAN(_dname, _type, _mask, _pre, _scale) \ |
524 | [VADC_##_dname] = { \ |
525 | .datasheet_name = __stringify(_dname), \ |
526 | .prescale_index = _pre, \ |
527 | .type = _type, \ |
528 | .info_mask = _mask, \ |
529 | .scale_fn_type = _scale \ |
530 | }, \ |
531 | |
532 | #define VADC_NO_CHAN(_dname, _type, _mask, _pre) \ |
533 | [VADC_##_dname] = { \ |
534 | .datasheet_name = __stringify(_dname), \ |
535 | .prescale_index = _pre, \ |
536 | .type = _type, \ |
537 | .info_mask = _mask \ |
538 | }, |
539 | |
540 | #define VADC_CHAN_TEMP(_dname, _pre, _scale) \ |
541 | VADC_CHAN(_dname, IIO_TEMP, \ |
542 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED), \ |
543 | _pre, _scale) \ |
544 | |
545 | #define VADC_CHAN_VOLT(_dname, _pre, _scale) \ |
546 | VADC_CHAN(_dname, IIO_VOLTAGE, \ |
547 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED),\ |
548 | _pre, _scale) \ |
549 | |
550 | #define VADC_CHAN_NO_SCALE(_dname, _pre) \ |
551 | VADC_NO_CHAN(_dname, IIO_VOLTAGE, \ |
552 | BIT(IIO_CHAN_INFO_RAW), \ |
553 | _pre) \ |
554 | |
555 | /* |
556 | * The array represents all possible ADC channels found in the supported PMICs. |
557 | * Every index in the array is equal to the channel number per datasheet. The |
558 | * gaps in the array should be treated as reserved channels. |
559 | */ |
560 | static const struct vadc_channels vadc_chans[] = { |
561 | VADC_CHAN_VOLT(USBIN, 4, SCALE_DEFAULT) |
562 | VADC_CHAN_VOLT(DCIN, 4, SCALE_DEFAULT) |
563 | VADC_CHAN_NO_SCALE(VCHG_SNS, 3) |
564 | VADC_CHAN_NO_SCALE(SPARE1_03, 1) |
565 | VADC_CHAN_NO_SCALE(USB_ID_MV, 1) |
566 | VADC_CHAN_VOLT(VCOIN, 1, SCALE_DEFAULT) |
567 | VADC_CHAN_NO_SCALE(VBAT_SNS, 1) |
568 | VADC_CHAN_VOLT(VSYS, 1, SCALE_DEFAULT) |
569 | VADC_CHAN_TEMP(DIE_TEMP, 0, SCALE_PMIC_THERM) |
570 | VADC_CHAN_VOLT(REF_625MV, 0, SCALE_DEFAULT) |
571 | VADC_CHAN_VOLT(REF_1250MV, 0, SCALE_DEFAULT) |
572 | VADC_CHAN_NO_SCALE(CHG_TEMP, 0) |
573 | VADC_CHAN_NO_SCALE(SPARE1, 0) |
574 | VADC_CHAN_TEMP(SPARE2, 0, SCALE_PMI_CHG_TEMP) |
575 | VADC_CHAN_VOLT(GND_REF, 0, SCALE_DEFAULT) |
576 | VADC_CHAN_VOLT(VDD_VADC, 0, SCALE_DEFAULT) |
577 | |
578 | VADC_CHAN_NO_SCALE(P_MUX1_1_1, 0) |
579 | VADC_CHAN_NO_SCALE(P_MUX2_1_1, 0) |
580 | VADC_CHAN_NO_SCALE(P_MUX3_1_1, 0) |
581 | VADC_CHAN_NO_SCALE(P_MUX4_1_1, 0) |
582 | VADC_CHAN_NO_SCALE(P_MUX5_1_1, 0) |
583 | VADC_CHAN_NO_SCALE(P_MUX6_1_1, 0) |
584 | VADC_CHAN_NO_SCALE(P_MUX7_1_1, 0) |
585 | VADC_CHAN_NO_SCALE(P_MUX8_1_1, 0) |
586 | VADC_CHAN_NO_SCALE(P_MUX9_1_1, 0) |
587 | VADC_CHAN_NO_SCALE(P_MUX10_1_1, 0) |
588 | VADC_CHAN_NO_SCALE(P_MUX11_1_1, 0) |
589 | VADC_CHAN_NO_SCALE(P_MUX12_1_1, 0) |
590 | VADC_CHAN_NO_SCALE(P_MUX13_1_1, 0) |
591 | VADC_CHAN_NO_SCALE(P_MUX14_1_1, 0) |
592 | VADC_CHAN_NO_SCALE(P_MUX15_1_1, 0) |
593 | VADC_CHAN_NO_SCALE(P_MUX16_1_1, 0) |
594 | |
595 | VADC_CHAN_NO_SCALE(P_MUX1_1_3, 1) |
596 | VADC_CHAN_NO_SCALE(P_MUX2_1_3, 1) |
597 | VADC_CHAN_NO_SCALE(P_MUX3_1_3, 1) |
598 | VADC_CHAN_NO_SCALE(P_MUX4_1_3, 1) |
599 | VADC_CHAN_NO_SCALE(P_MUX5_1_3, 1) |
600 | VADC_CHAN_NO_SCALE(P_MUX6_1_3, 1) |
601 | VADC_CHAN_NO_SCALE(P_MUX7_1_3, 1) |
602 | VADC_CHAN_NO_SCALE(P_MUX8_1_3, 1) |
603 | VADC_CHAN_NO_SCALE(P_MUX9_1_3, 1) |
604 | VADC_CHAN_NO_SCALE(P_MUX10_1_3, 1) |
605 | VADC_CHAN_NO_SCALE(P_MUX11_1_3, 1) |
606 | VADC_CHAN_NO_SCALE(P_MUX12_1_3, 1) |
607 | VADC_CHAN_NO_SCALE(P_MUX13_1_3, 1) |
608 | VADC_CHAN_NO_SCALE(P_MUX14_1_3, 1) |
609 | VADC_CHAN_NO_SCALE(P_MUX15_1_3, 1) |
610 | VADC_CHAN_NO_SCALE(P_MUX16_1_3, 1) |
611 | |
612 | VADC_CHAN_NO_SCALE(LR_MUX1_BAT_THERM, 0) |
613 | VADC_CHAN_VOLT(LR_MUX2_BAT_ID, 0, SCALE_DEFAULT) |
614 | VADC_CHAN_NO_SCALE(LR_MUX3_XO_THERM, 0) |
615 | VADC_CHAN_NO_SCALE(LR_MUX4_AMUX_THM1, 0) |
616 | VADC_CHAN_NO_SCALE(LR_MUX5_AMUX_THM2, 0) |
617 | VADC_CHAN_NO_SCALE(LR_MUX6_AMUX_THM3, 0) |
618 | VADC_CHAN_NO_SCALE(LR_MUX7_HW_ID, 0) |
619 | VADC_CHAN_NO_SCALE(LR_MUX8_AMUX_THM4, 0) |
620 | VADC_CHAN_NO_SCALE(LR_MUX9_AMUX_THM5, 0) |
621 | VADC_CHAN_NO_SCALE(LR_MUX10_USB_ID, 0) |
622 | VADC_CHAN_NO_SCALE(AMUX_PU1, 0) |
623 | VADC_CHAN_NO_SCALE(AMUX_PU2, 0) |
624 | VADC_CHAN_NO_SCALE(LR_MUX3_BUF_XO_THERM, 0) |
625 | |
626 | VADC_CHAN_NO_SCALE(LR_MUX1_PU1_BAT_THERM, 0) |
627 | VADC_CHAN_NO_SCALE(LR_MUX2_PU1_BAT_ID, 0) |
628 | VADC_CHAN_NO_SCALE(LR_MUX3_PU1_XO_THERM, 0) |
629 | VADC_CHAN_TEMP(LR_MUX4_PU1_AMUX_THM1, 0, SCALE_THERM_100K_PULLUP) |
630 | VADC_CHAN_TEMP(LR_MUX5_PU1_AMUX_THM2, 0, SCALE_THERM_100K_PULLUP) |
631 | VADC_CHAN_TEMP(LR_MUX6_PU1_AMUX_THM3, 0, SCALE_THERM_100K_PULLUP) |
632 | VADC_CHAN_NO_SCALE(LR_MUX7_PU1_AMUX_HW_ID, 0) |
633 | VADC_CHAN_TEMP(LR_MUX8_PU1_AMUX_THM4, 0, SCALE_THERM_100K_PULLUP) |
634 | VADC_CHAN_TEMP(LR_MUX9_PU1_AMUX_THM5, 0, SCALE_THERM_100K_PULLUP) |
635 | VADC_CHAN_NO_SCALE(LR_MUX10_PU1_AMUX_USB_ID, 0) |
636 | VADC_CHAN_TEMP(LR_MUX3_BUF_PU1_XO_THERM, 0, SCALE_XOTHERM) |
637 | |
638 | VADC_CHAN_NO_SCALE(LR_MUX1_PU2_BAT_THERM, 0) |
639 | VADC_CHAN_NO_SCALE(LR_MUX2_PU2_BAT_ID, 0) |
640 | VADC_CHAN_NO_SCALE(LR_MUX3_PU2_XO_THERM, 0) |
641 | VADC_CHAN_NO_SCALE(LR_MUX4_PU2_AMUX_THM1, 0) |
642 | VADC_CHAN_NO_SCALE(LR_MUX5_PU2_AMUX_THM2, 0) |
643 | VADC_CHAN_NO_SCALE(LR_MUX6_PU2_AMUX_THM3, 0) |
644 | VADC_CHAN_NO_SCALE(LR_MUX7_PU2_AMUX_HW_ID, 0) |
645 | VADC_CHAN_NO_SCALE(LR_MUX8_PU2_AMUX_THM4, 0) |
646 | VADC_CHAN_NO_SCALE(LR_MUX9_PU2_AMUX_THM5, 0) |
647 | VADC_CHAN_NO_SCALE(LR_MUX10_PU2_AMUX_USB_ID, 0) |
648 | VADC_CHAN_NO_SCALE(LR_MUX3_BUF_PU2_XO_THERM, 0) |
649 | |
650 | VADC_CHAN_NO_SCALE(LR_MUX1_PU1_PU2_BAT_THERM, 0) |
651 | VADC_CHAN_NO_SCALE(LR_MUX2_PU1_PU2_BAT_ID, 0) |
652 | VADC_CHAN_NO_SCALE(LR_MUX3_PU1_PU2_XO_THERM, 0) |
653 | VADC_CHAN_NO_SCALE(LR_MUX4_PU1_PU2_AMUX_THM1, 0) |
654 | VADC_CHAN_NO_SCALE(LR_MUX5_PU1_PU2_AMUX_THM2, 0) |
655 | VADC_CHAN_NO_SCALE(LR_MUX6_PU1_PU2_AMUX_THM3, 0) |
656 | VADC_CHAN_NO_SCALE(LR_MUX7_PU1_PU2_AMUX_HW_ID, 0) |
657 | VADC_CHAN_NO_SCALE(LR_MUX8_PU1_PU2_AMUX_THM4, 0) |
658 | VADC_CHAN_NO_SCALE(LR_MUX9_PU1_PU2_AMUX_THM5, 0) |
659 | VADC_CHAN_NO_SCALE(LR_MUX10_PU1_PU2_AMUX_USB_ID, 0) |
660 | VADC_CHAN_NO_SCALE(LR_MUX3_BUF_PU1_PU2_XO_THERM, 0) |
661 | }; |
662 | |
663 | static int vadc_get_fw_channel_data(struct device *dev, |
664 | struct vadc_channel_prop *prop, |
665 | struct fwnode_handle *fwnode) |
666 | { |
667 | const char *name = fwnode_get_name(fwnode), *label; |
668 | u32 chan, value, varr[2]; |
669 | int ret; |
670 | |
671 | ret = fwnode_property_read_u32(fwnode, propname: "reg" , val: &chan); |
672 | if (ret) { |
673 | dev_err(dev, "invalid channel number %s\n" , name); |
674 | return ret; |
675 | } |
676 | |
677 | if (chan > VADC_CHAN_MAX || chan < VADC_CHAN_MIN) { |
678 | dev_err(dev, "%s invalid channel number %d\n" , name, chan); |
679 | return -EINVAL; |
680 | } |
681 | |
682 | ret = fwnode_property_read_string(fwnode, propname: "label" , val: &label); |
683 | if (ret) |
684 | label = vadc_chans[chan].datasheet_name; |
685 | prop->channel_name = label; |
686 | |
687 | /* the channel has DT description */ |
688 | prop->channel = chan; |
689 | |
690 | ret = fwnode_property_read_u32(fwnode, propname: "qcom,decimation" , val: &value); |
691 | if (!ret) { |
692 | ret = qcom_vadc_decimation_from_dt(value); |
693 | if (ret < 0) { |
694 | dev_err(dev, "%02x invalid decimation %d\n" , |
695 | chan, value); |
696 | return ret; |
697 | } |
698 | prop->decimation = ret; |
699 | } else { |
700 | prop->decimation = VADC_DEF_DECIMATION; |
701 | } |
702 | |
703 | ret = fwnode_property_read_u32_array(fwnode, propname: "qcom,pre-scaling" , val: varr, nval: 2); |
704 | if (!ret) { |
705 | ret = vadc_prescaling_from_dt(numerator: varr[0], denominator: varr[1]); |
706 | if (ret < 0) { |
707 | dev_err(dev, "%02x invalid pre-scaling <%d %d>\n" , |
708 | chan, varr[0], varr[1]); |
709 | return ret; |
710 | } |
711 | prop->prescale = ret; |
712 | } else { |
713 | prop->prescale = vadc_chans[prop->channel].prescale_index; |
714 | } |
715 | |
716 | ret = fwnode_property_read_u32(fwnode, propname: "qcom,hw-settle-time" , val: &value); |
717 | if (!ret) { |
718 | ret = vadc_hw_settle_time_from_dt(value); |
719 | if (ret < 0) { |
720 | dev_err(dev, "%02x invalid hw-settle-time %d us\n" , |
721 | chan, value); |
722 | return ret; |
723 | } |
724 | prop->hw_settle_time = ret; |
725 | } else { |
726 | prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME; |
727 | } |
728 | |
729 | ret = fwnode_property_read_u32(fwnode, propname: "qcom,avg-samples" , val: &value); |
730 | if (!ret) { |
731 | ret = vadc_avg_samples_from_dt(value); |
732 | if (ret < 0) { |
733 | dev_err(dev, "%02x invalid avg-samples %d\n" , |
734 | chan, value); |
735 | return ret; |
736 | } |
737 | prop->avg_samples = ret; |
738 | } else { |
739 | prop->avg_samples = VADC_DEF_AVG_SAMPLES; |
740 | } |
741 | |
742 | if (fwnode_property_read_bool(fwnode, propname: "qcom,ratiometric" )) |
743 | prop->calibration = VADC_CALIB_RATIOMETRIC; |
744 | else |
745 | prop->calibration = VADC_CALIB_ABSOLUTE; |
746 | |
747 | dev_dbg(dev, "%02x name %s\n" , chan, name); |
748 | |
749 | return 0; |
750 | } |
751 | |
752 | static int vadc_get_fw_data(struct vadc_priv *vadc) |
753 | { |
754 | const struct vadc_channels *vadc_chan; |
755 | struct iio_chan_spec *iio_chan; |
756 | struct vadc_channel_prop prop; |
757 | struct fwnode_handle *child; |
758 | unsigned int index = 0; |
759 | int ret; |
760 | |
761 | vadc->nchannels = device_get_child_node_count(dev: vadc->dev); |
762 | if (!vadc->nchannels) |
763 | return -EINVAL; |
764 | |
765 | vadc->iio_chans = devm_kcalloc(dev: vadc->dev, n: vadc->nchannels, |
766 | size: sizeof(*vadc->iio_chans), GFP_KERNEL); |
767 | if (!vadc->iio_chans) |
768 | return -ENOMEM; |
769 | |
770 | vadc->chan_props = devm_kcalloc(dev: vadc->dev, n: vadc->nchannels, |
771 | size: sizeof(*vadc->chan_props), GFP_KERNEL); |
772 | if (!vadc->chan_props) |
773 | return -ENOMEM; |
774 | |
775 | iio_chan = vadc->iio_chans; |
776 | |
777 | device_for_each_child_node(vadc->dev, child) { |
778 | ret = vadc_get_fw_channel_data(dev: vadc->dev, prop: &prop, fwnode: child); |
779 | if (ret) { |
780 | fwnode_handle_put(fwnode: child); |
781 | return ret; |
782 | } |
783 | |
784 | prop.scale_fn_type = vadc_chans[prop.channel].scale_fn_type; |
785 | vadc->chan_props[index] = prop; |
786 | |
787 | vadc_chan = &vadc_chans[prop.channel]; |
788 | |
789 | iio_chan->channel = prop.channel; |
790 | iio_chan->datasheet_name = vadc_chan->datasheet_name; |
791 | iio_chan->info_mask_separate = vadc_chan->info_mask; |
792 | iio_chan->type = vadc_chan->type; |
793 | iio_chan->indexed = 1; |
794 | iio_chan->address = index++; |
795 | |
796 | iio_chan++; |
797 | } |
798 | |
799 | /* These channels are mandatory, they are used as reference points */ |
800 | if (!vadc_get_channel(vadc, VADC_REF_1250MV)) { |
801 | dev_err(vadc->dev, "Please define 1.25V channel\n" ); |
802 | return -ENODEV; |
803 | } |
804 | |
805 | if (!vadc_get_channel(vadc, VADC_REF_625MV)) { |
806 | dev_err(vadc->dev, "Please define 0.625V channel\n" ); |
807 | return -ENODEV; |
808 | } |
809 | |
810 | if (!vadc_get_channel(vadc, VADC_VDD_VADC)) { |
811 | dev_err(vadc->dev, "Please define VDD channel\n" ); |
812 | return -ENODEV; |
813 | } |
814 | |
815 | if (!vadc_get_channel(vadc, VADC_GND_REF)) { |
816 | dev_err(vadc->dev, "Please define GND channel\n" ); |
817 | return -ENODEV; |
818 | } |
819 | |
820 | return 0; |
821 | } |
822 | |
823 | static irqreturn_t vadc_isr(int irq, void *dev_id) |
824 | { |
825 | struct vadc_priv *vadc = dev_id; |
826 | |
827 | complete(&vadc->complete); |
828 | |
829 | return IRQ_HANDLED; |
830 | } |
831 | |
832 | static int vadc_check_revision(struct vadc_priv *vadc) |
833 | { |
834 | u8 val; |
835 | int ret; |
836 | |
837 | ret = vadc_read(vadc, VADC_PERPH_TYPE, data: &val); |
838 | if (ret) |
839 | return ret; |
840 | |
841 | if (val < VADC_PERPH_TYPE_ADC) { |
842 | dev_err(vadc->dev, "%d is not ADC\n" , val); |
843 | return -ENODEV; |
844 | } |
845 | |
846 | ret = vadc_read(vadc, VADC_PERPH_SUBTYPE, data: &val); |
847 | if (ret) |
848 | return ret; |
849 | |
850 | if (val < VADC_PERPH_SUBTYPE_VADC) { |
851 | dev_err(vadc->dev, "%d is not VADC\n" , val); |
852 | return -ENODEV; |
853 | } |
854 | |
855 | ret = vadc_read(vadc, VADC_REVISION2, data: &val); |
856 | if (ret) |
857 | return ret; |
858 | |
859 | if (val < VADC_REVISION2_SUPPORTED_VADC) { |
860 | dev_err(vadc->dev, "revision %d not supported\n" , val); |
861 | return -ENODEV; |
862 | } |
863 | |
864 | return 0; |
865 | } |
866 | |
867 | static int vadc_probe(struct platform_device *pdev) |
868 | { |
869 | struct device *dev = &pdev->dev; |
870 | struct iio_dev *indio_dev; |
871 | struct vadc_priv *vadc; |
872 | struct regmap *regmap; |
873 | int ret, irq_eoc; |
874 | u32 reg; |
875 | |
876 | regmap = dev_get_regmap(dev: dev->parent, NULL); |
877 | if (!regmap) |
878 | return -ENODEV; |
879 | |
880 | ret = device_property_read_u32(dev, propname: "reg" , val: ®); |
881 | if (ret < 0) |
882 | return ret; |
883 | |
884 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*vadc)); |
885 | if (!indio_dev) |
886 | return -ENOMEM; |
887 | |
888 | vadc = iio_priv(indio_dev); |
889 | vadc->regmap = regmap; |
890 | vadc->dev = dev; |
891 | vadc->base = reg; |
892 | vadc->are_ref_measured = false; |
893 | init_completion(x: &vadc->complete); |
894 | mutex_init(&vadc->lock); |
895 | |
896 | ret = vadc_check_revision(vadc); |
897 | if (ret) |
898 | return ret; |
899 | |
900 | ret = vadc_get_fw_data(vadc); |
901 | if (ret) |
902 | return ret; |
903 | |
904 | irq_eoc = platform_get_irq(pdev, 0); |
905 | if (irq_eoc < 0) { |
906 | if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL) |
907 | return irq_eoc; |
908 | vadc->poll_eoc = true; |
909 | } else { |
910 | ret = devm_request_irq(dev, irq: irq_eoc, handler: vadc_isr, irqflags: 0, |
911 | devname: "spmi-vadc" , dev_id: vadc); |
912 | if (ret) |
913 | return ret; |
914 | } |
915 | |
916 | ret = vadc_reset(vadc); |
917 | if (ret) { |
918 | dev_err(dev, "reset failed\n" ); |
919 | return ret; |
920 | } |
921 | |
922 | ret = vadc_measure_ref_points(vadc); |
923 | if (ret) |
924 | return ret; |
925 | |
926 | indio_dev->name = pdev->name; |
927 | indio_dev->modes = INDIO_DIRECT_MODE; |
928 | indio_dev->info = &vadc_info; |
929 | indio_dev->channels = vadc->iio_chans; |
930 | indio_dev->num_channels = vadc->nchannels; |
931 | |
932 | return devm_iio_device_register(dev, indio_dev); |
933 | } |
934 | |
935 | static const struct of_device_id vadc_match_table[] = { |
936 | { .compatible = "qcom,spmi-vadc" }, |
937 | { } |
938 | }; |
939 | MODULE_DEVICE_TABLE(of, vadc_match_table); |
940 | |
941 | static struct platform_driver vadc_driver = { |
942 | .driver = { |
943 | .name = "qcom-spmi-vadc" , |
944 | .of_match_table = vadc_match_table, |
945 | }, |
946 | .probe = vadc_probe, |
947 | }; |
948 | module_platform_driver(vadc_driver); |
949 | |
950 | MODULE_ALIAS("platform:qcom-spmi-vadc" ); |
951 | MODULE_DESCRIPTION("Qualcomm SPMI PMIC voltage ADC driver" ); |
952 | MODULE_LICENSE("GPL v2" ); |
953 | MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>" ); |
954 | MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>" ); |
955 | |