iio: adc: Add ADC5 driver snapshot

ADC5 peripheral is used by client to read VADC
channels. Clients include reading vph_pwr and on board
system thermistors used for thermal mitigation.
Register ADC5 peripheral with IIO framework.

This snapshot is taken as of msm-4.14
'commit <ab8d48dd> ("Merge "diag: Increase the
MHI buffer size to 4k"")'.

Change-Id: I16b1178f7fa44c910fdde533aa199d9928d767e6
Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
This commit is contained in:
Siddartha Mohanadoss
2018-12-10 13:39:10 -08:00
parent af7d5e7766
commit a94f4a9cec
5 changed files with 2005 additions and 2 deletions

View File

@@ -567,6 +567,26 @@ config QCOM_PM8XXX_XOADC
To compile this driver as a module, choose M here: the module
will be called qcom-pm8xxx-xoadc.
config QCOM_SPMI_ADC5
tristate "Qualcomm Technologies Inc. SPMI PMIC5 ADC"
depends on SPMI
select REGMAP_SPMI
select QCOM_VADC_COMMON
help
This is the IIO Voltage PMIC5 ADC driver for Qualcomm Technologies Inc.
The driver supports multiple channels read. The ADC is a 16-bit
sigma-delta ADC. The hardware supports calibrated results for
conversion requests and clients include reading voltage phone
power, on board system thermistors connected to the PMIC ADC,
PMIC die temperature, charger temperature, battery current, USB voltage
input, voltage signals connected to supported PMIC GPIO inputs. The
hardware supports internal pull-up for thermistors and can choose between
a 100k, 30k and 400k pull up using the ADC channels.
To compile this driver as a module, choose M here: the module will
be called qcom-spmi-adc5.
config QCOM_SPMI_IADC
tristate "Qualcomm SPMI PMIC current ADC"
depends on SPMI

View File

@@ -53,6 +53,7 @@ obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o
obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o
obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
obj-$(CONFIG_QCOM_VADC_COMMON) += qcom-vadc-common.o
obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
@@ -47,6 +47,529 @@ static const struct vadc_map_pt adcmap_100k_104ef_104fb[] = {
{44, 125}
};
/*
* Voltage to temperature table for 100k pull up for NTCG104EF104 with
* 1.875V reference.
*/
static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
{ 1831, -40000 },
{ 1814, -35000 },
{ 1791, -30000 },
{ 1761, -25000 },
{ 1723, -20000 },
{ 1675, -15000 },
{ 1616, -10000 },
{ 1545, -5000 },
{ 1463, 0 },
{ 1370, 5000 },
{ 1268, 10000 },
{ 1160, 15000 },
{ 1049, 20000 },
{ 937, 25000 },
{ 828, 30000 },
{ 726, 35000 },
{ 630, 40000 },
{ 544, 45000 },
{ 467, 50000 },
{ 399, 55000 },
{ 340, 60000 },
{ 290, 65000 },
{ 247, 70000 },
{ 209, 75000 },
{ 179, 80000 },
{ 153, 85000 },
{ 130, 90000 },
{ 112, 95000 },
{ 96, 100000 },
{ 82, 105000 },
{ 71, 110000 },
{ 62, 115000 },
{ 53, 120000 },
{ 46, 125000 },
};
/*
* Voltage to temperature table for 100k pull up for bat_therm with
* Alium.
*/
static const struct vadc_map_pt adcmap_batt_therm_100k[] = {
{1840, -400},
{1835, -380},
{1828, -360},
{1821, -340},
{1813, -320},
{1803, -300},
{1793, -280},
{1781, -260},
{1768, -240},
{1753, -220},
{1737, -200},
{1719, -180},
{1700, -160},
{1679, -140},
{1655, -120},
{1630, -100},
{1603, -80},
{1574, -60},
{1543, -40},
{1510, -20},
{1475, 0},
{1438, 20},
{1400, 40},
{1360, 60},
{1318, 80},
{1276, 100},
{1232, 120},
{1187, 140},
{1142, 160},
{1097, 180},
{1051, 200},
{1005, 220},
{960, 240},
{915, 260},
{871, 280},
{828, 300},
{786, 320},
{745, 340},
{705, 360},
{666, 380},
{629, 400},
{594, 420},
{560, 440},
{527, 460},
{497, 480},
{467, 500},
{439, 520},
{413, 540},
{388, 560},
{365, 580},
{343, 600},
{322, 620},
{302, 640},
{284, 660},
{267, 680},
{251, 700},
{235, 720},
{221, 740},
{208, 760},
{195, 780},
{184, 800},
{173, 820},
{163, 840},
{153, 860},
{144, 880},
{136, 900},
{128, 920},
{120, 940},
{114, 960},
{107, 980}
};
/*
* Voltage to temperature table for 100k pull up for bat_therm with
* MLP356477.
*/
static const struct vadc_map_pt adcmap_batt_therm_100k_6125[] = {
{1770, -400},
{1757, -380},
{1743, -360},
{1727, -340},
{1710, -320},
{1691, -300},
{1671, -280},
{1650, -260},
{1627, -240},
{1602, -220},
{1576, -200},
{1548, -180},
{1519, -160},
{1488, -140},
{1456, -120},
{1423, -100},
{1388, -80},
{1353, -60},
{1316, -40},
{1278, -20},
{1240, 0},
{1201, 20},
{1162, 40},
{1122, 60},
{1082, 80},
{1042, 100},
{1003, 120},
{964, 140},
{925, 160},
{887, 180},
{849, 200},
{812, 220},
{777, 240},
{742, 260},
{708, 280},
{675, 300},
{643, 320},
{613, 340},
{583, 360},
{555, 380},
{528, 400},
{502, 420},
{477, 440},
{453, 460},
{430, 480},
{409, 500},
{388, 520},
{369, 540},
{350, 560},
{333, 580},
{316, 600},
{300, 620},
{285, 640},
{271, 660},
{257, 680},
{245, 700},
{233, 720},
{221, 740},
{210, 760},
{200, 780},
{190, 800},
{181, 820},
{173, 840},
{164, 860},
{157, 880},
{149, 900},
{142, 920},
{136, 940},
{129, 960},
{124, 980},
};
/*
* Voltage to temperature table for 30k pull up for bat_therm with
* Alium.
*/
static const struct vadc_map_pt adcmap_batt_therm_30k[] = {
{1864, -400},
{1863, -380},
{1861, -360},
{1858, -340},
{1856, -320},
{1853, -300},
{1850, -280},
{1846, -260},
{1842, -240},
{1837, -220},
{1831, -200},
{1825, -180},
{1819, -160},
{1811, -140},
{1803, -120},
{1794, -100},
{1784, -80},
{1773, -60},
{1761, -40},
{1748, -20},
{1734, 0},
{1718, 20},
{1702, 40},
{1684, 60},
{1664, 80},
{1643, 100},
{1621, 120},
{1597, 140},
{1572, 160},
{1546, 180},
{1518, 200},
{1489, 220},
{1458, 240},
{1426, 260},
{1393, 280},
{1359, 300},
{1324, 320},
{1288, 340},
{1252, 360},
{1214, 380},
{1176, 400},
{1138, 420},
{1100, 440},
{1061, 460},
{1023, 480},
{985, 500},
{947, 520},
{910, 540},
{873, 560},
{836, 580},
{801, 600},
{766, 620},
{732, 640},
{699, 660},
{668, 680},
{637, 700},
{607, 720},
{578, 740},
{550, 760},
{524, 780},
{498, 800},
{474, 820},
{451, 840},
{428, 860},
{407, 880},
{387, 900},
{367, 920},
{349, 940},
{332, 960},
{315, 980}
};
/*
* Voltage to temperature table for 30k pull up for bat_therm with
* MLP356477.
*/
static const struct vadc_map_pt adcmap_batt_therm_30k_6125[] = {
{1842, -400},
{1838, -380},
{1833, -360},
{1828, -340},
{1822, -320},
{1816, -300},
{1809, -280},
{1801, -260},
{1793, -240},
{1784, -220},
{1774, -200},
{1763, -180},
{1752, -160},
{1739, -140},
{1726, -120},
{1712, -100},
{1697, -80},
{1680, -60},
{1663, -40},
{1645, -20},
{1625, 0},
{1605, 20},
{1583, 40},
{1561, 60},
{1537, 80},
{1513, 100},
{1487, 120},
{1461, 140},
{1433, 160},
{1405, 180},
{1376, 200},
{1347, 220},
{1316, 240},
{1286, 260},
{1254, 280},
{1223, 300},
{1191, 320},
{1159, 340},
{1126, 360},
{1094, 380},
{1062, 400},
{1029, 420},
{997, 440},
{966, 460},
{934, 480},
{903, 500},
{873, 520},
{843, 540},
{813, 560},
{784, 580},
{756, 600},
{728, 620},
{702, 640},
{675, 660},
{650, 680},
{625, 700},
{601, 720},
{578, 740},
{556, 760},
{534, 780},
{513, 800},
{493, 820},
{474, 840},
{455, 860},
{437, 880},
{420, 900},
{403, 920},
{387, 940},
{372, 960},
{357, 980},
};
/*
* Voltage to temperature table for 400k pull up for bat_therm with
* Alium.
*/
static const struct vadc_map_pt adcmap_batt_therm_400k[] = {
{1744, -400},
{1724, -380},
{1701, -360},
{1676, -340},
{1648, -320},
{1618, -300},
{1584, -280},
{1548, -260},
{1509, -240},
{1468, -220},
{1423, -200},
{1377, -180},
{1328, -160},
{1277, -140},
{1225, -120},
{1171, -100},
{1117, -80},
{1062, -60},
{1007, -40},
{953, -20},
{899, 0},
{847, 20},
{795, 40},
{745, 60},
{697, 80},
{651, 100},
{607, 120},
{565, 140},
{526, 160},
{488, 180},
{453, 200},
{420, 220},
{390, 240},
{361, 260},
{334, 280},
{309, 300},
{286, 320},
{265, 340},
{245, 360},
{227, 380},
{210, 400},
{195, 420},
{180, 440},
{167, 460},
{155, 480},
{144, 500},
{133, 520},
{124, 540},
{115, 560},
{107, 580},
{99, 600},
{92, 620},
{86, 640},
{80, 660},
{75, 680},
{70, 700},
{65, 720},
{61, 740},
{57, 760},
{53, 780},
{50, 800},
{46, 820},
{43, 840},
{41, 860},
{38, 880},
{36, 900},
{34, 920},
{32, 940},
{30, 960},
{28, 980}
};
/*
* Voltage to temperature table for 400k pull up for bat_therm with
* MLP356477.
*/
static const struct vadc_map_pt adcmap_batt_therm_400k_6125[] = {
{1516, -400},
{1478, -380},
{1438, -360},
{1396, -340},
{1353, -320},
{1307, -300},
{1261, -280},
{1213, -260},
{1164, -240},
{1115, -220},
{1066, -200},
{1017, -180},
{968, -160},
{920, -140},
{872, -120},
{826, -100},
{781, -80},
{737, -60},
{694, -40},
{654, -20},
{615, 0},
{578, 20},
{542, 40},
{509, 60},
{477, 80},
{447, 100},
{419, 120},
{392, 140},
{367, 160},
{343, 180},
{321, 200},
{301, 220},
{282, 240},
{264, 260},
{247, 280},
{231, 300},
{216, 320},
{203, 340},
{190, 360},
{178, 380},
{167, 400},
{157, 420},
{147, 440},
{138, 460},
{130, 480},
{122, 500},
{115, 520},
{108, 540},
{102, 560},
{96, 580},
{90, 600},
{85, 620},
{80, 640},
{76, 660},
{72, 680},
{68, 700},
{64, 720},
{61, 740},
{57, 760},
{54, 780},
{52, 800},
{49, 820},
{46, 840},
{44, 860},
{42, 880},
{40, 900},
{38, 920},
{36, 940},
{34, 960},
{32, 980},
};
struct lut_table {
const struct vadc_map_pt *table;
u32 tablesize;
};
static const struct lut_table lut_table_30[] = {
{adcmap_batt_therm_30k, ARRAY_SIZE(adcmap_batt_therm_30k)},
{adcmap_batt_therm_30k_6125, ARRAY_SIZE(adcmap_batt_therm_30k_6125)},
};
static const struct lut_table lut_table_100[] = {
{adcmap_batt_therm_100k, ARRAY_SIZE(adcmap_batt_therm_100k)},
{adcmap_batt_therm_100k_6125, ARRAY_SIZE(adcmap_batt_therm_100k_6125)},
};
static const struct lut_table lut_table_400[] = {
{adcmap_batt_therm_400k, ARRAY_SIZE(adcmap_batt_therm_400k)},
{adcmap_batt_therm_400k_6125, ARRAY_SIZE(adcmap_batt_therm_400k_6125)},
};
static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts,
u32 tablesize, s32 input, s64 *output)
{
@@ -191,6 +714,271 @@ static int qcom_vadc_scale_chg_temp(const struct vadc_linear_graph *calib_graph,
return 0;
}
static int qcom_vadc_scale_hw_calib_volt(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
u16 adc_code, int *result_uv)
{
s64 voltage = 0, result = 0, adc_vdd_ref_mv = 1875;
if (adc_code > VADC5_MAX_CODE)
adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
voltage = div64_s64(voltage, data->full_scale_code_volt);
voltage = voltage * prescale->den;
result = div64_s64(voltage, prescale->num);
*result_uv = result;
return 0;
}
static int qcom_vadc_scale_hw_calib_therm(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
u16 adc_code, int *result_mdec)
{
s64 voltage = 0, result = 0, adc_vdd_ref_mv = 1875;
int ret;
if (adc_code > VADC5_MAX_CODE)
adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
voltage = div64_s64(voltage, (data->full_scale_code_volt
* 1000));
ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
voltage, &result);
if (ret)
return ret;
*result_mdec = result;
return 0;
}
static int qcom_vadc_scale_hw_calib_batt_therm_100(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
unsigned int lut_index,
u16 adc_code, int *result_mdec)
{
s64 voltage = 0, result = 0, adc_vdd_ref_mv = 1875;
int ret;
u32 size;
const struct vadc_map_pt *lut;
if (lut_index >= ARRAY_SIZE(lut_table_100)) {
pr_err("LUT index out of range\n");
return -EINVAL;
}
if (adc_code > VADC5_MAX_CODE)
adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
voltage = div64_s64(voltage, (data->full_scale_code_volt
* 1000));
lut = lut_table_100[lut_index].table;
size = lut_table_100[lut_index].tablesize;
ret = qcom_vadc_map_voltage_temp(lut, size, voltage, &result);
if (ret)
return ret;
*result_mdec = result;
return 0;
}
static int qcom_vadc_scale_hw_calib_batt_therm_30(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
unsigned int lut_index,
u16 adc_code, int *result_mdec)
{
s64 voltage = 0, result = 0, adc_vdd_ref_mv = 1875;
int ret;
u32 size;
const struct vadc_map_pt *lut;
if (lut_index >= ARRAY_SIZE(lut_table_30)) {
pr_err("LUT index out of range\n");
return -EINVAL;
}
if (adc_code > VADC5_MAX_CODE)
adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
voltage = div64_s64(voltage, (data->full_scale_code_volt
* 1000));
lut = lut_table_30[lut_index].table;
size = lut_table_30[lut_index].tablesize;
ret = qcom_vadc_map_voltage_temp(lut, size, voltage, &result);
if (ret)
return ret;
*result_mdec = result;
return 0;
}
static int qcom_vadc_scale_hw_calib_batt_therm_400(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
unsigned int lut_index,
u16 adc_code, int *result_mdec)
{
s64 voltage = 0, result = 0, adc_vdd_ref_mv = 1875;
int ret;
u32 size;
const struct vadc_map_pt *lut;
if (lut_index >= ARRAY_SIZE(lut_table_400)) {
pr_err("LUT index out of range\n");
return -EINVAL;
}
if (adc_code > VADC5_MAX_CODE)
adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
voltage = div64_s64(voltage, (data->full_scale_code_volt
* 1000));
lut = lut_table_400[lut_index].table;
size = lut_table_400[lut_index].tablesize;
ret = qcom_vadc_map_voltage_temp(lut, size, voltage, &result);
if (ret)
return ret;
*result_mdec = result;
return 0;
}
static int qcom_vadc_scale_hw_calib_die_temp(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
u16 adc_code, int *result_mdec)
{
s64 voltage = 0, adc_vdd_ref_mv = 1875;
u64 temp; /* Temporary variable for do_div */
if (adc_code > VADC5_MAX_CODE)
adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
voltage = div64_s64(voltage, data->full_scale_code_volt);
if (voltage > 0) {
temp = voltage * prescale->den;
do_div(temp, prescale->num * 2);
voltage = temp;
} else {
voltage = 0;
}
voltage -= KELVINMIL_CELSIUSMIL;
*result_mdec = voltage;
return 0;
}
static int qcom_vadc_scale_hw_smb_temp(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
u16 adc_code, int *result_mdec)
{
s64 voltage = 0, adc_vdd_ref_mv = 1875;
u64 temp;
if (adc_code > VADC5_MAX_CODE)
adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
voltage = div64_s64(voltage, data->full_scale_code_volt);
if (voltage > 0) {
temp = voltage * prescale->den;
temp *= 100;
do_div(temp, prescale->num * PMIC5_SMB_TEMP_SCALE_FACTOR);
voltage = temp;
} else {
voltage = 0;
}
voltage = PMIC5_SMB_TEMP_CONSTANT - voltage;
*result_mdec = voltage;
return 0;
}
static int qcom_vadc_scale_hw_chg5_temp(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
u16 adc_code, int *result_mdec)
{
s64 voltage = 0, adc_vdd_ref_mv = 1875;
u64 temp;
if (adc_code > VADC5_MAX_CODE)
adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
voltage = div64_s64(voltage, data->full_scale_code_volt);
if (voltage > 0) {
temp = voltage * prescale->den;
do_div(temp, prescale->num * 4);
voltage = temp;
} else {
voltage = 0;
}
voltage = PMIC5_CHG_TEMP_SCALE_FACTOR - voltage;
*result_mdec = voltage;
return 0;
}
static int qcom_adc_scale_hw_calib_cur(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
u16 adc_code, int *result_uamps)
{
s64 voltage = 0, result = 0;
if ((adc_code & ADC_USR_DATA_CHECK) == 0) {
voltage = (s64) adc_code * data->full_scale_code_cur * 1000;
voltage = div64_s64(voltage, VADC5_MAX_CODE);
voltage = voltage * prescale->den;
result = div64_s64(voltage, prescale->num);
*result_uamps = result;
} else {
adc_code = ~adc_code + 1;
voltage = (s64) adc_code;
voltage = (s64) adc_code * data->full_scale_code_cur * 1000;
voltage = div64_s64(voltage, VADC5_MAX_CODE);
voltage = voltage * prescale->den;
result = div64_s64(voltage, prescale->num);
*result_uamps = -result;
}
return 0;
}
int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
const struct vadc_linear_graph *calib_graph,
const struct vadc_prescale_ratio *prescale,
@@ -221,6 +1009,46 @@ int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
}
EXPORT_SYMBOL(qcom_vadc_scale);
int qcom_vadc_hw_scale(enum vadc_scale_fn_type scaletype,
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data, unsigned int lut_index,
u16 adc_code, int *result)
{
switch (scaletype) {
case SCALE_HW_CALIB_DEFAULT:
return qcom_vadc_scale_hw_calib_volt(prescale, data,
adc_code, result);
case SCALE_HW_CALIB_THERM_100K_PULLUP:
case SCALE_HW_CALIB_XOTHERM:
return qcom_vadc_scale_hw_calib_therm(prescale, data,
adc_code, result);
case SCALE_HW_CALIB_BATT_THERM_100K:
return qcom_vadc_scale_hw_calib_batt_therm_100(prescale,
data, lut_index, adc_code, result);
case SCALE_HW_CALIB_BATT_THERM_30K:
return qcom_vadc_scale_hw_calib_batt_therm_30(prescale,
data, lut_index, adc_code, result);
case SCALE_HW_CALIB_BATT_THERM_400K:
return qcom_vadc_scale_hw_calib_batt_therm_400(prescale,
data, lut_index, adc_code, result);
case SCALE_HW_CALIB_PMIC_THERM:
return qcom_vadc_scale_hw_calib_die_temp(prescale, data,
adc_code, result);
case SCALE_HW_CALIB_CUR:
return qcom_adc_scale_hw_calib_cur(prescale, data,
adc_code, result);
case SCALE_HW_CALIB_PM5_CHG_TEMP:
return qcom_vadc_scale_hw_chg5_temp(prescale, data,
adc_code, result);
case SCALE_HW_CALIB_PM5_SMB_TEMP:
return qcom_vadc_scale_hw_smb_temp(prescale, data,
adc_code, result);
default:
return -EINVAL;
}
}
EXPORT_SYMBOL(qcom_vadc_hw_scale);
int qcom_vadc_decimation_from_dt(u32 value)
{
if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN ||
@@ -231,5 +1059,17 @@ int qcom_vadc_decimation_from_dt(u32 value)
}
EXPORT_SYMBOL(qcom_vadc_decimation_from_dt);
int qcom_adc5_decimation_from_dt(u32 value, const unsigned int *decimation)
{
uint32_t i;
for (i = 0; i < ADC_DECIMATION_SAMPLES_MAX; i++) {
if (value == decimation[i])
return i;
}
return -EINVAL;
}
EXPORT_SYMBOL(qcom_adc5_decimation_from_dt);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Qualcomm ADC common functionality");

View File

@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Code shared between the different Qualcomm PMIC voltage ADCs
*/
@@ -22,18 +22,36 @@
#define VADC_DEF_HW_SETTLE_TIME 0 /* 0 us */
#define VADC_DEF_AVG_SAMPLES 0 /* 1 sample */
#define VADC_DEF_CALIB_TYPE VADC_CALIB_ABSOLUTE
#define VADC_DEF_VBAT_PRESCALING 1 /* 1:3 */
#define VADC_DEF_LUT_INDEX 0 /* Default or no LUT used */
#define VADC_DECIMATION_MIN 512
#define VADC_DECIMATION_MAX 4096
#define ADC5_DECIMATION_SHORT 250
#define ADC5_DECIMATION_MEDIUM 420
#define ADC5_DECIMATION_LONG 840
/* Default decimation - 1024 for rev2, 840 for pmic5 */
#define ADC_DECIMATION_DEFAULT 2
#define ADC_DECIMATION_SAMPLES_MAX 3
#define VADC_HW_SETTLE_DELAY_MAX 10000
#define VADC_HW_SETTLE_SAMPLES_MAX 16
#define VADC_AVG_SAMPLES_MAX 512
#define ADC5_AVG_SAMPLES_MAX 16
#define KELVINMIL_CELSIUSMIL 273150
#define PMIC5_CHG_TEMP_SCALE_FACTOR 377500
#define PMIC5_SMB_TEMP_CONSTANT 419400
#define PMIC5_SMB_TEMP_SCALE_FACTOR 356
#define PMI_CHG_SCALE_1 -138890
#define PMI_CHG_SCALE_2 391750000000LL
#define VADC5_MAX_CODE 0x7fff
#define VADC5_FULL_SCALE_CODE 0x70e4
#define ADC_USR_DATA_CHECK 0x8000
/**
* struct vadc_map_pt - Map the graph representation for ADC channel
* @x: Represent the ADC digitized code.
@@ -89,6 +107,28 @@ struct vadc_prescale_ratio {
* SCALE_PMIC_THERM: Returns result in milli degree's Centigrade.
* SCALE_XOTHERM: Returns XO thermistor voltage in millidegC.
* SCALE_PMI_CHG_TEMP: Conversion for PMI CHG temp
* SCALE_HW_CALIB_DEFAULT: Default scaling to convert raw adc code to
* voltage (uV) with hardware applied offset/slope values to adc code.
* SCALE_HW_CALIB_THERM_100K_PULLUP: Returns temperature in millidegC using
* lookup table. The hardware applies offset/slope to adc code.
* SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using
* 100k pullup. The hardware applies offset/slope to adc code.
* SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
* The hardware applies offset/slope to adc code.
* SCALE_HW_CALIB_CUR: Returns result in uA for PMIC5.
* SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5
* charger temperature.
* SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5
* SMB1390 temperature.
* SCALE_HW_CALIB_BATT_THERM_100K: Returns battery thermistor voltage in
* decidegC using 100k pullup. The hardware applies offset/slope to adc
* code.
* SCALE_HW_CALIB_BATT_THERM_30K: Returns battery thermistor voltage in
* decidegC using 30k pullup. The hardware applies offset/slope to adc
* code.
* SCALE_HW_CALIB_BATT_THERM_400K: Returns battery thermistor voltage in
* decidegC using 400k pullup. The hardware applies offset/slope to adc
* code.
*/
enum vadc_scale_fn_type {
SCALE_DEFAULT = 0,
@@ -96,6 +136,24 @@ enum vadc_scale_fn_type {
SCALE_PMIC_THERM,
SCALE_XOTHERM,
SCALE_PMI_CHG_TEMP,
SCALE_HW_CALIB_DEFAULT,
SCALE_HW_CALIB_THERM_100K_PULLUP,
SCALE_HW_CALIB_XOTHERM,
SCALE_HW_CALIB_PMIC_THERM,
SCALE_HW_CALIB_CUR,
SCALE_HW_CALIB_PM5_CHG_TEMP,
SCALE_HW_CALIB_PM5_SMB_TEMP,
SCALE_HW_CALIB_BATT_THERM_100K,
SCALE_HW_CALIB_BATT_THERM_30K,
SCALE_HW_CALIB_BATT_THERM_400K,
};
struct adc_data {
const u32 full_scale_code_volt;
const u32 full_scale_code_cur;
const struct adc_channels *adc_chans;
unsigned int *decimation;
unsigned int *hw_settle;
};
int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
@@ -104,6 +162,13 @@ int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
bool absolute,
u16 adc_code, int *result_mdec);
int qcom_vadc_hw_scale(enum vadc_scale_fn_type scaletype,
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data, unsigned int lut_index,
u16 adc_code, int *result_mdec);
int qcom_vadc_decimation_from_dt(u32 value);
int qcom_adc5_decimation_from_dt(u32 value, const unsigned int *decimation);
#endif /* QCOM_VADC_COMMON_H */