iio: adc: Add missing features in PMIC5 ADC

Add the following PMIC5 ADC features:
Update ADC polling time delay for end of conversion (EOC) to match
values on kernel 4.19.
Add missing channels in driver's channel list (bat_therm, bat_id
and some thermistor channels), which may be needed by PMIC5 clients.
Add scaling functions for bat_therm and smb_therm.

Change-Id: I0612560513fbb3f29ff3fda6ad86b939f190410e
Signed-off-by: Jishnu Prakash <jprakash@codeaurora.org>
[quic_subbaram@quicinc.com: Fixed trivial merge conflict in
 qcom-spmi-adc5.c and in qcom-vadc-common.h due to location change]
Signed-off-by: Subbaraman Narayanamurthy <quic_subbaram@quicinc.com>
[quic_collinsd@quicinc.com: changed struct vadc_prescale_ratio to
 struct u32_fract]
Signed-off-by: David Collins <quic_collinsd@quicinc.com>
This commit is contained in:
Jishnu Prakash 2020-04-07 13:41:56 +05:30 committed by David Collins
parent ec8afe7e56
commit 2b64262524
3 changed files with 366 additions and 10 deletions

View File

@ -75,9 +75,10 @@
* samples and measurements queued across different VADC peripherals.
* Set the timeout to a max of 100ms.
*/
#define ADC5_CONV_TIME_MIN_US 263
#define ADC5_CONV_TIME_MAX_US 264
#define ADC5_CONV_TIME_RETRY 400
#define ADC5_POLL_DELAY_MIN_US 10000
#define ADC5_POLL_DELAY_MAX_US 10001
#define ADC5_CONV_TIME_RETRY_POLL 40
#define ADC5_CONV_TIME_RETRY 30
#define ADC5_CONV_TIMEOUT msecs_to_jiffies(100)
/* Digital version >= 5.3 supports hw_settle_2 */
@ -195,12 +196,17 @@ static int adc5_read_voltage_data(struct adc5_chip *adc, u16 *data)
return 0;
}
static int adc5_poll_wait_eoc(struct adc5_chip *adc)
static int adc5_poll_wait_eoc(struct adc5_chip *adc, bool poll_only)
{
unsigned int count, retry = ADC5_CONV_TIME_RETRY;
u8 status1;
int ret;
if (poll_only)
retry = ADC5_CONV_TIME_RETRY_POLL;
else
retry = ADC5_CONV_TIME_RETRY;
for (count = 0; count < retry; count++) {
ret = adc5_read(adc, ADC5_USR_STATUS1, &status1,
sizeof(status1));
@ -211,7 +217,7 @@ static int adc5_poll_wait_eoc(struct adc5_chip *adc)
if (status1 == ADC5_USR_STATUS1_EOC)
return 0;
usleep_range(ADC5_CONV_TIME_MIN_US, ADC5_CONV_TIME_MAX_US);
usleep_range(ADC5_POLL_DELAY_MIN_US, ADC5_POLL_DELAY_MAX_US);
}
return -ETIMEDOUT;
@ -327,7 +333,7 @@ static int adc5_do_conversion(struct adc5_chip *adc,
}
if (adc->poll_eoc) {
ret = adc5_poll_wait_eoc(adc);
ret = adc5_poll_wait_eoc(adc, true);
if (ret) {
dev_err(adc->dev, "EOC bit not set\n");
goto unlock;
@ -337,7 +343,7 @@ static int adc5_do_conversion(struct adc5_chip *adc,
ADC5_CONV_TIMEOUT);
if (!ret) {
dev_dbg(adc->dev, "Did not get completion timeout.\n");
ret = adc5_poll_wait_eoc(adc);
ret = adc5_poll_wait_eoc(adc, false);
if (ret) {
dev_err(adc->dev, "EOC bit not set\n");
goto unlock;
@ -541,14 +547,32 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
SCALE_HW_CALIB_DEFAULT)
[ADC5_XO_THERM_100K_PU] = ADC5_CHAN_TEMP("xo_therm", 0,
SCALE_HW_CALIB_XOTHERM)
[ADC5_BAT_THERM_100K_PU] = ADC5_CHAN_TEMP("bat_therm_100k_pu", 0,
SCALE_HW_CALIB_BATT_THERM_100K)
[ADC5_BAT_THERM_30K_PU] = ADC5_CHAN_TEMP("bat_therm_30k_pu", 0,
SCALE_HW_CALIB_BATT_THERM_30K)
[ADC5_BAT_THERM_400K_PU] = ADC5_CHAN_TEMP("bat_therm_400k_pu", 0,
SCALE_HW_CALIB_BATT_THERM_400K)
[ADC5_BAT_ID_100K_PU] = ADC5_CHAN_TEMP("bat_id", 0,
SCALE_HW_CALIB_DEFAULT)
[ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 0,
SCALE_HW_CALIB_THERM_100K_PULLUP)
[ADC5_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_100k_pu", 0,
SCALE_HW_CALIB_THERM_100K_PULLUP)
[ADC5_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_100k_pu", 0,
SCALE_HW_CALIB_THERM_100K_PULLUP)
[ADC5_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_100k_pu", 0,
SCALE_HW_CALIB_THERM_100K_PULLUP)
[ADC5_AMUX_THM2] = ADC5_CHAN_TEMP("amux_thm2", 0,
SCALE_HW_CALIB_PM5_SMB_TEMP)
[ADC5_GPIO1_100K_PU] = ADC5_CHAN_TEMP("gpio1_100k_pu", 0,
SCALE_HW_CALIB_THERM_100K_PULLUP)
[ADC5_GPIO2_100K_PU] = ADC5_CHAN_TEMP("gpio2_100k_pu", 0,
SCALE_HW_CALIB_THERM_100K_PULLUP)
[ADC5_GPIO3_100K_PU] = ADC5_CHAN_TEMP("gpio3_100k_pu", 0,
SCALE_HW_CALIB_THERM_100K_PULLUP)
[ADC5_GPIO4_100K_PU] = ADC5_CHAN_TEMP("gpio4_100k_pu", 0,
SCALE_HW_CALIB_THERM_100K_PULLUP)
};
static const struct adc5_channels adc7_chans_pmic[ADC5_MAX_CHANNEL] = {

View File

@ -100,6 +100,237 @@ static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
{ 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 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 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}
};
static const struct vadc_map_pt adcmap7_die_temp[] = {
{ 857300, 160000 },
{ 820100, 140000 },
@ -309,6 +540,18 @@ static int qcom_vadc_scale_hw_calib_therm(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec);
static int qcom_vadc_scale_hw_calib_batt_therm_100(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec);
static int qcom_vadc_scale_hw_calib_batt_therm_30(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec);
static int qcom_vadc_scale_hw_calib_batt_therm_400(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec);
static int qcom_vadc7_scale_hw_calib_therm(
const struct u32_fract *prescale,
const struct adc5_data *data,
@ -317,6 +560,10 @@ static int qcom_vadc_scale_hw_smb_temp(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec);
static int qcom_vadc_scale_hw_smb1398_temp(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec);
static int qcom_vadc_scale_hw_chg5_temp(
const struct u32_fract *prescale,
const struct adc5_data *data,
@ -333,6 +580,12 @@ static int qcom_vadc7_scale_hw_calib_die_temp(
static struct qcom_adc5_scale_type scale_adc5_fn[] = {
[SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
[SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
[SCALE_HW_CALIB_BATT_THERM_100K] = {
qcom_vadc_scale_hw_calib_batt_therm_100},
[SCALE_HW_CALIB_BATT_THERM_30K] = {
qcom_vadc_scale_hw_calib_batt_therm_30},
[SCALE_HW_CALIB_BATT_THERM_400K] = {
qcom_vadc_scale_hw_calib_batt_therm_400},
[SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
[SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
qcom_vadc7_scale_hw_calib_therm},
@ -341,6 +594,7 @@ static struct qcom_adc5_scale_type scale_adc5_fn[] = {
qcom_vadc7_scale_hw_calib_die_temp},
[SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp},
[SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp},
[SCALE_HW_CALIB_PM5_SMB1398_TEMP] = {qcom_vadc_scale_hw_smb1398_temp},
};
static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts,
@ -583,6 +837,54 @@ static int qcom_vadc_scale_hw_calib_therm(
voltage, result_mdec);
}
static int qcom_vadc_scale_hw_calib_batt_therm_100(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec)
{
int voltage;
voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
prescale, data, 1000);
/* Map voltage to temperature from look-up table */
return qcom_vadc_map_voltage_temp(adcmap_batt_therm_100k,
ARRAY_SIZE(adcmap_batt_therm_100k),
voltage, result_mdec);
}
static int qcom_vadc_scale_hw_calib_batt_therm_30(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec)
{
int voltage;
voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
prescale, data, 1000);
/* Map voltage to temperature from look-up table */
return qcom_vadc_map_voltage_temp(adcmap_batt_therm_30k,
ARRAY_SIZE(adcmap_batt_therm_30k),
voltage, result_mdec);
}
static int qcom_vadc_scale_hw_calib_batt_therm_400(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec)
{
int voltage;
voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
prescale, data, 1000);
/* Map voltage to temperature from look-up table */
return qcom_vadc_map_voltage_temp(adcmap_batt_therm_400k,
ARRAY_SIZE(adcmap_batt_therm_400k),
voltage, result_mdec);
}
static int qcom_vadc_scale_hw_calib_die_temp(
const struct u32_fract *prescale,
const struct adc5_data *data,
@ -622,6 +924,18 @@ static int qcom_vadc_scale_hw_smb_temp(
return 0;
}
static int qcom_vadc_scale_hw_smb1398_temp(
const struct u32_fract *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec)
{
*result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code * 100,
prescale, data, PMIC5_SMB1398_TEMP_SCALE_FACTOR);
*result_mdec = PMIC5_SMB1398_TEMP_CONSTANT - *result_mdec;
return 0;
}
static int qcom_vadc_scale_hw_chg5_temp(
const struct u32_fract *prescale,
const struct adc5_data *data,

View File

@ -44,6 +44,8 @@
#define PMIC5_CHG_TEMP_SCALE_FACTOR 377500
#define PMIC5_SMB_TEMP_CONSTANT 419400
#define PMIC5_SMB_TEMP_SCALE_FACTOR 356
#define PMIC5_SMB1398_TEMP_CONSTANT 268235
#define PMIC5_SMB1398_TEMP_SCALE_FACTOR 340
#define PMI_CHG_SCALE_1 -138890
#define PMI_CHG_SCALE_2 391750000000LL
@ -99,12 +101,23 @@ struct vadc_linear_graph {
* lookup table for PMIC7. 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_PMIC_THERM: Returns result in milli degree's Centigrade.
* SCALE_HW_CALIB_PMIC_THERM_PM7: Returns result in milli degree's Centigrade.
* The hardware applies offset/slope to adc code. This is for PMIC7.
* 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.
* SCALE_HW_CALIB_PM5_SMB1398_TEMP: Returns result in millidegrees for PMIC5
* SMB1398 temperature.
*/
enum vadc_scale_fn_type {
SCALE_DEFAULT = 0,
@ -115,11 +128,16 @@ enum vadc_scale_fn_type {
SCALE_HW_CALIB_DEFAULT,
SCALE_HW_CALIB_THERM_100K_PULLUP,
SCALE_HW_CALIB_XOTHERM,
SCALE_HW_CALIB_THERM_100K_PU_PM7,
SCALE_HW_CALIB_PMIC_THERM,
SCALE_HW_CALIB_PMIC_THERM_PM7,
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,
SCALE_HW_CALIB_PM5_SMB1398_TEMP,
SCALE_HW_CALIB_THERM_100K_PU_PM7,
SCALE_HW_CALIB_PMIC_THERM_PM7,
SCALE_HW_CALIB_INVALID,
};