diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c index 87438d1e5c0b..3b602a2ffaa3 100644 --- a/drivers/iio/adc/qcom-spmi-adc5.c +++ b/drivers/iio/adc/qcom-spmi-adc5.c @@ -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] = { diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c index 6c6aec848f98..99ef49e191a4 100644 --- a/drivers/iio/adc/qcom-vadc-common.c +++ b/drivers/iio/adc/qcom-vadc-common.c @@ -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, diff --git a/include/linux/iio/adc/qcom-vadc-common.h b/include/linux/iio/adc/qcom-vadc-common.h index ce78d4804994..ba6eaa113e22 100644 --- a/include/linux/iio/adc/qcom-vadc-common.h +++ b/include/linux/iio/adc/qcom-vadc-common.h @@ -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, };