1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (C) 2018 Spreadtrum Communications Inc. |
3 | |
4 | #include <linux/hwspinlock.h> |
5 | #include <linux/iio/iio.h> |
6 | #include <linux/module.h> |
7 | #include <linux/mutex.h> |
8 | #include <linux/nvmem-consumer.h> |
9 | #include <linux/of.h> |
10 | #include <linux/platform_device.h> |
11 | #include <linux/regmap.h> |
12 | #include <linux/regulator/consumer.h> |
13 | #include <linux/slab.h> |
14 | |
15 | /* PMIC global registers definition */ |
16 | #define SC2730_MODULE_EN 0x1808 |
17 | #define SC2731_MODULE_EN 0xc08 |
18 | #define SC27XX_MODULE_ADC_EN BIT(5) |
19 | #define SC2721_ARM_CLK_EN 0xc0c |
20 | #define SC2730_ARM_CLK_EN 0x180c |
21 | #define SC2731_ARM_CLK_EN 0xc10 |
22 | #define SC27XX_CLK_ADC_EN BIT(5) |
23 | #define SC27XX_CLK_ADC_CLK_EN BIT(6) |
24 | |
25 | /* ADC controller registers definition */ |
26 | #define SC27XX_ADC_CTL 0x0 |
27 | #define SC27XX_ADC_CH_CFG 0x4 |
28 | #define SC27XX_ADC_DATA 0x4c |
29 | #define SC27XX_ADC_INT_EN 0x50 |
30 | #define SC27XX_ADC_INT_CLR 0x54 |
31 | #define SC27XX_ADC_INT_STS 0x58 |
32 | #define SC27XX_ADC_INT_RAW 0x5c |
33 | |
34 | /* Bits and mask definition for SC27XX_ADC_CTL register */ |
35 | #define SC27XX_ADC_EN BIT(0) |
36 | #define SC27XX_ADC_CHN_RUN BIT(1) |
37 | #define SC27XX_ADC_12BIT_MODE BIT(2) |
38 | #define SC27XX_ADC_RUN_NUM_MASK GENMASK(7, 4) |
39 | #define SC27XX_ADC_RUN_NUM_SHIFT 4 |
40 | |
41 | /* Bits and mask definition for SC27XX_ADC_CH_CFG register */ |
42 | #define SC27XX_ADC_CHN_ID_MASK GENMASK(4, 0) |
43 | #define SC27XX_ADC_SCALE_MASK GENMASK(10, 9) |
44 | #define SC2721_ADC_SCALE_MASK BIT(5) |
45 | #define SC27XX_ADC_SCALE_SHIFT 9 |
46 | #define SC2721_ADC_SCALE_SHIFT 5 |
47 | |
48 | /* Bits definitions for SC27XX_ADC_INT_EN registers */ |
49 | #define SC27XX_ADC_IRQ_EN BIT(0) |
50 | |
51 | /* Bits definitions for SC27XX_ADC_INT_CLR registers */ |
52 | #define SC27XX_ADC_IRQ_CLR BIT(0) |
53 | |
54 | /* Bits definitions for SC27XX_ADC_INT_RAW registers */ |
55 | #define SC27XX_ADC_IRQ_RAW BIT(0) |
56 | |
57 | /* Mask definition for SC27XX_ADC_DATA register */ |
58 | #define SC27XX_ADC_DATA_MASK GENMASK(11, 0) |
59 | |
60 | /* Timeout (ms) for the trylock of hardware spinlocks */ |
61 | #define SC27XX_ADC_HWLOCK_TIMEOUT 5000 |
62 | |
63 | /* Timeout (us) for ADC data conversion according to ADC datasheet */ |
64 | #define SC27XX_ADC_RDY_TIMEOUT 1000000 |
65 | #define SC27XX_ADC_POLL_RAW_STATUS 500 |
66 | |
67 | /* Maximum ADC channel number */ |
68 | #define SC27XX_ADC_CHANNEL_MAX 32 |
69 | |
70 | /* ADC voltage ratio definition */ |
71 | #define SC27XX_VOLT_RATIO(n, d) \ |
72 | (((n) << SC27XX_RATIO_NUMERATOR_OFFSET) | (d)) |
73 | #define SC27XX_RATIO_NUMERATOR_OFFSET 16 |
74 | #define SC27XX_RATIO_DENOMINATOR_MASK GENMASK(15, 0) |
75 | |
76 | /* ADC specific channel reference voltage 3.5V */ |
77 | #define SC27XX_ADC_REFVOL_VDD35 3500000 |
78 | |
79 | /* ADC default channel reference voltage is 2.8V */ |
80 | #define SC27XX_ADC_REFVOL_VDD28 2800000 |
81 | |
82 | struct sc27xx_adc_data { |
83 | struct device *dev; |
84 | struct regulator *volref; |
85 | struct regmap *regmap; |
86 | /* lock to protect against multiple access to the device */ |
87 | struct mutex lock; |
88 | /* |
89 | * One hardware spinlock to synchronize between the multiple |
90 | * subsystems which will access the unique ADC controller. |
91 | */ |
92 | struct hwspinlock *hwlock; |
93 | int channel_scale[SC27XX_ADC_CHANNEL_MAX]; |
94 | u32 base; |
95 | int irq; |
96 | const struct sc27xx_adc_variant_data *var_data; |
97 | }; |
98 | |
99 | /* |
100 | * Since different PMICs of SC27xx series can have different |
101 | * address and ratio, we should save ratio config and base |
102 | * in the device data structure. |
103 | */ |
104 | struct sc27xx_adc_variant_data { |
105 | u32 module_en; |
106 | u32 clk_en; |
107 | u32 scale_shift; |
108 | u32 scale_mask; |
109 | const struct sc27xx_adc_linear_graph *bscale_cal; |
110 | const struct sc27xx_adc_linear_graph *sscale_cal; |
111 | void (*init_scale)(struct sc27xx_adc_data *data); |
112 | int (*get_ratio)(int channel, int scale); |
113 | bool set_volref; |
114 | }; |
115 | |
116 | struct sc27xx_adc_linear_graph { |
117 | int volt0; |
118 | int adc0; |
119 | int volt1; |
120 | int adc1; |
121 | }; |
122 | |
123 | /* |
124 | * According to the datasheet, we can convert one ADC value to one voltage value |
125 | * through 2 points in the linear graph. If the voltage is less than 1.2v, we |
126 | * should use the small-scale graph, and if more than 1.2v, we should use the |
127 | * big-scale graph. |
128 | */ |
129 | static struct sc27xx_adc_linear_graph big_scale_graph = { |
130 | 4200, 3310, |
131 | 3600, 2832, |
132 | }; |
133 | |
134 | static struct sc27xx_adc_linear_graph small_scale_graph = { |
135 | 1000, 3413, |
136 | 100, 341, |
137 | }; |
138 | |
139 | static const struct sc27xx_adc_linear_graph sc2731_big_scale_graph_calib = { |
140 | 4200, 850, |
141 | 3600, 728, |
142 | }; |
143 | |
144 | static const struct sc27xx_adc_linear_graph sc2731_small_scale_graph_calib = { |
145 | 1000, 838, |
146 | 100, 84, |
147 | }; |
148 | |
149 | static const struct sc27xx_adc_linear_graph big_scale_graph_calib = { |
150 | 4200, 856, |
151 | 3600, 733, |
152 | }; |
153 | |
154 | static const struct sc27xx_adc_linear_graph small_scale_graph_calib = { |
155 | 1000, 833, |
156 | 100, 80, |
157 | }; |
158 | |
159 | static int sc27xx_adc_get_calib_data(u32 calib_data, int calib_adc) |
160 | { |
161 | return ((calib_data & 0xff) + calib_adc - 128) * 4; |
162 | } |
163 | |
164 | /* get the adc nvmem cell calibration data */ |
165 | static int adc_nvmem_cell_calib_data(struct sc27xx_adc_data *data, const char *cell_name) |
166 | { |
167 | struct nvmem_cell *cell; |
168 | void *buf; |
169 | u32 origin_calib_data = 0; |
170 | size_t len; |
171 | |
172 | if (!data) |
173 | return -EINVAL; |
174 | |
175 | cell = nvmem_cell_get(dev: data->dev, id: cell_name); |
176 | if (IS_ERR(ptr: cell)) |
177 | return PTR_ERR(ptr: cell); |
178 | |
179 | buf = nvmem_cell_read(cell, len: &len); |
180 | if (IS_ERR(ptr: buf)) { |
181 | nvmem_cell_put(cell); |
182 | return PTR_ERR(ptr: buf); |
183 | } |
184 | |
185 | memcpy(&origin_calib_data, buf, min(len, sizeof(u32))); |
186 | |
187 | kfree(objp: buf); |
188 | nvmem_cell_put(cell); |
189 | return origin_calib_data; |
190 | } |
191 | |
192 | static int sc27xx_adc_scale_calibration(struct sc27xx_adc_data *data, |
193 | bool big_scale) |
194 | { |
195 | const struct sc27xx_adc_linear_graph *calib_graph; |
196 | struct sc27xx_adc_linear_graph *graph; |
197 | const char *cell_name; |
198 | u32 calib_data = 0; |
199 | |
200 | if (big_scale) { |
201 | calib_graph = data->var_data->bscale_cal; |
202 | graph = &big_scale_graph; |
203 | cell_name = "big_scale_calib" ; |
204 | } else { |
205 | calib_graph = data->var_data->sscale_cal; |
206 | graph = &small_scale_graph; |
207 | cell_name = "small_scale_calib" ; |
208 | } |
209 | |
210 | calib_data = adc_nvmem_cell_calib_data(data, cell_name); |
211 | |
212 | /* Only need to calibrate the adc values in the linear graph. */ |
213 | graph->adc0 = sc27xx_adc_get_calib_data(calib_data, calib_adc: calib_graph->adc0); |
214 | graph->adc1 = sc27xx_adc_get_calib_data(calib_data: calib_data >> 8, |
215 | calib_adc: calib_graph->adc1); |
216 | |
217 | return 0; |
218 | } |
219 | |
220 | static int sc2720_adc_get_ratio(int channel, int scale) |
221 | { |
222 | switch (channel) { |
223 | case 14: |
224 | switch (scale) { |
225 | case 0: |
226 | return SC27XX_VOLT_RATIO(68, 900); |
227 | case 1: |
228 | return SC27XX_VOLT_RATIO(68, 1760); |
229 | case 2: |
230 | return SC27XX_VOLT_RATIO(68, 2327); |
231 | case 3: |
232 | return SC27XX_VOLT_RATIO(68, 3654); |
233 | default: |
234 | return SC27XX_VOLT_RATIO(1, 1); |
235 | } |
236 | case 16: |
237 | switch (scale) { |
238 | case 0: |
239 | return SC27XX_VOLT_RATIO(48, 100); |
240 | case 1: |
241 | return SC27XX_VOLT_RATIO(480, 1955); |
242 | case 2: |
243 | return SC27XX_VOLT_RATIO(480, 2586); |
244 | case 3: |
245 | return SC27XX_VOLT_RATIO(48, 406); |
246 | default: |
247 | return SC27XX_VOLT_RATIO(1, 1); |
248 | } |
249 | case 21: |
250 | case 22: |
251 | case 23: |
252 | switch (scale) { |
253 | case 0: |
254 | return SC27XX_VOLT_RATIO(3, 8); |
255 | case 1: |
256 | return SC27XX_VOLT_RATIO(375, 1955); |
257 | case 2: |
258 | return SC27XX_VOLT_RATIO(375, 2586); |
259 | case 3: |
260 | return SC27XX_VOLT_RATIO(300, 3248); |
261 | default: |
262 | return SC27XX_VOLT_RATIO(1, 1); |
263 | } |
264 | default: |
265 | switch (scale) { |
266 | case 0: |
267 | return SC27XX_VOLT_RATIO(1, 1); |
268 | case 1: |
269 | return SC27XX_VOLT_RATIO(1000, 1955); |
270 | case 2: |
271 | return SC27XX_VOLT_RATIO(1000, 2586); |
272 | case 3: |
273 | return SC27XX_VOLT_RATIO(100, 406); |
274 | default: |
275 | return SC27XX_VOLT_RATIO(1, 1); |
276 | } |
277 | } |
278 | return SC27XX_VOLT_RATIO(1, 1); |
279 | } |
280 | |
281 | static int sc2721_adc_get_ratio(int channel, int scale) |
282 | { |
283 | switch (channel) { |
284 | case 1: |
285 | case 2: |
286 | case 3: |
287 | case 4: |
288 | return scale ? SC27XX_VOLT_RATIO(400, 1025) : |
289 | SC27XX_VOLT_RATIO(1, 1); |
290 | case 5: |
291 | return SC27XX_VOLT_RATIO(7, 29); |
292 | case 7: |
293 | case 9: |
294 | return scale ? SC27XX_VOLT_RATIO(100, 125) : |
295 | SC27XX_VOLT_RATIO(1, 1); |
296 | case 14: |
297 | return SC27XX_VOLT_RATIO(68, 900); |
298 | case 16: |
299 | return SC27XX_VOLT_RATIO(48, 100); |
300 | case 19: |
301 | return SC27XX_VOLT_RATIO(1, 3); |
302 | default: |
303 | return SC27XX_VOLT_RATIO(1, 1); |
304 | } |
305 | return SC27XX_VOLT_RATIO(1, 1); |
306 | } |
307 | |
308 | static int sc2730_adc_get_ratio(int channel, int scale) |
309 | { |
310 | switch (channel) { |
311 | case 14: |
312 | switch (scale) { |
313 | case 0: |
314 | return SC27XX_VOLT_RATIO(68, 900); |
315 | case 1: |
316 | return SC27XX_VOLT_RATIO(68, 1760); |
317 | case 2: |
318 | return SC27XX_VOLT_RATIO(68, 2327); |
319 | case 3: |
320 | return SC27XX_VOLT_RATIO(68, 3654); |
321 | default: |
322 | return SC27XX_VOLT_RATIO(1, 1); |
323 | } |
324 | case 15: |
325 | switch (scale) { |
326 | case 0: |
327 | return SC27XX_VOLT_RATIO(1, 3); |
328 | case 1: |
329 | return SC27XX_VOLT_RATIO(1000, 5865); |
330 | case 2: |
331 | return SC27XX_VOLT_RATIO(500, 3879); |
332 | case 3: |
333 | return SC27XX_VOLT_RATIO(500, 6090); |
334 | default: |
335 | return SC27XX_VOLT_RATIO(1, 1); |
336 | } |
337 | case 16: |
338 | switch (scale) { |
339 | case 0: |
340 | return SC27XX_VOLT_RATIO(48, 100); |
341 | case 1: |
342 | return SC27XX_VOLT_RATIO(480, 1955); |
343 | case 2: |
344 | return SC27XX_VOLT_RATIO(480, 2586); |
345 | case 3: |
346 | return SC27XX_VOLT_RATIO(48, 406); |
347 | default: |
348 | return SC27XX_VOLT_RATIO(1, 1); |
349 | } |
350 | case 21: |
351 | case 22: |
352 | case 23: |
353 | switch (scale) { |
354 | case 0: |
355 | return SC27XX_VOLT_RATIO(3, 8); |
356 | case 1: |
357 | return SC27XX_VOLT_RATIO(375, 1955); |
358 | case 2: |
359 | return SC27XX_VOLT_RATIO(375, 2586); |
360 | case 3: |
361 | return SC27XX_VOLT_RATIO(300, 3248); |
362 | default: |
363 | return SC27XX_VOLT_RATIO(1, 1); |
364 | } |
365 | default: |
366 | switch (scale) { |
367 | case 0: |
368 | return SC27XX_VOLT_RATIO(1, 1); |
369 | case 1: |
370 | return SC27XX_VOLT_RATIO(1000, 1955); |
371 | case 2: |
372 | return SC27XX_VOLT_RATIO(1000, 2586); |
373 | case 3: |
374 | return SC27XX_VOLT_RATIO(1000, 4060); |
375 | default: |
376 | return SC27XX_VOLT_RATIO(1, 1); |
377 | } |
378 | } |
379 | return SC27XX_VOLT_RATIO(1, 1); |
380 | } |
381 | |
382 | static int sc2731_adc_get_ratio(int channel, int scale) |
383 | { |
384 | switch (channel) { |
385 | case 1: |
386 | case 2: |
387 | case 3: |
388 | case 4: |
389 | return scale ? SC27XX_VOLT_RATIO(400, 1025) : |
390 | SC27XX_VOLT_RATIO(1, 1); |
391 | case 5: |
392 | return SC27XX_VOLT_RATIO(7, 29); |
393 | case 6: |
394 | return SC27XX_VOLT_RATIO(375, 9000); |
395 | case 7: |
396 | case 8: |
397 | return scale ? SC27XX_VOLT_RATIO(100, 125) : |
398 | SC27XX_VOLT_RATIO(1, 1); |
399 | case 19: |
400 | return SC27XX_VOLT_RATIO(1, 3); |
401 | default: |
402 | return SC27XX_VOLT_RATIO(1, 1); |
403 | } |
404 | return SC27XX_VOLT_RATIO(1, 1); |
405 | } |
406 | |
407 | /* |
408 | * According to the datasheet set specific value on some channel. |
409 | */ |
410 | static void sc2720_adc_scale_init(struct sc27xx_adc_data *data) |
411 | { |
412 | int i; |
413 | |
414 | for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) { |
415 | switch (i) { |
416 | case 5: |
417 | data->channel_scale[i] = 3; |
418 | break; |
419 | case 7: |
420 | case 9: |
421 | data->channel_scale[i] = 2; |
422 | break; |
423 | case 13: |
424 | data->channel_scale[i] = 1; |
425 | break; |
426 | case 19: |
427 | case 30: |
428 | case 31: |
429 | data->channel_scale[i] = 3; |
430 | break; |
431 | default: |
432 | data->channel_scale[i] = 0; |
433 | break; |
434 | } |
435 | } |
436 | } |
437 | |
438 | static void sc2730_adc_scale_init(struct sc27xx_adc_data *data) |
439 | { |
440 | int i; |
441 | |
442 | for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) { |
443 | switch (i) { |
444 | case 5: |
445 | case 10: |
446 | case 19: |
447 | case 30: |
448 | case 31: |
449 | data->channel_scale[i] = 3; |
450 | break; |
451 | case 7: |
452 | case 9: |
453 | data->channel_scale[i] = 2; |
454 | break; |
455 | case 13: |
456 | data->channel_scale[i] = 1; |
457 | break; |
458 | default: |
459 | data->channel_scale[i] = 0; |
460 | break; |
461 | } |
462 | } |
463 | } |
464 | |
465 | static void sc2731_adc_scale_init(struct sc27xx_adc_data *data) |
466 | { |
467 | int i; |
468 | /* |
469 | * In the current software design, SC2731 support 2 scales, |
470 | * channels 5 uses big scale, others use smale. |
471 | */ |
472 | for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) { |
473 | switch (i) { |
474 | case 5: |
475 | data->channel_scale[i] = 1; |
476 | break; |
477 | default: |
478 | data->channel_scale[i] = 0; |
479 | break; |
480 | } |
481 | } |
482 | } |
483 | |
484 | static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, |
485 | int scale, int *val) |
486 | { |
487 | int ret, ret_volref; |
488 | u32 tmp, value, status; |
489 | |
490 | ret = hwspin_lock_timeout_raw(hwlock: data->hwlock, SC27XX_ADC_HWLOCK_TIMEOUT); |
491 | if (ret) { |
492 | dev_err(data->dev, "timeout to get the hwspinlock\n" ); |
493 | return ret; |
494 | } |
495 | |
496 | /* |
497 | * According to the sc2721 chip data sheet, the reference voltage of |
498 | * specific channel 30 and channel 31 in ADC module needs to be set from |
499 | * the default 2.8v to 3.5v. |
500 | */ |
501 | if ((data->var_data->set_volref) && (channel == 30 || channel == 31)) { |
502 | ret = regulator_set_voltage(regulator: data->volref, |
503 | SC27XX_ADC_REFVOL_VDD35, |
504 | SC27XX_ADC_REFVOL_VDD35); |
505 | if (ret) { |
506 | dev_err(data->dev, "failed to set the volref 3.5v\n" ); |
507 | goto unlock_adc; |
508 | } |
509 | } |
510 | |
511 | ret = regmap_update_bits(map: data->regmap, reg: data->base + SC27XX_ADC_CTL, |
512 | SC27XX_ADC_EN, SC27XX_ADC_EN); |
513 | if (ret) |
514 | goto regulator_restore; |
515 | |
516 | ret = regmap_update_bits(map: data->regmap, reg: data->base + SC27XX_ADC_INT_CLR, |
517 | SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR); |
518 | if (ret) |
519 | goto disable_adc; |
520 | |
521 | /* Configure the channel id and scale */ |
522 | tmp = (scale << data->var_data->scale_shift) & data->var_data->scale_mask; |
523 | tmp |= channel & SC27XX_ADC_CHN_ID_MASK; |
524 | ret = regmap_update_bits(map: data->regmap, reg: data->base + SC27XX_ADC_CH_CFG, |
525 | SC27XX_ADC_CHN_ID_MASK | |
526 | data->var_data->scale_mask, |
527 | val: tmp); |
528 | if (ret) |
529 | goto disable_adc; |
530 | |
531 | /* Select 12bit conversion mode, and only sample 1 time */ |
532 | tmp = SC27XX_ADC_12BIT_MODE; |
533 | tmp |= (0 << SC27XX_ADC_RUN_NUM_SHIFT) & SC27XX_ADC_RUN_NUM_MASK; |
534 | ret = regmap_update_bits(map: data->regmap, reg: data->base + SC27XX_ADC_CTL, |
535 | SC27XX_ADC_RUN_NUM_MASK | SC27XX_ADC_12BIT_MODE, |
536 | val: tmp); |
537 | if (ret) |
538 | goto disable_adc; |
539 | |
540 | ret = regmap_update_bits(map: data->regmap, reg: data->base + SC27XX_ADC_CTL, |
541 | SC27XX_ADC_CHN_RUN, SC27XX_ADC_CHN_RUN); |
542 | if (ret) |
543 | goto disable_adc; |
544 | |
545 | ret = regmap_read_poll_timeout(data->regmap, |
546 | data->base + SC27XX_ADC_INT_RAW, |
547 | status, (status & SC27XX_ADC_IRQ_RAW), |
548 | SC27XX_ADC_POLL_RAW_STATUS, |
549 | SC27XX_ADC_RDY_TIMEOUT); |
550 | if (ret) { |
551 | dev_err(data->dev, "read adc timeout, status = 0x%x\n" , status); |
552 | goto disable_adc; |
553 | } |
554 | |
555 | ret = regmap_read(map: data->regmap, reg: data->base + SC27XX_ADC_DATA, val: &value); |
556 | if (ret) |
557 | goto disable_adc; |
558 | |
559 | value &= SC27XX_ADC_DATA_MASK; |
560 | |
561 | disable_adc: |
562 | regmap_update_bits(map: data->regmap, reg: data->base + SC27XX_ADC_CTL, |
563 | SC27XX_ADC_EN, val: 0); |
564 | regulator_restore: |
565 | if ((data->var_data->set_volref) && (channel == 30 || channel == 31)) { |
566 | ret_volref = regulator_set_voltage(regulator: data->volref, |
567 | SC27XX_ADC_REFVOL_VDD28, |
568 | SC27XX_ADC_REFVOL_VDD28); |
569 | if (ret_volref) { |
570 | dev_err(data->dev, "failed to set the volref 2.8v,ret_volref = 0x%x\n" , |
571 | ret_volref); |
572 | ret = ret || ret_volref; |
573 | } |
574 | } |
575 | unlock_adc: |
576 | hwspin_unlock_raw(hwlock: data->hwlock); |
577 | |
578 | if (!ret) |
579 | *val = value; |
580 | |
581 | return ret; |
582 | } |
583 | |
584 | static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data, int channel, int scale, |
585 | struct u32_fract *fract) |
586 | { |
587 | u32 ratio; |
588 | |
589 | ratio = data->var_data->get_ratio(channel, scale); |
590 | fract->numerator = ratio >> SC27XX_RATIO_NUMERATOR_OFFSET; |
591 | fract->denominator = ratio & SC27XX_RATIO_DENOMINATOR_MASK; |
592 | } |
593 | |
594 | static int adc_to_volt(struct sc27xx_adc_linear_graph *graph, |
595 | int raw_adc) |
596 | { |
597 | int tmp; |
598 | |
599 | tmp = (graph->volt0 - graph->volt1) * (raw_adc - graph->adc1); |
600 | tmp /= (graph->adc0 - graph->adc1); |
601 | tmp += graph->volt1; |
602 | |
603 | return tmp; |
604 | } |
605 | |
606 | static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph, |
607 | int raw_adc) |
608 | { |
609 | int tmp; |
610 | |
611 | tmp = adc_to_volt(graph, raw_adc); |
612 | |
613 | return tmp < 0 ? 0 : tmp; |
614 | } |
615 | |
616 | static int sc27xx_adc_convert_volt(struct sc27xx_adc_data *data, int channel, |
617 | int scale, int raw_adc) |
618 | { |
619 | struct u32_fract fract; |
620 | u32 volt; |
621 | |
622 | /* |
623 | * Convert ADC values to voltage values according to the linear graph, |
624 | * and channel 5 and channel 1 has been calibrated, so we can just |
625 | * return the voltage values calculated by the linear graph. But other |
626 | * channels need be calculated to the real voltage values with the |
627 | * voltage ratio. |
628 | */ |
629 | switch (channel) { |
630 | case 5: |
631 | return sc27xx_adc_to_volt(graph: &big_scale_graph, raw_adc); |
632 | |
633 | case 1: |
634 | return sc27xx_adc_to_volt(graph: &small_scale_graph, raw_adc); |
635 | |
636 | default: |
637 | volt = sc27xx_adc_to_volt(graph: &small_scale_graph, raw_adc); |
638 | break; |
639 | } |
640 | |
641 | sc27xx_adc_volt_ratio(data, channel, scale, fract: &fract); |
642 | |
643 | return DIV_ROUND_CLOSEST(volt * fract.denominator, fract.numerator); |
644 | } |
645 | |
646 | static int sc27xx_adc_read_processed(struct sc27xx_adc_data *data, |
647 | int channel, int scale, int *val) |
648 | { |
649 | int ret, raw_adc; |
650 | |
651 | ret = sc27xx_adc_read(data, channel, scale, val: &raw_adc); |
652 | if (ret) |
653 | return ret; |
654 | |
655 | *val = sc27xx_adc_convert_volt(data, channel, scale, raw_adc); |
656 | return 0; |
657 | } |
658 | |
659 | static int sc27xx_adc_read_raw(struct iio_dev *indio_dev, |
660 | struct iio_chan_spec const *chan, |
661 | int *val, int *val2, long mask) |
662 | { |
663 | struct sc27xx_adc_data *data = iio_priv(indio_dev); |
664 | int scale = data->channel_scale[chan->channel]; |
665 | int ret, tmp; |
666 | |
667 | switch (mask) { |
668 | case IIO_CHAN_INFO_RAW: |
669 | mutex_lock(&data->lock); |
670 | ret = sc27xx_adc_read(data, channel: chan->channel, scale, val: &tmp); |
671 | mutex_unlock(lock: &data->lock); |
672 | |
673 | if (ret) |
674 | return ret; |
675 | |
676 | *val = tmp; |
677 | return IIO_VAL_INT; |
678 | |
679 | case IIO_CHAN_INFO_PROCESSED: |
680 | mutex_lock(&data->lock); |
681 | ret = sc27xx_adc_read_processed(data, channel: chan->channel, scale, |
682 | val: &tmp); |
683 | mutex_unlock(lock: &data->lock); |
684 | |
685 | if (ret) |
686 | return ret; |
687 | |
688 | *val = tmp; |
689 | return IIO_VAL_INT; |
690 | |
691 | case IIO_CHAN_INFO_SCALE: |
692 | *val = scale; |
693 | return IIO_VAL_INT; |
694 | |
695 | default: |
696 | return -EINVAL; |
697 | } |
698 | } |
699 | |
700 | static int sc27xx_adc_write_raw(struct iio_dev *indio_dev, |
701 | struct iio_chan_spec const *chan, |
702 | int val, int val2, long mask) |
703 | { |
704 | struct sc27xx_adc_data *data = iio_priv(indio_dev); |
705 | |
706 | switch (mask) { |
707 | case IIO_CHAN_INFO_SCALE: |
708 | data->channel_scale[chan->channel] = val; |
709 | return IIO_VAL_INT; |
710 | |
711 | default: |
712 | return -EINVAL; |
713 | } |
714 | } |
715 | |
716 | static const struct iio_info sc27xx_info = { |
717 | .read_raw = &sc27xx_adc_read_raw, |
718 | .write_raw = &sc27xx_adc_write_raw, |
719 | }; |
720 | |
721 | #define SC27XX_ADC_CHANNEL(index, mask) { \ |
722 | .type = IIO_VOLTAGE, \ |
723 | .channel = index, \ |
724 | .info_mask_separate = mask | BIT(IIO_CHAN_INFO_SCALE), \ |
725 | .datasheet_name = "CH##index", \ |
726 | .indexed = 1, \ |
727 | } |
728 | |
729 | static const struct iio_chan_spec sc27xx_channels[] = { |
730 | SC27XX_ADC_CHANNEL(0, BIT(IIO_CHAN_INFO_PROCESSED)), |
731 | SC27XX_ADC_CHANNEL(1, BIT(IIO_CHAN_INFO_PROCESSED)), |
732 | SC27XX_ADC_CHANNEL(2, BIT(IIO_CHAN_INFO_PROCESSED)), |
733 | SC27XX_ADC_CHANNEL(3, BIT(IIO_CHAN_INFO_PROCESSED)), |
734 | SC27XX_ADC_CHANNEL(4, BIT(IIO_CHAN_INFO_PROCESSED)), |
735 | SC27XX_ADC_CHANNEL(5, BIT(IIO_CHAN_INFO_PROCESSED)), |
736 | SC27XX_ADC_CHANNEL(6, BIT(IIO_CHAN_INFO_PROCESSED)), |
737 | SC27XX_ADC_CHANNEL(7, BIT(IIO_CHAN_INFO_PROCESSED)), |
738 | SC27XX_ADC_CHANNEL(8, BIT(IIO_CHAN_INFO_PROCESSED)), |
739 | SC27XX_ADC_CHANNEL(9, BIT(IIO_CHAN_INFO_PROCESSED)), |
740 | SC27XX_ADC_CHANNEL(10, BIT(IIO_CHAN_INFO_PROCESSED)), |
741 | SC27XX_ADC_CHANNEL(11, BIT(IIO_CHAN_INFO_PROCESSED)), |
742 | SC27XX_ADC_CHANNEL(12, BIT(IIO_CHAN_INFO_PROCESSED)), |
743 | SC27XX_ADC_CHANNEL(13, BIT(IIO_CHAN_INFO_PROCESSED)), |
744 | SC27XX_ADC_CHANNEL(14, BIT(IIO_CHAN_INFO_PROCESSED)), |
745 | SC27XX_ADC_CHANNEL(15, BIT(IIO_CHAN_INFO_PROCESSED)), |
746 | SC27XX_ADC_CHANNEL(16, BIT(IIO_CHAN_INFO_PROCESSED)), |
747 | SC27XX_ADC_CHANNEL(17, BIT(IIO_CHAN_INFO_PROCESSED)), |
748 | SC27XX_ADC_CHANNEL(18, BIT(IIO_CHAN_INFO_PROCESSED)), |
749 | SC27XX_ADC_CHANNEL(19, BIT(IIO_CHAN_INFO_PROCESSED)), |
750 | SC27XX_ADC_CHANNEL(20, BIT(IIO_CHAN_INFO_RAW)), |
751 | SC27XX_ADC_CHANNEL(21, BIT(IIO_CHAN_INFO_PROCESSED)), |
752 | SC27XX_ADC_CHANNEL(22, BIT(IIO_CHAN_INFO_PROCESSED)), |
753 | SC27XX_ADC_CHANNEL(23, BIT(IIO_CHAN_INFO_PROCESSED)), |
754 | SC27XX_ADC_CHANNEL(24, BIT(IIO_CHAN_INFO_PROCESSED)), |
755 | SC27XX_ADC_CHANNEL(25, BIT(IIO_CHAN_INFO_PROCESSED)), |
756 | SC27XX_ADC_CHANNEL(26, BIT(IIO_CHAN_INFO_PROCESSED)), |
757 | SC27XX_ADC_CHANNEL(27, BIT(IIO_CHAN_INFO_PROCESSED)), |
758 | SC27XX_ADC_CHANNEL(28, BIT(IIO_CHAN_INFO_PROCESSED)), |
759 | SC27XX_ADC_CHANNEL(29, BIT(IIO_CHAN_INFO_PROCESSED)), |
760 | SC27XX_ADC_CHANNEL(30, BIT(IIO_CHAN_INFO_PROCESSED)), |
761 | SC27XX_ADC_CHANNEL(31, BIT(IIO_CHAN_INFO_PROCESSED)), |
762 | }; |
763 | |
764 | static int sc27xx_adc_enable(struct sc27xx_adc_data *data) |
765 | { |
766 | int ret; |
767 | |
768 | ret = regmap_update_bits(map: data->regmap, reg: data->var_data->module_en, |
769 | SC27XX_MODULE_ADC_EN, SC27XX_MODULE_ADC_EN); |
770 | if (ret) |
771 | return ret; |
772 | |
773 | /* Enable ADC work clock and controller clock */ |
774 | ret = regmap_update_bits(map: data->regmap, reg: data->var_data->clk_en, |
775 | SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, |
776 | SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN); |
777 | if (ret) |
778 | goto disable_adc; |
779 | |
780 | /* ADC channel scales' calibration from nvmem device */ |
781 | ret = sc27xx_adc_scale_calibration(data, big_scale: true); |
782 | if (ret) |
783 | goto disable_clk; |
784 | |
785 | ret = sc27xx_adc_scale_calibration(data, big_scale: false); |
786 | if (ret) |
787 | goto disable_clk; |
788 | |
789 | return 0; |
790 | |
791 | disable_clk: |
792 | regmap_update_bits(map: data->regmap, reg: data->var_data->clk_en, |
793 | SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, val: 0); |
794 | disable_adc: |
795 | regmap_update_bits(map: data->regmap, reg: data->var_data->module_en, |
796 | SC27XX_MODULE_ADC_EN, val: 0); |
797 | |
798 | return ret; |
799 | } |
800 | |
801 | static void sc27xx_adc_disable(void *_data) |
802 | { |
803 | struct sc27xx_adc_data *data = _data; |
804 | |
805 | /* Disable ADC work clock and controller clock */ |
806 | regmap_update_bits(map: data->regmap, reg: data->var_data->clk_en, |
807 | SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, val: 0); |
808 | |
809 | regmap_update_bits(map: data->regmap, reg: data->var_data->module_en, |
810 | SC27XX_MODULE_ADC_EN, val: 0); |
811 | } |
812 | |
813 | static const struct sc27xx_adc_variant_data sc2731_data = { |
814 | .module_en = SC2731_MODULE_EN, |
815 | .clk_en = SC2731_ARM_CLK_EN, |
816 | .scale_shift = SC27XX_ADC_SCALE_SHIFT, |
817 | .scale_mask = SC27XX_ADC_SCALE_MASK, |
818 | .bscale_cal = &sc2731_big_scale_graph_calib, |
819 | .sscale_cal = &sc2731_small_scale_graph_calib, |
820 | .init_scale = sc2731_adc_scale_init, |
821 | .get_ratio = sc2731_adc_get_ratio, |
822 | .set_volref = false, |
823 | }; |
824 | |
825 | static const struct sc27xx_adc_variant_data sc2730_data = { |
826 | .module_en = SC2730_MODULE_EN, |
827 | .clk_en = SC2730_ARM_CLK_EN, |
828 | .scale_shift = SC27XX_ADC_SCALE_SHIFT, |
829 | .scale_mask = SC27XX_ADC_SCALE_MASK, |
830 | .bscale_cal = &big_scale_graph_calib, |
831 | .sscale_cal = &small_scale_graph_calib, |
832 | .init_scale = sc2730_adc_scale_init, |
833 | .get_ratio = sc2730_adc_get_ratio, |
834 | .set_volref = false, |
835 | }; |
836 | |
837 | static const struct sc27xx_adc_variant_data sc2721_data = { |
838 | .module_en = SC2731_MODULE_EN, |
839 | .clk_en = SC2721_ARM_CLK_EN, |
840 | .scale_shift = SC2721_ADC_SCALE_SHIFT, |
841 | .scale_mask = SC2721_ADC_SCALE_MASK, |
842 | .bscale_cal = &sc2731_big_scale_graph_calib, |
843 | .sscale_cal = &sc2731_small_scale_graph_calib, |
844 | .init_scale = sc2731_adc_scale_init, |
845 | .get_ratio = sc2721_adc_get_ratio, |
846 | .set_volref = true, |
847 | }; |
848 | |
849 | static const struct sc27xx_adc_variant_data sc2720_data = { |
850 | .module_en = SC2731_MODULE_EN, |
851 | .clk_en = SC2721_ARM_CLK_EN, |
852 | .scale_shift = SC27XX_ADC_SCALE_SHIFT, |
853 | .scale_mask = SC27XX_ADC_SCALE_MASK, |
854 | .bscale_cal = &big_scale_graph_calib, |
855 | .sscale_cal = &small_scale_graph_calib, |
856 | .init_scale = sc2720_adc_scale_init, |
857 | .get_ratio = sc2720_adc_get_ratio, |
858 | .set_volref = false, |
859 | }; |
860 | |
861 | static int sc27xx_adc_probe(struct platform_device *pdev) |
862 | { |
863 | struct device *dev = &pdev->dev; |
864 | struct device_node *np = dev->of_node; |
865 | struct sc27xx_adc_data *sc27xx_data; |
866 | const struct sc27xx_adc_variant_data *pdata; |
867 | struct iio_dev *indio_dev; |
868 | int ret; |
869 | |
870 | pdata = of_device_get_match_data(dev); |
871 | if (!pdata) { |
872 | dev_err(dev, "No matching driver data found\n" ); |
873 | return -EINVAL; |
874 | } |
875 | |
876 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*sc27xx_data)); |
877 | if (!indio_dev) |
878 | return -ENOMEM; |
879 | |
880 | sc27xx_data = iio_priv(indio_dev); |
881 | |
882 | sc27xx_data->regmap = dev_get_regmap(dev: dev->parent, NULL); |
883 | if (!sc27xx_data->regmap) { |
884 | dev_err(dev, "failed to get ADC regmap\n" ); |
885 | return -ENODEV; |
886 | } |
887 | |
888 | ret = of_property_read_u32(np, propname: "reg" , out_value: &sc27xx_data->base); |
889 | if (ret) { |
890 | dev_err(dev, "failed to get ADC base address\n" ); |
891 | return ret; |
892 | } |
893 | |
894 | sc27xx_data->irq = platform_get_irq(pdev, 0); |
895 | if (sc27xx_data->irq < 0) |
896 | return sc27xx_data->irq; |
897 | |
898 | ret = of_hwspin_lock_get_id(np, index: 0); |
899 | if (ret < 0) { |
900 | dev_err(dev, "failed to get hwspinlock id\n" ); |
901 | return ret; |
902 | } |
903 | |
904 | sc27xx_data->hwlock = devm_hwspin_lock_request_specific(dev, id: ret); |
905 | if (!sc27xx_data->hwlock) { |
906 | dev_err(dev, "failed to request hwspinlock\n" ); |
907 | return -ENXIO; |
908 | } |
909 | |
910 | sc27xx_data->dev = dev; |
911 | if (pdata->set_volref) { |
912 | sc27xx_data->volref = devm_regulator_get(dev, id: "vref" ); |
913 | if (IS_ERR(ptr: sc27xx_data->volref)) { |
914 | ret = PTR_ERR(ptr: sc27xx_data->volref); |
915 | return dev_err_probe(dev, err: ret, fmt: "failed to get ADC volref\n" ); |
916 | } |
917 | } |
918 | |
919 | sc27xx_data->var_data = pdata; |
920 | sc27xx_data->var_data->init_scale(sc27xx_data); |
921 | |
922 | ret = sc27xx_adc_enable(data: sc27xx_data); |
923 | if (ret) { |
924 | dev_err(dev, "failed to enable ADC module\n" ); |
925 | return ret; |
926 | } |
927 | |
928 | ret = devm_add_action_or_reset(dev, sc27xx_adc_disable, sc27xx_data); |
929 | if (ret) { |
930 | dev_err(dev, "failed to add ADC disable action\n" ); |
931 | return ret; |
932 | } |
933 | |
934 | indio_dev->name = dev_name(dev); |
935 | indio_dev->modes = INDIO_DIRECT_MODE; |
936 | indio_dev->info = &sc27xx_info; |
937 | indio_dev->channels = sc27xx_channels; |
938 | indio_dev->num_channels = ARRAY_SIZE(sc27xx_channels); |
939 | |
940 | mutex_init(&sc27xx_data->lock); |
941 | |
942 | ret = devm_iio_device_register(dev, indio_dev); |
943 | if (ret) |
944 | dev_err(dev, "could not register iio (ADC)" ); |
945 | |
946 | return ret; |
947 | } |
948 | |
949 | static const struct of_device_id sc27xx_adc_of_match[] = { |
950 | { .compatible = "sprd,sc2731-adc" , .data = &sc2731_data}, |
951 | { .compatible = "sprd,sc2730-adc" , .data = &sc2730_data}, |
952 | { .compatible = "sprd,sc2721-adc" , .data = &sc2721_data}, |
953 | { .compatible = "sprd,sc2720-adc" , .data = &sc2720_data}, |
954 | { } |
955 | }; |
956 | MODULE_DEVICE_TABLE(of, sc27xx_adc_of_match); |
957 | |
958 | static struct platform_driver sc27xx_adc_driver = { |
959 | .probe = sc27xx_adc_probe, |
960 | .driver = { |
961 | .name = "sc27xx-adc" , |
962 | .of_match_table = sc27xx_adc_of_match, |
963 | }, |
964 | }; |
965 | |
966 | module_platform_driver(sc27xx_adc_driver); |
967 | |
968 | MODULE_AUTHOR("Freeman Liu <freeman.liu@spreadtrum.com>" ); |
969 | MODULE_DESCRIPTION("Spreadtrum SC27XX ADC Driver" ); |
970 | MODULE_LICENSE("GPL v2" ); |
971 | |