hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/iio/adc/qcom-vadc-common.c
....@@ -6,6 +6,7 @@
66 #include <linux/log2.h>
77 #include <linux/err.h>
88 #include <linux/module.h>
9
+#include <linux/units.h>
910
1011 #include "qcom-vadc-common.h"
1112
....@@ -47,8 +48,280 @@
4748 {44, 125}
4849 };
4950
51
+/*
52
+ * Voltage to temperature table for 100k pull up for NTCG104EF104 with
53
+ * 1.875V reference.
54
+ */
55
+static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
56
+ { 1831, -40000 },
57
+ { 1814, -35000 },
58
+ { 1791, -30000 },
59
+ { 1761, -25000 },
60
+ { 1723, -20000 },
61
+ { 1675, -15000 },
62
+ { 1616, -10000 },
63
+ { 1545, -5000 },
64
+ { 1463, 0 },
65
+ { 1370, 5000 },
66
+ { 1268, 10000 },
67
+ { 1160, 15000 },
68
+ { 1049, 20000 },
69
+ { 937, 25000 },
70
+ { 828, 30000 },
71
+ { 726, 35000 },
72
+ { 630, 40000 },
73
+ { 544, 45000 },
74
+ { 467, 50000 },
75
+ { 399, 55000 },
76
+ { 340, 60000 },
77
+ { 290, 65000 },
78
+ { 247, 70000 },
79
+ { 209, 75000 },
80
+ { 179, 80000 },
81
+ { 153, 85000 },
82
+ { 130, 90000 },
83
+ { 112, 95000 },
84
+ { 96, 100000 },
85
+ { 82, 105000 },
86
+ { 71, 110000 },
87
+ { 62, 115000 },
88
+ { 53, 120000 },
89
+ { 46, 125000 },
90
+};
91
+
92
+static const struct vadc_map_pt adcmap7_die_temp[] = {
93
+ { 433700, 1967},
94
+ { 473100, 1964},
95
+ { 512400, 1957},
96
+ { 551500, 1949},
97
+ { 590500, 1940},
98
+ { 629300, 1930},
99
+ { 667900, 1921},
100
+ { 706400, 1910},
101
+ { 744600, 1896},
102
+ { 782500, 1878},
103
+ { 820100, 1859},
104
+ { 857300, 0},
105
+};
106
+
107
+/*
108
+ * Resistance to temperature table for 100k pull up for NTCG104EF104.
109
+ */
110
+static const struct vadc_map_pt adcmap7_100k[] = {
111
+ { 4250657, -40960 },
112
+ { 3962085, -39936 },
113
+ { 3694875, -38912 },
114
+ { 3447322, -37888 },
115
+ { 3217867, -36864 },
116
+ { 3005082, -35840 },
117
+ { 2807660, -34816 },
118
+ { 2624405, -33792 },
119
+ { 2454218, -32768 },
120
+ { 2296094, -31744 },
121
+ { 2149108, -30720 },
122
+ { 2012414, -29696 },
123
+ { 1885232, -28672 },
124
+ { 1766846, -27648 },
125
+ { 1656598, -26624 },
126
+ { 1553884, -25600 },
127
+ { 1458147, -24576 },
128
+ { 1368873, -23552 },
129
+ { 1285590, -22528 },
130
+ { 1207863, -21504 },
131
+ { 1135290, -20480 },
132
+ { 1067501, -19456 },
133
+ { 1004155, -18432 },
134
+ { 944935, -17408 },
135
+ { 889550, -16384 },
136
+ { 837731, -15360 },
137
+ { 789229, -14336 },
138
+ { 743813, -13312 },
139
+ { 701271, -12288 },
140
+ { 661405, -11264 },
141
+ { 624032, -10240 },
142
+ { 588982, -9216 },
143
+ { 556100, -8192 },
144
+ { 525239, -7168 },
145
+ { 496264, -6144 },
146
+ { 469050, -5120 },
147
+ { 443480, -4096 },
148
+ { 419448, -3072 },
149
+ { 396851, -2048 },
150
+ { 375597, -1024 },
151
+ { 355598, 0 },
152
+ { 336775, 1024 },
153
+ { 319052, 2048 },
154
+ { 302359, 3072 },
155
+ { 286630, 4096 },
156
+ { 271806, 5120 },
157
+ { 257829, 6144 },
158
+ { 244646, 7168 },
159
+ { 232209, 8192 },
160
+ { 220471, 9216 },
161
+ { 209390, 10240 },
162
+ { 198926, 11264 },
163
+ { 189040, 12288 },
164
+ { 179698, 13312 },
165
+ { 170868, 14336 },
166
+ { 162519, 15360 },
167
+ { 154622, 16384 },
168
+ { 147150, 17408 },
169
+ { 140079, 18432 },
170
+ { 133385, 19456 },
171
+ { 127046, 20480 },
172
+ { 121042, 21504 },
173
+ { 115352, 22528 },
174
+ { 109960, 23552 },
175
+ { 104848, 24576 },
176
+ { 100000, 25600 },
177
+ { 95402, 26624 },
178
+ { 91038, 27648 },
179
+ { 86897, 28672 },
180
+ { 82965, 29696 },
181
+ { 79232, 30720 },
182
+ { 75686, 31744 },
183
+ { 72316, 32768 },
184
+ { 69114, 33792 },
185
+ { 66070, 34816 },
186
+ { 63176, 35840 },
187
+ { 60423, 36864 },
188
+ { 57804, 37888 },
189
+ { 55312, 38912 },
190
+ { 52940, 39936 },
191
+ { 50681, 40960 },
192
+ { 48531, 41984 },
193
+ { 46482, 43008 },
194
+ { 44530, 44032 },
195
+ { 42670, 45056 },
196
+ { 40897, 46080 },
197
+ { 39207, 47104 },
198
+ { 37595, 48128 },
199
+ { 36057, 49152 },
200
+ { 34590, 50176 },
201
+ { 33190, 51200 },
202
+ { 31853, 52224 },
203
+ { 30577, 53248 },
204
+ { 29358, 54272 },
205
+ { 28194, 55296 },
206
+ { 27082, 56320 },
207
+ { 26020, 57344 },
208
+ { 25004, 58368 },
209
+ { 24033, 59392 },
210
+ { 23104, 60416 },
211
+ { 22216, 61440 },
212
+ { 21367, 62464 },
213
+ { 20554, 63488 },
214
+ { 19776, 64512 },
215
+ { 19031, 65536 },
216
+ { 18318, 66560 },
217
+ { 17636, 67584 },
218
+ { 16982, 68608 },
219
+ { 16355, 69632 },
220
+ { 15755, 70656 },
221
+ { 15180, 71680 },
222
+ { 14628, 72704 },
223
+ { 14099, 73728 },
224
+ { 13592, 74752 },
225
+ { 13106, 75776 },
226
+ { 12640, 76800 },
227
+ { 12192, 77824 },
228
+ { 11762, 78848 },
229
+ { 11350, 79872 },
230
+ { 10954, 80896 },
231
+ { 10574, 81920 },
232
+ { 10209, 82944 },
233
+ { 9858, 83968 },
234
+ { 9521, 84992 },
235
+ { 9197, 86016 },
236
+ { 8886, 87040 },
237
+ { 8587, 88064 },
238
+ { 8299, 89088 },
239
+ { 8023, 90112 },
240
+ { 7757, 91136 },
241
+ { 7501, 92160 },
242
+ { 7254, 93184 },
243
+ { 7017, 94208 },
244
+ { 6789, 95232 },
245
+ { 6570, 96256 },
246
+ { 6358, 97280 },
247
+ { 6155, 98304 },
248
+ { 5959, 99328 },
249
+ { 5770, 100352 },
250
+ { 5588, 101376 },
251
+ { 5412, 102400 },
252
+ { 5243, 103424 },
253
+ { 5080, 104448 },
254
+ { 4923, 105472 },
255
+ { 4771, 106496 },
256
+ { 4625, 107520 },
257
+ { 4484, 108544 },
258
+ { 4348, 109568 },
259
+ { 4217, 110592 },
260
+ { 4090, 111616 },
261
+ { 3968, 112640 },
262
+ { 3850, 113664 },
263
+ { 3736, 114688 },
264
+ { 3626, 115712 },
265
+ { 3519, 116736 },
266
+ { 3417, 117760 },
267
+ { 3317, 118784 },
268
+ { 3221, 119808 },
269
+ { 3129, 120832 },
270
+ { 3039, 121856 },
271
+ { 2952, 122880 },
272
+ { 2868, 123904 },
273
+ { 2787, 124928 },
274
+ { 2709, 125952 },
275
+ { 2633, 126976 },
276
+ { 2560, 128000 },
277
+ { 2489, 129024 },
278
+ { 2420, 130048 }
279
+};
280
+
281
+static int qcom_vadc_scale_hw_calib_volt(
282
+ const struct vadc_prescale_ratio *prescale,
283
+ const struct adc5_data *data,
284
+ u16 adc_code, int *result_uv);
285
+static int qcom_vadc_scale_hw_calib_therm(
286
+ const struct vadc_prescale_ratio *prescale,
287
+ const struct adc5_data *data,
288
+ u16 adc_code, int *result_mdec);
289
+static int qcom_vadc7_scale_hw_calib_therm(
290
+ const struct vadc_prescale_ratio *prescale,
291
+ const struct adc5_data *data,
292
+ u16 adc_code, int *result_mdec);
293
+static int qcom_vadc_scale_hw_smb_temp(
294
+ const struct vadc_prescale_ratio *prescale,
295
+ const struct adc5_data *data,
296
+ u16 adc_code, int *result_mdec);
297
+static int qcom_vadc_scale_hw_chg5_temp(
298
+ const struct vadc_prescale_ratio *prescale,
299
+ const struct adc5_data *data,
300
+ u16 adc_code, int *result_mdec);
301
+static int qcom_vadc_scale_hw_calib_die_temp(
302
+ const struct vadc_prescale_ratio *prescale,
303
+ const struct adc5_data *data,
304
+ u16 adc_code, int *result_mdec);
305
+static int qcom_vadc7_scale_hw_calib_die_temp(
306
+ const struct vadc_prescale_ratio *prescale,
307
+ const struct adc5_data *data,
308
+ u16 adc_code, int *result_mdec);
309
+
310
+static struct qcom_adc5_scale_type scale_adc5_fn[] = {
311
+ [SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
312
+ [SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
313
+ [SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
314
+ [SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
315
+ qcom_vadc7_scale_hw_calib_therm},
316
+ [SCALE_HW_CALIB_PMIC_THERM] = {qcom_vadc_scale_hw_calib_die_temp},
317
+ [SCALE_HW_CALIB_PMIC_THERM_PM7] = {
318
+ qcom_vadc7_scale_hw_calib_die_temp},
319
+ [SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp},
320
+ [SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp},
321
+};
322
+
50323 static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts,
51
- u32 tablesize, s32 input, s64 *output)
324
+ u32 tablesize, s32 input, int *output)
52325 {
53326 bool descending = 1;
54327 u32 i = 0;
....@@ -128,7 +401,7 @@
128401 bool absolute, u16 adc_code,
129402 int *result_mdec)
130403 {
131
- s64 voltage = 0, result = 0;
404
+ s64 voltage = 0;
132405 int ret;
133406
134407 qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
....@@ -138,12 +411,11 @@
138411
139412 ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb,
140413 ARRAY_SIZE(adcmap_100k_104ef_104fb),
141
- voltage, &result);
414
+ voltage, result_mdec);
142415 if (ret)
143416 return ret;
144417
145
- result *= 1000;
146
- *result_mdec = result;
418
+ *result_mdec *= 1000;
147419
148420 return 0;
149421 }
....@@ -166,8 +438,7 @@
166438 voltage = 0;
167439 }
168440
169
- voltage -= KELVINMIL_CELSIUSMIL;
170
- *result_mdec = voltage;
441
+ *result_mdec = milli_kelvin_to_millicelsius(voltage);
171442
172443 return 0;
173444 }
....@@ -187,6 +458,160 @@
187458 voltage = (voltage + PMI_CHG_SCALE_2);
188459 result = div64_s64(voltage, 1000000);
189460 *result_mdec = result;
461
+
462
+ return 0;
463
+}
464
+
465
+static int qcom_vadc_scale_code_voltage_factor(u16 adc_code,
466
+ const struct vadc_prescale_ratio *prescale,
467
+ const struct adc5_data *data,
468
+ unsigned int factor)
469
+{
470
+ s64 voltage, temp, adc_vdd_ref_mv = 1875;
471
+
472
+ /*
473
+ * The normal data range is between 0V to 1.875V. On cases where
474
+ * we read low voltage values, the ADC code can go beyond the
475
+ * range and the scale result is incorrect so we clamp the values
476
+ * for the cases where the code represents a value below 0V
477
+ */
478
+ if (adc_code > VADC5_MAX_CODE)
479
+ adc_code = 0;
480
+
481
+ /* (ADC code * vref_vadc (1.875V)) / full_scale_code */
482
+ voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
483
+ voltage = div64_s64(voltage, data->full_scale_code_volt);
484
+ if (voltage > 0) {
485
+ voltage *= prescale->den;
486
+ temp = prescale->num * factor;
487
+ voltage = div64_s64(voltage, temp);
488
+ } else {
489
+ voltage = 0;
490
+ }
491
+
492
+ return (int) voltage;
493
+}
494
+
495
+static int qcom_vadc7_scale_hw_calib_therm(
496
+ const struct vadc_prescale_ratio *prescale,
497
+ const struct adc5_data *data,
498
+ u16 adc_code, int *result_mdec)
499
+{
500
+ s64 resistance = adc_code;
501
+ int ret, result;
502
+
503
+ if (adc_code >= RATIO_MAX_ADC7)
504
+ return -EINVAL;
505
+
506
+ /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/
507
+ resistance *= R_PU_100K;
508
+ resistance = div64_s64(resistance, RATIO_MAX_ADC7 - adc_code);
509
+
510
+ ret = qcom_vadc_map_voltage_temp(adcmap7_100k,
511
+ ARRAY_SIZE(adcmap7_100k),
512
+ resistance, &result);
513
+ if (ret)
514
+ return ret;
515
+
516
+ *result_mdec = result;
517
+
518
+ return 0;
519
+}
520
+
521
+static int qcom_vadc_scale_hw_calib_volt(
522
+ const struct vadc_prescale_ratio *prescale,
523
+ const struct adc5_data *data,
524
+ u16 adc_code, int *result_uv)
525
+{
526
+ *result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
527
+ prescale, data, 1);
528
+
529
+ return 0;
530
+}
531
+
532
+static int qcom_vadc_scale_hw_calib_therm(
533
+ const struct vadc_prescale_ratio *prescale,
534
+ const struct adc5_data *data,
535
+ u16 adc_code, int *result_mdec)
536
+{
537
+ int voltage;
538
+
539
+ voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
540
+ prescale, data, 1000);
541
+
542
+ /* Map voltage to temperature from look-up table */
543
+ return qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
544
+ ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
545
+ voltage, result_mdec);
546
+}
547
+
548
+static int qcom_vadc_scale_hw_calib_die_temp(
549
+ const struct vadc_prescale_ratio *prescale,
550
+ const struct adc5_data *data,
551
+ u16 adc_code, int *result_mdec)
552
+{
553
+ *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code,
554
+ prescale, data, 2);
555
+ *result_mdec = milli_kelvin_to_millicelsius(*result_mdec);
556
+
557
+ return 0;
558
+}
559
+
560
+static int qcom_vadc7_scale_hw_calib_die_temp(
561
+ const struct vadc_prescale_ratio *prescale,
562
+ const struct adc5_data *data,
563
+ u16 adc_code, int *result_mdec)
564
+{
565
+
566
+ int voltage, vtemp0, temp, i;
567
+
568
+ voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
569
+ prescale, data, 1);
570
+
571
+ if (adcmap7_die_temp[0].x > voltage) {
572
+ *result_mdec = DIE_TEMP_ADC7_SCALE_1;
573
+ return 0;
574
+ }
575
+
576
+ if (adcmap7_die_temp[ARRAY_SIZE(adcmap7_die_temp) - 1].x <= voltage) {
577
+ *result_mdec = DIE_TEMP_ADC7_MAX;
578
+ return 0;
579
+ }
580
+
581
+ for (i = 0; i < ARRAY_SIZE(adcmap7_die_temp); i++)
582
+ if (adcmap7_die_temp[i].x > voltage)
583
+ break;
584
+
585
+ vtemp0 = adcmap7_die_temp[i - 1].x;
586
+ voltage = voltage - vtemp0;
587
+ temp = div64_s64(voltage * DIE_TEMP_ADC7_SCALE_FACTOR,
588
+ adcmap7_die_temp[i - 1].y);
589
+ temp += DIE_TEMP_ADC7_SCALE_1 + (DIE_TEMP_ADC7_SCALE_2 * (i - 1));
590
+ *result_mdec = temp;
591
+
592
+ return 0;
593
+}
594
+
595
+static int qcom_vadc_scale_hw_smb_temp(
596
+ const struct vadc_prescale_ratio *prescale,
597
+ const struct adc5_data *data,
598
+ u16 adc_code, int *result_mdec)
599
+{
600
+ *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code * 100,
601
+ prescale, data, PMIC5_SMB_TEMP_SCALE_FACTOR);
602
+ *result_mdec = PMIC5_SMB_TEMP_CONSTANT - *result_mdec;
603
+
604
+ return 0;
605
+}
606
+
607
+static int qcom_vadc_scale_hw_chg5_temp(
608
+ const struct vadc_prescale_ratio *prescale,
609
+ const struct adc5_data *data,
610
+ u16 adc_code, int *result_mdec)
611
+{
612
+ *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code,
613
+ prescale, data, 4);
614
+ *result_mdec = PMIC5_CHG_TEMP_SCALE_FACTOR - *result_mdec;
190615
191616 return 0;
192617 }
....@@ -221,6 +646,22 @@
221646 }
222647 EXPORT_SYMBOL(qcom_vadc_scale);
223648
649
+int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype,
650
+ const struct vadc_prescale_ratio *prescale,
651
+ const struct adc5_data *data,
652
+ u16 adc_code, int *result)
653
+{
654
+ if (!(scaletype >= SCALE_HW_CALIB_DEFAULT &&
655
+ scaletype < SCALE_HW_CALIB_INVALID)) {
656
+ pr_err("Invalid scale type %d\n", scaletype);
657
+ return -EINVAL;
658
+ }
659
+
660
+ return scale_adc5_fn[scaletype].scale_fn(prescale, data,
661
+ adc_code, result);
662
+}
663
+EXPORT_SYMBOL(qcom_adc5_hw_scale);
664
+
224665 int qcom_vadc_decimation_from_dt(u32 value)
225666 {
226667 if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN ||