blob: fb2f1d5cd912e133fb6f3cb09ca48d812de48b61 [file] [log] [blame]
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -07001/*
2 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <linux/module.h>
17#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
18#define KELVINMIL_DEGMIL 273160
19
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -080020/* Units for temperature below (on x axis) is in 0.1DegC as
21 required by the battery driver. Note the resolution used
22 here to compute the table was done for DegC to milli-volts.
23 In consideration to limit the size of the table for the given
24 temperature range below, the result is linearly interpolated
25 and provided to the battery driver in the units desired for
26 their framework which is 0.1DegC. True resolution of 0.1DegC
27 will result in the below table size to increase by 10 times */
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -070028static const struct pm8xxx_adc_map_pt adcmap_btm_threshold[] = {
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -080029 {-300, 1642},
30 {-200, 1544},
31 {-100, 1414},
Siddartha Mohanadossae39c902011-11-09 17:54:31 -080032 {0, 1260},
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -080033 {10, 1244},
34 {20, 1228},
35 {30, 1212},
36 {40, 1195},
37 {50, 1179},
38 {60, 1162},
39 {70, 1146},
40 {80, 1129},
41 {90, 1113},
42 {100, 1097},
43 {110, 1080},
44 {120, 1064},
45 {130, 1048},
46 {140, 1032},
47 {150, 1016},
48 {160, 1000},
49 {170, 985},
50 {180, 969},
51 {190, 954},
52 {200, 939},
53 {210, 924},
54 {220, 909},
55 {230, 894},
56 {240, 880},
57 {250, 866},
58 {260, 852},
59 {270, 838},
60 {280, 824},
61 {290, 811},
62 {300, 798},
63 {310, 785},
64 {320, 773},
65 {330, 760},
66 {340, 748},
67 {350, 736},
68 {360, 725},
69 {370, 713},
70 {380, 702},
71 {390, 691},
72 {400, 681},
73 {410, 670},
74 {420, 660},
75 {430, 650},
76 {440, 640},
77 {450, 631},
78 {460, 622},
79 {470, 613},
80 {480, 604},
81 {490, 595},
82 {500, 587},
83 {510, 579},
84 {520, 571},
85 {530, 563},
86 {540, 556},
87 {550, 548},
88 {560, 541},
89 {570, 534},
90 {580, 527},
91 {590, 521},
92 {600, 514},
93 {610, 508},
94 {620, 502},
95 {630, 496},
96 {640, 490},
97 {650, 485},
98 {660, 281},
99 {670, 274},
100 {680, 267},
101 {690, 260},
102 {700, 254},
103 {710, 247},
104 {720, 241},
105 {730, 235},
106 {740, 229},
107 {750, 224},
108 {760, 218},
109 {770, 213},
110 {780, 208},
111 {790, 203}
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700112};
113
114static const struct pm8xxx_adc_map_pt adcmap_pa_therm[] = {
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800115 {1677, -30},
116 {1671, -29},
117 {1663, -28},
118 {1656, -27},
119 {1648, -26},
120 {1640, -25},
121 {1632, -24},
122 {1623, -23},
123 {1615, -22},
124 {1605, -21},
125 {1596, -20},
126 {1586, -19},
127 {1576, -18},
128 {1565, -17},
129 {1554, -16},
130 {1543, -15},
131 {1531, -14},
132 {1519, -13},
133 {1507, -12},
134 {1494, -11},
135 {1482, -10},
136 {1468, -9},
137 {1455, -8},
138 {1441, -7},
139 {1427, -6},
140 {1412, -5},
141 {1398, -4},
142 {1383, -3},
143 {1367, -2},
144 {1352, -1},
145 {1336, 0},
146 {1320, 1},
147 {1304, 2},
148 {1287, 3},
149 {1271, 4},
150 {1254, 5},
151 {1237, 6},
152 {1219, 7},
153 {1202, 8},
154 {1185, 9},
155 {1167, 10},
156 {1149, 11},
157 {1131, 12},
158 {1114, 13},
159 {1096, 14},
160 {1078, 15},
161 {1060, 16},
162 {1042, 17},
163 {1024, 18},
164 {1006, 19},
165 {988, 20},
166 {970, 21},
167 {952, 22},
168 {934, 23},
169 {917, 24},
170 {899, 25},
171 {882, 26},
172 {865, 27},
173 {848, 28},
174 {831, 29},
175 {814, 30},
176 {797, 31},
177 {781, 32},
178 {764, 33},
179 {748, 34},
180 {732, 35},
181 {717, 36},
182 {701, 37},
183 {686, 38},
184 {671, 39},
185 {656, 40},
186 {642, 41},
187 {627, 42},
188 {613, 43},
189 {599, 44},
190 {586, 45},
191 {572, 46},
192 {559, 47},
193 {546, 48},
194 {534, 49},
195 {522, 50},
196 {509, 51},
197 {498, 52},
198 {486, 53},
199 {475, 54},
200 {463, 55},
201 {452, 56},
202 {442, 57},
203 {431, 58},
204 {421, 59},
205 {411, 60},
206 {401, 61},
207 {392, 62},
208 {383, 63},
209 {374, 64},
210 {365, 65},
211 {356, 66},
212 {348, 67},
213 {339, 68},
214 {331, 69},
215 {323, 70},
216 {316, 71},
217 {308, 72},
218 {301, 73},
219 {294, 74},
220 {287, 75},
221 {280, 76},
222 {273, 77},
223 {267, 78},
224 {261, 79},
225 {255, 80},
226 {249, 81},
227 {243, 82},
228 {237, 83},
229 {232, 84},
230 {226, 85},
231 {221, 86},
232 {216, 87},
233 {211, 88},
234 {206, 89},
235 {201, 90}
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700236};
237
238static const struct pm8xxx_adc_map_pt adcmap_ntcg_104ef_104fb[] = {
239 {696483, -40960},
240 {649148, -39936},
241 {605368, -38912},
242 {564809, -37888},
243 {527215, -36864},
244 {492322, -35840},
245 {460007, -34816},
246 {429982, -33792},
247 {402099, -32768},
248 {376192, -31744},
249 {352075, -30720},
250 {329714, -29696},
251 {308876, -28672},
252 {289480, -27648},
253 {271417, -26624},
254 {254574, -25600},
255 {238903, -24576},
256 {224276, -23552},
257 {210631, -22528},
258 {197896, -21504},
259 {186007, -20480},
260 {174899, -19456},
261 {164521, -18432},
262 {154818, -17408},
263 {145744, -16384},
264 {137265, -15360},
265 {129307, -14336},
266 {121866, -13312},
267 {114896, -12288},
268 {108365, -11264},
269 {102252, -10240},
270 {96499, -9216},
271 {91111, -8192},
272 {86055, -7168},
273 {81308, -6144},
274 {76857, -5120},
275 {72660, -4096},
276 {68722, -3072},
277 {65020, -2048},
278 {61538, -1024},
279 {58261, 0},
280 {55177, 1024},
281 {52274, 2048},
282 {49538, 3072},
283 {46962, 4096},
284 {44531, 5120},
285 {42243, 6144},
286 {40083, 7168},
287 {38045, 8192},
288 {36122, 9216},
289 {34308, 10240},
290 {32592, 11264},
291 {30972, 12288},
292 {29442, 13312},
293 {27995, 14336},
294 {26624, 15360},
295 {25333, 16384},
296 {24109, 17408},
297 {22951, 18432},
298 {21854, 19456},
299 {20807, 20480},
300 {19831, 21504},
301 {18899, 22528},
302 {18016, 23552},
303 {17178, 24576},
304 {16384, 25600},
305 {15631, 26624},
306 {14916, 27648},
307 {14237, 28672},
308 {13593, 29696},
309 {12976, 30720},
310 {12400, 31744},
311 {11848, 32768},
312 {11324, 33792},
313 {10825, 34816},
314 {10354, 35840},
315 {9900, 36864},
316 {9471, 37888},
317 {9062, 38912},
318 {8674, 39936},
319 {8306, 40960},
320 {7951, 41984},
321 {7616, 43008},
322 {7296, 44032},
323 {6991, 45056},
324 {6701, 46080},
325 {6424, 47104},
326 {6160, 48128},
327 {5908, 49152},
328 {5667, 50176},
329 {5439, 51200},
330 {5219, 52224},
331 {5010, 53248},
332 {4810, 54272},
333 {4619, 55296},
334 {4440, 56320},
335 {4263, 57344},
336 {4097, 58368},
337 {3938, 59392},
338 {3785, 60416},
339 {3637, 61440},
340 {3501, 62464},
341 {3368, 63488},
342 {3240, 64512},
343 {3118, 65536},
344 {2998, 66560},
345 {2889, 67584},
346 {2782, 68608},
347 {2680, 69632},
348 {2581, 70656},
349 {2490, 71680},
350 {2397, 72704},
351 {2310, 73728},
352 {2227, 74752},
353 {2147, 75776},
354 {2064, 76800},
355 {1998, 77824},
356 {1927, 78848},
357 {1860, 79872},
358 {1795, 80896},
359 {1736, 81920},
360 {1673, 82944},
361 {1615, 83968},
362 {1560, 84992},
363 {1507, 86016},
364 {1456, 87040},
365 {1407, 88064},
366 {1360, 89088},
367 {1314, 90112},
368 {1271, 91136},
369 {1228, 92160},
370 {1189, 93184},
371 {1150, 94208},
372 {1112, 95232},
373 {1076, 96256},
374 {1042, 97280},
375 {1008, 98304},
376 {976, 99328},
377 {945, 100352},
378 {915, 101376},
379 {886, 102400},
380 {859, 103424},
381 {832, 104448},
382 {807, 105472},
383 {782, 106496},
384 {756, 107520},
385 {735, 108544},
386 {712, 109568},
387 {691, 110592},
388 {670, 111616},
389 {650, 112640},
390 {631, 113664},
391 {612, 114688},
392 {594, 115712},
393 {577, 116736},
394 {560, 117760},
395 {544, 118784},
396 {528, 119808},
397 {513, 120832},
398 {498, 121856},
399 {483, 122880},
400 {470, 123904},
401 {457, 124928},
402 {444, 125952},
403 {431, 126976},
404 {419, 128000}
405};
406
407static int32_t pm8xxx_adc_map_linear(const struct pm8xxx_adc_map_pt *pts,
408 uint32_t tablesize, int32_t input, int64_t *output)
409{
410 bool descending = 1;
411 uint32_t i = 0;
412
413 if ((pts == NULL) || (output == NULL))
414 return -EINVAL;
415
416 /* Check if table is descending or ascending */
417 if (tablesize > 1) {
418 if (pts[0].x < pts[1].x)
419 descending = 0;
420 }
421
422 while (i < tablesize) {
423 if ((descending == 1) && (pts[i].x < input)) {
424 /* table entry is less than measured
425 value and table is descending, stop */
426 break;
427 } else if ((descending == 0) &&
428 (pts[i].x > input)) {
429 /* table entry is greater than measured
430 value and table is ascending, stop */
431 break;
432 } else {
433 i++;
434 }
435 }
436
437 if (i == 0)
438 *output = pts[0].y;
439 else if (i == tablesize)
440 *output = pts[tablesize-1].y;
441 else {
442 /* result is between search_index and search_index-1 */
443 /* interpolate linearly */
444 *output = (((int32_t) ((pts[i].y - pts[i-1].y)*
445 (input - pts[i-1].x))/
446 (pts[i].x - pts[i-1].x))+
447 pts[i-1].y);
448 }
449
450 return 0;
451}
452
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800453static int32_t pm8xxx_adc_map_batt_therm(const struct pm8xxx_adc_map_pt *pts,
454 uint32_t tablesize, int32_t input, int64_t *output)
455{
456 bool descending = 1;
457 uint32_t i = 0;
458
459 if ((pts == NULL) || (output == NULL))
460 return -EINVAL;
461
462 /* Check if table is descending or ascending */
463 if (tablesize > 1) {
464 if (pts[0].y < pts[1].y)
465 descending = 0;
466 }
467
468 while (i < tablesize) {
469 if ((descending == 1) && (pts[i].y < input)) {
470 /* table entry is less than measured
471 value and table is descending, stop */
472 break;
473 } else if ((descending == 0) && (pts[i].y > input)) {
474 /* table entry is greater than measured
475 value and table is ascending, stop */
476 break;
477 } else {
478 i++;
479 }
480 }
481
482 if (i == 0) {
483 *output = pts[0].x;
484 } else if (i == tablesize) {
485 *output = pts[tablesize-1].x;
486 } else {
487 /* result is between search_index and search_index-1 */
488 /* interpolate linearly */
489 *output = (((int32_t) ((pts[i].x - pts[i-1].x)*
490 (input - pts[i-1].y))/
491 (pts[i].y - pts[i-1].y))+
492 pts[i-1].x);
493 }
494
495 return 0;
496}
497
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700498int32_t pm8xxx_adc_scale_default(int32_t adc_code,
499 const struct pm8xxx_adc_properties *adc_properties,
500 const struct pm8xxx_adc_chan_properties *chan_properties,
501 struct pm8xxx_adc_chan_result *adc_chan_result)
502{
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800503 bool negative_rawfromoffset = 0, negative_offset = 0;
504 int64_t scale_voltage = 0;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700505
506 if (!chan_properties || !chan_properties->offset_gain_numerator ||
507 !chan_properties->offset_gain_denominator || !adc_properties
508 || !adc_chan_result)
509 return -EINVAL;
510
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800511 scale_voltage = (adc_code -
512 chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].adc_gnd)
513 * chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
514 if (scale_voltage < 0) {
515 negative_offset = 1;
516 scale_voltage = -scale_voltage;
517 }
518 do_div(scale_voltage,
519 chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dy);
520 if (negative_offset)
521 scale_voltage = -scale_voltage;
522 scale_voltage += chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700523
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800524 if (scale_voltage < 0) {
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700525 if (adc_properties->bipolar) {
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800526 scale_voltage = -scale_voltage;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700527 negative_rawfromoffset = 1;
528 } else {
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800529 scale_voltage = 0;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700530 }
531 }
532
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800533 adc_chan_result->measurement = scale_voltage *
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700534 chan_properties->offset_gain_denominator;
535
536 /* do_div only perform positive integer division! */
537 do_div(adc_chan_result->measurement,
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700538 chan_properties->offset_gain_numerator);
539
540 if (negative_rawfromoffset)
541 adc_chan_result->measurement = -adc_chan_result->measurement;
542
543 /* Note: adc_chan_result->measurement is in the unit of
544 * adc_properties.adc_reference. For generic channel processing,
545 * channel measurement is a scale/ratio relative to the adc
546 * reference input */
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800547 adc_chan_result->physical = adc_chan_result->measurement;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700548
549 return 0;
550}
551EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_default);
552
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800553static int64_t pm8xxx_adc_scale_ratiometric_calib(int32_t adc_code,
554 const struct pm8xxx_adc_properties *adc_properties,
555 const struct pm8xxx_adc_chan_properties *chan_properties)
556{
557 int64_t adc_voltage = 0;
558 bool negative_offset = 0;
559
560 if (!chan_properties || !chan_properties->offset_gain_numerator ||
561 !chan_properties->offset_gain_denominator || !adc_properties)
562 return -EINVAL;
563
564 adc_voltage = (adc_code -
565 chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd)
566 * adc_properties->adc_vdd_reference;
567 if (adc_voltage < 0) {
568 negative_offset = 1;
569 adc_voltage = -adc_voltage;
570 }
571 do_div(adc_voltage,
572 chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy);
573 if (negative_offset)
574 adc_voltage = -adc_voltage;
575
576 return adc_voltage;
577}
578
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700579int32_t pm8xxx_adc_scale_batt_therm(int32_t adc_code,
580 const struct pm8xxx_adc_properties *adc_properties,
581 const struct pm8xxx_adc_chan_properties *chan_properties,
582 struct pm8xxx_adc_chan_result *adc_chan_result)
583{
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800584 int64_t bat_voltage = 0;
585
586 bat_voltage = pm8xxx_adc_scale_ratiometric_calib(adc_code,
587 adc_properties, chan_properties);
588
589 return pm8xxx_adc_map_batt_therm(
590 adcmap_btm_threshold,
591 ARRAY_SIZE(adcmap_btm_threshold),
592 bat_voltage,
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700593 &adc_chan_result->physical);
594}
595EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_batt_therm);
596
597int32_t pm8xxx_adc_scale_pa_therm(int32_t adc_code,
598 const struct pm8xxx_adc_properties *adc_properties,
599 const struct pm8xxx_adc_chan_properties *chan_properties,
600 struct pm8xxx_adc_chan_result *adc_chan_result)
601{
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800602 int64_t pa_voltage = 0;
603
604 pa_voltage = pm8xxx_adc_scale_ratiometric_calib(adc_code,
605 adc_properties, chan_properties);
606
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700607 return pm8xxx_adc_map_linear(
608 adcmap_pa_therm,
609 ARRAY_SIZE(adcmap_pa_therm),
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800610 pa_voltage,
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700611 &adc_chan_result->physical);
612}
613EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_pa_therm);
614
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800615int32_t pm8xxx_adc_scale_batt_id(int32_t adc_code,
616 const struct pm8xxx_adc_properties *adc_properties,
617 const struct pm8xxx_adc_chan_properties *chan_properties,
618 struct pm8xxx_adc_chan_result *adc_chan_result)
619{
620 int64_t batt_id_voltage = 0;
621
622 batt_id_voltage = pm8xxx_adc_scale_ratiometric_calib(adc_code,
623 adc_properties, chan_properties);
624 adc_chan_result->physical = batt_id_voltage;
625 adc_chan_result->physical = adc_chan_result->measurement;
626
627 return 0;
628}
629EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_batt_id);
630
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700631int32_t pm8xxx_adc_scale_pmic_therm(int32_t adc_code,
632 const struct pm8xxx_adc_properties *adc_properties,
633 const struct pm8xxx_adc_chan_properties *chan_properties,
634 struct pm8xxx_adc_chan_result *adc_chan_result)
635{
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800636 int64_t pmic_voltage = 0;
637 bool negative_offset = 0;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700638
639 if (!chan_properties || !chan_properties->offset_gain_numerator ||
640 !chan_properties->offset_gain_denominator || !adc_properties
641 || !adc_chan_result)
642 return -EINVAL;
643
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800644 pmic_voltage = (adc_code -
645 chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].adc_gnd)
646 * chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
647 if (pmic_voltage < 0) {
648 negative_offset = 1;
649 pmic_voltage = -pmic_voltage;
650 }
651 do_div(pmic_voltage,
652 chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dy);
653 if (negative_offset)
654 pmic_voltage = -pmic_voltage;
655 pmic_voltage += chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
656
657 if (pmic_voltage > 0) {
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700658 /* 2mV/K */
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800659 adc_chan_result->measurement = pmic_voltage*
660 chan_properties->offset_gain_denominator;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700661
662 do_div(adc_chan_result->measurement,
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800663 chan_properties->offset_gain_numerator * 2);
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700664 } else {
665 adc_chan_result->measurement = 0;
666 }
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700667 /* Change to .001 deg C */
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800668 adc_chan_result->measurement -= KELVINMIL_DEGMIL;
669 adc_chan_result->physical = (int32_t)adc_chan_result->measurement;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700670
671 return 0;
672}
673EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_pmic_therm);
674
675/* Scales the ADC code to 0.001 degrees C using the map
676 * table for the XO thermistor.
677 */
678int32_t pm8xxx_adc_tdkntcg_therm(int32_t adc_code,
679 const struct pm8xxx_adc_properties *adc_properties,
680 const struct pm8xxx_adc_chan_properties *chan_properties,
681 struct pm8xxx_adc_chan_result *adc_chan_result)
682{
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800683 int64_t xo_thm = 0;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700684
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800685 if (!chan_properties || !chan_properties->offset_gain_numerator ||
686 !chan_properties->offset_gain_denominator || !adc_properties
687 || !adc_chan_result)
688 return -EINVAL;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700689
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800690 xo_thm = pm8xxx_adc_scale_ratiometric_calib(adc_code,
691 adc_properties, chan_properties);
692 xo_thm <<= 4;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700693 pm8xxx_adc_map_linear(adcmap_ntcg_104ef_104fb,
694 ARRAY_SIZE(adcmap_ntcg_104ef_104fb),
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800695 xo_thm, &adc_chan_result->physical);
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700696
697 return 0;
698}
699EXPORT_SYMBOL_GPL(pm8xxx_adc_tdkntcg_therm);
700
Siddartha Mohanadossae39c902011-11-09 17:54:31 -0800701int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *btm_param,
702 const struct pm8xxx_adc_properties *adc_properties,
703 const struct pm8xxx_adc_chan_properties *chan_properties)
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700704{
705 int rc;
706
707 rc = pm8xxx_adc_map_linear(
708 adcmap_btm_threshold,
709 ARRAY_SIZE(adcmap_btm_threshold),
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800710 (btm_param->low_thr_temp),
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700711 &btm_param->low_thr_voltage);
Siddartha Mohanadossae39c902011-11-09 17:54:31 -0800712 if (rc)
713 return rc;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700714
Siddartha Mohanadossae39c902011-11-09 17:54:31 -0800715 btm_param->low_thr_voltage *=
716 chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy;
717 do_div(btm_param->low_thr_voltage, adc_properties->adc_vdd_reference);
718 btm_param->low_thr_voltage +=
719 chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd;
720
721 rc = pm8xxx_adc_map_linear(
722 adcmap_btm_threshold,
723 ARRAY_SIZE(adcmap_btm_threshold),
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800724 (btm_param->high_thr_temp),
Siddartha Mohanadossae39c902011-11-09 17:54:31 -0800725 &btm_param->high_thr_voltage);
726 if (rc)
727 return rc;
728
729 btm_param->high_thr_voltage *=
730 chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy;
731 do_div(btm_param->high_thr_voltage, adc_properties->adc_vdd_reference);
732 btm_param->high_thr_voltage +=
733 chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd;
734
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700735
736 return rc;
737}
738EXPORT_SYMBOL_GPL(pm8xxx_adc_batt_scaler);