1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2e932d4f0SLinus Walleij #include <linux/bug.h> 3e932d4f0SLinus Walleij #include <linux/kernel.h> 4e932d4f0SLinus Walleij #include <linux/bitops.h> 5e2621acdSDmitry Baryshkov #include <linux/fixp-arith.h> 6ec82edb2SDmitry Baryshkov #include <linux/iio/adc/qcom-vadc-common.h> 7e932d4f0SLinus Walleij #include <linux/math64.h> 8e932d4f0SLinus Walleij #include <linux/log2.h> 9e932d4f0SLinus Walleij #include <linux/err.h> 109a0ebbc9SLinus Walleij #include <linux/module.h> 11f88b4265SAkinobu Mita #include <linux/units.h> 12e932d4f0SLinus Walleij 13*bb01e263SDmitry Baryshkov /** 14*bb01e263SDmitry Baryshkov * struct vadc_map_pt - Map the graph representation for ADC channel 15*bb01e263SDmitry Baryshkov * @x: Represent the ADC digitized code. 16*bb01e263SDmitry Baryshkov * @y: Represent the physical data which can be temperature, voltage, 17*bb01e263SDmitry Baryshkov * resistance. 18*bb01e263SDmitry Baryshkov */ 19*bb01e263SDmitry Baryshkov struct vadc_map_pt { 20*bb01e263SDmitry Baryshkov s32 x; 21*bb01e263SDmitry Baryshkov s32 y; 22*bb01e263SDmitry Baryshkov }; 23*bb01e263SDmitry Baryshkov 24e932d4f0SLinus Walleij /* Voltage to temperature */ 25e932d4f0SLinus Walleij static const struct vadc_map_pt adcmap_100k_104ef_104fb[] = { 26e932d4f0SLinus Walleij {1758, -40}, 27e932d4f0SLinus Walleij {1742, -35}, 28e932d4f0SLinus Walleij {1719, -30}, 29e932d4f0SLinus Walleij {1691, -25}, 30e932d4f0SLinus Walleij {1654, -20}, 31e932d4f0SLinus Walleij {1608, -15}, 32e932d4f0SLinus Walleij {1551, -10}, 33e932d4f0SLinus Walleij {1483, -5}, 34e932d4f0SLinus Walleij {1404, 0}, 35e932d4f0SLinus Walleij {1315, 5}, 36e932d4f0SLinus Walleij {1218, 10}, 37e932d4f0SLinus Walleij {1114, 15}, 38e932d4f0SLinus Walleij {1007, 20}, 39e932d4f0SLinus Walleij {900, 25}, 40e932d4f0SLinus Walleij {795, 30}, 41e932d4f0SLinus Walleij {696, 35}, 42e932d4f0SLinus Walleij {605, 40}, 43e932d4f0SLinus Walleij {522, 45}, 44e932d4f0SLinus Walleij {448, 50}, 45e932d4f0SLinus Walleij {383, 55}, 46e932d4f0SLinus Walleij {327, 60}, 47e932d4f0SLinus Walleij {278, 65}, 48e932d4f0SLinus Walleij {237, 70}, 49e932d4f0SLinus Walleij {202, 75}, 50e932d4f0SLinus Walleij {172, 80}, 51e932d4f0SLinus Walleij {146, 85}, 52e932d4f0SLinus Walleij {125, 90}, 53e932d4f0SLinus Walleij {107, 95}, 54e932d4f0SLinus Walleij {92, 100}, 55e932d4f0SLinus Walleij {79, 105}, 56e932d4f0SLinus Walleij {68, 110}, 57e932d4f0SLinus Walleij {59, 115}, 58e932d4f0SLinus Walleij {51, 120}, 59e932d4f0SLinus Walleij {44, 125} 60e932d4f0SLinus Walleij }; 61e932d4f0SLinus Walleij 62e13d7572SSiddartha Mohanadoss /* 63e13d7572SSiddartha Mohanadoss * Voltage to temperature table for 100k pull up for NTCG104EF104 with 64e13d7572SSiddartha Mohanadoss * 1.875V reference. 65e13d7572SSiddartha Mohanadoss */ 66e13d7572SSiddartha Mohanadoss static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = { 67e13d7572SSiddartha Mohanadoss { 1831, -40000 }, 68e13d7572SSiddartha Mohanadoss { 1814, -35000 }, 69e13d7572SSiddartha Mohanadoss { 1791, -30000 }, 70e13d7572SSiddartha Mohanadoss { 1761, -25000 }, 71e13d7572SSiddartha Mohanadoss { 1723, -20000 }, 72e13d7572SSiddartha Mohanadoss { 1675, -15000 }, 73e13d7572SSiddartha Mohanadoss { 1616, -10000 }, 74e13d7572SSiddartha Mohanadoss { 1545, -5000 }, 75e13d7572SSiddartha Mohanadoss { 1463, 0 }, 76e13d7572SSiddartha Mohanadoss { 1370, 5000 }, 77e13d7572SSiddartha Mohanadoss { 1268, 10000 }, 78e13d7572SSiddartha Mohanadoss { 1160, 15000 }, 79e13d7572SSiddartha Mohanadoss { 1049, 20000 }, 80e13d7572SSiddartha Mohanadoss { 937, 25000 }, 81e13d7572SSiddartha Mohanadoss { 828, 30000 }, 82e13d7572SSiddartha Mohanadoss { 726, 35000 }, 83e13d7572SSiddartha Mohanadoss { 630, 40000 }, 84e13d7572SSiddartha Mohanadoss { 544, 45000 }, 85e13d7572SSiddartha Mohanadoss { 467, 50000 }, 86e13d7572SSiddartha Mohanadoss { 399, 55000 }, 87e13d7572SSiddartha Mohanadoss { 340, 60000 }, 88e13d7572SSiddartha Mohanadoss { 290, 65000 }, 89e13d7572SSiddartha Mohanadoss { 247, 70000 }, 90e13d7572SSiddartha Mohanadoss { 209, 75000 }, 91e13d7572SSiddartha Mohanadoss { 179, 80000 }, 92e13d7572SSiddartha Mohanadoss { 153, 85000 }, 93e13d7572SSiddartha Mohanadoss { 130, 90000 }, 94e13d7572SSiddartha Mohanadoss { 112, 95000 }, 95e13d7572SSiddartha Mohanadoss { 96, 100000 }, 96e13d7572SSiddartha Mohanadoss { 82, 105000 }, 97e13d7572SSiddartha Mohanadoss { 71, 110000 }, 98e13d7572SSiddartha Mohanadoss { 62, 115000 }, 99e13d7572SSiddartha Mohanadoss { 53, 120000 }, 100e13d7572SSiddartha Mohanadoss { 46, 125000 }, 101e13d7572SSiddartha Mohanadoss }; 102e13d7572SSiddartha Mohanadoss 103082111e5SJishnu Prakash static const struct vadc_map_pt adcmap7_die_temp[] = { 104082111e5SJishnu Prakash { 433700, 1967}, 105082111e5SJishnu Prakash { 473100, 1964}, 106082111e5SJishnu Prakash { 512400, 1957}, 107082111e5SJishnu Prakash { 551500, 1949}, 108082111e5SJishnu Prakash { 590500, 1940}, 109082111e5SJishnu Prakash { 629300, 1930}, 110082111e5SJishnu Prakash { 667900, 1921}, 111082111e5SJishnu Prakash { 706400, 1910}, 112082111e5SJishnu Prakash { 744600, 1896}, 113082111e5SJishnu Prakash { 782500, 1878}, 114082111e5SJishnu Prakash { 820100, 1859}, 115082111e5SJishnu Prakash { 857300, 0}, 116082111e5SJishnu Prakash }; 117082111e5SJishnu Prakash 118082111e5SJishnu Prakash /* 119082111e5SJishnu Prakash * Resistance to temperature table for 100k pull up for NTCG104EF104. 120082111e5SJishnu Prakash */ 121082111e5SJishnu Prakash static const struct vadc_map_pt adcmap7_100k[] = { 122082111e5SJishnu Prakash { 4250657, -40960 }, 123082111e5SJishnu Prakash { 3962085, -39936 }, 124082111e5SJishnu Prakash { 3694875, -38912 }, 125082111e5SJishnu Prakash { 3447322, -37888 }, 126082111e5SJishnu Prakash { 3217867, -36864 }, 127082111e5SJishnu Prakash { 3005082, -35840 }, 128082111e5SJishnu Prakash { 2807660, -34816 }, 129082111e5SJishnu Prakash { 2624405, -33792 }, 130082111e5SJishnu Prakash { 2454218, -32768 }, 131082111e5SJishnu Prakash { 2296094, -31744 }, 132082111e5SJishnu Prakash { 2149108, -30720 }, 133082111e5SJishnu Prakash { 2012414, -29696 }, 134082111e5SJishnu Prakash { 1885232, -28672 }, 135082111e5SJishnu Prakash { 1766846, -27648 }, 136082111e5SJishnu Prakash { 1656598, -26624 }, 137082111e5SJishnu Prakash { 1553884, -25600 }, 138082111e5SJishnu Prakash { 1458147, -24576 }, 139082111e5SJishnu Prakash { 1368873, -23552 }, 140082111e5SJishnu Prakash { 1285590, -22528 }, 141082111e5SJishnu Prakash { 1207863, -21504 }, 142082111e5SJishnu Prakash { 1135290, -20480 }, 143082111e5SJishnu Prakash { 1067501, -19456 }, 144082111e5SJishnu Prakash { 1004155, -18432 }, 145082111e5SJishnu Prakash { 944935, -17408 }, 146082111e5SJishnu Prakash { 889550, -16384 }, 147082111e5SJishnu Prakash { 837731, -15360 }, 148082111e5SJishnu Prakash { 789229, -14336 }, 149082111e5SJishnu Prakash { 743813, -13312 }, 150082111e5SJishnu Prakash { 701271, -12288 }, 151082111e5SJishnu Prakash { 661405, -11264 }, 152082111e5SJishnu Prakash { 624032, -10240 }, 153082111e5SJishnu Prakash { 588982, -9216 }, 154082111e5SJishnu Prakash { 556100, -8192 }, 155082111e5SJishnu Prakash { 525239, -7168 }, 156082111e5SJishnu Prakash { 496264, -6144 }, 157082111e5SJishnu Prakash { 469050, -5120 }, 158082111e5SJishnu Prakash { 443480, -4096 }, 159082111e5SJishnu Prakash { 419448, -3072 }, 160082111e5SJishnu Prakash { 396851, -2048 }, 161082111e5SJishnu Prakash { 375597, -1024 }, 162082111e5SJishnu Prakash { 355598, 0 }, 163082111e5SJishnu Prakash { 336775, 1024 }, 164082111e5SJishnu Prakash { 319052, 2048 }, 165082111e5SJishnu Prakash { 302359, 3072 }, 166082111e5SJishnu Prakash { 286630, 4096 }, 167082111e5SJishnu Prakash { 271806, 5120 }, 168082111e5SJishnu Prakash { 257829, 6144 }, 169082111e5SJishnu Prakash { 244646, 7168 }, 170082111e5SJishnu Prakash { 232209, 8192 }, 171082111e5SJishnu Prakash { 220471, 9216 }, 172082111e5SJishnu Prakash { 209390, 10240 }, 173082111e5SJishnu Prakash { 198926, 11264 }, 174082111e5SJishnu Prakash { 189040, 12288 }, 175082111e5SJishnu Prakash { 179698, 13312 }, 176082111e5SJishnu Prakash { 170868, 14336 }, 177082111e5SJishnu Prakash { 162519, 15360 }, 178082111e5SJishnu Prakash { 154622, 16384 }, 179082111e5SJishnu Prakash { 147150, 17408 }, 180082111e5SJishnu Prakash { 140079, 18432 }, 181082111e5SJishnu Prakash { 133385, 19456 }, 182082111e5SJishnu Prakash { 127046, 20480 }, 183082111e5SJishnu Prakash { 121042, 21504 }, 184082111e5SJishnu Prakash { 115352, 22528 }, 185082111e5SJishnu Prakash { 109960, 23552 }, 186082111e5SJishnu Prakash { 104848, 24576 }, 187082111e5SJishnu Prakash { 100000, 25600 }, 188082111e5SJishnu Prakash { 95402, 26624 }, 189082111e5SJishnu Prakash { 91038, 27648 }, 190082111e5SJishnu Prakash { 86897, 28672 }, 191082111e5SJishnu Prakash { 82965, 29696 }, 192082111e5SJishnu Prakash { 79232, 30720 }, 193082111e5SJishnu Prakash { 75686, 31744 }, 194082111e5SJishnu Prakash { 72316, 32768 }, 195082111e5SJishnu Prakash { 69114, 33792 }, 196082111e5SJishnu Prakash { 66070, 34816 }, 197082111e5SJishnu Prakash { 63176, 35840 }, 198082111e5SJishnu Prakash { 60423, 36864 }, 199082111e5SJishnu Prakash { 57804, 37888 }, 200082111e5SJishnu Prakash { 55312, 38912 }, 201082111e5SJishnu Prakash { 52940, 39936 }, 202082111e5SJishnu Prakash { 50681, 40960 }, 203082111e5SJishnu Prakash { 48531, 41984 }, 204082111e5SJishnu Prakash { 46482, 43008 }, 205082111e5SJishnu Prakash { 44530, 44032 }, 206082111e5SJishnu Prakash { 42670, 45056 }, 207082111e5SJishnu Prakash { 40897, 46080 }, 208082111e5SJishnu Prakash { 39207, 47104 }, 209082111e5SJishnu Prakash { 37595, 48128 }, 210082111e5SJishnu Prakash { 36057, 49152 }, 211082111e5SJishnu Prakash { 34590, 50176 }, 212082111e5SJishnu Prakash { 33190, 51200 }, 213082111e5SJishnu Prakash { 31853, 52224 }, 214082111e5SJishnu Prakash { 30577, 53248 }, 215082111e5SJishnu Prakash { 29358, 54272 }, 216082111e5SJishnu Prakash { 28194, 55296 }, 217082111e5SJishnu Prakash { 27082, 56320 }, 218082111e5SJishnu Prakash { 26020, 57344 }, 219082111e5SJishnu Prakash { 25004, 58368 }, 220082111e5SJishnu Prakash { 24033, 59392 }, 221082111e5SJishnu Prakash { 23104, 60416 }, 222082111e5SJishnu Prakash { 22216, 61440 }, 223082111e5SJishnu Prakash { 21367, 62464 }, 224082111e5SJishnu Prakash { 20554, 63488 }, 225082111e5SJishnu Prakash { 19776, 64512 }, 226082111e5SJishnu Prakash { 19031, 65536 }, 227082111e5SJishnu Prakash { 18318, 66560 }, 228082111e5SJishnu Prakash { 17636, 67584 }, 229082111e5SJishnu Prakash { 16982, 68608 }, 230082111e5SJishnu Prakash { 16355, 69632 }, 231082111e5SJishnu Prakash { 15755, 70656 }, 232082111e5SJishnu Prakash { 15180, 71680 }, 233082111e5SJishnu Prakash { 14628, 72704 }, 234082111e5SJishnu Prakash { 14099, 73728 }, 235082111e5SJishnu Prakash { 13592, 74752 }, 236082111e5SJishnu Prakash { 13106, 75776 }, 237082111e5SJishnu Prakash { 12640, 76800 }, 238082111e5SJishnu Prakash { 12192, 77824 }, 239082111e5SJishnu Prakash { 11762, 78848 }, 240082111e5SJishnu Prakash { 11350, 79872 }, 241082111e5SJishnu Prakash { 10954, 80896 }, 242082111e5SJishnu Prakash { 10574, 81920 }, 243082111e5SJishnu Prakash { 10209, 82944 }, 244082111e5SJishnu Prakash { 9858, 83968 }, 245082111e5SJishnu Prakash { 9521, 84992 }, 246082111e5SJishnu Prakash { 9197, 86016 }, 247082111e5SJishnu Prakash { 8886, 87040 }, 248082111e5SJishnu Prakash { 8587, 88064 }, 249082111e5SJishnu Prakash { 8299, 89088 }, 250082111e5SJishnu Prakash { 8023, 90112 }, 251082111e5SJishnu Prakash { 7757, 91136 }, 252082111e5SJishnu Prakash { 7501, 92160 }, 253082111e5SJishnu Prakash { 7254, 93184 }, 254082111e5SJishnu Prakash { 7017, 94208 }, 255082111e5SJishnu Prakash { 6789, 95232 }, 256082111e5SJishnu Prakash { 6570, 96256 }, 257082111e5SJishnu Prakash { 6358, 97280 }, 258082111e5SJishnu Prakash { 6155, 98304 }, 259082111e5SJishnu Prakash { 5959, 99328 }, 260082111e5SJishnu Prakash { 5770, 100352 }, 261082111e5SJishnu Prakash { 5588, 101376 }, 262082111e5SJishnu Prakash { 5412, 102400 }, 263082111e5SJishnu Prakash { 5243, 103424 }, 264082111e5SJishnu Prakash { 5080, 104448 }, 265082111e5SJishnu Prakash { 4923, 105472 }, 266082111e5SJishnu Prakash { 4771, 106496 }, 267082111e5SJishnu Prakash { 4625, 107520 }, 268082111e5SJishnu Prakash { 4484, 108544 }, 269082111e5SJishnu Prakash { 4348, 109568 }, 270082111e5SJishnu Prakash { 4217, 110592 }, 271082111e5SJishnu Prakash { 4090, 111616 }, 272082111e5SJishnu Prakash { 3968, 112640 }, 273082111e5SJishnu Prakash { 3850, 113664 }, 274082111e5SJishnu Prakash { 3736, 114688 }, 275082111e5SJishnu Prakash { 3626, 115712 }, 276082111e5SJishnu Prakash { 3519, 116736 }, 277082111e5SJishnu Prakash { 3417, 117760 }, 278082111e5SJishnu Prakash { 3317, 118784 }, 279082111e5SJishnu Prakash { 3221, 119808 }, 280082111e5SJishnu Prakash { 3129, 120832 }, 281082111e5SJishnu Prakash { 3039, 121856 }, 282082111e5SJishnu Prakash { 2952, 122880 }, 283082111e5SJishnu Prakash { 2868, 123904 }, 284082111e5SJishnu Prakash { 2787, 124928 }, 285082111e5SJishnu Prakash { 2709, 125952 }, 286082111e5SJishnu Prakash { 2633, 126976 }, 287082111e5SJishnu Prakash { 2560, 128000 }, 288082111e5SJishnu Prakash { 2489, 129024 }, 289082111e5SJishnu Prakash { 2420, 130048 } 290082111e5SJishnu Prakash }; 291082111e5SJishnu Prakash 292c7ba98fcSDmitry Baryshkov static const struct vadc_prescale_ratio adc5_prescale_ratios[] = { 293c7ba98fcSDmitry Baryshkov {.num = 1, .den = 1}, 294c7ba98fcSDmitry Baryshkov {.num = 1, .den = 3}, 295c7ba98fcSDmitry Baryshkov {.num = 1, .den = 4}, 296c7ba98fcSDmitry Baryshkov {.num = 1, .den = 6}, 297c7ba98fcSDmitry Baryshkov {.num = 1, .den = 20}, 298c7ba98fcSDmitry Baryshkov {.num = 1, .den = 8}, 299c7ba98fcSDmitry Baryshkov {.num = 10, .den = 81}, 300c7ba98fcSDmitry Baryshkov {.num = 1, .den = 10}, 301c7ba98fcSDmitry Baryshkov {.num = 1, .den = 16} 302c7ba98fcSDmitry Baryshkov }; 303c7ba98fcSDmitry Baryshkov 304e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_volt( 305e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 306e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 307e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_uv); 308e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_therm( 309e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 310e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 311e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec); 312082111e5SJishnu Prakash static int qcom_vadc7_scale_hw_calib_therm( 313082111e5SJishnu Prakash const struct vadc_prescale_ratio *prescale, 314082111e5SJishnu Prakash const struct adc5_data *data, 315082111e5SJishnu Prakash u16 adc_code, int *result_mdec); 316e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_smb_temp( 317e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 318e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 319e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec); 320e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_chg5_temp( 321e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 322e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 323e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec); 324e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_die_temp( 325e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 326e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 327e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec); 328082111e5SJishnu Prakash static int qcom_vadc7_scale_hw_calib_die_temp( 329082111e5SJishnu Prakash const struct vadc_prescale_ratio *prescale, 330082111e5SJishnu Prakash const struct adc5_data *data, 331082111e5SJishnu Prakash u16 adc_code, int *result_mdec); 332e13d7572SSiddartha Mohanadoss 333e13d7572SSiddartha Mohanadoss static struct qcom_adc5_scale_type scale_adc5_fn[] = { 334e13d7572SSiddartha Mohanadoss [SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt}, 335e13d7572SSiddartha Mohanadoss [SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm}, 336e13d7572SSiddartha Mohanadoss [SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm}, 337082111e5SJishnu Prakash [SCALE_HW_CALIB_THERM_100K_PU_PM7] = { 338082111e5SJishnu Prakash qcom_vadc7_scale_hw_calib_therm}, 339e13d7572SSiddartha Mohanadoss [SCALE_HW_CALIB_PMIC_THERM] = {qcom_vadc_scale_hw_calib_die_temp}, 340082111e5SJishnu Prakash [SCALE_HW_CALIB_PMIC_THERM_PM7] = { 341082111e5SJishnu Prakash qcom_vadc7_scale_hw_calib_die_temp}, 342e13d7572SSiddartha Mohanadoss [SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp}, 343e13d7572SSiddartha Mohanadoss [SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp}, 344e13d7572SSiddartha Mohanadoss }; 345e13d7572SSiddartha Mohanadoss 346e932d4f0SLinus Walleij static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts, 347e13d7572SSiddartha Mohanadoss u32 tablesize, s32 input, int *output) 348e932d4f0SLinus Walleij { 349e932d4f0SLinus Walleij bool descending = 1; 350e932d4f0SLinus Walleij u32 i = 0; 351e932d4f0SLinus Walleij 352e932d4f0SLinus Walleij if (!pts) 353e932d4f0SLinus Walleij return -EINVAL; 354e932d4f0SLinus Walleij 355e932d4f0SLinus Walleij /* Check if table is descending or ascending */ 356e932d4f0SLinus Walleij if (tablesize > 1) { 357e932d4f0SLinus Walleij if (pts[0].x < pts[1].x) 358e932d4f0SLinus Walleij descending = 0; 359e932d4f0SLinus Walleij } 360e932d4f0SLinus Walleij 361e932d4f0SLinus Walleij while (i < tablesize) { 362e932d4f0SLinus Walleij if ((descending) && (pts[i].x < input)) { 363e932d4f0SLinus Walleij /* table entry is less than measured*/ 364e932d4f0SLinus Walleij /* value and table is descending, stop */ 365e932d4f0SLinus Walleij break; 366e932d4f0SLinus Walleij } else if ((!descending) && 367e932d4f0SLinus Walleij (pts[i].x > input)) { 368e932d4f0SLinus Walleij /* table entry is greater than measured*/ 369e932d4f0SLinus Walleij /*value and table is ascending, stop */ 370e932d4f0SLinus Walleij break; 371e932d4f0SLinus Walleij } 372e932d4f0SLinus Walleij i++; 373e932d4f0SLinus Walleij } 374e932d4f0SLinus Walleij 375e932d4f0SLinus Walleij if (i == 0) { 376e932d4f0SLinus Walleij *output = pts[0].y; 377e932d4f0SLinus Walleij } else if (i == tablesize) { 378e932d4f0SLinus Walleij *output = pts[tablesize - 1].y; 379e932d4f0SLinus Walleij } else { 380e932d4f0SLinus Walleij /* result is between search_index and search_index-1 */ 381e932d4f0SLinus Walleij /* interpolate linearly */ 382e2621acdSDmitry Baryshkov *output = fixp_linear_interpolate(pts[i - 1].x, pts[i - 1].y, 383e2621acdSDmitry Baryshkov pts[i].x, pts[i].y, 384e2621acdSDmitry Baryshkov input); 385e932d4f0SLinus Walleij } 386e932d4f0SLinus Walleij 387e932d4f0SLinus Walleij return 0; 388e932d4f0SLinus Walleij } 389e932d4f0SLinus Walleij 390e932d4f0SLinus Walleij static void qcom_vadc_scale_calib(const struct vadc_linear_graph *calib_graph, 391e932d4f0SLinus Walleij u16 adc_code, 392e932d4f0SLinus Walleij bool absolute, 393e932d4f0SLinus Walleij s64 *scale_voltage) 394e932d4f0SLinus Walleij { 395e932d4f0SLinus Walleij *scale_voltage = (adc_code - calib_graph->gnd); 396e932d4f0SLinus Walleij *scale_voltage *= calib_graph->dx; 397e932d4f0SLinus Walleij *scale_voltage = div64_s64(*scale_voltage, calib_graph->dy); 398e932d4f0SLinus Walleij if (absolute) 399e932d4f0SLinus Walleij *scale_voltage += calib_graph->dx; 400e932d4f0SLinus Walleij 401e932d4f0SLinus Walleij if (*scale_voltage < 0) 402e932d4f0SLinus Walleij *scale_voltage = 0; 403e932d4f0SLinus Walleij } 404e932d4f0SLinus Walleij 405e932d4f0SLinus Walleij static int qcom_vadc_scale_volt(const struct vadc_linear_graph *calib_graph, 406e932d4f0SLinus Walleij const struct vadc_prescale_ratio *prescale, 407e932d4f0SLinus Walleij bool absolute, u16 adc_code, 408e932d4f0SLinus Walleij int *result_uv) 409e932d4f0SLinus Walleij { 410e932d4f0SLinus Walleij s64 voltage = 0, result = 0; 411e932d4f0SLinus Walleij 412e932d4f0SLinus Walleij qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage); 413e932d4f0SLinus Walleij 414e932d4f0SLinus Walleij voltage = voltage * prescale->den; 415e932d4f0SLinus Walleij result = div64_s64(voltage, prescale->num); 416e932d4f0SLinus Walleij *result_uv = result; 417e932d4f0SLinus Walleij 418e932d4f0SLinus Walleij return 0; 419e932d4f0SLinus Walleij } 420e932d4f0SLinus Walleij 421e932d4f0SLinus Walleij static int qcom_vadc_scale_therm(const struct vadc_linear_graph *calib_graph, 422e932d4f0SLinus Walleij const struct vadc_prescale_ratio *prescale, 423e932d4f0SLinus Walleij bool absolute, u16 adc_code, 424e932d4f0SLinus Walleij int *result_mdec) 425e932d4f0SLinus Walleij { 426e13d7572SSiddartha Mohanadoss s64 voltage = 0; 427e932d4f0SLinus Walleij int ret; 428e932d4f0SLinus Walleij 429e932d4f0SLinus Walleij qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage); 430e932d4f0SLinus Walleij 431e932d4f0SLinus Walleij if (absolute) 432e932d4f0SLinus Walleij voltage = div64_s64(voltage, 1000); 433e932d4f0SLinus Walleij 434e932d4f0SLinus Walleij ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb, 435e932d4f0SLinus Walleij ARRAY_SIZE(adcmap_100k_104ef_104fb), 436e13d7572SSiddartha Mohanadoss voltage, result_mdec); 437e932d4f0SLinus Walleij if (ret) 438e932d4f0SLinus Walleij return ret; 439e932d4f0SLinus Walleij 440e13d7572SSiddartha Mohanadoss *result_mdec *= 1000; 441e932d4f0SLinus Walleij 442e932d4f0SLinus Walleij return 0; 443e932d4f0SLinus Walleij } 444e932d4f0SLinus Walleij 445e932d4f0SLinus Walleij static int qcom_vadc_scale_die_temp(const struct vadc_linear_graph *calib_graph, 446e932d4f0SLinus Walleij const struct vadc_prescale_ratio *prescale, 447e932d4f0SLinus Walleij bool absolute, 448e932d4f0SLinus Walleij u16 adc_code, int *result_mdec) 449e932d4f0SLinus Walleij { 450e932d4f0SLinus Walleij s64 voltage = 0; 451e932d4f0SLinus Walleij u64 temp; /* Temporary variable for do_div */ 452e932d4f0SLinus Walleij 453e932d4f0SLinus Walleij qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage); 454e932d4f0SLinus Walleij 455e932d4f0SLinus Walleij if (voltage > 0) { 456e932d4f0SLinus Walleij temp = voltage * prescale->den; 457e932d4f0SLinus Walleij do_div(temp, prescale->num * 2); 458e932d4f0SLinus Walleij voltage = temp; 459e932d4f0SLinus Walleij } else { 460e932d4f0SLinus Walleij voltage = 0; 461e932d4f0SLinus Walleij } 462e932d4f0SLinus Walleij 463f88b4265SAkinobu Mita *result_mdec = milli_kelvin_to_millicelsius(voltage); 464e932d4f0SLinus Walleij 465e932d4f0SLinus Walleij return 0; 466e932d4f0SLinus Walleij } 467e932d4f0SLinus Walleij 468e932d4f0SLinus Walleij static int qcom_vadc_scale_chg_temp(const struct vadc_linear_graph *calib_graph, 469e932d4f0SLinus Walleij const struct vadc_prescale_ratio *prescale, 470e932d4f0SLinus Walleij bool absolute, 471e932d4f0SLinus Walleij u16 adc_code, int *result_mdec) 472e932d4f0SLinus Walleij { 473e932d4f0SLinus Walleij s64 voltage = 0, result = 0; 474e932d4f0SLinus Walleij 475e932d4f0SLinus Walleij qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage); 476e932d4f0SLinus Walleij 477e932d4f0SLinus Walleij voltage = voltage * prescale->den; 478e932d4f0SLinus Walleij voltage = div64_s64(voltage, prescale->num); 479e932d4f0SLinus Walleij voltage = ((PMI_CHG_SCALE_1) * (voltage * 2)); 480e932d4f0SLinus Walleij voltage = (voltage + PMI_CHG_SCALE_2); 481e932d4f0SLinus Walleij result = div64_s64(voltage, 1000000); 482e932d4f0SLinus Walleij *result_mdec = result; 483e932d4f0SLinus Walleij 484e932d4f0SLinus Walleij return 0; 485e932d4f0SLinus Walleij } 486e932d4f0SLinus Walleij 487e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_code_voltage_factor(u16 adc_code, 488e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 489e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 490e13d7572SSiddartha Mohanadoss unsigned int factor) 491e13d7572SSiddartha Mohanadoss { 492e13d7572SSiddartha Mohanadoss s64 voltage, temp, adc_vdd_ref_mv = 1875; 493e13d7572SSiddartha Mohanadoss 494e13d7572SSiddartha Mohanadoss /* 495e13d7572SSiddartha Mohanadoss * The normal data range is between 0V to 1.875V. On cases where 496e13d7572SSiddartha Mohanadoss * we read low voltage values, the ADC code can go beyond the 497e13d7572SSiddartha Mohanadoss * range and the scale result is incorrect so we clamp the values 498e13d7572SSiddartha Mohanadoss * for the cases where the code represents a value below 0V 499e13d7572SSiddartha Mohanadoss */ 500e13d7572SSiddartha Mohanadoss if (adc_code > VADC5_MAX_CODE) 501e13d7572SSiddartha Mohanadoss adc_code = 0; 502e13d7572SSiddartha Mohanadoss 503e13d7572SSiddartha Mohanadoss /* (ADC code * vref_vadc (1.875V)) / full_scale_code */ 504e13d7572SSiddartha Mohanadoss voltage = (s64) adc_code * adc_vdd_ref_mv * 1000; 505e13d7572SSiddartha Mohanadoss voltage = div64_s64(voltage, data->full_scale_code_volt); 506e13d7572SSiddartha Mohanadoss if (voltage > 0) { 507e13d7572SSiddartha Mohanadoss voltage *= prescale->den; 508e13d7572SSiddartha Mohanadoss temp = prescale->num * factor; 509e13d7572SSiddartha Mohanadoss voltage = div64_s64(voltage, temp); 510e13d7572SSiddartha Mohanadoss } else { 511e13d7572SSiddartha Mohanadoss voltage = 0; 512e13d7572SSiddartha Mohanadoss } 513e13d7572SSiddartha Mohanadoss 514e13d7572SSiddartha Mohanadoss return (int) voltage; 515e13d7572SSiddartha Mohanadoss } 516e13d7572SSiddartha Mohanadoss 517082111e5SJishnu Prakash static int qcom_vadc7_scale_hw_calib_therm( 518082111e5SJishnu Prakash const struct vadc_prescale_ratio *prescale, 519082111e5SJishnu Prakash const struct adc5_data *data, 520082111e5SJishnu Prakash u16 adc_code, int *result_mdec) 521082111e5SJishnu Prakash { 522082111e5SJishnu Prakash s64 resistance = adc_code; 523082111e5SJishnu Prakash int ret, result; 524082111e5SJishnu Prakash 525082111e5SJishnu Prakash if (adc_code >= RATIO_MAX_ADC7) 526082111e5SJishnu Prakash return -EINVAL; 527082111e5SJishnu Prakash 528082111e5SJishnu Prakash /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/ 529082111e5SJishnu Prakash resistance *= R_PU_100K; 530082111e5SJishnu Prakash resistance = div64_s64(resistance, RATIO_MAX_ADC7 - adc_code); 531082111e5SJishnu Prakash 532082111e5SJishnu Prakash ret = qcom_vadc_map_voltage_temp(adcmap7_100k, 533082111e5SJishnu Prakash ARRAY_SIZE(adcmap7_100k), 534082111e5SJishnu Prakash resistance, &result); 535082111e5SJishnu Prakash if (ret) 536082111e5SJishnu Prakash return ret; 537082111e5SJishnu Prakash 538082111e5SJishnu Prakash *result_mdec = result; 539082111e5SJishnu Prakash 540082111e5SJishnu Prakash return 0; 541082111e5SJishnu Prakash } 542082111e5SJishnu Prakash 543e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_volt( 544e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 545e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 546e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_uv) 547e13d7572SSiddartha Mohanadoss { 548e13d7572SSiddartha Mohanadoss *result_uv = qcom_vadc_scale_code_voltage_factor(adc_code, 549e13d7572SSiddartha Mohanadoss prescale, data, 1); 550e13d7572SSiddartha Mohanadoss 551e13d7572SSiddartha Mohanadoss return 0; 552e13d7572SSiddartha Mohanadoss } 553e13d7572SSiddartha Mohanadoss 554e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_therm( 555e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 556e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 557e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec) 558e13d7572SSiddartha Mohanadoss { 559e13d7572SSiddartha Mohanadoss int voltage; 560e13d7572SSiddartha Mohanadoss 561e13d7572SSiddartha Mohanadoss voltage = qcom_vadc_scale_code_voltage_factor(adc_code, 562e13d7572SSiddartha Mohanadoss prescale, data, 1000); 563e13d7572SSiddartha Mohanadoss 564e13d7572SSiddartha Mohanadoss /* Map voltage to temperature from look-up table */ 565e13d7572SSiddartha Mohanadoss return qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref, 566e13d7572SSiddartha Mohanadoss ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref), 567e13d7572SSiddartha Mohanadoss voltage, result_mdec); 568e13d7572SSiddartha Mohanadoss } 569e13d7572SSiddartha Mohanadoss 570e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_die_temp( 571e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 572e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 573e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec) 574e13d7572SSiddartha Mohanadoss { 575e13d7572SSiddartha Mohanadoss *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code, 576e13d7572SSiddartha Mohanadoss prescale, data, 2); 577f88b4265SAkinobu Mita *result_mdec = milli_kelvin_to_millicelsius(*result_mdec); 578e13d7572SSiddartha Mohanadoss 579e13d7572SSiddartha Mohanadoss return 0; 580e13d7572SSiddartha Mohanadoss } 581e13d7572SSiddartha Mohanadoss 582082111e5SJishnu Prakash static int qcom_vadc7_scale_hw_calib_die_temp( 583082111e5SJishnu Prakash const struct vadc_prescale_ratio *prescale, 584082111e5SJishnu Prakash const struct adc5_data *data, 585082111e5SJishnu Prakash u16 adc_code, int *result_mdec) 586082111e5SJishnu Prakash { 587082111e5SJishnu Prakash 588082111e5SJishnu Prakash int voltage, vtemp0, temp, i; 589082111e5SJishnu Prakash 590082111e5SJishnu Prakash voltage = qcom_vadc_scale_code_voltage_factor(adc_code, 591082111e5SJishnu Prakash prescale, data, 1); 592082111e5SJishnu Prakash 593082111e5SJishnu Prakash if (adcmap7_die_temp[0].x > voltage) { 594082111e5SJishnu Prakash *result_mdec = DIE_TEMP_ADC7_SCALE_1; 595082111e5SJishnu Prakash return 0; 596082111e5SJishnu Prakash } 597082111e5SJishnu Prakash 598082111e5SJishnu Prakash if (adcmap7_die_temp[ARRAY_SIZE(adcmap7_die_temp) - 1].x <= voltage) { 599082111e5SJishnu Prakash *result_mdec = DIE_TEMP_ADC7_MAX; 600082111e5SJishnu Prakash return 0; 601082111e5SJishnu Prakash } 602082111e5SJishnu Prakash 603082111e5SJishnu Prakash for (i = 0; i < ARRAY_SIZE(adcmap7_die_temp); i++) 604082111e5SJishnu Prakash if (adcmap7_die_temp[i].x > voltage) 605082111e5SJishnu Prakash break; 606082111e5SJishnu Prakash 607082111e5SJishnu Prakash vtemp0 = adcmap7_die_temp[i - 1].x; 608082111e5SJishnu Prakash voltage = voltage - vtemp0; 609082111e5SJishnu Prakash temp = div64_s64(voltage * DIE_TEMP_ADC7_SCALE_FACTOR, 610082111e5SJishnu Prakash adcmap7_die_temp[i - 1].y); 611082111e5SJishnu Prakash temp += DIE_TEMP_ADC7_SCALE_1 + (DIE_TEMP_ADC7_SCALE_2 * (i - 1)); 612082111e5SJishnu Prakash *result_mdec = temp; 613082111e5SJishnu Prakash 614082111e5SJishnu Prakash return 0; 615082111e5SJishnu Prakash } 616082111e5SJishnu Prakash 617e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_smb_temp( 618e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 619e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 620e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec) 621e13d7572SSiddartha Mohanadoss { 622e13d7572SSiddartha Mohanadoss *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code * 100, 623e13d7572SSiddartha Mohanadoss prescale, data, PMIC5_SMB_TEMP_SCALE_FACTOR); 624e13d7572SSiddartha Mohanadoss *result_mdec = PMIC5_SMB_TEMP_CONSTANT - *result_mdec; 625e13d7572SSiddartha Mohanadoss 626e13d7572SSiddartha Mohanadoss return 0; 627e13d7572SSiddartha Mohanadoss } 628e13d7572SSiddartha Mohanadoss 629e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_chg5_temp( 630e13d7572SSiddartha Mohanadoss const struct vadc_prescale_ratio *prescale, 631e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 632e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec) 633e13d7572SSiddartha Mohanadoss { 634e13d7572SSiddartha Mohanadoss *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code, 635e13d7572SSiddartha Mohanadoss prescale, data, 4); 636e13d7572SSiddartha Mohanadoss *result_mdec = PMIC5_CHG_TEMP_SCALE_FACTOR - *result_mdec; 637e13d7572SSiddartha Mohanadoss 638e13d7572SSiddartha Mohanadoss return 0; 639e13d7572SSiddartha Mohanadoss } 640e13d7572SSiddartha Mohanadoss 641e932d4f0SLinus Walleij int qcom_vadc_scale(enum vadc_scale_fn_type scaletype, 642e932d4f0SLinus Walleij const struct vadc_linear_graph *calib_graph, 643e932d4f0SLinus Walleij const struct vadc_prescale_ratio *prescale, 644e932d4f0SLinus Walleij bool absolute, 645e932d4f0SLinus Walleij u16 adc_code, int *result) 646e932d4f0SLinus Walleij { 647e932d4f0SLinus Walleij switch (scaletype) { 648e932d4f0SLinus Walleij case SCALE_DEFAULT: 649e932d4f0SLinus Walleij return qcom_vadc_scale_volt(calib_graph, prescale, 650e932d4f0SLinus Walleij absolute, adc_code, 651e932d4f0SLinus Walleij result); 652e932d4f0SLinus Walleij case SCALE_THERM_100K_PULLUP: 653e932d4f0SLinus Walleij case SCALE_XOTHERM: 654e932d4f0SLinus Walleij return qcom_vadc_scale_therm(calib_graph, prescale, 655e932d4f0SLinus Walleij absolute, adc_code, 656e932d4f0SLinus Walleij result); 657e932d4f0SLinus Walleij case SCALE_PMIC_THERM: 658e932d4f0SLinus Walleij return qcom_vadc_scale_die_temp(calib_graph, prescale, 659e932d4f0SLinus Walleij absolute, adc_code, 660e932d4f0SLinus Walleij result); 661e932d4f0SLinus Walleij case SCALE_PMI_CHG_TEMP: 662e932d4f0SLinus Walleij return qcom_vadc_scale_chg_temp(calib_graph, prescale, 663e932d4f0SLinus Walleij absolute, adc_code, 664e932d4f0SLinus Walleij result); 665e932d4f0SLinus Walleij default: 666e932d4f0SLinus Walleij return -EINVAL; 667e932d4f0SLinus Walleij } 668e932d4f0SLinus Walleij } 669e932d4f0SLinus Walleij EXPORT_SYMBOL(qcom_vadc_scale); 670e932d4f0SLinus Walleij 671e13d7572SSiddartha Mohanadoss int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype, 672c7ba98fcSDmitry Baryshkov unsigned int prescale_ratio, 673e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 674e13d7572SSiddartha Mohanadoss u16 adc_code, int *result) 675e13d7572SSiddartha Mohanadoss { 676c7ba98fcSDmitry Baryshkov const struct vadc_prescale_ratio *prescale = &adc5_prescale_ratios[prescale_ratio]; 677c7ba98fcSDmitry Baryshkov 678e13d7572SSiddartha Mohanadoss if (!(scaletype >= SCALE_HW_CALIB_DEFAULT && 679e13d7572SSiddartha Mohanadoss scaletype < SCALE_HW_CALIB_INVALID)) { 680e13d7572SSiddartha Mohanadoss pr_err("Invalid scale type %d\n", scaletype); 681e13d7572SSiddartha Mohanadoss return -EINVAL; 682e13d7572SSiddartha Mohanadoss } 683e13d7572SSiddartha Mohanadoss 684e13d7572SSiddartha Mohanadoss return scale_adc5_fn[scaletype].scale_fn(prescale, data, 685e13d7572SSiddartha Mohanadoss adc_code, result); 686e13d7572SSiddartha Mohanadoss } 687e13d7572SSiddartha Mohanadoss EXPORT_SYMBOL(qcom_adc5_hw_scale); 688e13d7572SSiddartha Mohanadoss 689c7ba98fcSDmitry Baryshkov int qcom_adc5_prescaling_from_dt(u32 num, u32 den) 690c7ba98fcSDmitry Baryshkov { 691c7ba98fcSDmitry Baryshkov unsigned int pre; 692c7ba98fcSDmitry Baryshkov 693c7ba98fcSDmitry Baryshkov for (pre = 0; pre < ARRAY_SIZE(adc5_prescale_ratios); pre++) 694c7ba98fcSDmitry Baryshkov if (adc5_prescale_ratios[pre].num == num && 695c7ba98fcSDmitry Baryshkov adc5_prescale_ratios[pre].den == den) 696c7ba98fcSDmitry Baryshkov break; 697c7ba98fcSDmitry Baryshkov 698c7ba98fcSDmitry Baryshkov if (pre == ARRAY_SIZE(adc5_prescale_ratios)) 699c7ba98fcSDmitry Baryshkov return -EINVAL; 700c7ba98fcSDmitry Baryshkov 701c7ba98fcSDmitry Baryshkov return pre; 702c7ba98fcSDmitry Baryshkov } 703c7ba98fcSDmitry Baryshkov EXPORT_SYMBOL(qcom_adc5_prescaling_from_dt); 704c7ba98fcSDmitry Baryshkov 705c7ba98fcSDmitry Baryshkov int qcom_adc5_hw_settle_time_from_dt(u32 value, 706c7ba98fcSDmitry Baryshkov const unsigned int *hw_settle) 707c7ba98fcSDmitry Baryshkov { 708c7ba98fcSDmitry Baryshkov unsigned int i; 709c7ba98fcSDmitry Baryshkov 710c7ba98fcSDmitry Baryshkov for (i = 0; i < VADC_HW_SETTLE_SAMPLES_MAX; i++) { 711c7ba98fcSDmitry Baryshkov if (value == hw_settle[i]) 712c7ba98fcSDmitry Baryshkov return i; 713c7ba98fcSDmitry Baryshkov } 714c7ba98fcSDmitry Baryshkov 715c7ba98fcSDmitry Baryshkov return -EINVAL; 716c7ba98fcSDmitry Baryshkov } 717c7ba98fcSDmitry Baryshkov EXPORT_SYMBOL(qcom_adc5_hw_settle_time_from_dt); 718c7ba98fcSDmitry Baryshkov 719c7ba98fcSDmitry Baryshkov int qcom_adc5_avg_samples_from_dt(u32 value) 720c7ba98fcSDmitry Baryshkov { 721c7ba98fcSDmitry Baryshkov if (!is_power_of_2(value) || value > ADC5_AVG_SAMPLES_MAX) 722c7ba98fcSDmitry Baryshkov return -EINVAL; 723c7ba98fcSDmitry Baryshkov 724c7ba98fcSDmitry Baryshkov return __ffs(value); 725c7ba98fcSDmitry Baryshkov } 726c7ba98fcSDmitry Baryshkov EXPORT_SYMBOL(qcom_adc5_avg_samples_from_dt); 727c7ba98fcSDmitry Baryshkov 728c7ba98fcSDmitry Baryshkov int qcom_adc5_decimation_from_dt(u32 value, const unsigned int *decimation) 729c7ba98fcSDmitry Baryshkov { 730c7ba98fcSDmitry Baryshkov unsigned int i; 731c7ba98fcSDmitry Baryshkov 732c7ba98fcSDmitry Baryshkov for (i = 0; i < ADC5_DECIMATION_SAMPLES_MAX; i++) { 733c7ba98fcSDmitry Baryshkov if (value == decimation[i]) 734c7ba98fcSDmitry Baryshkov return i; 735c7ba98fcSDmitry Baryshkov } 736c7ba98fcSDmitry Baryshkov 737c7ba98fcSDmitry Baryshkov return -EINVAL; 738c7ba98fcSDmitry Baryshkov } 739c7ba98fcSDmitry Baryshkov EXPORT_SYMBOL(qcom_adc5_decimation_from_dt); 740c7ba98fcSDmitry Baryshkov 741e932d4f0SLinus Walleij int qcom_vadc_decimation_from_dt(u32 value) 742e932d4f0SLinus Walleij { 743e932d4f0SLinus Walleij if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN || 744e932d4f0SLinus Walleij value > VADC_DECIMATION_MAX) 745e932d4f0SLinus Walleij return -EINVAL; 746e932d4f0SLinus Walleij 747e932d4f0SLinus Walleij return __ffs64(value / VADC_DECIMATION_MIN); 748e932d4f0SLinus Walleij } 749e932d4f0SLinus Walleij EXPORT_SYMBOL(qcom_vadc_decimation_from_dt); 7509a0ebbc9SLinus Walleij 7519a0ebbc9SLinus Walleij MODULE_LICENSE("GPL v2"); 7529a0ebbc9SLinus Walleij MODULE_DESCRIPTION("Qualcomm ADC common functionality"); 753