qcom-vadc-common.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528
  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. /*
  100. * Voltage to temperature table for 100k pull up for bat_therm with
  101. * Alium.
  102. */
  103. static const struct vadc_map_pt adcmap_batt_therm_100k[] = {
  104. {1840, -400},
  105. {1835, -380},
  106. {1828, -360},
  107. {1821, -340},
  108. {1813, -320},
  109. {1803, -300},
  110. {1793, -280},
  111. {1781, -260},
  112. {1768, -240},
  113. {1753, -220},
  114. {1737, -200},
  115. {1719, -180},
  116. {1700, -160},
  117. {1679, -140},
  118. {1655, -120},
  119. {1630, -100},
  120. {1603, -80},
  121. {1574, -60},
  122. {1543, -40},
  123. {1510, -20},
  124. {1475, 0},
  125. {1438, 20},
  126. {1400, 40},
  127. {1360, 60},
  128. {1318, 80},
  129. {1276, 100},
  130. {1232, 120},
  131. {1187, 140},
  132. {1142, 160},
  133. {1097, 180},
  134. {1051, 200},
  135. {1005, 220},
  136. {960, 240},
  137. {915, 260},
  138. {871, 280},
  139. {828, 300},
  140. {786, 320},
  141. {745, 340},
  142. {705, 360},
  143. {666, 380},
  144. {629, 400},
  145. {594, 420},
  146. {560, 440},
  147. {527, 460},
  148. {497, 480},
  149. {467, 500},
  150. {439, 520},
  151. {413, 540},
  152. {388, 560},
  153. {365, 580},
  154. {343, 600},
  155. {322, 620},
  156. {302, 640},
  157. {284, 660},
  158. {267, 680},
  159. {251, 700},
  160. {235, 720},
  161. {221, 740},
  162. {208, 760},
  163. {195, 780},
  164. {184, 800},
  165. {173, 820},
  166. {163, 840},
  167. {153, 860},
  168. {144, 880},
  169. {136, 900},
  170. {128, 920},
  171. {120, 940},
  172. {114, 960},
  173. {107, 980}
  174. };
  175. /*
  176. * Voltage to temperature table for 30k pull up for bat_therm with
  177. * Alium.
  178. */
  179. static const struct vadc_map_pt adcmap_batt_therm_30k[] = {
  180. {1864, -400},
  181. {1863, -380},
  182. {1861, -360},
  183. {1858, -340},
  184. {1856, -320},
  185. {1853, -300},
  186. {1850, -280},
  187. {1846, -260},
  188. {1842, -240},
  189. {1837, -220},
  190. {1831, -200},
  191. {1825, -180},
  192. {1819, -160},
  193. {1811, -140},
  194. {1803, -120},
  195. {1794, -100},
  196. {1784, -80},
  197. {1773, -60},
  198. {1761, -40},
  199. {1748, -20},
  200. {1734, 0},
  201. {1718, 20},
  202. {1702, 40},
  203. {1684, 60},
  204. {1664, 80},
  205. {1643, 100},
  206. {1621, 120},
  207. {1597, 140},
  208. {1572, 160},
  209. {1546, 180},
  210. {1518, 200},
  211. {1489, 220},
  212. {1458, 240},
  213. {1426, 260},
  214. {1393, 280},
  215. {1359, 300},
  216. {1324, 320},
  217. {1288, 340},
  218. {1252, 360},
  219. {1214, 380},
  220. {1176, 400},
  221. {1138, 420},
  222. {1100, 440},
  223. {1061, 460},
  224. {1023, 480},
  225. {985, 500},
  226. {947, 520},
  227. {910, 540},
  228. {873, 560},
  229. {836, 580},
  230. {801, 600},
  231. {766, 620},
  232. {732, 640},
  233. {699, 660},
  234. {668, 680},
  235. {637, 700},
  236. {607, 720},
  237. {578, 740},
  238. {550, 760},
  239. {524, 780},
  240. {498, 800},
  241. {474, 820},
  242. {451, 840},
  243. {428, 860},
  244. {407, 880},
  245. {387, 900},
  246. {367, 920},
  247. {349, 940},
  248. {332, 960},
  249. {315, 980}
  250. };
  251. /*
  252. * Voltage to temperature table for 400k pull up for bat_therm with
  253. * Alium.
  254. */
  255. static const struct vadc_map_pt adcmap_batt_therm_400k[] = {
  256. {1744, -400},
  257. {1724, -380},
  258. {1701, -360},
  259. {1676, -340},
  260. {1648, -320},
  261. {1618, -300},
  262. {1584, -280},
  263. {1548, -260},
  264. {1509, -240},
  265. {1468, -220},
  266. {1423, -200},
  267. {1377, -180},
  268. {1328, -160},
  269. {1277, -140},
  270. {1225, -120},
  271. {1171, -100},
  272. {1117, -80},
  273. {1062, -60},
  274. {1007, -40},
  275. {953, -20},
  276. {899, 0},
  277. {847, 20},
  278. {795, 40},
  279. {745, 60},
  280. {697, 80},
  281. {651, 100},
  282. {607, 120},
  283. {565, 140},
  284. {526, 160},
  285. {488, 180},
  286. {453, 200},
  287. {420, 220},
  288. {390, 240},
  289. {361, 260},
  290. {334, 280},
  291. {309, 300},
  292. {286, 320},
  293. {265, 340},
  294. {245, 360},
  295. {227, 380},
  296. {210, 400},
  297. {195, 420},
  298. {180, 440},
  299. {167, 460},
  300. {155, 480},
  301. {144, 500},
  302. {133, 520},
  303. {124, 540},
  304. {115, 560},
  305. {107, 580},
  306. {99, 600},
  307. {92, 620},
  308. {86, 640},
  309. {80, 660},
  310. {75, 680},
  311. {70, 700},
  312. {65, 720},
  313. {61, 740},
  314. {57, 760},
  315. {53, 780},
  316. {50, 800},
  317. {46, 820},
  318. {43, 840},
  319. {41, 860},
  320. {38, 880},
  321. {36, 900},
  322. {34, 920},
  323. {32, 940},
  324. {30, 960},
  325. {28, 980}
  326. };
  327. static const struct vadc_map_pt adcmap7_die_temp[] = {
  328. { 857300, 160000 },
  329. { 820100, 140000 },
  330. { 782500, 120000 },
  331. { 744600, 100000 },
  332. { 706400, 80000 },
  333. { 667900, 60000 },
  334. { 629300, 40000 },
  335. { 590500, 20000 },
  336. { 551500, 0 },
  337. { 512400, -20000 },
  338. { 473100, -40000 },
  339. { 433700, -60000 },
  340. };
  341. /*
  342. * Resistance to temperature table for 100k pull up for NTCG104EF104.
  343. */
  344. static const struct vadc_map_pt adcmap7_100k[] = {
  345. { 4250657, -40960 },
  346. { 3962085, -39936 },
  347. { 3694875, -38912 },
  348. { 3447322, -37888 },
  349. { 3217867, -36864 },
  350. { 3005082, -35840 },
  351. { 2807660, -34816 },
  352. { 2624405, -33792 },
  353. { 2454218, -32768 },
  354. { 2296094, -31744 },
  355. { 2149108, -30720 },
  356. { 2012414, -29696 },
  357. { 1885232, -28672 },
  358. { 1766846, -27648 },
  359. { 1656598, -26624 },
  360. { 1553884, -25600 },
  361. { 1458147, -24576 },
  362. { 1368873, -23552 },
  363. { 1285590, -22528 },
  364. { 1207863, -21504 },
  365. { 1135290, -20480 },
  366. { 1067501, -19456 },
  367. { 1004155, -18432 },
  368. { 944935, -17408 },
  369. { 889550, -16384 },
  370. { 837731, -15360 },
  371. { 789229, -14336 },
  372. { 743813, -13312 },
  373. { 701271, -12288 },
  374. { 661405, -11264 },
  375. { 624032, -10240 },
  376. { 588982, -9216 },
  377. { 556100, -8192 },
  378. { 525239, -7168 },
  379. { 496264, -6144 },
  380. { 469050, -5120 },
  381. { 443480, -4096 },
  382. { 419448, -3072 },
  383. { 396851, -2048 },
  384. { 375597, -1024 },
  385. { 355598, 0 },
  386. { 336775, 1024 },
  387. { 319052, 2048 },
  388. { 302359, 3072 },
  389. { 286630, 4096 },
  390. { 271806, 5120 },
  391. { 257829, 6144 },
  392. { 244646, 7168 },
  393. { 232209, 8192 },
  394. { 220471, 9216 },
  395. { 209390, 10240 },
  396. { 198926, 11264 },
  397. { 189040, 12288 },
  398. { 179698, 13312 },
  399. { 170868, 14336 },
  400. { 162519, 15360 },
  401. { 154622, 16384 },
  402. { 147150, 17408 },
  403. { 140079, 18432 },
  404. { 133385, 19456 },
  405. { 127046, 20480 },
  406. { 121042, 21504 },
  407. { 115352, 22528 },
  408. { 109960, 23552 },
  409. { 104848, 24576 },
  410. { 100000, 25600 },
  411. { 95402, 26624 },
  412. { 91038, 27648 },
  413. { 86897, 28672 },
  414. { 82965, 29696 },
  415. { 79232, 30720 },
  416. { 75686, 31744 },
  417. { 72316, 32768 },
  418. { 69114, 33792 },
  419. { 66070, 34816 },
  420. { 63176, 35840 },
  421. { 60423, 36864 },
  422. { 57804, 37888 },
  423. { 55312, 38912 },
  424. { 52940, 39936 },
  425. { 50681, 40960 },
  426. { 48531, 41984 },
  427. { 46482, 43008 },
  428. { 44530, 44032 },
  429. { 42670, 45056 },
  430. { 40897, 46080 },
  431. { 39207, 47104 },
  432. { 37595, 48128 },
  433. { 36057, 49152 },
  434. { 34590, 50176 },
  435. { 33190, 51200 },
  436. { 31853, 52224 },
  437. { 30577, 53248 },
  438. { 29358, 54272 },
  439. { 28194, 55296 },
  440. { 27082, 56320 },
  441. { 26020, 57344 },
  442. { 25004, 58368 },
  443. { 24033, 59392 },
  444. { 23104, 60416 },
  445. { 22216, 61440 },
  446. { 21367, 62464 },
  447. { 20554, 63488 },
  448. { 19776, 64512 },
  449. { 19031, 65536 },
  450. { 18318, 66560 },
  451. { 17636, 67584 },
  452. { 16982, 68608 },
  453. { 16355, 69632 },
  454. { 15755, 70656 },
  455. { 15180, 71680 },
  456. { 14628, 72704 },
  457. { 14099, 73728 },
  458. { 13592, 74752 },
  459. { 13106, 75776 },
  460. { 12640, 76800 },
  461. { 12192, 77824 },
  462. { 11762, 78848 },
  463. { 11350, 79872 },
  464. { 10954, 80896 },
  465. { 10574, 81920 },
  466. { 10209, 82944 },
  467. { 9858, 83968 },
  468. { 9521, 84992 },
  469. { 9197, 86016 },
  470. { 8886, 87040 },
  471. { 8587, 88064 },
  472. { 8299, 89088 },
  473. { 8023, 90112 },
  474. { 7757, 91136 },
  475. { 7501, 92160 },
  476. { 7254, 93184 },
  477. { 7017, 94208 },
  478. { 6789, 95232 },
  479. { 6570, 96256 },
  480. { 6358, 97280 },
  481. { 6155, 98304 },
  482. { 5959, 99328 },
  483. { 5770, 100352 },
  484. { 5588, 101376 },
  485. { 5412, 102400 },
  486. { 5243, 103424 },
  487. { 5080, 104448 },
  488. { 4923, 105472 },
  489. { 4771, 106496 },
  490. { 4625, 107520 },
  491. { 4484, 108544 },
  492. { 4348, 109568 },
  493. { 4217, 110592 },
  494. { 4090, 111616 },
  495. { 3968, 112640 },
  496. { 3850, 113664 },
  497. { 3736, 114688 },
  498. { 3626, 115712 },
  499. { 3519, 116736 },
  500. { 3417, 117760 },
  501. { 3317, 118784 },
  502. { 3221, 119808 },
  503. { 3129, 120832 },
  504. { 3039, 121856 },
  505. { 2952, 122880 },
  506. { 2868, 123904 },
  507. { 2787, 124928 },
  508. { 2709, 125952 },
  509. { 2633, 126976 },
  510. { 2560, 128000 },
  511. { 2489, 129024 },
  512. { 2420, 130048 }
  513. };
  514. /*
  515. * Resistance to temperature table for batt_therm.
  516. */
  517. static const struct vadc_map_pt adcmap_gen3_batt_therm_100k[] = {
  518. { 5319890, -400 },
  519. { 4555860, -380 },
  520. { 3911780, -360 },
  521. { 3367320, -340 },
  522. { 2905860, -320 },
  523. { 2513730, -300 },
  524. { 2179660, -280 },
  525. { 1894360, -260 },
  526. { 1650110, -240 },
  527. { 1440520, -220 },
  528. { 1260250, -200 },
  529. { 1104850, -180 },
  530. { 970600, -160 },
  531. { 854370, -140 },
  532. { 753530, -120 },
  533. { 665860, -100 },
  534. { 589490, -80 },
  535. { 522830, -60 },
  536. { 464540, -40 },
  537. { 413470, -20 },
  538. { 368640, 0 },
  539. { 329220, 20 },
  540. { 294490, 40 },
  541. { 263850, 60 },
  542. { 236770, 80 },
  543. { 212790, 100 },
  544. { 191530, 120 },
  545. { 172640, 140 },
  546. { 155840, 160 },
  547. { 140880, 180 },
  548. { 127520, 200 },
  549. { 115590, 220 },
  550. { 104910, 240 },
  551. { 95350, 260 },
  552. { 86760, 280 },
  553. { 79050, 300 },
  554. { 72110, 320 },
  555. { 65860, 340 },
  556. { 60220, 360 },
  557. { 55130, 380 },
  558. { 50520, 400 },
  559. { 46350, 420 },
  560. { 42570, 440 },
  561. { 39140, 460 },
  562. { 36030, 480 },
  563. { 33190, 500 },
  564. { 30620, 520 },
  565. { 28260, 540 },
  566. { 26120, 560 },
  567. { 24160, 580 },
  568. { 22370, 600 },
  569. { 20730, 620 },
  570. { 19230, 640 },
  571. { 17850, 660 },
  572. { 16580, 680 },
  573. { 15420, 700 },
  574. { 14350, 720 },
  575. { 13370, 740 },
  576. { 12470, 760 },
  577. { 11630, 780 },
  578. { 10860, 800 },
  579. { 10150, 820 },
  580. { 9490, 840 },
  581. { 8880, 860 },
  582. { 8320, 880 },
  583. { 7800, 900 },
  584. { 7310, 920 },
  585. { 6860, 940 },
  586. { 6450, 960 },
  587. { 6060, 980 }
  588. };
  589. static const struct u32_fract adc5_prescale_ratios[] = {
  590. { .numerator = 1, .denominator = 1 },
  591. { .numerator = 1, .denominator = 3 },
  592. { .numerator = 1, .denominator = 4 },
  593. { .numerator = 1, .denominator = 6 },
  594. { .numerator = 1, .denominator = 20 },
  595. { .numerator = 1, .denominator = 8 },
  596. { .numerator = 10, .denominator = 81 },
  597. { .numerator = 1, .denominator = 10 },
  598. { .numerator = 1, .denominator = 16 },
  599. { .numerator = 40, .denominator = 41 }, /* PM7_SMB_TEMP */
  600. /* Prescale ratios for current channels below */
  601. { .numerator = 32, .denominator = 100 }, /* IIN_FB, IIN_SMB */
  602. { .numerator = 16, .denominator = 100 }, /* ICHG_SMB */
  603. { .numerator = 1280, .denominator = 4100 }, /* IIN_SMB_new */
  604. { .numerator = 640, .denominator = 4100 }, /* ICHG_SMB_new */
  605. { .numerator = 1000, .denominator = 305185 }, /* ICHG_FB */
  606. { .numerator = 1000, .denominator = 610370 }, /* ICHG_FB_2X */
  607. { .numerator = 1000, .denominator = 366220 }, /* ICHG_FB ADC5_GEN3 */
  608. { .numerator = 1000, .denominator = 732440 }, /* ICHG_FB_2X ADC5_GEN3 */
  609. };
  610. static int qcom_vadc_scale_hw_calib_volt(
  611. const struct u32_fract *prescale,
  612. const struct adc5_data *data,
  613. u16 adc_code, int *result_uv);
  614. /* Current scaling for PMIC7 */
  615. static int qcom_vadc_scale_hw_calib_current(
  616. const struct u32_fract *prescale,
  617. const struct adc5_data *data,
  618. u16 adc_code, int *result_ua);
  619. /* Raw current for PMIC7 */
  620. static int qcom_vadc_scale_hw_calib_current_raw(
  621. const struct u32_fract *prescale,
  622. const struct adc5_data *data,
  623. u16 adc_code, int *result_ua);
  624. /* Current scaling for PMIC5 */
  625. static int qcom_vadc5_scale_hw_calib_current(
  626. const struct u32_fract *prescale,
  627. const struct adc5_data *data,
  628. u16 adc_code, int *result_ua);
  629. static int qcom_vadc_scale_hw_calib_therm(
  630. const struct u32_fract *prescale,
  631. const struct adc5_data *data,
  632. u16 adc_code, int *result_mdec);
  633. static int qcom_vadc_scale_hw_calib_batt_therm_100(
  634. const struct u32_fract *prescale,
  635. const struct adc5_data *data,
  636. u16 adc_code, int *result_mdec);
  637. static int qcom_vadc_scale_hw_calib_batt_therm_30(
  638. const struct u32_fract *prescale,
  639. const struct adc5_data *data,
  640. u16 adc_code, int *result_mdec);
  641. static int qcom_vadc_scale_hw_calib_batt_therm_400(
  642. const struct u32_fract *prescale,
  643. const struct adc5_data *data,
  644. u16 adc_code, int *result_mdec);
  645. static int qcom_vadc7_scale_hw_calib_therm(
  646. const struct u32_fract *prescale,
  647. const struct adc5_data *data,
  648. u16 adc_code, int *result_mdec);
  649. static int qcom_vadc_scale_hw_smb_temp(
  650. const struct u32_fract *prescale,
  651. const struct adc5_data *data,
  652. u16 adc_code, int *result_mdec);
  653. static int qcom_vadc_scale_hw_pm7_smb_temp(
  654. const struct u32_fract *prescale,
  655. const struct adc5_data *data,
  656. u16 adc_code, int *result_mdec);
  657. static int qcom_vadc_scale_hw_smb1398_temp(
  658. const struct u32_fract *prescale,
  659. const struct adc5_data *data,
  660. u16 adc_code, int *result_mdec);
  661. static int qcom_vadc_scale_hw_pm2250_s3_die_temp(
  662. const struct u32_fract *prescale,
  663. const struct adc5_data *data,
  664. u16 adc_code, int *result_mdec);
  665. static int qcom_adc5_gen3_scale_hw_calib_batt_therm_100(
  666. const struct u32_fract *prescale,
  667. const struct adc5_data *data,
  668. u16 adc_code, int *result_mdec);
  669. static int qcom_adc5_gen3_scale_hw_calib_batt_id_100(
  670. const struct u32_fract *prescale,
  671. const struct adc5_data *data,
  672. u16 adc_code, int *result_mdec);
  673. static int qcom_adc5_gen3_scale_hw_calib_usb_in_current(
  674. const struct u32_fract *prescale,
  675. const struct adc5_data *data,
  676. u16 adc_code, int *result_mdec);
  677. static int qcom_vadc_scale_hw_chg5_temp(
  678. const struct u32_fract *prescale,
  679. const struct adc5_data *data,
  680. u16 adc_code, int *result_mdec);
  681. static int qcom_vadc_scale_hw_pm7_chg_temp(
  682. const struct u32_fract *prescale,
  683. const struct adc5_data *data,
  684. u16 adc_code, int *result_mdec);
  685. static int qcom_vadc_scale_hw_calib_die_temp(
  686. const struct u32_fract *prescale,
  687. const struct adc5_data *data,
  688. u16 adc_code, int *result_mdec);
  689. static int qcom_vadc7_scale_hw_calib_die_temp(
  690. const struct u32_fract *prescale,
  691. const struct adc5_data *data,
  692. u16 adc_code, int *result_mdec);
  693. static struct qcom_adc5_scale_type scale_adc5_fn[] = {
  694. [SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
  695. [SCALE_HW_CALIB_CUR] = {qcom_vadc_scale_hw_calib_current},
  696. [SCALE_HW_CALIB_CUR_RAW] = {qcom_vadc_scale_hw_calib_current_raw},
  697. [SCALE_HW_CALIB_PM5_CUR] = {qcom_vadc5_scale_hw_calib_current},
  698. [SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
  699. [SCALE_HW_CALIB_BATT_THERM_100K] = {
  700. qcom_vadc_scale_hw_calib_batt_therm_100},
  701. [SCALE_HW_CALIB_BATT_THERM_30K] = {
  702. qcom_vadc_scale_hw_calib_batt_therm_30},
  703. [SCALE_HW_CALIB_BATT_THERM_400K] = {
  704. qcom_vadc_scale_hw_calib_batt_therm_400},
  705. [SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
  706. [SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
  707. qcom_vadc7_scale_hw_calib_therm},
  708. [SCALE_HW_CALIB_PMIC_THERM] = {qcom_vadc_scale_hw_calib_die_temp},
  709. [SCALE_HW_CALIB_PMIC_THERM_PM7] = {
  710. qcom_vadc7_scale_hw_calib_die_temp},
  711. [SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp},
  712. [SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp},
  713. [SCALE_HW_CALIB_PM5_SMB1398_TEMP] = {qcom_vadc_scale_hw_smb1398_temp},
  714. [SCALE_HW_CALIB_PM2250_S3_DIE_TEMP] = {qcom_vadc_scale_hw_pm2250_s3_die_temp},
  715. [SCALE_HW_CALIB_PM5_GEN3_BATT_THERM_100K] = {qcom_adc5_gen3_scale_hw_calib_batt_therm_100},
  716. [SCALE_HW_CALIB_PM5_GEN3_BATT_ID_100K] = {qcom_adc5_gen3_scale_hw_calib_batt_id_100},
  717. [SCALE_HW_CALIB_PM5_GEN3_USB_IN_I] = {qcom_adc5_gen3_scale_hw_calib_usb_in_current},
  718. [SCALE_HW_CALIB_PM7_SMB_TEMP] = {qcom_vadc_scale_hw_pm7_smb_temp},
  719. [SCALE_HW_CALIB_PM7_CHG_TEMP] = {qcom_vadc_scale_hw_pm7_chg_temp},
  720. };
  721. static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts,
  722. u32 tablesize, s32 input, int *output)
  723. {
  724. u32 i = 0;
  725. if (!pts)
  726. return -EINVAL;
  727. while (i < tablesize && pts[i].x > input)
  728. i++;
  729. if (i == 0) {
  730. *output = pts[0].y;
  731. } else if (i == tablesize) {
  732. *output = pts[tablesize - 1].y;
  733. } else {
  734. /* interpolate linearly */
  735. *output = fixp_linear_interpolate(pts[i - 1].x, pts[i - 1].y,
  736. pts[i].x, pts[i].y,
  737. input);
  738. }
  739. return 0;
  740. }
  741. static s32 qcom_vadc_map_temp_voltage(const struct vadc_map_pt *pts,
  742. u32 tablesize, int input)
  743. {
  744. u32 i = 0;
  745. /*
  746. * Table must be sorted, find the interval of 'y' which contains value
  747. * 'input' and map it to proper 'x' value
  748. */
  749. while (i < tablesize && pts[i].y < input)
  750. i++;
  751. if (i == 0)
  752. return pts[0].x;
  753. if (i == tablesize)
  754. return pts[tablesize - 1].x;
  755. /* interpolate linearly */
  756. return fixp_linear_interpolate(pts[i - 1].y, pts[i - 1].x,
  757. pts[i].y, pts[i].x, input);
  758. }
  759. static void qcom_vadc_scale_calib(const struct vadc_linear_graph *calib_graph,
  760. u16 adc_code,
  761. bool absolute,
  762. s64 *scale_voltage)
  763. {
  764. *scale_voltage = (adc_code - calib_graph->gnd);
  765. *scale_voltage *= calib_graph->dx;
  766. *scale_voltage = div64_s64(*scale_voltage, calib_graph->dy);
  767. if (absolute)
  768. *scale_voltage += calib_graph->dx;
  769. if (*scale_voltage < 0)
  770. *scale_voltage = 0;
  771. }
  772. static int qcom_vadc_scale_volt(const struct vadc_linear_graph *calib_graph,
  773. const struct u32_fract *prescale,
  774. bool absolute, u16 adc_code,
  775. int *result_uv)
  776. {
  777. s64 voltage = 0, result = 0;
  778. qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
  779. voltage *= prescale->denominator;
  780. result = div64_s64(voltage, prescale->numerator);
  781. *result_uv = result;
  782. return 0;
  783. }
  784. static int qcom_vadc_scale_therm(const struct vadc_linear_graph *calib_graph,
  785. const struct u32_fract *prescale,
  786. bool absolute, u16 adc_code,
  787. int *result_mdec)
  788. {
  789. s64 voltage = 0;
  790. int ret;
  791. qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
  792. if (absolute)
  793. voltage = div64_s64(voltage, 1000);
  794. ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb,
  795. ARRAY_SIZE(adcmap_100k_104ef_104fb),
  796. voltage, result_mdec);
  797. if (ret)
  798. return ret;
  799. return 0;
  800. }
  801. static int qcom_vadc_scale_die_temp(const struct vadc_linear_graph *calib_graph,
  802. const struct u32_fract *prescale,
  803. bool absolute,
  804. u16 adc_code, int *result_mdec)
  805. {
  806. s64 voltage = 0;
  807. u64 temp; /* Temporary variable for do_div */
  808. qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
  809. if (voltage > 0) {
  810. temp = voltage * prescale->denominator;
  811. do_div(temp, prescale->numerator * 2);
  812. voltage = temp;
  813. } else {
  814. voltage = 0;
  815. }
  816. *result_mdec = milli_kelvin_to_millicelsius(voltage);
  817. return 0;
  818. }
  819. static int qcom_vadc_scale_chg_temp(const struct vadc_linear_graph *calib_graph,
  820. const struct u32_fract *prescale,
  821. bool absolute,
  822. u16 adc_code, int *result_mdec)
  823. {
  824. s64 voltage = 0, result = 0;
  825. qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
  826. voltage *= prescale->denominator;
  827. voltage = div64_s64(voltage, prescale->numerator);
  828. voltage = ((PMI_CHG_SCALE_1) * (voltage * 2));
  829. voltage = (voltage + PMI_CHG_SCALE_2);
  830. result = div64_s64(voltage, 1000000);
  831. *result_mdec = result;
  832. return 0;
  833. }
  834. /* convert voltage to ADC code, using 1.875V reference */
  835. static u16 qcom_vadc_scale_voltage_code(s32 voltage,
  836. const struct u32_fract *prescale,
  837. const u32 full_scale_code_volt,
  838. unsigned int factor)
  839. {
  840. s64 volt = voltage;
  841. s64 adc_vdd_ref_mv = 1875; /* reference voltage */
  842. volt *= prescale->numerator * factor * full_scale_code_volt;
  843. volt = div64_s64(volt, (s64)prescale->denominator * adc_vdd_ref_mv * 1000);
  844. return volt;
  845. }
  846. static int qcom_vadc_scale_code_voltage_factor(u16 adc_code,
  847. const struct u32_fract *prescale,
  848. const struct adc5_data *data,
  849. unsigned int factor)
  850. {
  851. s64 voltage, temp, adc_vdd_ref_mv = 1875;
  852. /*
  853. * The normal data range is between 0V to 1.875V. On cases where
  854. * we read low voltage values, the ADC code can go beyond the
  855. * range and the scale result is incorrect so we clamp the values
  856. * for the cases where the code represents a value below 0V
  857. */
  858. if (adc_code > VADC5_MAX_CODE)
  859. adc_code = 0;
  860. /* (ADC code * vref_vadc (1.875V)) / full_scale_code */
  861. voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
  862. voltage = div64_s64(voltage, data->full_scale_code_volt);
  863. if (voltage > 0) {
  864. voltage *= prescale->denominator;
  865. temp = prescale->numerator * factor;
  866. voltage = div64_s64(voltage, temp);
  867. } else {
  868. voltage = 0;
  869. }
  870. return (int) voltage;
  871. }
  872. static int qcom_vadc7_scale_hw_calib_therm(
  873. const struct u32_fract *prescale,
  874. const struct adc5_data *data,
  875. u16 adc_code, int *result_mdec)
  876. {
  877. s64 resistance = adc_code;
  878. int ret, result;
  879. if (adc_code >= RATIO_MAX_ADC7)
  880. return -EINVAL;
  881. /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/
  882. resistance *= R_PU_100K;
  883. resistance = div64_s64(resistance, RATIO_MAX_ADC7 - adc_code);
  884. ret = qcom_vadc_map_voltage_temp(adcmap7_100k,
  885. ARRAY_SIZE(adcmap7_100k),
  886. resistance, &result);
  887. if (ret)
  888. return ret;
  889. *result_mdec = result;
  890. return 0;
  891. }
  892. static int qcom_vadc_scale_hw_calib_current_raw(
  893. const struct u32_fract *prescale,
  894. const struct adc5_data *data,
  895. u16 adc_code, int *result_ua)
  896. {
  897. s64 temp;
  898. if (!prescale->numerator)
  899. return -EINVAL;
  900. temp = div_s64((s64)(s16)adc_code * prescale->denominator,
  901. prescale->numerator);
  902. *result_ua = (int) temp;
  903. pr_debug("raw adc_code: %#x result_ua: %d\n", adc_code, *result_ua);
  904. return 0;
  905. }
  906. static int qcom_vadc_scale_hw_calib_current(
  907. const struct u32_fract *prescale,
  908. const struct adc5_data *data,
  909. u16 adc_code, int *result_ua)
  910. {
  911. u32 adc_vdd_ref_mv = 1875;
  912. s64 voltage;
  913. if (!prescale->numerator)
  914. return -EINVAL;
  915. /* (ADC code * vref_vadc (1.875V)) / full_scale_code */
  916. voltage = (s64)(s16) adc_code * adc_vdd_ref_mv * 1000;
  917. voltage = div_s64(voltage, data->full_scale_code_volt);
  918. voltage = div_s64(voltage * prescale->denominator, prescale->numerator);
  919. *result_ua = (int) voltage;
  920. pr_debug("adc_code: %#x result_ua: %d\n", adc_code, *result_ua);
  921. return 0;
  922. }
  923. static int qcom_vadc5_scale_hw_calib_current(
  924. const struct u32_fract *prescale,
  925. const struct adc5_data *data,
  926. u16 adc_code, int *result_ua)
  927. {
  928. s64 voltage = 0, result = 0;
  929. bool positive = true;
  930. if (adc_code & ADC5_USR_DATA_CHECK) {
  931. adc_code = ~adc_code + 1;
  932. positive = false;
  933. }
  934. voltage = (s64)(s16) adc_code * data->full_scale_code_cur * 1000;
  935. voltage = div64_s64(voltage, VADC5_MAX_CODE);
  936. result = div64_s64(voltage * prescale->denominator, prescale->numerator);
  937. *result_ua = result;
  938. if (!positive)
  939. *result_ua = -result;
  940. return 0;
  941. }
  942. static int qcom_vadc_scale_hw_calib_volt(
  943. const struct u32_fract *prescale,
  944. const struct adc5_data *data,
  945. u16 adc_code, int *result_uv)
  946. {
  947. *result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
  948. prescale, data, 1);
  949. return 0;
  950. }
  951. static int qcom_vadc_scale_hw_calib_therm(
  952. const struct u32_fract *prescale,
  953. const struct adc5_data *data,
  954. u16 adc_code, int *result_mdec)
  955. {
  956. int voltage;
  957. voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
  958. prescale, data, 1000);
  959. /* Map voltage to temperature from look-up table */
  960. return qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
  961. ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
  962. voltage, result_mdec);
  963. }
  964. static int qcom_vadc_scale_hw_calib_batt_therm_100(
  965. const struct u32_fract *prescale,
  966. const struct adc5_data *data,
  967. u16 adc_code, int *result_mdec)
  968. {
  969. int voltage;
  970. voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
  971. prescale, data, 1000);
  972. /* Map voltage to temperature from look-up table */
  973. return qcom_vadc_map_voltage_temp(adcmap_batt_therm_100k,
  974. ARRAY_SIZE(adcmap_batt_therm_100k),
  975. voltage, result_mdec);
  976. }
  977. static int qcom_vadc_scale_hw_calib_batt_therm_30(
  978. const struct u32_fract *prescale,
  979. const struct adc5_data *data,
  980. u16 adc_code, int *result_mdec)
  981. {
  982. int voltage;
  983. voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
  984. prescale, data, 1000);
  985. /* Map voltage to temperature from look-up table */
  986. return qcom_vadc_map_voltage_temp(adcmap_batt_therm_30k,
  987. ARRAY_SIZE(adcmap_batt_therm_30k),
  988. voltage, result_mdec);
  989. }
  990. static int qcom_vadc_scale_hw_calib_batt_therm_400(
  991. const struct u32_fract *prescale,
  992. const struct adc5_data *data,
  993. u16 adc_code, int *result_mdec)
  994. {
  995. int voltage;
  996. voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
  997. prescale, data, 1000);
  998. /* Map voltage to temperature from look-up table */
  999. return qcom_vadc_map_voltage_temp(adcmap_batt_therm_400k,
  1000. ARRAY_SIZE(adcmap_batt_therm_400k),
  1001. voltage, result_mdec);
  1002. }
  1003. static int qcom_vadc_scale_hw_calib_die_temp(
  1004. const struct u32_fract *prescale,
  1005. const struct adc5_data *data,
  1006. u16 adc_code, int *result_mdec)
  1007. {
  1008. *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code,
  1009. prescale, data, 2);
  1010. *result_mdec = milli_kelvin_to_millicelsius(*result_mdec);
  1011. return 0;
  1012. }
  1013. static int qcom_vadc7_scale_hw_calib_die_temp(
  1014. const struct u32_fract *prescale,
  1015. const struct adc5_data *data,
  1016. u16 adc_code, int *result_mdec)
  1017. {
  1018. int voltage;
  1019. voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
  1020. prescale, data, 1);
  1021. return qcom_vadc_map_voltage_temp(adcmap7_die_temp, ARRAY_SIZE(adcmap7_die_temp),
  1022. voltage, result_mdec);
  1023. }
  1024. static int qcom_vadc_scale_hw_pm7_chg_temp(
  1025. const struct u32_fract *prescale,
  1026. const struct adc5_data *data,
  1027. u16 adc_code, int *result_mdec)
  1028. {
  1029. s64 temp;
  1030. int result_uv;
  1031. result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
  1032. prescale, data, 1);
  1033. /* T(C) = Vadc/0.0033 – 277.12 */
  1034. temp = div_s64((30303LL * result_uv) - (27712 * 1000000LL), 100000);
  1035. pr_debug("adc_code: %u result_uv: %d temp: %lld\n", adc_code, result_uv,
  1036. temp);
  1037. *result_mdec = temp > 0 ? temp : 0;
  1038. return 0;
  1039. }
  1040. static int qcom_vadc_scale_hw_pm7_smb_temp(
  1041. const struct u32_fract *prescale,
  1042. const struct adc5_data *data,
  1043. u16 adc_code, int *result_mdec)
  1044. {
  1045. s64 temp;
  1046. int result_uv;
  1047. result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
  1048. prescale, data, 1);
  1049. /* T(C) = 25 + (25*Vadc - 24.885) / 0.0894 */
  1050. temp = div_s64(((25000LL * result_uv) - (24885 * 1000000LL)) * 10000,
  1051. 894 * 1000000) + 25000;
  1052. pr_debug("adc_code: %#x result_uv: %d temp: %lld\n", adc_code,
  1053. result_uv, temp);
  1054. *result_mdec = temp > 0 ? temp : 0;
  1055. return 0;
  1056. }
  1057. static int qcom_vadc_scale_hw_smb_temp(
  1058. const struct u32_fract *prescale,
  1059. const struct adc5_data *data,
  1060. u16 adc_code, int *result_mdec)
  1061. {
  1062. *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code * 100,
  1063. prescale, data, PMIC5_SMB_TEMP_SCALE_FACTOR);
  1064. *result_mdec = PMIC5_SMB_TEMP_CONSTANT - *result_mdec;
  1065. return 0;
  1066. }
  1067. static int qcom_vadc_scale_hw_smb1398_temp(
  1068. const struct u32_fract *prescale,
  1069. const struct adc5_data *data,
  1070. u16 adc_code, int *result_mdec)
  1071. {
  1072. s64 voltage = 0, adc_vdd_ref_mv = 1875;
  1073. u64 temp;
  1074. if (adc_code > VADC5_MAX_CODE)
  1075. adc_code = 0;
  1076. /* (ADC code * vref_vadc (1.875V)) / full_scale_code */
  1077. voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
  1078. voltage = div64_s64(voltage, data->full_scale_code_volt);
  1079. if (voltage > 0) {
  1080. temp = voltage * prescale->denominator;
  1081. temp *= 100;
  1082. do_div(temp, prescale->numerator * PMIC5_SMB1398_TEMP_SCALE_FACTOR);
  1083. voltage = temp;
  1084. } else {
  1085. voltage = 0;
  1086. }
  1087. voltage = voltage - PMIC5_SMB1398_TEMP_CONSTANT;
  1088. *result_mdec = voltage;
  1089. return 0;
  1090. }
  1091. static int qcom_vadc_scale_hw_pm2250_s3_die_temp(
  1092. const struct u32_fract *prescale,
  1093. const struct adc5_data *data,
  1094. u16 adc_code, int *result_mdec)
  1095. {
  1096. s64 voltage = 0, adc_vdd_ref_mv = 1875;
  1097. if (adc_code > VADC5_MAX_CODE)
  1098. adc_code = 0;
  1099. /* (ADC code * vref_vadc (1.875V)) / full_scale_code */
  1100. voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
  1101. voltage = div64_s64(voltage, data->full_scale_code_volt);
  1102. if (voltage > 0) {
  1103. voltage *= prescale->denominator;
  1104. voltage = div64_s64(voltage, prescale->numerator);
  1105. } else {
  1106. voltage = 0;
  1107. }
  1108. voltage = PMIC5_PM2250_S3_DIE_TEMP_CONSTANT - voltage;
  1109. voltage *= 100000;
  1110. voltage = div64_s64(voltage, PMIC5_PM2250_S3_DIE_TEMP_SCALE_FACTOR);
  1111. *result_mdec = voltage;
  1112. return 0;
  1113. }
  1114. static int qcom_adc5_gen3_scale_hw_calib_batt_therm_100(
  1115. const struct u32_fract *prescale,
  1116. const struct adc5_data *data,
  1117. u16 adc_code, int *result_mdec)
  1118. {
  1119. s64 resistance = 0;
  1120. int ret, result = 0;
  1121. if (adc_code >= RATIO_MAX_ADC7)
  1122. return -EINVAL;
  1123. /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/
  1124. resistance = (s64) adc_code * R_PU_100K;
  1125. resistance = div64_s64(resistance, (RATIO_MAX_ADC7 - adc_code));
  1126. ret = qcom_vadc_map_voltage_temp(adcmap_gen3_batt_therm_100k,
  1127. ARRAY_SIZE(adcmap_gen3_batt_therm_100k),
  1128. resistance, &result);
  1129. if (ret)
  1130. return ret;
  1131. *result_mdec = result;
  1132. return 0;
  1133. }
  1134. static int qcom_adc5_gen3_scale_hw_calib_batt_id_100(
  1135. const struct u32_fract *prescale,
  1136. const struct adc5_data *data,
  1137. u16 adc_code, int *result_mdec)
  1138. {
  1139. s64 resistance = 0;
  1140. if (adc_code >= RATIO_MAX_ADC7)
  1141. return -EINVAL;
  1142. /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/
  1143. resistance = (s64) adc_code * R_PU_100K;
  1144. resistance = div64_s64(resistance, (RATIO_MAX_ADC7 - adc_code));
  1145. *result_mdec = (int)resistance;
  1146. return 0;
  1147. };
  1148. static int qcom_adc5_gen3_scale_hw_calib_usb_in_current(
  1149. const struct u32_fract *prescale,
  1150. const struct adc5_data *data,
  1151. u16 adc_code, int *result_ua)
  1152. {
  1153. s64 voltage = 0, result = 0;
  1154. bool positive = true;
  1155. if (adc_code & ADC5_USR_DATA_CHECK) {
  1156. adc_code = ~adc_code + 1;
  1157. positive = false;
  1158. }
  1159. voltage = (s64)(s16) adc_code * 1000000;
  1160. voltage = div64_s64(voltage, PMIC5_GEN3_USB_IN_I_SCALE_FACTOR);
  1161. result = div64_s64(voltage * prescale->denominator, prescale->numerator);
  1162. *result_ua = (int)result;
  1163. if (!positive)
  1164. *result_ua = -(int)result;
  1165. return 0;
  1166. };
  1167. static int qcom_vadc_scale_hw_chg5_temp(
  1168. const struct u32_fract *prescale,
  1169. const struct adc5_data *data,
  1170. u16 adc_code, int *result_mdec)
  1171. {
  1172. *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code,
  1173. prescale, data, 4);
  1174. *result_mdec = PMIC5_CHG_TEMP_SCALE_FACTOR - *result_mdec;
  1175. return 0;
  1176. }
  1177. void adc_tm_scale_therm_voltage_100k_gen3(struct adc_tm_config *param)
  1178. {
  1179. int temp, ret;
  1180. int64_t resistance = 0;
  1181. /*
  1182. * High temperature maps to lower threshold voltage.
  1183. * Same API can be used for resistance-temperature table
  1184. */
  1185. resistance = qcom_vadc_map_temp_voltage(adcmap7_100k,
  1186. ARRAY_SIZE(adcmap7_100k),
  1187. param->high_thr_temp);
  1188. param->low_thr_voltage = resistance * RATIO_MAX_ADC7;
  1189. param->low_thr_voltage = div64_s64(param->low_thr_voltage,
  1190. (resistance + R_PU_100K));
  1191. /*
  1192. * low_thr_voltage is ADC raw code corresponding to upper temperature
  1193. * threshold.
  1194. * Instead of returning the ADC raw code obtained at this point,we first
  1195. * do a forward conversion on the (low voltage / high temperature) threshold code,
  1196. * to temperature, to check if that code, when read by TM, would translate to
  1197. * a temperature greater than or equal to the upper temperature limit (which is
  1198. * expected). If it is instead lower than the upper limit (not expected for correct
  1199. * TM functionality), we lower the raw code of the threshold written by 1
  1200. * to ensure TM does see a violation when it reads raw code corresponding
  1201. * to the upper limit temperature specified.
  1202. */
  1203. ret = qcom_vadc7_scale_hw_calib_therm(NULL, NULL, param->low_thr_voltage, &temp);
  1204. if (ret < 0)
  1205. return;
  1206. if (temp < param->high_thr_temp)
  1207. param->low_thr_voltage--;
  1208. /*
  1209. * Low temperature maps to higher threshold voltage
  1210. * Same API can be used for resistance-temperature table
  1211. */
  1212. resistance = qcom_vadc_map_temp_voltage(adcmap7_100k,
  1213. ARRAY_SIZE(adcmap7_100k),
  1214. param->low_thr_temp);
  1215. param->high_thr_voltage = resistance * RATIO_MAX_ADC7;
  1216. param->high_thr_voltage = div64_s64(param->high_thr_voltage,
  1217. (resistance + R_PU_100K));
  1218. /*
  1219. * high_thr_voltage is ADC raw code corresponding to lower temperature
  1220. * threshold.
  1221. * Similar to what is done above for low_thr voltage, we first
  1222. * do a forward conversion on the (high voltage / low temperature)threshold code,
  1223. * to temperature, to check if that code, when read by TM, would translate to a
  1224. * temperature less than or equal to the lower temperature limit (which is expected).
  1225. * If it is instead greater than the lower limit (not expected for correct
  1226. * TM functionality), we increase the raw code of the threshold written by 1
  1227. * to ensure TM does see a violation when it reads raw code corresponding
  1228. * to the lower limit temperature specified.
  1229. */
  1230. ret = qcom_vadc7_scale_hw_calib_therm(NULL, NULL, param->high_thr_voltage, &temp);
  1231. if (ret < 0)
  1232. return;
  1233. if (temp > param->low_thr_temp)
  1234. param->high_thr_voltage++;
  1235. }
  1236. EXPORT_SYMBOL(adc_tm_scale_therm_voltage_100k_gen3);
  1237. int32_t adc_tm_absolute_rthr_gen3(struct adc_tm_config *tm_config)
  1238. {
  1239. int64_t low_thr = 0, high_thr = 0;
  1240. low_thr = tm_config->low_thr_voltage;
  1241. low_thr *= ADC5_FULL_SCALE_CODE;
  1242. low_thr = div64_s64(low_thr, ADC_VDD_REF);
  1243. tm_config->low_thr_voltage = low_thr;
  1244. high_thr = tm_config->high_thr_voltage;
  1245. high_thr *= ADC5_FULL_SCALE_CODE;
  1246. high_thr = div64_s64(high_thr, ADC_VDD_REF);
  1247. tm_config->high_thr_voltage = high_thr;
  1248. return 0;
  1249. }
  1250. EXPORT_SYMBOL(adc_tm_absolute_rthr_gen3);
  1251. int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
  1252. const struct vadc_linear_graph *calib_graph,
  1253. const struct u32_fract *prescale,
  1254. bool absolute,
  1255. u16 adc_code, int *result)
  1256. {
  1257. switch (scaletype) {
  1258. case SCALE_DEFAULT:
  1259. return qcom_vadc_scale_volt(calib_graph, prescale,
  1260. absolute, adc_code,
  1261. result);
  1262. case SCALE_THERM_100K_PULLUP:
  1263. case SCALE_XOTHERM:
  1264. return qcom_vadc_scale_therm(calib_graph, prescale,
  1265. absolute, adc_code,
  1266. result);
  1267. case SCALE_PMIC_THERM:
  1268. return qcom_vadc_scale_die_temp(calib_graph, prescale,
  1269. absolute, adc_code,
  1270. result);
  1271. case SCALE_PMI_CHG_TEMP:
  1272. return qcom_vadc_scale_chg_temp(calib_graph, prescale,
  1273. absolute, adc_code,
  1274. result);
  1275. default:
  1276. return -EINVAL;
  1277. }
  1278. }
  1279. EXPORT_SYMBOL(qcom_vadc_scale);
  1280. u16 qcom_adc_tm5_temp_volt_scale(unsigned int prescale_ratio,
  1281. u32 full_scale_code_volt, int temp)
  1282. {
  1283. const struct u32_fract *prescale = &adc5_prescale_ratios[prescale_ratio];
  1284. s32 voltage;
  1285. voltage = qcom_vadc_map_temp_voltage(adcmap_100k_104ef_104fb_1875_vref,
  1286. ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
  1287. temp);
  1288. return qcom_vadc_scale_voltage_code(voltage, prescale, full_scale_code_volt, 1000);
  1289. }
  1290. EXPORT_SYMBOL(qcom_adc_tm5_temp_volt_scale);
  1291. u16 qcom_adc_tm5_gen2_temp_res_scale(int temp)
  1292. {
  1293. int64_t resistance;
  1294. resistance = qcom_vadc_map_temp_voltage(adcmap7_100k,
  1295. ARRAY_SIZE(adcmap7_100k), temp);
  1296. return div64_s64(resistance * RATIO_MAX_ADC7, resistance + R_PU_100K);
  1297. }
  1298. EXPORT_SYMBOL(qcom_adc_tm5_gen2_temp_res_scale);
  1299. int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype,
  1300. unsigned int prescale_ratio,
  1301. const struct adc5_data *data,
  1302. u16 adc_code, int *result)
  1303. {
  1304. const struct u32_fract *prescale = &adc5_prescale_ratios[prescale_ratio];
  1305. if (!(scaletype >= SCALE_HW_CALIB_DEFAULT &&
  1306. scaletype < SCALE_HW_CALIB_INVALID)) {
  1307. pr_err("Invalid scale type %d\n", scaletype);
  1308. return -EINVAL;
  1309. }
  1310. return scale_adc5_fn[scaletype].scale_fn(prescale, data,
  1311. adc_code, result);
  1312. }
  1313. EXPORT_SYMBOL(qcom_adc5_hw_scale);
  1314. int qcom_adc5_prescaling_from_dt(u32 numerator, u32 denominator)
  1315. {
  1316. unsigned int pre;
  1317. for (pre = 0; pre < ARRAY_SIZE(adc5_prescale_ratios); pre++)
  1318. if (adc5_prescale_ratios[pre].numerator == numerator &&
  1319. adc5_prescale_ratios[pre].denominator == denominator)
  1320. break;
  1321. if (pre == ARRAY_SIZE(adc5_prescale_ratios))
  1322. return -EINVAL;
  1323. return pre;
  1324. }
  1325. EXPORT_SYMBOL(qcom_adc5_prescaling_from_dt);
  1326. int qcom_adc5_hw_settle_time_from_dt(u32 value,
  1327. const unsigned int *hw_settle)
  1328. {
  1329. unsigned int i;
  1330. for (i = 0; i < VADC_HW_SETTLE_SAMPLES_MAX; i++) {
  1331. if (value == hw_settle[i])
  1332. return i;
  1333. }
  1334. return -EINVAL;
  1335. }
  1336. EXPORT_SYMBOL(qcom_adc5_hw_settle_time_from_dt);
  1337. int qcom_adc5_avg_samples_from_dt(u32 value)
  1338. {
  1339. if (!is_power_of_2(value) || value > ADC5_AVG_SAMPLES_MAX)
  1340. return -EINVAL;
  1341. return __ffs(value);
  1342. }
  1343. EXPORT_SYMBOL(qcom_adc5_avg_samples_from_dt);
  1344. int qcom_adc5_decimation_from_dt(u32 value, const unsigned int *decimation)
  1345. {
  1346. unsigned int i;
  1347. for (i = 0; i < ADC5_DECIMATION_SAMPLES_MAX; i++) {
  1348. if (value == decimation[i])
  1349. return i;
  1350. }
  1351. return -EINVAL;
  1352. }
  1353. EXPORT_SYMBOL(qcom_adc5_decimation_from_dt);
  1354. int qcom_vadc_decimation_from_dt(u32 value)
  1355. {
  1356. if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN ||
  1357. value > VADC_DECIMATION_MAX)
  1358. return -EINVAL;
  1359. return __ffs64(value / VADC_DECIMATION_MIN);
  1360. }
  1361. EXPORT_SYMBOL(qcom_vadc_decimation_from_dt);
  1362. MODULE_LICENSE("GPL v2");
  1363. MODULE_DESCRIPTION("Qualcomm ADC common functionality");