blob: e2fed6d48208fcbb4ba3f69e07787b264915aa33 [file] [log] [blame]
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -08001/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define pr_fmt(fmt) "%s: " fmt, __func__
14
15#include <linux/kernel.h>
16#include <linux/of.h>
17#include <linux/err.h>
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/mutex.h>
22#include <linux/types.h>
23#include <linux/hwmon.h>
24#include <linux/module.h>
25#include <linux/debugfs.h>
26#include <linux/spmi.h>
27#include <linux/of_irq.h>
28#include <linux/interrupt.h>
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -070029#include <linux/completion.h>
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -070030#include <linux/qpnp/qpnp-adc.h>
31#include <linux/platform_device.h>
32
33/* Min ADC code represets 0V */
34#define QPNP_VADC_MIN_ADC_CODE 0x6000
35/* Max ADC code represents full-scale range of 1.8V */
36#define QPNP_VADC_MAX_ADC_CODE 0xA800
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -070037#define KELVINMIL_DEGMIL 273160
38
39/* Units for temperature below (on x axis) is in 0.1DegC as
40 required by the battery driver. Note the resolution used
41 here to compute the table was done for DegC to milli-volts.
42 In consideration to limit the size of the table for the given
43 temperature range below, the result is linearly interpolated
44 and provided to the battery driver in the units desired for
45 their framework which is 0.1DegC. True resolution of 0.1DegC
46 will result in the below table size to increase by 10 times */
47static const struct qpnp_vadc_map_pt adcmap_btm_threshold[] = {
48 {-300, 1642},
49 {-200, 1544},
50 {-100, 1414},
51 {0, 1260},
52 {10, 1244},
53 {20, 1228},
54 {30, 1212},
55 {40, 1195},
56 {50, 1179},
57 {60, 1162},
58 {70, 1146},
59 {80, 1129},
60 {90, 1113},
61 {100, 1097},
62 {110, 1080},
63 {120, 1064},
64 {130, 1048},
65 {140, 1032},
66 {150, 1016},
67 {160, 1000},
68 {170, 985},
69 {180, 969},
70 {190, 954},
71 {200, 939},
72 {210, 924},
73 {220, 909},
74 {230, 894},
75 {240, 880},
76 {250, 866},
77 {260, 852},
78 {270, 838},
79 {280, 824},
80 {290, 811},
81 {300, 798},
82 {310, 785},
83 {320, 773},
84 {330, 760},
85 {340, 748},
86 {350, 736},
87 {360, 725},
88 {370, 713},
89 {380, 702},
90 {390, 691},
91 {400, 681},
92 {410, 670},
93 {420, 660},
94 {430, 650},
95 {440, 640},
96 {450, 631},
97 {460, 622},
98 {470, 613},
99 {480, 604},
100 {490, 595},
101 {500, 587},
102 {510, 579},
103 {520, 571},
104 {530, 563},
105 {540, 556},
106 {550, 548},
107 {560, 541},
108 {570, 534},
109 {580, 527},
110 {590, 521},
111 {600, 514},
112 {610, 508},
113 {620, 502},
114 {630, 496},
115 {640, 490},
116 {650, 485},
117 {660, 281},
118 {670, 274},
119 {680, 267},
120 {690, 260},
121 {700, 254},
122 {710, 247},
123 {720, 241},
124 {730, 235},
125 {740, 229},
126 {750, 224},
127 {760, 218},
128 {770, 213},
129 {780, 208},
130 {790, 203}
131};
132
Siddartha Mohanadossb99cfa92013-05-01 20:19:58 -0700133static const struct qpnp_vadc_map_pt adcmap_qrd_btm_threshold[] = {
Xu Kaid6a9c312013-07-27 12:42:31 +0800134 {-200, 1540},
135 {-180, 1517},
136 {-160, 1492},
137 {-140, 1467},
138 {-120, 1440},
139 {-100, 1412},
140 {-80, 1383},
141 {-60, 1353},
142 {-40, 1323},
143 {-20, 1292},
144 {0, 1260},
145 {20, 1228},
146 {40, 1196},
147 {60, 1163},
148 {80, 1131},
149 {100, 1098},
150 {120, 1066},
151 {140, 1034},
152 {160, 1002},
153 {180, 971},
154 {200, 941},
155 {220, 911},
156 {240, 882},
157 {260, 854},
158 {280, 826},
159 {300, 800},
160 {320, 774},
161 {340, 749},
162 {360, 726},
163 {380, 703},
164 {400, 681},
165 {420, 660},
166 {440, 640},
167 {460, 621},
168 {480, 602},
169 {500, 585},
170 {520, 568},
171 {540, 552},
172 {560, 537},
173 {580, 523},
174 {600, 510},
175 {620, 497},
176 {640, 485},
177 {660, 473},
178 {680, 462},
179 {700, 452},
180 {720, 442},
181 {740, 433},
182 {760, 424},
183 {780, 416},
184 {800, 408},
Siddartha Mohanadossb99cfa92013-05-01 20:19:58 -0700185};
186
Siddartha Mohanadosse84f8e62012-11-16 09:34:41 -0800187/* Voltage to temperature */
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700188static const struct qpnp_vadc_map_pt adcmap_100k_104ef_104fb[] = {
Siddartha Mohanadosse84f8e62012-11-16 09:34:41 -0800189 {1758, -40},
190 {1742, -35},
191 {1719, -30},
192 {1691, -25},
193 {1654, -20},
194 {1608, -15},
195 {1551, -10},
196 {1483, -5},
197 {1404, 0},
198 {1315, 5},
199 {1218, 10},
200 {1114, 15},
201 {1007, 20},
202 {900, 25},
203 {795, 30},
204 {696, 35},
205 {605, 40},
206 {522, 45},
207 {448, 50},
208 {383, 55},
209 {327, 60},
210 {278, 65},
211 {237, 70},
212 {202, 75},
213 {172, 80},
214 {146, 85},
215 {125, 90},
216 {107, 95},
217 {92, 100},
218 {79, 105},
219 {68, 110},
220 {59, 115},
221 {51, 120},
222 {44, 125}
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700223};
224
Siddartha Mohanadosse84f8e62012-11-16 09:34:41 -0800225/* Voltage to temperature */
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700226static const struct qpnp_vadc_map_pt adcmap_150k_104ef_104fb[] = {
Siddartha Mohanadosse84f8e62012-11-16 09:34:41 -0800227 {1738, -40},
228 {1714, -35},
229 {1682, -30},
230 {1641, -25},
231 {1589, -20},
232 {1526, -15},
233 {1451, -10},
234 {1363, -5},
235 {1266, 0},
236 {1159, 5},
237 {1048, 10},
238 {936, 15},
239 {825, 20},
240 {720, 25},
241 {622, 30},
242 {533, 35},
243 {454, 40},
244 {385, 45},
245 {326, 50},
246 {275, 55},
247 {232, 60},
248 {195, 65},
249 {165, 70},
250 {139, 75},
251 {118, 80},
252 {100, 85},
253 {85, 90},
254 {73, 95},
255 {62, 100},
256 {53, 105},
257 {46, 110},
258 {40, 115},
259 {34, 120},
260 {30, 125}
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700261};
262
Siddartha Mohanadoss4a27b1c2012-11-16 09:34:41 -0800263static int32_t qpnp_adc_map_voltage_temp(const struct qpnp_vadc_map_pt *pts,
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700264 uint32_t tablesize, int32_t input, int64_t *output)
265{
266 bool descending = 1;
267 uint32_t i = 0;
268
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700269 if (pts == NULL)
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700270 return -EINVAL;
271
272 /* Check if table is descending or ascending */
273 if (tablesize > 1) {
274 if (pts[0].x < pts[1].x)
275 descending = 0;
276 }
277
278 while (i < tablesize) {
279 if ((descending == 1) && (pts[i].x < input)) {
280 /* table entry is less than measured
281 value and table is descending, stop */
282 break;
283 } else if ((descending == 0) &&
284 (pts[i].x > input)) {
285 /* table entry is greater than measured
286 value and table is ascending, stop */
287 break;
288 } else {
289 i++;
290 }
291 }
292
293 if (i == 0)
294 *output = pts[0].y;
295 else if (i == tablesize)
296 *output = pts[tablesize-1].y;
297 else {
298 /* result is between search_index and search_index-1 */
299 /* interpolate linearly */
300 *output = (((int32_t) ((pts[i].y - pts[i-1].y)*
301 (input - pts[i-1].x))/
302 (pts[i].x - pts[i-1].x))+
303 pts[i-1].y);
304 }
305
306 return 0;
307}
308
Siddartha Mohanadoss4a27b1c2012-11-16 09:34:41 -0800309static int32_t qpnp_adc_map_temp_voltage(const struct qpnp_vadc_map_pt *pts,
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700310 uint32_t tablesize, int32_t input, int64_t *output)
311{
312 bool descending = 1;
313 uint32_t i = 0;
314
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700315 if (pts == NULL)
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700316 return -EINVAL;
317
318 /* Check if table is descending or ascending */
319 if (tablesize > 1) {
320 if (pts[0].y < pts[1].y)
321 descending = 0;
322 }
323
324 while (i < tablesize) {
325 if ((descending == 1) && (pts[i].y < input)) {
326 /* table entry is less than measured
327 value and table is descending, stop */
328 break;
329 } else if ((descending == 0) && (pts[i].y > input)) {
330 /* table entry is greater than measured
331 value and table is ascending, stop */
332 break;
333 } else {
334 i++;
335 }
336 }
337
338 if (i == 0) {
339 *output = pts[0].x;
340 } else if (i == tablesize) {
341 *output = pts[tablesize-1].x;
342 } else {
343 /* result is between search_index and search_index-1 */
344 /* interpolate linearly */
345 *output = (((int32_t) ((pts[i].x - pts[i-1].x)*
346 (input - pts[i-1].y))/
347 (pts[i].y - pts[i-1].y))+
348 pts[i-1].x);
349 }
350
351 return 0;
352}
353
354static int64_t qpnp_adc_scale_ratiometric_calib(int32_t adc_code,
355 const struct qpnp_adc_properties *adc_properties,
356 const struct qpnp_vadc_chan_properties *chan_properties)
357{
358 int64_t adc_voltage = 0;
359 bool negative_offset = 0;
360
361 if (!chan_properties || !chan_properties->offset_gain_numerator ||
362 !chan_properties->offset_gain_denominator || !adc_properties)
363 return -EINVAL;
364
365 adc_voltage = (adc_code -
366 chan_properties->adc_graph[CALIB_RATIOMETRIC].adc_gnd)
367 * adc_properties->adc_vdd_reference;
368 if (adc_voltage < 0) {
369 negative_offset = 1;
370 adc_voltage = -adc_voltage;
371 }
372 do_div(adc_voltage,
373 chan_properties->adc_graph[CALIB_RATIOMETRIC].dy);
374 if (negative_offset)
375 adc_voltage = -adc_voltage;
376
377 return adc_voltage;
378}
379
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700380int32_t qpnp_adc_scale_pmic_therm(struct qpnp_vadc_chip *vadc,
381 int32_t adc_code,
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700382 const struct qpnp_adc_properties *adc_properties,
383 const struct qpnp_vadc_chan_properties *chan_properties,
384 struct qpnp_vadc_result *adc_chan_result)
385{
386 int64_t pmic_voltage = 0;
387 bool negative_offset = 0;
388
389 if (!chan_properties || !chan_properties->offset_gain_numerator ||
390 !chan_properties->offset_gain_denominator || !adc_properties
391 || !adc_chan_result)
392 return -EINVAL;
393
394 pmic_voltage = (adc_code -
395 chan_properties->adc_graph[CALIB_ABSOLUTE].adc_gnd)
396 * chan_properties->adc_graph[CALIB_ABSOLUTE].dx;
397 if (pmic_voltage < 0) {
398 negative_offset = 1;
399 pmic_voltage = -pmic_voltage;
400 }
401 do_div(pmic_voltage,
402 chan_properties->adc_graph[CALIB_ABSOLUTE].dy);
403 if (negative_offset)
404 pmic_voltage = -pmic_voltage;
405 pmic_voltage += chan_properties->adc_graph[CALIB_ABSOLUTE].dx;
406
407 if (pmic_voltage > 0) {
408 /* 2mV/K */
409 adc_chan_result->measurement = pmic_voltage*
410 chan_properties->offset_gain_denominator;
411
412 do_div(adc_chan_result->measurement,
413 chan_properties->offset_gain_numerator * 2);
414 } else {
415 adc_chan_result->measurement = 0;
416 }
417 /* Change to .001 deg C */
418 adc_chan_result->measurement -= KELVINMIL_DEGMIL;
419 adc_chan_result->physical = (int32_t)adc_chan_result->measurement;
420
421 return 0;
422}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700423EXPORT_SYMBOL(qpnp_adc_scale_pmic_therm);
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700424
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700425int32_t qpnp_adc_scale_millidegc_pmic_voltage_thr(struct qpnp_vadc_chip *chip,
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800426 struct qpnp_adc_tm_btm_param *param,
427 uint32_t *low_threshold, uint32_t *high_threshold)
428{
429 struct qpnp_vadc_linear_graph btm_param;
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700430 int64_t low_output = 0, high_output = 0;
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700431 int rc = 0, sign = 0;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800432
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700433 rc = qpnp_get_vadc_gain_and_offset(chip, &btm_param, CALIB_ABSOLUTE);
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800434 if (rc < 0) {
435 pr_err("Could not acquire gain and offset\n");
436 return rc;
437 }
438
439 /* Convert to Kelvin and account for voltage to be written as 2mV/K */
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700440 low_output = (param->low_temp + KELVINMIL_DEGMIL) * 2;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800441 /* Convert to voltage threshold */
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700442 low_output = (low_output - QPNP_ADC_625_UV) * btm_param.dy;
443 if (low_output < 0) {
444 sign = 1;
445 low_output = -low_output;
446 }
447 do_div(low_output, QPNP_ADC_625_UV);
448 if (sign)
449 low_output = -low_output;
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700450 low_output += btm_param.adc_gnd;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800451
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700452 sign = 0;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800453 /* Convert to Kelvin and account for voltage to be written as 2mV/K */
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700454 high_output = (param->high_temp + KELVINMIL_DEGMIL) * 2;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800455 /* Convert to voltage threshold */
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700456 high_output = (high_output - QPNP_ADC_625_UV) * btm_param.dy;
457 if (high_output < 0) {
458 sign = 1;
459 high_output = -high_output;
460 }
461 do_div(high_output, QPNP_ADC_625_UV);
462 if (sign)
463 high_output = -high_output;
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700464 high_output += btm_param.adc_gnd;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800465
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700466 *low_threshold = (uint32_t) low_output;
467 *high_threshold = (uint32_t) high_output;
468 pr_debug("high_temp:%d, low_temp:%d\n", param->high_temp,
469 param->low_temp);
470 pr_debug("adc_code_high:%x, adc_code_low:%x\n", *high_threshold,
471 *low_threshold);
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800472
473 return 0;
474}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700475EXPORT_SYMBOL(qpnp_adc_scale_millidegc_pmic_voltage_thr);
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800476
477/* Scales the ADC code to degC using the mapping
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700478 * table for the XO thermistor.
479 */
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700480int32_t qpnp_adc_tdkntcg_therm(struct qpnp_vadc_chip *chip,
481 int32_t adc_code,
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700482 const struct qpnp_adc_properties *adc_properties,
483 const struct qpnp_vadc_chan_properties *chan_properties,
484 struct qpnp_vadc_result *adc_chan_result)
485{
486 int64_t xo_thm = 0;
487
488 if (!chan_properties || !chan_properties->offset_gain_numerator ||
489 !chan_properties->offset_gain_denominator || !adc_properties
490 || !adc_chan_result)
491 return -EINVAL;
492
493 xo_thm = qpnp_adc_scale_ratiometric_calib(adc_code,
494 adc_properties, chan_properties);
Siddartha Mohanadoss0dc06942012-12-23 17:10:10 -0800495
496 qpnp_adc_map_voltage_temp(adcmap_100k_104ef_104fb,
497 ARRAY_SIZE(adcmap_100k_104ef_104fb),
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700498 xo_thm, &adc_chan_result->physical);
499
500 return 0;
501}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700502EXPORT_SYMBOL(qpnp_adc_tdkntcg_therm);
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700503
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700504int32_t qpnp_adc_scale_batt_therm(struct qpnp_vadc_chip *chip,
505 int32_t adc_code,
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700506 const struct qpnp_adc_properties *adc_properties,
507 const struct qpnp_vadc_chan_properties *chan_properties,
508 struct qpnp_vadc_result *adc_chan_result)
509{
510 int64_t bat_voltage = 0;
511
512 bat_voltage = qpnp_adc_scale_ratiometric_calib(adc_code,
513 adc_properties, chan_properties);
514
Siddartha Mohanadoss4a27b1c2012-11-16 09:34:41 -0800515 return qpnp_adc_map_temp_voltage(
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700516 adcmap_btm_threshold,
517 ARRAY_SIZE(adcmap_btm_threshold),
518 bat_voltage,
519 &adc_chan_result->physical);
520}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700521EXPORT_SYMBOL(qpnp_adc_scale_batt_therm);
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700522
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700523int32_t qpnp_adc_scale_qrd_batt_therm(struct qpnp_vadc_chip *chip,
524 int32_t adc_code,
Siddartha Mohanadossb99cfa92013-05-01 20:19:58 -0700525 const struct qpnp_adc_properties *adc_properties,
526 const struct qpnp_vadc_chan_properties *chan_properties,
527 struct qpnp_vadc_result *adc_chan_result)
528{
529 int64_t bat_voltage = 0;
530
531 bat_voltage = qpnp_adc_scale_ratiometric_calib(adc_code,
532 adc_properties, chan_properties);
533
534 return qpnp_adc_map_temp_voltage(
535 adcmap_qrd_btm_threshold,
536 ARRAY_SIZE(adcmap_qrd_btm_threshold),
537 bat_voltage,
538 &adc_chan_result->physical);
539}
540EXPORT_SYMBOL(qpnp_adc_scale_qrd_batt_therm);
541
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700542int32_t qpnp_adc_scale_therm_pu1(struct qpnp_vadc_chip *chip,
543 int32_t adc_code,
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700544 const struct qpnp_adc_properties *adc_properties,
545 const struct qpnp_vadc_chan_properties *chan_properties,
546 struct qpnp_vadc_result *adc_chan_result)
547{
548 int64_t therm_voltage = 0;
549
550 therm_voltage = qpnp_adc_scale_ratiometric_calib(adc_code,
551 adc_properties, chan_properties);
552
Siddartha Mohanadosse84f8e62012-11-16 09:34:41 -0800553 qpnp_adc_map_voltage_temp(adcmap_150k_104ef_104fb,
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700554 ARRAY_SIZE(adcmap_150k_104ef_104fb),
555 therm_voltage, &adc_chan_result->physical);
556
557 return 0;
558}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700559EXPORT_SYMBOL(qpnp_adc_scale_therm_pu1);
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700560
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700561int32_t qpnp_adc_scale_therm_pu2(struct qpnp_vadc_chip *chip,
562 int32_t adc_code,
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700563 const struct qpnp_adc_properties *adc_properties,
564 const struct qpnp_vadc_chan_properties *chan_properties,
565 struct qpnp_vadc_result *adc_chan_result)
566{
567 int64_t therm_voltage = 0;
568
569 therm_voltage = qpnp_adc_scale_ratiometric_calib(adc_code,
570 adc_properties, chan_properties);
571
Siddartha Mohanadosse84f8e62012-11-16 09:34:41 -0800572 qpnp_adc_map_voltage_temp(adcmap_100k_104ef_104fb,
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700573 ARRAY_SIZE(adcmap_100k_104ef_104fb),
574 therm_voltage, &adc_chan_result->physical);
575
576 return 0;
577}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700578EXPORT_SYMBOL(qpnp_adc_scale_therm_pu2);
Siddartha Mohanadosse77edf12012-09-13 14:26:32 -0700579
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700580int32_t qpnp_adc_tm_scale_voltage_therm_pu2(struct qpnp_vadc_chip *chip,
581 uint32_t reg, int64_t *result)
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800582{
583 int64_t adc_voltage = 0;
584 struct qpnp_vadc_linear_graph param1;
585 int negative_offset;
586
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700587 qpnp_get_vadc_gain_and_offset(chip, &param1, CALIB_RATIOMETRIC);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800588
589 adc_voltage = (reg - param1.adc_gnd) * param1.adc_vref;
590 if (adc_voltage < 0) {
591 negative_offset = 1;
592 adc_voltage = -adc_voltage;
593 }
594
595 do_div(adc_voltage, param1.dy);
596
Siddartha Mohanadoss31f60962012-11-27 14:11:02 -0800597 qpnp_adc_map_voltage_temp(adcmap_100k_104ef_104fb,
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800598 ARRAY_SIZE(adcmap_100k_104ef_104fb),
599 adc_voltage, result);
600 if (negative_offset)
601 adc_voltage = -adc_voltage;
602
603 return 0;
604}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700605EXPORT_SYMBOL(qpnp_adc_tm_scale_voltage_therm_pu2);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800606
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700607int32_t qpnp_adc_tm_scale_therm_voltage_pu2(struct qpnp_vadc_chip *chip,
608 struct qpnp_adc_tm_config *param)
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800609{
610 struct qpnp_vadc_linear_graph param1;
611 int rc;
612
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700613 qpnp_get_vadc_gain_and_offset(chip, &param1, CALIB_RATIOMETRIC);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800614
Siddartha Mohanadoss31f60962012-11-27 14:11:02 -0800615 rc = qpnp_adc_map_temp_voltage(adcmap_100k_104ef_104fb,
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800616 ARRAY_SIZE(adcmap_100k_104ef_104fb),
617 param->low_thr_temp, &param->low_thr_voltage);
618 if (rc)
619 return rc;
620
621 param->low_thr_voltage *= param1.dy;
622 do_div(param->low_thr_voltage, param1.adc_vref);
623 param->low_thr_voltage += param1.adc_gnd;
624
Siddartha Mohanadoss31f60962012-11-27 14:11:02 -0800625 rc = qpnp_adc_map_temp_voltage(adcmap_100k_104ef_104fb,
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800626 ARRAY_SIZE(adcmap_100k_104ef_104fb),
627 param->high_thr_temp, &param->high_thr_voltage);
628 if (rc)
629 return rc;
630
631 param->high_thr_voltage *= param1.dy;
632 do_div(param->high_thr_voltage, param1.adc_vref);
633 param->high_thr_voltage += param1.adc_gnd;
634
635 return 0;
636}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700637EXPORT_SYMBOL(qpnp_adc_tm_scale_therm_voltage_pu2);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800638
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700639int32_t qpnp_adc_scale_batt_id(struct qpnp_vadc_chip *chip,
640 int32_t adc_code,
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700641 const struct qpnp_adc_properties *adc_properties,
642 const struct qpnp_vadc_chan_properties *chan_properties,
643 struct qpnp_vadc_result *adc_chan_result)
644{
645 int64_t batt_id_voltage = 0;
646
647 batt_id_voltage = qpnp_adc_scale_ratiometric_calib(adc_code,
648 adc_properties, chan_properties);
649 adc_chan_result->physical = batt_id_voltage;
650 adc_chan_result->physical = adc_chan_result->measurement;
651
652 return 0;
653}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700654EXPORT_SYMBOL(qpnp_adc_scale_batt_id);
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700655
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700656int32_t qpnp_adc_scale_default(struct qpnp_vadc_chip *vadc,
657 int32_t adc_code,
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700658 const struct qpnp_adc_properties *adc_properties,
659 const struct qpnp_vadc_chan_properties *chan_properties,
660 struct qpnp_vadc_result *adc_chan_result)
661{
662 bool negative_rawfromoffset = 0, negative_offset = 0;
663 int64_t scale_voltage = 0;
664
665 if (!chan_properties || !chan_properties->offset_gain_numerator ||
666 !chan_properties->offset_gain_denominator || !adc_properties
667 || !adc_chan_result)
668 return -EINVAL;
669
670 scale_voltage = (adc_code -
671 chan_properties->adc_graph[CALIB_ABSOLUTE].adc_gnd)
672 * chan_properties->adc_graph[CALIB_ABSOLUTE].dx;
673 if (scale_voltage < 0) {
674 negative_offset = 1;
675 scale_voltage = -scale_voltage;
676 }
677 do_div(scale_voltage,
678 chan_properties->adc_graph[CALIB_ABSOLUTE].dy);
679 if (negative_offset)
680 scale_voltage = -scale_voltage;
681 scale_voltage += chan_properties->adc_graph[CALIB_ABSOLUTE].dx;
682
683 if (scale_voltage < 0) {
684 if (adc_properties->bipolar) {
685 scale_voltage = -scale_voltage;
686 negative_rawfromoffset = 1;
687 } else {
688 scale_voltage = 0;
689 }
690 }
691
692 adc_chan_result->measurement = scale_voltage *
693 chan_properties->offset_gain_denominator;
694
695 /* do_div only perform positive integer division! */
696 do_div(adc_chan_result->measurement,
697 chan_properties->offset_gain_numerator);
698
699 if (negative_rawfromoffset)
700 adc_chan_result->measurement = -adc_chan_result->measurement;
701
702 /*
703 * Note: adc_chan_result->measurement is in the unit of
704 * adc_properties.adc_reference. For generic channel processing,
705 * channel measurement is a scale/ratio relative to the adc
706 * reference input
707 */
708 adc_chan_result->physical = adc_chan_result->measurement;
709
710 return 0;
711}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700712EXPORT_SYMBOL(qpnp_adc_scale_default);
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700713
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700714int32_t qpnp_adc_usb_scaler(struct qpnp_vadc_chip *chip,
715 struct qpnp_adc_tm_btm_param *param,
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800716 uint32_t *low_threshold, uint32_t *high_threshold)
717{
718 struct qpnp_vadc_linear_graph usb_param;
719
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700720 qpnp_get_vadc_gain_and_offset(chip, &usb_param, CALIB_RATIOMETRIC);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800721
722 *low_threshold = param->low_thr * usb_param.dy;
723 do_div(*low_threshold, usb_param.adc_vref);
724 *low_threshold += usb_param.adc_gnd;
725
726 *high_threshold = param->high_thr * usb_param.dy;
727 do_div(*high_threshold, usb_param.adc_vref);
728 *high_threshold += usb_param.adc_gnd;
729
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800730 pr_debug("high_volt:%d, low_volt:%d\n", param->high_thr,
731 param->low_thr);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800732 return 0;
733}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700734EXPORT_SYMBOL(qpnp_adc_usb_scaler);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800735
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700736int32_t qpnp_adc_vbatt_rscaler(struct qpnp_vadc_chip *chip,
737 struct qpnp_adc_tm_btm_param *param,
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800738 uint32_t *low_threshold, uint32_t *high_threshold)
739{
740 struct qpnp_vadc_linear_graph vbatt_param;
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700741 int rc = 0, sign = 0;
Siddartha Mohanadoss91a1cd62013-04-19 19:34:36 -0700742 int64_t low_thr = 0, high_thr = 0;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800743
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700744 rc = qpnp_get_vadc_gain_and_offset(chip, &vbatt_param, CALIB_ABSOLUTE);
Siddartha Mohanadossc4140482013-03-28 18:44:54 -0700745 if (rc < 0)
746 return rc;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800747
Siddartha Mohanadoss91a1cd62013-04-19 19:34:36 -0700748 low_thr = (((param->low_thr/3) - QPNP_ADC_625_UV) *
Siddartha Mohanadossc4140482013-03-28 18:44:54 -0700749 vbatt_param.dy);
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700750 if (low_thr < 0) {
751 sign = 1;
752 low_thr = -low_thr;
753 }
Siddartha Mohanadoss91a1cd62013-04-19 19:34:36 -0700754 do_div(low_thr, QPNP_ADC_625_UV);
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700755 if (sign)
756 low_thr = -low_thr;
Siddartha Mohanadoss91a1cd62013-04-19 19:34:36 -0700757 *low_threshold = low_thr + vbatt_param.adc_gnd;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800758
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700759 sign = 0;
Siddartha Mohanadoss91a1cd62013-04-19 19:34:36 -0700760 high_thr = (((param->high_thr/3) - QPNP_ADC_625_UV) *
Siddartha Mohanadossc4140482013-03-28 18:44:54 -0700761 vbatt_param.dy);
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700762 if (high_thr < 0) {
763 sign = 1;
764 high_thr = -high_thr;
765 }
Siddartha Mohanadoss91a1cd62013-04-19 19:34:36 -0700766 do_div(high_thr, QPNP_ADC_625_UV);
Siddartha Mohanadoss71218f22013-04-23 16:24:14 -0700767 if (sign)
768 high_thr = -high_thr;
Siddartha Mohanadoss91a1cd62013-04-19 19:34:36 -0700769 *high_threshold = high_thr + vbatt_param.adc_gnd;
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800770
771 pr_debug("high_volt:%d, low_volt:%d\n", param->high_thr,
772 param->low_thr);
Siddartha Mohanadossc4140482013-03-28 18:44:54 -0700773 pr_debug("adc_code_high:%x, adc_code_low:%x\n", *high_threshold,
774 *low_threshold);
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800775 return 0;
776}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700777EXPORT_SYMBOL(qpnp_adc_vbatt_rscaler);
Siddartha Mohanadossa3e35512013-02-22 17:06:07 -0800778
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700779int32_t qpnp_adc_btm_scaler(struct qpnp_vadc_chip *chip,
780 struct qpnp_adc_tm_btm_param *param,
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800781 uint32_t *low_threshold, uint32_t *high_threshold)
782{
783 struct qpnp_vadc_linear_graph btm_param;
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700784 int64_t low_output = 0, high_output = 0;
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800785 int rc = 0;
786
Siddartha Mohanadoss3cb2b6b2013-06-21 12:07:05 -0700787 qpnp_get_vadc_gain_and_offset(chip, &btm_param, CALIB_RATIOMETRIC);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800788
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700789 pr_debug("warm_temp:%d and cool_temp:%d\n", param->high_temp,
790 param->low_temp);
791 rc = qpnp_adc_map_voltage_temp(
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800792 adcmap_btm_threshold,
793 ARRAY_SIZE(adcmap_btm_threshold),
794 (param->low_temp),
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700795 &low_output);
796 if (rc) {
797 pr_debug("low_temp mapping failed with %d\n", rc);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800798 return rc;
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700799 }
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800800
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700801 pr_debug("low_output:%lld\n", low_output);
802 low_output *= btm_param.dy;
803 do_div(low_output, btm_param.adc_vref);
804 low_output += btm_param.adc_gnd;
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800805
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700806 rc = qpnp_adc_map_voltage_temp(
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800807 adcmap_btm_threshold,
808 ARRAY_SIZE(adcmap_btm_threshold),
809 (param->high_temp),
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700810 &high_output);
811 if (rc) {
812 pr_debug("high temp mapping failed with %d\n", rc);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800813 return rc;
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700814 }
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800815
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700816 pr_debug("high_output:%lld\n", high_output);
817 high_output *= btm_param.dy;
818 do_div(high_output, btm_param.adc_vref);
819 high_output += btm_param.adc_gnd;
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800820
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700821 /* btm low temperature correspondes to high voltage threshold */
822 *low_threshold = high_output;
823 /* btm high temperature correspondes to low voltage threshold */
824 *high_threshold = low_output;
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800825
Siddartha Mohanadossb8109da2013-03-25 09:53:43 -0700826 pr_debug("high_volt:%d, low_volt:%d\n", *high_threshold,
827 *low_threshold);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800828 return 0;
829}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700830EXPORT_SYMBOL(qpnp_adc_btm_scaler);
Siddartha Mohanadossd0f4fd12012-11-20 16:28:40 -0800831
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700832int32_t qpnp_vadc_check_result(int32_t *data)
833{
834 if (*data < QPNP_VADC_MIN_ADC_CODE)
835 *data = QPNP_VADC_MIN_ADC_CODE;
836 else if (*data > QPNP_VADC_MAX_ADC_CODE)
837 *data = QPNP_VADC_MAX_ADC_CODE;
838
839 return 0;
840}
Siddartha Mohanadoss271d00f2013-03-26 18:24:14 -0700841EXPORT_SYMBOL(qpnp_vadc_check_result);
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700842
843int32_t qpnp_adc_get_devicetree_data(struct spmi_device *spmi,
844 struct qpnp_adc_drv *adc_qpnp)
845{
846 struct device_node *node = spmi->dev.of_node;
847 struct resource *res;
848 struct device_node *child;
Siddartha Mohanadoss31f60962012-11-27 14:11:02 -0800849 struct qpnp_adc_amux *adc_channel_list;
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700850 struct qpnp_adc_properties *adc_prop;
Siddartha Mohanadossc4a6af12012-07-13 18:50:12 -0700851 struct qpnp_adc_amux_properties *amux_prop;
Siddartha Mohanadossae1da732012-08-08 16:39:02 -0700852 int count_adc_channel_list = 0, decimation, rc = 0, i = 0;
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700853
854 if (!node)
855 return -EINVAL;
856
857 for_each_child_of_node(node, child)
858 count_adc_channel_list++;
859
860 if (!count_adc_channel_list) {
861 pr_err("No channel listing\n");
862 return -EINVAL;
863 }
864
865 adc_qpnp->spmi = spmi;
866
867 adc_prop = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_adc_properties),
868 GFP_KERNEL);
869 if (!adc_prop) {
870 dev_err(&spmi->dev, "Unable to allocate memory\n");
871 return -ENOMEM;
872 }
873 adc_channel_list = devm_kzalloc(&spmi->dev,
Siddartha Mohanadoss31f60962012-11-27 14:11:02 -0800874 ((sizeof(struct qpnp_adc_amux)) * count_adc_channel_list),
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700875 GFP_KERNEL);
876 if (!adc_channel_list) {
877 dev_err(&spmi->dev, "Unable to allocate memory\n");
878 return -ENOMEM;
879 }
880
881 amux_prop = devm_kzalloc(&spmi->dev,
Siddartha Mohanadossc4a6af12012-07-13 18:50:12 -0700882 sizeof(struct qpnp_adc_amux_properties) +
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700883 sizeof(struct qpnp_vadc_chan_properties), GFP_KERNEL);
884 if (!amux_prop) {
885 dev_err(&spmi->dev, "Unable to allocate memory\n");
886 return -ENOMEM;
887 }
888
Siddartha Mohanadossae1da732012-08-08 16:39:02 -0700889 adc_qpnp->adc_channels = adc_channel_list;
890 adc_qpnp->amux_prop = amux_prop;
891
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700892 for_each_child_of_node(node, child) {
893 int channel_num, scaling, post_scaling, hw_settle_time;
Siddartha Mohanadossae1da732012-08-08 16:39:02 -0700894 int fast_avg_setup, calib_type, rc;
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700895 const char *calibration_param, *channel_name;
896
897 channel_name = of_get_property(child,
898 "label", NULL) ? : child->name;
899 if (!channel_name) {
900 pr_err("Invalid channel name\n");
901 return -EINVAL;
902 }
903
Siddartha Mohanadoss96be0a02012-12-07 14:38:48 -0800904 rc = of_property_read_u32(child, "reg", &channel_num);
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700905 if (rc) {
906 pr_err("Invalid channel num\n");
907 return -EINVAL;
908 }
909 rc = of_property_read_u32(child, "qcom,decimation",
910 &decimation);
911 if (rc) {
912 pr_err("Invalid channel decimation property\n");
913 return -EINVAL;
914 }
915 rc = of_property_read_u32(child,
916 "qcom,pre-div-channel-scaling", &scaling);
917 if (rc) {
918 pr_err("Invalid channel scaling property\n");
919 return -EINVAL;
920 }
921 rc = of_property_read_u32(child,
922 "qcom,scale-function", &post_scaling);
923 if (rc) {
924 pr_err("Invalid channel post scaling property\n");
925 return -EINVAL;
926 }
927 rc = of_property_read_u32(child,
928 "qcom,hw-settle-time", &hw_settle_time);
929 if (rc) {
930 pr_err("Invalid channel hw settle time property\n");
931 return -EINVAL;
932 }
933 rc = of_property_read_u32(child,
934 "qcom,fast-avg-setup", &fast_avg_setup);
935 if (rc) {
936 pr_err("Invalid channel fast average setup\n");
937 return -EINVAL;
938 }
Siddartha Mohanadoss630def02013-06-27 14:53:38 -0700939 rc = of_property_read_string(child, "qcom,calibration-type",
940 &calibration_param);
941 if (rc) {
942 pr_err("Invalid calibration type\n");
943 return -EINVAL;
944 }
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700945 if (!strncmp(calibration_param, "absolute", 8))
946 calib_type = CALIB_ABSOLUTE;
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700947 else if (!strncmp(calibration_param, "ratiometric", 11))
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700948 calib_type = CALIB_RATIOMETRIC;
949 else {
950 pr_err("%s: Invalid calibration property\n", __func__);
951 return -EINVAL;
952 }
953 /* Individual channel properties */
954 adc_channel_list[i].name = (char *)channel_name;
955 adc_channel_list[i].channel_num = channel_num;
956 adc_channel_list[i].chan_path_prescaling = scaling;
957 adc_channel_list[i].adc_decimation = decimation;
958 adc_channel_list[i].adc_scale_fn = post_scaling;
959 adc_channel_list[i].hw_settle_time = hw_settle_time;
960 adc_channel_list[i].fast_avg_setup = fast_avg_setup;
961 i++;
962 }
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700963
964 /* Get the ADC VDD reference voltage and ADC bit resolution */
965 rc = of_property_read_u32(node, "qcom,adc-vdd-reference",
966 &adc_prop->adc_vdd_reference);
967 if (rc) {
968 pr_err("Invalid adc vdd reference property\n");
969 return -EINVAL;
970 }
971 rc = of_property_read_u32(node, "qcom,adc-bit-resolution",
972 &adc_prop->bitresolution);
973 if (rc) {
974 pr_err("Invalid adc bit resolution property\n");
975 return -EINVAL;
976 }
977 adc_qpnp->adc_prop = adc_prop;
978
979 /* Get the peripheral address */
980 res = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0);
981 if (!res) {
982 pr_err("No base address definition\n");
983 return -EINVAL;
984 }
985
986 adc_qpnp->slave = spmi->sid;
987 adc_qpnp->offset = res->start;
988
989 /* Register the ADC peripheral interrupt */
Siddartha Mohanadoss12109952012-11-20 14:57:51 -0800990 adc_qpnp->adc_irq_eoc = spmi_get_irq_byname(spmi, NULL,
991 "eoc-int-en-set");
992 if (adc_qpnp->adc_irq_eoc < 0) {
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700993 pr_err("Invalid irq\n");
994 return -ENXIO;
995 }
996
Siddartha Mohanadoss5ace1102012-08-20 23:18:10 -0700997 init_completion(&adc_qpnp->adc_rslt_completion);
998
Siddartha Mohanadoss7b116e12012-06-05 23:27:46 -0700999 return 0;
1000}
1001EXPORT_SYMBOL(qpnp_adc_get_devicetree_data);