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 13bb01e263SDmitry Baryshkov /** 14bb01e263SDmitry Baryshkov * struct vadc_map_pt - Map the graph representation for ADC channel 15bb01e263SDmitry Baryshkov * @x: Represent the ADC digitized code. 16bb01e263SDmitry Baryshkov * @y: Represent the physical data which can be temperature, voltage, 17bb01e263SDmitry Baryshkov * resistance. 18bb01e263SDmitry Baryshkov */ 19bb01e263SDmitry Baryshkov struct vadc_map_pt { 20bb01e263SDmitry Baryshkov s32 x; 21bb01e263SDmitry Baryshkov s32 y; 22bb01e263SDmitry Baryshkov }; 23bb01e263SDmitry Baryshkov 24e932d4f0SLinus Walleij /* Voltage to temperature */ 25e932d4f0SLinus Walleij static const struct vadc_map_pt adcmap_100k_104ef_104fb[] = { 2624a7dc6fSDmitry Baryshkov {1758, -40000 }, 2724a7dc6fSDmitry Baryshkov {1742, -35000 }, 2824a7dc6fSDmitry Baryshkov {1719, -30000 }, 2924a7dc6fSDmitry Baryshkov {1691, -25000 }, 3024a7dc6fSDmitry Baryshkov {1654, -20000 }, 3124a7dc6fSDmitry Baryshkov {1608, -15000 }, 3224a7dc6fSDmitry Baryshkov {1551, -10000 }, 3324a7dc6fSDmitry Baryshkov {1483, -5000 }, 34e932d4f0SLinus Walleij {1404, 0 }, 3524a7dc6fSDmitry Baryshkov {1315, 5000 }, 3624a7dc6fSDmitry Baryshkov {1218, 10000 }, 3724a7dc6fSDmitry Baryshkov {1114, 15000 }, 3824a7dc6fSDmitry Baryshkov {1007, 20000 }, 3924a7dc6fSDmitry Baryshkov {900, 25000 }, 4024a7dc6fSDmitry Baryshkov {795, 30000 }, 4124a7dc6fSDmitry Baryshkov {696, 35000 }, 4224a7dc6fSDmitry Baryshkov {605, 40000 }, 4324a7dc6fSDmitry Baryshkov {522, 45000 }, 4424a7dc6fSDmitry Baryshkov {448, 50000 }, 4524a7dc6fSDmitry Baryshkov {383, 55000 }, 4624a7dc6fSDmitry Baryshkov {327, 60000 }, 4724a7dc6fSDmitry Baryshkov {278, 65000 }, 4824a7dc6fSDmitry Baryshkov {237, 70000 }, 4924a7dc6fSDmitry Baryshkov {202, 75000 }, 5024a7dc6fSDmitry Baryshkov {172, 80000 }, 5124a7dc6fSDmitry Baryshkov {146, 85000 }, 5224a7dc6fSDmitry Baryshkov {125, 90000 }, 5324a7dc6fSDmitry Baryshkov {107, 95000 }, 5424a7dc6fSDmitry Baryshkov {92, 100000 }, 5524a7dc6fSDmitry Baryshkov {79, 105000 }, 5624a7dc6fSDmitry Baryshkov {68, 110000 }, 5724a7dc6fSDmitry Baryshkov {59, 115000 }, 5824a7dc6fSDmitry Baryshkov {51, 120000 }, 5924a7dc6fSDmitry Baryshkov {44, 125000 } 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[] = { 1043bd0ceb5SDmitry Baryshkov { 857300, 160000 }, 1053bd0ceb5SDmitry Baryshkov { 820100, 140000 }, 1063bd0ceb5SDmitry Baryshkov { 782500, 120000 }, 1073bd0ceb5SDmitry Baryshkov { 744600, 100000 }, 1083bd0ceb5SDmitry Baryshkov { 706400, 80000 }, 1093bd0ceb5SDmitry Baryshkov { 667900, 60000 }, 1103bd0ceb5SDmitry Baryshkov { 629300, 40000 }, 1113bd0ceb5SDmitry Baryshkov { 590500, 20000 }, 1123bd0ceb5SDmitry Baryshkov { 551500, 0 }, 1133bd0ceb5SDmitry Baryshkov { 512400, -20000 }, 1143bd0ceb5SDmitry Baryshkov { 473100, -40000 }, 1153bd0ceb5SDmitry Baryshkov { 433700, -60000 }, 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 292*a5e9b2ddSAndy Shevchenko static const struct u32_fract adc5_prescale_ratios[] = { 293*a5e9b2ddSAndy Shevchenko { .numerator = 1, .denominator = 1 }, 294*a5e9b2ddSAndy Shevchenko { .numerator = 1, .denominator = 3 }, 295*a5e9b2ddSAndy Shevchenko { .numerator = 1, .denominator = 4 }, 296*a5e9b2ddSAndy Shevchenko { .numerator = 1, .denominator = 6 }, 297*a5e9b2ddSAndy Shevchenko { .numerator = 1, .denominator = 20 }, 298*a5e9b2ddSAndy Shevchenko { .numerator = 1, .denominator = 8 }, 299*a5e9b2ddSAndy Shevchenko { .numerator = 10, .denominator = 81 }, 300*a5e9b2ddSAndy Shevchenko { .numerator = 1, .denominator = 10 }, 301*a5e9b2ddSAndy Shevchenko { .numerator = 1, .denominator = 16 }, 302c7ba98fcSDmitry Baryshkov }; 303c7ba98fcSDmitry Baryshkov 304e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_volt( 305*a5e9b2ddSAndy Shevchenko const struct u32_fract *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( 309*a5e9b2ddSAndy Shevchenko const struct u32_fract *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( 313*a5e9b2ddSAndy Shevchenko const struct u32_fract *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( 317*a5e9b2ddSAndy Shevchenko const struct u32_fract *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( 321*a5e9b2ddSAndy Shevchenko const struct u32_fract *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( 325*a5e9b2ddSAndy Shevchenko const struct u32_fract *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( 329*a5e9b2ddSAndy Shevchenko const struct u32_fract *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 u32 i = 0; 350e932d4f0SLinus Walleij 351e932d4f0SLinus Walleij if (!pts) 352e932d4f0SLinus Walleij return -EINVAL; 353e932d4f0SLinus Walleij 35448d2e2ffSDmitry Baryshkov while (i < tablesize && pts[i].x > input) 355e932d4f0SLinus Walleij i++; 356e932d4f0SLinus Walleij 357e932d4f0SLinus Walleij if (i == 0) { 358e932d4f0SLinus Walleij *output = pts[0].y; 359e932d4f0SLinus Walleij } else if (i == tablesize) { 360e932d4f0SLinus Walleij *output = pts[tablesize - 1].y; 361e932d4f0SLinus Walleij } else { 362e932d4f0SLinus Walleij /* interpolate linearly */ 363e2621acdSDmitry Baryshkov *output = fixp_linear_interpolate(pts[i - 1].x, pts[i - 1].y, 364e2621acdSDmitry Baryshkov pts[i].x, pts[i].y, 365e2621acdSDmitry Baryshkov input); 366e932d4f0SLinus Walleij } 367e932d4f0SLinus Walleij 368e932d4f0SLinus Walleij return 0; 369e932d4f0SLinus Walleij } 370e932d4f0SLinus Walleij 371ca66dca5SDmitry Baryshkov static s32 qcom_vadc_map_temp_voltage(const struct vadc_map_pt *pts, 372ca66dca5SDmitry Baryshkov u32 tablesize, int input) 373ca66dca5SDmitry Baryshkov { 374ca66dca5SDmitry Baryshkov u32 i = 0; 375ca66dca5SDmitry Baryshkov 376ca66dca5SDmitry Baryshkov /* 377ca66dca5SDmitry Baryshkov * Table must be sorted, find the interval of 'y' which contains value 378ca66dca5SDmitry Baryshkov * 'input' and map it to proper 'x' value 379ca66dca5SDmitry Baryshkov */ 380ca66dca5SDmitry Baryshkov while (i < tablesize && pts[i].y < input) 381ca66dca5SDmitry Baryshkov i++; 382ca66dca5SDmitry Baryshkov 383ca66dca5SDmitry Baryshkov if (i == 0) 384ca66dca5SDmitry Baryshkov return pts[0].x; 385ca66dca5SDmitry Baryshkov if (i == tablesize) 386ca66dca5SDmitry Baryshkov return pts[tablesize - 1].x; 387ca66dca5SDmitry Baryshkov 388ca66dca5SDmitry Baryshkov /* interpolate linearly */ 389ca66dca5SDmitry Baryshkov return fixp_linear_interpolate(pts[i - 1].y, pts[i - 1].x, 390ca66dca5SDmitry Baryshkov pts[i].y, pts[i].x, input); 391ca66dca5SDmitry Baryshkov } 392ca66dca5SDmitry Baryshkov 393e932d4f0SLinus Walleij static void qcom_vadc_scale_calib(const struct vadc_linear_graph *calib_graph, 394e932d4f0SLinus Walleij u16 adc_code, 395e932d4f0SLinus Walleij bool absolute, 396e932d4f0SLinus Walleij s64 *scale_voltage) 397e932d4f0SLinus Walleij { 398e932d4f0SLinus Walleij *scale_voltage = (adc_code - calib_graph->gnd); 399e932d4f0SLinus Walleij *scale_voltage *= calib_graph->dx; 400e932d4f0SLinus Walleij *scale_voltage = div64_s64(*scale_voltage, calib_graph->dy); 401e932d4f0SLinus Walleij if (absolute) 402e932d4f0SLinus Walleij *scale_voltage += calib_graph->dx; 403e932d4f0SLinus Walleij 404e932d4f0SLinus Walleij if (*scale_voltage < 0) 405e932d4f0SLinus Walleij *scale_voltage = 0; 406e932d4f0SLinus Walleij } 407e932d4f0SLinus Walleij 408e932d4f0SLinus Walleij static int qcom_vadc_scale_volt(const struct vadc_linear_graph *calib_graph, 409*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 410e932d4f0SLinus Walleij bool absolute, u16 adc_code, 411e932d4f0SLinus Walleij int *result_uv) 412e932d4f0SLinus Walleij { 413e932d4f0SLinus Walleij s64 voltage = 0, result = 0; 414e932d4f0SLinus Walleij 415e932d4f0SLinus Walleij qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage); 416e932d4f0SLinus Walleij 417*a5e9b2ddSAndy Shevchenko voltage *= prescale->denominator; 418*a5e9b2ddSAndy Shevchenko result = div64_s64(voltage, prescale->numerator); 419e932d4f0SLinus Walleij *result_uv = result; 420e932d4f0SLinus Walleij 421e932d4f0SLinus Walleij return 0; 422e932d4f0SLinus Walleij } 423e932d4f0SLinus Walleij 424e932d4f0SLinus Walleij static int qcom_vadc_scale_therm(const struct vadc_linear_graph *calib_graph, 425*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 426e932d4f0SLinus Walleij bool absolute, u16 adc_code, 427e932d4f0SLinus Walleij int *result_mdec) 428e932d4f0SLinus Walleij { 429e13d7572SSiddartha Mohanadoss s64 voltage = 0; 430e932d4f0SLinus Walleij int ret; 431e932d4f0SLinus Walleij 432e932d4f0SLinus Walleij qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage); 433e932d4f0SLinus Walleij 434e932d4f0SLinus Walleij if (absolute) 435e932d4f0SLinus Walleij voltage = div64_s64(voltage, 1000); 436e932d4f0SLinus Walleij 437e932d4f0SLinus Walleij ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb, 438e932d4f0SLinus Walleij ARRAY_SIZE(adcmap_100k_104ef_104fb), 439e13d7572SSiddartha Mohanadoss voltage, result_mdec); 440e932d4f0SLinus Walleij if (ret) 441e932d4f0SLinus Walleij return ret; 442e932d4f0SLinus Walleij 443e932d4f0SLinus Walleij return 0; 444e932d4f0SLinus Walleij } 445e932d4f0SLinus Walleij 446e932d4f0SLinus Walleij static int qcom_vadc_scale_die_temp(const struct vadc_linear_graph *calib_graph, 447*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 448e932d4f0SLinus Walleij bool absolute, 449e932d4f0SLinus Walleij u16 adc_code, int *result_mdec) 450e932d4f0SLinus Walleij { 451e932d4f0SLinus Walleij s64 voltage = 0; 452e932d4f0SLinus Walleij u64 temp; /* Temporary variable for do_div */ 453e932d4f0SLinus Walleij 454e932d4f0SLinus Walleij qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage); 455e932d4f0SLinus Walleij 456e932d4f0SLinus Walleij if (voltage > 0) { 457*a5e9b2ddSAndy Shevchenko temp = voltage * prescale->denominator; 458*a5e9b2ddSAndy Shevchenko do_div(temp, prescale->numerator * 2); 459e932d4f0SLinus Walleij voltage = temp; 460e932d4f0SLinus Walleij } else { 461e932d4f0SLinus Walleij voltage = 0; 462e932d4f0SLinus Walleij } 463e932d4f0SLinus Walleij 464f88b4265SAkinobu Mita *result_mdec = milli_kelvin_to_millicelsius(voltage); 465e932d4f0SLinus Walleij 466e932d4f0SLinus Walleij return 0; 467e932d4f0SLinus Walleij } 468e932d4f0SLinus Walleij 469e932d4f0SLinus Walleij static int qcom_vadc_scale_chg_temp(const struct vadc_linear_graph *calib_graph, 470*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 471e932d4f0SLinus Walleij bool absolute, 472e932d4f0SLinus Walleij u16 adc_code, int *result_mdec) 473e932d4f0SLinus Walleij { 474e932d4f0SLinus Walleij s64 voltage = 0, result = 0; 475e932d4f0SLinus Walleij 476e932d4f0SLinus Walleij qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage); 477e932d4f0SLinus Walleij 478*a5e9b2ddSAndy Shevchenko voltage *= prescale->denominator; 479*a5e9b2ddSAndy Shevchenko voltage = div64_s64(voltage, prescale->numerator); 480e932d4f0SLinus Walleij voltage = ((PMI_CHG_SCALE_1) * (voltage * 2)); 481e932d4f0SLinus Walleij voltage = (voltage + PMI_CHG_SCALE_2); 482e932d4f0SLinus Walleij result = div64_s64(voltage, 1000000); 483e932d4f0SLinus Walleij *result_mdec = result; 484e932d4f0SLinus Walleij 485e932d4f0SLinus Walleij return 0; 486e932d4f0SLinus Walleij } 487e932d4f0SLinus Walleij 488ca66dca5SDmitry Baryshkov /* convert voltage to ADC code, using 1.875V reference */ 489ca66dca5SDmitry Baryshkov static u16 qcom_vadc_scale_voltage_code(s32 voltage, 490*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 491ca66dca5SDmitry Baryshkov const u32 full_scale_code_volt, 492ca66dca5SDmitry Baryshkov unsigned int factor) 493ca66dca5SDmitry Baryshkov { 494ca66dca5SDmitry Baryshkov s64 volt = voltage; 495ca66dca5SDmitry Baryshkov s64 adc_vdd_ref_mv = 1875; /* reference voltage */ 496ca66dca5SDmitry Baryshkov 497*a5e9b2ddSAndy Shevchenko volt *= prescale->numerator * factor * full_scale_code_volt; 498*a5e9b2ddSAndy Shevchenko volt = div64_s64(volt, (s64)prescale->denominator * adc_vdd_ref_mv * 1000); 499ca66dca5SDmitry Baryshkov 500ca66dca5SDmitry Baryshkov return volt; 501ca66dca5SDmitry Baryshkov } 502ca66dca5SDmitry Baryshkov 503e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_code_voltage_factor(u16 adc_code, 504*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 505e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 506e13d7572SSiddartha Mohanadoss unsigned int factor) 507e13d7572SSiddartha Mohanadoss { 508e13d7572SSiddartha Mohanadoss s64 voltage, temp, adc_vdd_ref_mv = 1875; 509e13d7572SSiddartha Mohanadoss 510e13d7572SSiddartha Mohanadoss /* 511e13d7572SSiddartha Mohanadoss * The normal data range is between 0V to 1.875V. On cases where 512e13d7572SSiddartha Mohanadoss * we read low voltage values, the ADC code can go beyond the 513e13d7572SSiddartha Mohanadoss * range and the scale result is incorrect so we clamp the values 514e13d7572SSiddartha Mohanadoss * for the cases where the code represents a value below 0V 515e13d7572SSiddartha Mohanadoss */ 516e13d7572SSiddartha Mohanadoss if (adc_code > VADC5_MAX_CODE) 517e13d7572SSiddartha Mohanadoss adc_code = 0; 518e13d7572SSiddartha Mohanadoss 519e13d7572SSiddartha Mohanadoss /* (ADC code * vref_vadc (1.875V)) / full_scale_code */ 520e13d7572SSiddartha Mohanadoss voltage = (s64) adc_code * adc_vdd_ref_mv * 1000; 521e13d7572SSiddartha Mohanadoss voltage = div64_s64(voltage, data->full_scale_code_volt); 522e13d7572SSiddartha Mohanadoss if (voltage > 0) { 523*a5e9b2ddSAndy Shevchenko voltage *= prescale->denominator; 524*a5e9b2ddSAndy Shevchenko temp = prescale->numerator * factor; 525e13d7572SSiddartha Mohanadoss voltage = div64_s64(voltage, temp); 526e13d7572SSiddartha Mohanadoss } else { 527e13d7572SSiddartha Mohanadoss voltage = 0; 528e13d7572SSiddartha Mohanadoss } 529e13d7572SSiddartha Mohanadoss 530e13d7572SSiddartha Mohanadoss return (int) voltage; 531e13d7572SSiddartha Mohanadoss } 532e13d7572SSiddartha Mohanadoss 533082111e5SJishnu Prakash static int qcom_vadc7_scale_hw_calib_therm( 534*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 535082111e5SJishnu Prakash const struct adc5_data *data, 536082111e5SJishnu Prakash u16 adc_code, int *result_mdec) 537082111e5SJishnu Prakash { 538082111e5SJishnu Prakash s64 resistance = adc_code; 539082111e5SJishnu Prakash int ret, result; 540082111e5SJishnu Prakash 541082111e5SJishnu Prakash if (adc_code >= RATIO_MAX_ADC7) 542082111e5SJishnu Prakash return -EINVAL; 543082111e5SJishnu Prakash 544082111e5SJishnu Prakash /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/ 545082111e5SJishnu Prakash resistance *= R_PU_100K; 546082111e5SJishnu Prakash resistance = div64_s64(resistance, RATIO_MAX_ADC7 - adc_code); 547082111e5SJishnu Prakash 548082111e5SJishnu Prakash ret = qcom_vadc_map_voltage_temp(adcmap7_100k, 549082111e5SJishnu Prakash ARRAY_SIZE(adcmap7_100k), 550082111e5SJishnu Prakash resistance, &result); 551082111e5SJishnu Prakash if (ret) 552082111e5SJishnu Prakash return ret; 553082111e5SJishnu Prakash 554082111e5SJishnu Prakash *result_mdec = result; 555082111e5SJishnu Prakash 556082111e5SJishnu Prakash return 0; 557082111e5SJishnu Prakash } 558082111e5SJishnu Prakash 559e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_volt( 560*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 561e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 562e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_uv) 563e13d7572SSiddartha Mohanadoss { 564e13d7572SSiddartha Mohanadoss *result_uv = qcom_vadc_scale_code_voltage_factor(adc_code, 565e13d7572SSiddartha Mohanadoss prescale, data, 1); 566e13d7572SSiddartha Mohanadoss 567e13d7572SSiddartha Mohanadoss return 0; 568e13d7572SSiddartha Mohanadoss } 569e13d7572SSiddartha Mohanadoss 570e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_therm( 571*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 572e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 573e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec) 574e13d7572SSiddartha Mohanadoss { 575e13d7572SSiddartha Mohanadoss int voltage; 576e13d7572SSiddartha Mohanadoss 577e13d7572SSiddartha Mohanadoss voltage = qcom_vadc_scale_code_voltage_factor(adc_code, 578e13d7572SSiddartha Mohanadoss prescale, data, 1000); 579e13d7572SSiddartha Mohanadoss 580e13d7572SSiddartha Mohanadoss /* Map voltage to temperature from look-up table */ 581e13d7572SSiddartha Mohanadoss return qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref, 582e13d7572SSiddartha Mohanadoss ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref), 583e13d7572SSiddartha Mohanadoss voltage, result_mdec); 584e13d7572SSiddartha Mohanadoss } 585e13d7572SSiddartha Mohanadoss 586e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_calib_die_temp( 587*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 588e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 589e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec) 590e13d7572SSiddartha Mohanadoss { 591e13d7572SSiddartha Mohanadoss *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code, 592e13d7572SSiddartha Mohanadoss prescale, data, 2); 593f88b4265SAkinobu Mita *result_mdec = milli_kelvin_to_millicelsius(*result_mdec); 594e13d7572SSiddartha Mohanadoss 595e13d7572SSiddartha Mohanadoss return 0; 596e13d7572SSiddartha Mohanadoss } 597e13d7572SSiddartha Mohanadoss 598082111e5SJishnu Prakash static int qcom_vadc7_scale_hw_calib_die_temp( 599*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 600082111e5SJishnu Prakash const struct adc5_data *data, 601082111e5SJishnu Prakash u16 adc_code, int *result_mdec) 602082111e5SJishnu Prakash { 603082111e5SJishnu Prakash 6043bd0ceb5SDmitry Baryshkov int voltage; 605082111e5SJishnu Prakash 606082111e5SJishnu Prakash voltage = qcom_vadc_scale_code_voltage_factor(adc_code, 607082111e5SJishnu Prakash prescale, data, 1); 608082111e5SJishnu Prakash 6093bd0ceb5SDmitry Baryshkov return qcom_vadc_map_voltage_temp(adcmap7_die_temp, ARRAY_SIZE(adcmap7_die_temp), 6103bd0ceb5SDmitry Baryshkov voltage, result_mdec); 611082111e5SJishnu Prakash } 612082111e5SJishnu Prakash 613e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_smb_temp( 614*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 615e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 616e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec) 617e13d7572SSiddartha Mohanadoss { 618e13d7572SSiddartha Mohanadoss *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code * 100, 619e13d7572SSiddartha Mohanadoss prescale, data, PMIC5_SMB_TEMP_SCALE_FACTOR); 620e13d7572SSiddartha Mohanadoss *result_mdec = PMIC5_SMB_TEMP_CONSTANT - *result_mdec; 621e13d7572SSiddartha Mohanadoss 622e13d7572SSiddartha Mohanadoss return 0; 623e13d7572SSiddartha Mohanadoss } 624e13d7572SSiddartha Mohanadoss 625e13d7572SSiddartha Mohanadoss static int qcom_vadc_scale_hw_chg5_temp( 626*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 627e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 628e13d7572SSiddartha Mohanadoss u16 adc_code, int *result_mdec) 629e13d7572SSiddartha Mohanadoss { 630e13d7572SSiddartha Mohanadoss *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code, 631e13d7572SSiddartha Mohanadoss prescale, data, 4); 632e13d7572SSiddartha Mohanadoss *result_mdec = PMIC5_CHG_TEMP_SCALE_FACTOR - *result_mdec; 633e13d7572SSiddartha Mohanadoss 634e13d7572SSiddartha Mohanadoss return 0; 635e13d7572SSiddartha Mohanadoss } 636e13d7572SSiddartha Mohanadoss 637e932d4f0SLinus Walleij int qcom_vadc_scale(enum vadc_scale_fn_type scaletype, 638e932d4f0SLinus Walleij const struct vadc_linear_graph *calib_graph, 639*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale, 640e932d4f0SLinus Walleij bool absolute, 641e932d4f0SLinus Walleij u16 adc_code, int *result) 642e932d4f0SLinus Walleij { 643e932d4f0SLinus Walleij switch (scaletype) { 644e932d4f0SLinus Walleij case SCALE_DEFAULT: 645e932d4f0SLinus Walleij return qcom_vadc_scale_volt(calib_graph, prescale, 646e932d4f0SLinus Walleij absolute, adc_code, 647e932d4f0SLinus Walleij result); 648e932d4f0SLinus Walleij case SCALE_THERM_100K_PULLUP: 649e932d4f0SLinus Walleij case SCALE_XOTHERM: 650e932d4f0SLinus Walleij return qcom_vadc_scale_therm(calib_graph, prescale, 651e932d4f0SLinus Walleij absolute, adc_code, 652e932d4f0SLinus Walleij result); 653e932d4f0SLinus Walleij case SCALE_PMIC_THERM: 654e932d4f0SLinus Walleij return qcom_vadc_scale_die_temp(calib_graph, prescale, 655e932d4f0SLinus Walleij absolute, adc_code, 656e932d4f0SLinus Walleij result); 657e932d4f0SLinus Walleij case SCALE_PMI_CHG_TEMP: 658e932d4f0SLinus Walleij return qcom_vadc_scale_chg_temp(calib_graph, prescale, 659e932d4f0SLinus Walleij absolute, adc_code, 660e932d4f0SLinus Walleij result); 661e932d4f0SLinus Walleij default: 662e932d4f0SLinus Walleij return -EINVAL; 663e932d4f0SLinus Walleij } 664e932d4f0SLinus Walleij } 665e932d4f0SLinus Walleij EXPORT_SYMBOL(qcom_vadc_scale); 666e932d4f0SLinus Walleij 667ca66dca5SDmitry Baryshkov u16 qcom_adc_tm5_temp_volt_scale(unsigned int prescale_ratio, 668ca66dca5SDmitry Baryshkov u32 full_scale_code_volt, int temp) 669ca66dca5SDmitry Baryshkov { 670*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale = &adc5_prescale_ratios[prescale_ratio]; 671ca66dca5SDmitry Baryshkov s32 voltage; 672ca66dca5SDmitry Baryshkov 673ca66dca5SDmitry Baryshkov voltage = qcom_vadc_map_temp_voltage(adcmap_100k_104ef_104fb_1875_vref, 674ca66dca5SDmitry Baryshkov ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref), 675ca66dca5SDmitry Baryshkov temp); 676ca66dca5SDmitry Baryshkov return qcom_vadc_scale_voltage_code(voltage, prescale, full_scale_code_volt, 1000); 677ca66dca5SDmitry Baryshkov } 678ca66dca5SDmitry Baryshkov EXPORT_SYMBOL(qcom_adc_tm5_temp_volt_scale); 679ca66dca5SDmitry Baryshkov 680e13d7572SSiddartha Mohanadoss int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype, 681c7ba98fcSDmitry Baryshkov unsigned int prescale_ratio, 682e13d7572SSiddartha Mohanadoss const struct adc5_data *data, 683e13d7572SSiddartha Mohanadoss u16 adc_code, int *result) 684e13d7572SSiddartha Mohanadoss { 685*a5e9b2ddSAndy Shevchenko const struct u32_fract *prescale = &adc5_prescale_ratios[prescale_ratio]; 686c7ba98fcSDmitry Baryshkov 687e13d7572SSiddartha Mohanadoss if (!(scaletype >= SCALE_HW_CALIB_DEFAULT && 688e13d7572SSiddartha Mohanadoss scaletype < SCALE_HW_CALIB_INVALID)) { 689e13d7572SSiddartha Mohanadoss pr_err("Invalid scale type %d\n", scaletype); 690e13d7572SSiddartha Mohanadoss return -EINVAL; 691e13d7572SSiddartha Mohanadoss } 692e13d7572SSiddartha Mohanadoss 693e13d7572SSiddartha Mohanadoss return scale_adc5_fn[scaletype].scale_fn(prescale, data, 694e13d7572SSiddartha Mohanadoss adc_code, result); 695e13d7572SSiddartha Mohanadoss } 696e13d7572SSiddartha Mohanadoss EXPORT_SYMBOL(qcom_adc5_hw_scale); 697e13d7572SSiddartha Mohanadoss 698*a5e9b2ddSAndy Shevchenko int qcom_adc5_prescaling_from_dt(u32 numerator, u32 denominator) 699c7ba98fcSDmitry Baryshkov { 700c7ba98fcSDmitry Baryshkov unsigned int pre; 701c7ba98fcSDmitry Baryshkov 702c7ba98fcSDmitry Baryshkov for (pre = 0; pre < ARRAY_SIZE(adc5_prescale_ratios); pre++) 703*a5e9b2ddSAndy Shevchenko if (adc5_prescale_ratios[pre].numerator == numerator && 704*a5e9b2ddSAndy Shevchenko adc5_prescale_ratios[pre].denominator == denominator) 705c7ba98fcSDmitry Baryshkov break; 706c7ba98fcSDmitry Baryshkov 707c7ba98fcSDmitry Baryshkov if (pre == ARRAY_SIZE(adc5_prescale_ratios)) 708c7ba98fcSDmitry Baryshkov return -EINVAL; 709c7ba98fcSDmitry Baryshkov 710c7ba98fcSDmitry Baryshkov return pre; 711c7ba98fcSDmitry Baryshkov } 712c7ba98fcSDmitry Baryshkov EXPORT_SYMBOL(qcom_adc5_prescaling_from_dt); 713c7ba98fcSDmitry Baryshkov 714c7ba98fcSDmitry Baryshkov int qcom_adc5_hw_settle_time_from_dt(u32 value, 715c7ba98fcSDmitry Baryshkov const unsigned int *hw_settle) 716c7ba98fcSDmitry Baryshkov { 717c7ba98fcSDmitry Baryshkov unsigned int i; 718c7ba98fcSDmitry Baryshkov 719c7ba98fcSDmitry Baryshkov for (i = 0; i < VADC_HW_SETTLE_SAMPLES_MAX; i++) { 720c7ba98fcSDmitry Baryshkov if (value == hw_settle[i]) 721c7ba98fcSDmitry Baryshkov return i; 722c7ba98fcSDmitry Baryshkov } 723c7ba98fcSDmitry Baryshkov 724c7ba98fcSDmitry Baryshkov return -EINVAL; 725c7ba98fcSDmitry Baryshkov } 726c7ba98fcSDmitry Baryshkov EXPORT_SYMBOL(qcom_adc5_hw_settle_time_from_dt); 727c7ba98fcSDmitry Baryshkov 728c7ba98fcSDmitry Baryshkov int qcom_adc5_avg_samples_from_dt(u32 value) 729c7ba98fcSDmitry Baryshkov { 730c7ba98fcSDmitry Baryshkov if (!is_power_of_2(value) || value > ADC5_AVG_SAMPLES_MAX) 731c7ba98fcSDmitry Baryshkov return -EINVAL; 732c7ba98fcSDmitry Baryshkov 733c7ba98fcSDmitry Baryshkov return __ffs(value); 734c7ba98fcSDmitry Baryshkov } 735c7ba98fcSDmitry Baryshkov EXPORT_SYMBOL(qcom_adc5_avg_samples_from_dt); 736c7ba98fcSDmitry Baryshkov 737c7ba98fcSDmitry Baryshkov int qcom_adc5_decimation_from_dt(u32 value, const unsigned int *decimation) 738c7ba98fcSDmitry Baryshkov { 739c7ba98fcSDmitry Baryshkov unsigned int i; 740c7ba98fcSDmitry Baryshkov 741c7ba98fcSDmitry Baryshkov for (i = 0; i < ADC5_DECIMATION_SAMPLES_MAX; i++) { 742c7ba98fcSDmitry Baryshkov if (value == decimation[i]) 743c7ba98fcSDmitry Baryshkov return i; 744c7ba98fcSDmitry Baryshkov } 745c7ba98fcSDmitry Baryshkov 746c7ba98fcSDmitry Baryshkov return -EINVAL; 747c7ba98fcSDmitry Baryshkov } 748c7ba98fcSDmitry Baryshkov EXPORT_SYMBOL(qcom_adc5_decimation_from_dt); 749c7ba98fcSDmitry Baryshkov 750e932d4f0SLinus Walleij int qcom_vadc_decimation_from_dt(u32 value) 751e932d4f0SLinus Walleij { 752e932d4f0SLinus Walleij if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN || 753e932d4f0SLinus Walleij value > VADC_DECIMATION_MAX) 754e932d4f0SLinus Walleij return -EINVAL; 755e932d4f0SLinus Walleij 756e932d4f0SLinus Walleij return __ffs64(value / VADC_DECIMATION_MIN); 757e932d4f0SLinus Walleij } 758e932d4f0SLinus Walleij EXPORT_SYMBOL(qcom_vadc_decimation_from_dt); 7599a0ebbc9SLinus Walleij 7609a0ebbc9SLinus Walleij MODULE_LICENSE("GPL v2"); 7619a0ebbc9SLinus Walleij MODULE_DESCRIPTION("Qualcomm ADC common functionality"); 762