qcom-vadc-common.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/bug.h>
  3. #include <linux/kernel.h>
  4. #include <linux/bitops.h>
  5. #include <linux/fixp-arith.h>
  6. #include <linux/iio/adc/qcom-vadc-common.h>
  7. #include <linux/math64.h>
  8. #include <linux/log2.h>
  9. #include <linux/err.h>
  10. #include <linux/module.h>
  11. #include <linux/units.h>
  12. /**
  13. * struct vadc_map_pt - Map the graph representation for ADC channel
  14. * @x: Represent the ADC digitized code.
  15. * @y: Represent the physical data which can be temperature, voltage,
  16. * resistance.
  17. */
  18. struct vadc_map_pt {
  19. s32 x;
  20. s32 y;
  21. };
  22. /* Voltage to temperature */
  23. static const struct vadc_map_pt adcmap_100k_104ef_104fb[] = {
  24. {1758, -40000 },
  25. {1742, -35000 },
  26. {1719, -30000 },
  27. {1691, -25000 },
  28. {1654, -20000 },
  29. {1608, -15000 },
  30. {1551, -10000 },
  31. {1483, -5000 },
  32. {1404, 0 },
  33. {1315, 5000 },
  34. {1218, 10000 },
  35. {1114, 15000 },
  36. {1007, 20000 },
  37. {900, 25000 },
  38. {795, 30000 },
  39. {696, 35000 },
  40. {605, 40000 },
  41. {522, 45000 },
  42. {448, 50000 },
  43. {383, 55000 },
  44. {327, 60000 },
  45. {278, 65000 },
  46. {237, 70000 },
  47. {202, 75000 },
  48. {172, 80000 },
  49. {146, 85000 },
  50. {125, 90000 },
  51. {107, 95000 },
  52. {92, 100000 },
  53. {79, 105000 },
  54. {68, 110000 },
  55. {59, 115000 },
  56. {51, 120000 },
  57. {44, 125000 }
  58. };
  59. /*
  60. * Voltage to temperature table for 100k pull up for NTCG104EF104 with
  61. * 1.875V reference.
  62. */
  63. static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
  64. { 1831, -40000 },
  65. { 1814, -35000 },
  66. { 1791, -30000 },
  67. { 1761, -25000 },
  68. { 1723, -20000 },
  69. { 1675, -15000 },
  70. { 1616, -10000 },
  71. { 1545, -5000 },
  72. { 1463, 0 },
  73. { 1370, 5000 },
  74. { 1268, 10000 },
  75. { 1160, 15000 },
  76. { 1049, 20000 },
  77. { 937, 25000 },
  78. { 828, 30000 },
  79. { 726, 35000 },
  80. { 630, 40000 },
  81. { 544, 45000 },
  82. { 467, 50000 },
  83. { 399, 55000 },
  84. { 340, 60000 },
  85. { 290, 65000 },
  86. { 247, 70000 },
  87. { 209, 75000 },
  88. { 179, 80000 },
  89. { 153, 85000 },
  90. { 130, 90000 },
  91. { 112, 95000 },
  92. { 96, 100000 },
  93. { 82, 105000 },
  94. { 71, 110000 },
  95. { 62, 115000 },
  96. { 53, 120000 },
  97. { 46, 125000 },
  98. };
  99. static const struct vadc_map_pt adcmap7_die_temp[] = {
  100. { 857300, 160000 },
  101. { 820100, 140000 },
  102. { 782500, 120000 },
  103. { 744600, 100000 },
  104. { 706400, 80000 },
  105. { 667900, 60000 },
  106. { 629300, 40000 },
  107. { 590500, 20000 },
  108. { 551500, 0 },
  109. { 512400, -20000 },
  110. { 473100, -40000 },
  111. { 433700, -60000 },
  112. };
  113. /*
  114. * Resistance to temperature table for 100k pull up for NTCG104EF104.
  115. */
  116. static const struct vadc_map_pt adcmap7_100k[] = {
  117. { 4250657, -40960 },
  118. { 3962085, -39936 },
  119. { 3694875, -38912 },
  120. { 3447322, -37888 },
  121. { 3217867, -36864 },
  122. { 3005082, -35840 },
  123. { 2807660, -34816 },
  124. { 2624405, -33792 },
  125. { 2454218, -32768 },
  126. { 2296094, -31744 },
  127. { 2149108, -30720 },
  128. { 2012414, -29696 },
  129. { 1885232, -28672 },
  130. { 1766846, -27648 },
  131. { 1656598, -26624 },
  132. { 1553884, -25600 },
  133. { 1458147, -24576 },
  134. { 1368873, -23552 },
  135. { 1285590, -22528 },
  136. { 1207863, -21504 },
  137. { 1135290, -20480 },
  138. { 1067501, -19456 },
  139. { 1004155, -18432 },
  140. { 944935, -17408 },
  141. { 889550, -16384 },
  142. { 837731, -15360 },
  143. { 789229, -14336 },
  144. { 743813, -13312 },
  145. { 701271, -12288 },
  146. { 661405, -11264 },
  147. { 624032, -10240 },
  148. { 588982, -9216 },
  149. { 556100, -8192 },
  150. { 525239, -7168 },
  151. { 496264, -6144 },
  152. { 469050, -5120 },
  153. { 443480, -4096 },
  154. { 419448, -3072 },
  155. { 396851, -2048 },
  156. { 375597, -1024 },
  157. { 355598, 0 },
  158. { 336775, 1024 },
  159. { 319052, 2048 },
  160. { 302359, 3072 },
  161. { 286630, 4096 },
  162. { 271806, 5120 },
  163. { 257829, 6144 },
  164. { 244646, 7168 },
  165. { 232209, 8192 },
  166. { 220471, 9216 },
  167. { 209390, 10240 },
  168. { 198926, 11264 },
  169. { 189040, 12288 },
  170. { 179698, 13312 },
  171. { 170868, 14336 },
  172. { 162519, 15360 },
  173. { 154622, 16384 },
  174. { 147150, 17408 },
  175. { 140079, 18432 },
  176. { 133385, 19456 },
  177. { 127046, 20480 },
  178. { 121042, 21504 },
  179. { 115352, 22528 },
  180. { 109960, 23552 },
  181. { 104848, 24576 },
  182. { 100000, 25600 },
  183. { 95402, 26624 },
  184. { 91038, 27648 },
  185. { 86897, 28672 },
  186. { 82965, 29696 },
  187. { 79232, 30720 },
  188. { 75686, 31744 },
  189. { 72316, 32768 },
  190. { 69114, 33792 },
  191. { 66070, 34816 },
  192. { 63176, 35840 },
  193. { 60423, 36864 },
  194. { 57804, 37888 },
  195. { 55312, 38912 },
  196. { 52940, 39936 },
  197. { 50681, 40960 },
  198. { 48531, 41984 },
  199. { 46482, 43008 },
  200. { 44530, 44032 },
  201. { 42670, 45056 },
  202. { 40897, 46080 },
  203. { 39207, 47104 },
  204. { 37595, 48128 },
  205. { 36057, 49152 },
  206. { 34590, 50176 },
  207. { 33190, 51200 },
  208. { 31853, 52224 },
  209. { 30577, 53248 },
  210. { 29358, 54272 },
  211. { 28194, 55296 },
  212. { 27082, 56320 },
  213. { 26020, 57344 },
  214. { 25004, 58368 },
  215. { 24033, 59392 },
  216. { 23104, 60416 },
  217. { 22216, 61440 },
  218. { 21367, 62464 },
  219. { 20554, 63488 },
  220. { 19776, 64512 },
  221. { 19031, 65536 },
  222. { 18318, 66560 },
  223. { 17636, 67584 },
  224. { 16982, 68608 },
  225. { 16355, 69632 },
  226. { 15755, 70656 },
  227. { 15180, 71680 },
  228. { 14628, 72704 },
  229. { 14099, 73728 },
  230. { 13592, 74752 },
  231. { 13106, 75776 },
  232. { 12640, 76800 },
  233. { 12192, 77824 },
  234. { 11762, 78848 },
  235. { 11350, 79872 },
  236. { 10954, 80896 },
  237. { 10574, 81920 },
  238. { 10209, 82944 },
  239. { 9858, 83968 },
  240. { 9521, 84992 },
  241. { 9197, 86016 },
  242. { 8886, 87040 },
  243. { 8587, 88064 },
  244. { 8299, 89088 },
  245. { 8023, 90112 },
  246. { 7757, 91136 },
  247. { 7501, 92160 },
  248. { 7254, 93184 },
  249. { 7017, 94208 },
  250. { 6789, 95232 },
  251. { 6570, 96256 },
  252. { 6358, 97280 },
  253. { 6155, 98304 },
  254. { 5959, 99328 },
  255. { 5770, 100352 },
  256. { 5588, 101376 },
  257. { 5412, 102400 },
  258. { 5243, 103424 },
  259. { 5080, 104448 },
  260. { 4923, 105472 },
  261. { 4771, 106496 },
  262. { 4625, 107520 },
  263. { 4484, 108544 },
  264. { 4348, 109568 },
  265. { 4217, 110592 },
  266. { 4090, 111616 },
  267. { 3968, 112640 },
  268. { 3850, 113664 },
  269. { 3736, 114688 },
  270. { 3626, 115712 },
  271. { 3519, 116736 },
  272. { 3417, 117760 },
  273. { 3317, 118784 },
  274. { 3221, 119808 },
  275. { 3129, 120832 },
  276. { 3039, 121856 },
  277. { 2952, 122880 },
  278. { 2868, 123904 },
  279. { 2787, 124928 },
  280. { 2709, 125952 },
  281. { 2633, 126976 },
  282. { 2560, 128000 },
  283. { 2489, 129024 },
  284. { 2420, 130048 }
  285. };
  286. static const struct u32_fract adc5_prescale_ratios[] = {
  287. { .numerator = 1, .denominator = 1 },
  288. { .numerator = 1, .denominator = 3 },
  289. { .numerator = 1, .denominator = 4 },
  290. { .numerator = 1, .denominator = 6 },
  291. { .numerator = 1, .denominator = 20 },
  292. { .numerator = 1, .denominator = 8 },
  293. { .numerator = 10, .denominator = 81 },
  294. { .numerator = 1, .denominator = 10 },
  295. { .numerator = 1, .denominator = 16 },
  296. };
  297. static int qcom_vadc_scale_hw_calib_volt(
  298. const struct u32_fract *prescale,
  299. const struct adc5_data *data,
  300. u16 adc_code, int *result_uv);
  301. static int qcom_vadc_scale_hw_calib_therm(
  302. const struct u32_fract *prescale,
  303. const struct adc5_data *data,
  304. u16 adc_code, int *result_mdec);
  305. static int qcom_vadc7_scale_hw_calib_therm(
  306. const struct u32_fract *prescale,
  307. const struct adc5_data *data,
  308. u16 adc_code, int *result_mdec);
  309. static int qcom_vadc_scale_hw_smb_temp(
  310. const struct u32_fract *prescale,
  311. const struct adc5_data *data,
  312. u16 adc_code, int *result_mdec);
  313. static int qcom_vadc_scale_hw_chg5_temp(
  314. const struct u32_fract *prescale,
  315. const struct adc5_data *data,
  316. u16 adc_code, int *result_mdec);
  317. static int qcom_vadc_scale_hw_calib_die_temp(
  318. const struct u32_fract *prescale,
  319. const struct adc5_data *data,
  320. u16 adc_code, int *result_mdec);
  321. static int qcom_vadc7_scale_hw_calib_die_temp(
  322. const struct u32_fract *prescale,
  323. const struct adc5_data *data,
  324. u16 adc_code, int *result_mdec);
  325. static struct qcom_adc5_scale_type scale_adc5_fn[] = {
  326. [SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
  327. [SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
  328. [SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
  329. [SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
  330. qcom_vadc7_scale_hw_calib_therm},
  331. [SCALE_HW_CALIB_PMIC_THERM] = {qcom_vadc_scale_hw_calib_die_temp},
  332. [SCALE_HW_CALIB_PMIC_THERM_PM7] = {
  333. qcom_vadc7_scale_hw_calib_die_temp},
  334. [SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp},
  335. [SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp},
  336. };
  337. static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts,
  338. u32 tablesize, s32 input, int *output)
  339. {
  340. u32 i = 0;
  341. if (!pts)
  342. return -EINVAL;
  343. while (i < tablesize && pts[i].x > input)
  344. i++;
  345. if (i == 0) {
  346. *output = pts[0].y;
  347. } else if (i == tablesize) {
  348. *output = pts[tablesize - 1].y;
  349. } else {
  350. /* interpolate linearly */
  351. *output = fixp_linear_interpolate(pts[i - 1].x, pts[i - 1].y,
  352. pts[i].x, pts[i].y,
  353. input);
  354. }
  355. return 0;
  356. }
  357. static s32 qcom_vadc_map_temp_voltage(const struct vadc_map_pt *pts,
  358. u32 tablesize, int input)
  359. {
  360. u32 i = 0;
  361. /*
  362. * Table must be sorted, find the interval of 'y' which contains value
  363. * 'input' and map it to proper 'x' value
  364. */
  365. while (i < tablesize && pts[i].y < input)
  366. i++;
  367. if (i == 0)
  368. return pts[0].x;
  369. if (i == tablesize)
  370. return pts[tablesize - 1].x;
  371. /* interpolate linearly */
  372. return fixp_linear_interpolate(pts[i - 1].y, pts[i - 1].x,
  373. pts[i].y, pts[i].x, input);
  374. }
  375. static void qcom_vadc_scale_calib(const struct vadc_linear_graph *calib_graph,
  376. u16 adc_code,
  377. bool absolute,
  378. s64 *scale_voltage)
  379. {
  380. *scale_voltage = (adc_code - calib_graph->gnd);
  381. *scale_voltage *= calib_graph->dx;
  382. *scale_voltage = div64_s64(*scale_voltage, calib_graph->dy);
  383. if (absolute)
  384. *scale_voltage += calib_graph->dx;
  385. if (*scale_voltage < 0)
  386. *scale_voltage = 0;
  387. }
  388. static int qcom_vadc_scale_volt(const struct vadc_linear_graph *calib_graph,
  389. const struct u32_fract *prescale,
  390. bool absolute, u16 adc_code,
  391. int *result_uv)
  392. {
  393. s64 voltage = 0, result = 0;
  394. qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
  395. voltage *= prescale->denominator;
  396. result = div64_s64(voltage, prescale->numerator);
  397. *result_uv = result;
  398. return 0;
  399. }
  400. static int qcom_vadc_scale_therm(const struct vadc_linear_graph *calib_graph,
  401. const struct u32_fract *prescale,
  402. bool absolute, u16 adc_code,
  403. int *result_mdec)
  404. {
  405. s64 voltage = 0;
  406. int ret;
  407. qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
  408. if (absolute)
  409. voltage = div64_s64(voltage, 1000);
  410. ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb,
  411. ARRAY_SIZE(adcmap_100k_104ef_104fb),
  412. voltage, result_mdec);
  413. if (ret)
  414. return ret;
  415. return 0;
  416. }
  417. static int qcom_vadc_scale_die_temp(const struct vadc_linear_graph *calib_graph,
  418. const struct u32_fract *prescale,
  419. bool absolute,
  420. u16 adc_code, int *result_mdec)
  421. {
  422. s64 voltage = 0;
  423. u64 temp; /* Temporary variable for do_div */
  424. qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
  425. if (voltage > 0) {
  426. temp = voltage * prescale->denominator;
  427. do_div(temp, prescale->numerator * 2);
  428. voltage = temp;
  429. } else {
  430. voltage = 0;
  431. }
  432. *result_mdec = milli_kelvin_to_millicelsius(voltage);
  433. return 0;
  434. }
  435. static int qcom_vadc_scale_chg_temp(const struct vadc_linear_graph *calib_graph,
  436. const struct u32_fract *prescale,
  437. bool absolute,
  438. u16 adc_code, int *result_mdec)
  439. {
  440. s64 voltage = 0, result = 0;
  441. qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
  442. voltage *= prescale->denominator;
  443. voltage = div64_s64(voltage, prescale->numerator);
  444. voltage = ((PMI_CHG_SCALE_1) * (voltage * 2));
  445. voltage = (voltage + PMI_CHG_SCALE_2);
  446. result = div64_s64(voltage, 1000000);
  447. *result_mdec = result;
  448. return 0;
  449. }
  450. /* convert voltage to ADC code, using 1.875V reference */
  451. static u16 qcom_vadc_scale_voltage_code(s32 voltage,
  452. const struct u32_fract *prescale,
  453. const u32 full_scale_code_volt,
  454. unsigned int factor)
  455. {
  456. s64 volt = voltage;
  457. s64 adc_vdd_ref_mv = 1875; /* reference voltage */
  458. volt *= prescale->numerator * factor * full_scale_code_volt;
  459. volt = div64_s64(volt, (s64)prescale->denominator * adc_vdd_ref_mv * 1000);
  460. return volt;
  461. }
  462. static int qcom_vadc_scale_code_voltage_factor(u16 adc_code,
  463. const struct u32_fract *prescale,
  464. const struct adc5_data *data,
  465. unsigned int factor)
  466. {
  467. s64 voltage, temp, adc_vdd_ref_mv = 1875;
  468. /*
  469. * The normal data range is between 0V to 1.875V. On cases where
  470. * we read low voltage values, the ADC code can go beyond the
  471. * range and the scale result is incorrect so we clamp the values
  472. * for the cases where the code represents a value below 0V
  473. */
  474. if (adc_code > VADC5_MAX_CODE)
  475. adc_code = 0;
  476. /* (ADC code * vref_vadc (1.875V)) / full_scale_code */
  477. voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
  478. voltage = div64_s64(voltage, data->full_scale_code_volt);
  479. if (voltage > 0) {
  480. voltage *= prescale->denominator;
  481. temp = prescale->numerator * factor;
  482. voltage = div64_s64(voltage, temp);
  483. } else {
  484. voltage = 0;
  485. }
  486. return (int) voltage;
  487. }
  488. static int qcom_vadc7_scale_hw_calib_therm(
  489. const struct u32_fract *prescale,
  490. const struct adc5_data *data,
  491. u16 adc_code, int *result_mdec)
  492. {
  493. s64 resistance = adc_code;
  494. int ret, result;
  495. if (adc_code >= RATIO_MAX_ADC7)
  496. return -EINVAL;
  497. /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/
  498. resistance *= R_PU_100K;
  499. resistance = div64_s64(resistance, RATIO_MAX_ADC7 - adc_code);
  500. ret = qcom_vadc_map_voltage_temp(adcmap7_100k,
  501. ARRAY_SIZE(adcmap7_100k),
  502. resistance, &result);
  503. if (ret)
  504. return ret;
  505. *result_mdec = result;
  506. return 0;
  507. }
  508. static int qcom_vadc_scale_hw_calib_volt(
  509. const struct u32_fract *prescale,
  510. const struct adc5_data *data,
  511. u16 adc_code, int *result_uv)
  512. {
  513. *result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
  514. prescale, data, 1);
  515. return 0;
  516. }
  517. static int qcom_vadc_scale_hw_calib_therm(
  518. const struct u32_fract *prescale,
  519. const struct adc5_data *data,
  520. u16 adc_code, int *result_mdec)
  521. {
  522. int voltage;
  523. voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
  524. prescale, data, 1000);
  525. /* Map voltage to temperature from look-up table */
  526. return qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
  527. ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
  528. voltage, result_mdec);
  529. }
  530. static int qcom_vadc_scale_hw_calib_die_temp(
  531. const struct u32_fract *prescale,
  532. const struct adc5_data *data,
  533. u16 adc_code, int *result_mdec)
  534. {
  535. *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code,
  536. prescale, data, 2);
  537. *result_mdec = milli_kelvin_to_millicelsius(*result_mdec);
  538. return 0;
  539. }
  540. static int qcom_vadc7_scale_hw_calib_die_temp(
  541. const struct u32_fract *prescale,
  542. const struct adc5_data *data,
  543. u16 adc_code, int *result_mdec)
  544. {
  545. int voltage;
  546. voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
  547. prescale, data, 1);
  548. return qcom_vadc_map_voltage_temp(adcmap7_die_temp, ARRAY_SIZE(adcmap7_die_temp),
  549. voltage, result_mdec);
  550. }
  551. static int qcom_vadc_scale_hw_smb_temp(
  552. const struct u32_fract *prescale,
  553. const struct adc5_data *data,
  554. u16 adc_code, int *result_mdec)
  555. {
  556. *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code * 100,
  557. prescale, data, PMIC5_SMB_TEMP_SCALE_FACTOR);
  558. *result_mdec = PMIC5_SMB_TEMP_CONSTANT - *result_mdec;
  559. return 0;
  560. }
  561. static int qcom_vadc_scale_hw_chg5_temp(
  562. const struct u32_fract *prescale,
  563. const struct adc5_data *data,
  564. u16 adc_code, int *result_mdec)
  565. {
  566. *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code,
  567. prescale, data, 4);
  568. *result_mdec = PMIC5_CHG_TEMP_SCALE_FACTOR - *result_mdec;
  569. return 0;
  570. }
  571. int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
  572. const struct vadc_linear_graph *calib_graph,
  573. const struct u32_fract *prescale,
  574. bool absolute,
  575. u16 adc_code, int *result)
  576. {
  577. switch (scaletype) {
  578. case SCALE_DEFAULT:
  579. return qcom_vadc_scale_volt(calib_graph, prescale,
  580. absolute, adc_code,
  581. result);
  582. case SCALE_THERM_100K_PULLUP:
  583. case SCALE_XOTHERM:
  584. return qcom_vadc_scale_therm(calib_graph, prescale,
  585. absolute, adc_code,
  586. result);
  587. case SCALE_PMIC_THERM:
  588. return qcom_vadc_scale_die_temp(calib_graph, prescale,
  589. absolute, adc_code,
  590. result);
  591. case SCALE_PMI_CHG_TEMP:
  592. return qcom_vadc_scale_chg_temp(calib_graph, prescale,
  593. absolute, adc_code,
  594. result);
  595. default:
  596. return -EINVAL;
  597. }
  598. }
  599. EXPORT_SYMBOL(qcom_vadc_scale);
  600. u16 qcom_adc_tm5_temp_volt_scale(unsigned int prescale_ratio,
  601. u32 full_scale_code_volt, int temp)
  602. {
  603. const struct u32_fract *prescale = &adc5_prescale_ratios[prescale_ratio];
  604. s32 voltage;
  605. voltage = qcom_vadc_map_temp_voltage(adcmap_100k_104ef_104fb_1875_vref,
  606. ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
  607. temp);
  608. return qcom_vadc_scale_voltage_code(voltage, prescale, full_scale_code_volt, 1000);
  609. }
  610. EXPORT_SYMBOL(qcom_adc_tm5_temp_volt_scale);
  611. u16 qcom_adc_tm5_gen2_temp_res_scale(int temp)
  612. {
  613. int64_t resistance;
  614. resistance = qcom_vadc_map_temp_voltage(adcmap7_100k,
  615. ARRAY_SIZE(adcmap7_100k), temp);
  616. return div64_s64(resistance * RATIO_MAX_ADC7, resistance + R_PU_100K);
  617. }
  618. EXPORT_SYMBOL(qcom_adc_tm5_gen2_temp_res_scale);
  619. int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype,
  620. unsigned int prescale_ratio,
  621. const struct adc5_data *data,
  622. u16 adc_code, int *result)
  623. {
  624. const struct u32_fract *prescale = &adc5_prescale_ratios[prescale_ratio];
  625. if (!(scaletype >= SCALE_HW_CALIB_DEFAULT &&
  626. scaletype < SCALE_HW_CALIB_INVALID)) {
  627. pr_err("Invalid scale type %d\n", scaletype);
  628. return -EINVAL;
  629. }
  630. return scale_adc5_fn[scaletype].scale_fn(prescale, data,
  631. adc_code, result);
  632. }
  633. EXPORT_SYMBOL(qcom_adc5_hw_scale);
  634. int qcom_adc5_prescaling_from_dt(u32 numerator, u32 denominator)
  635. {
  636. unsigned int pre;
  637. for (pre = 0; pre < ARRAY_SIZE(adc5_prescale_ratios); pre++)
  638. if (adc5_prescale_ratios[pre].numerator == numerator &&
  639. adc5_prescale_ratios[pre].denominator == denominator)
  640. break;
  641. if (pre == ARRAY_SIZE(adc5_prescale_ratios))
  642. return -EINVAL;
  643. return pre;
  644. }
  645. EXPORT_SYMBOL(qcom_adc5_prescaling_from_dt);
  646. int qcom_adc5_hw_settle_time_from_dt(u32 value,
  647. const unsigned int *hw_settle)
  648. {
  649. unsigned int i;
  650. for (i = 0; i < VADC_HW_SETTLE_SAMPLES_MAX; i++) {
  651. if (value == hw_settle[i])
  652. return i;
  653. }
  654. return -EINVAL;
  655. }
  656. EXPORT_SYMBOL(qcom_adc5_hw_settle_time_from_dt);
  657. int qcom_adc5_avg_samples_from_dt(u32 value)
  658. {
  659. if (!is_power_of_2(value) || value > ADC5_AVG_SAMPLES_MAX)
  660. return -EINVAL;
  661. return __ffs(value);
  662. }
  663. EXPORT_SYMBOL(qcom_adc5_avg_samples_from_dt);
  664. int qcom_adc5_decimation_from_dt(u32 value, const unsigned int *decimation)
  665. {
  666. unsigned int i;
  667. for (i = 0; i < ADC5_DECIMATION_SAMPLES_MAX; i++) {
  668. if (value == decimation[i])
  669. return i;
  670. }
  671. return -EINVAL;
  672. }
  673. EXPORT_SYMBOL(qcom_adc5_decimation_from_dt);
  674. int qcom_vadc_decimation_from_dt(u32 value)
  675. {
  676. if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN ||
  677. value > VADC_DECIMATION_MAX)
  678. return -EINVAL;
  679. return __ffs64(value / VADC_DECIMATION_MIN);
  680. }
  681. EXPORT_SYMBOL(qcom_vadc_decimation_from_dt);
  682. MODULE_LICENSE("GPL v2");
  683. MODULE_DESCRIPTION("Qualcomm ADC common functionality");