cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qcom-vadc-common.c (18661B)


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