[PATCH v2 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels

Luca Weiss
2026-02-20T09:19:14Z

Add the BAT_THERM channels with millivolt as output, which can then be
used along with information regarding the NTC in the battery, to get the
actual battery temperature.

A static lookup table in the ADC driver won't work since different
devices have different Ohm and Beta values in their battery NTCs, for
example a NTC can be 10kOhm & B=3435K.

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
drivers/iio/adc/qcom-spmi-adc5.c | 6 ++++++
drivers/iio/adc/qcom-vadc-common.c | 16 ++++++++++++++++
include/linux/iio/adc/qcom-vadc-common.h | 3 +++
3 files changed, 25 insertions(+)

diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c
index af3c2f659f5e..6ad75368d3a3 100644
--- a/drivers/iio/adc/qcom-spmi-adc5.c
+++ b/drivers/iio/adc/qcom-spmi-adc5.c
@@ -543,6 +543,12 @@ 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_30K_PU] = ADC5_CHAN_VOLT("bat_therm_30k_pu", 0,
+ SCALE_HW_CALIB_THERM_VOLT)
+ [ADC5_BAT_THERM_100K_PU] = ADC5_CHAN_VOLT("bat_therm_100k_pu", 0,
+ SCALE_HW_CALIB_THERM_VOLT)
+ [ADC5_BAT_THERM_400K_PU] = ADC5_CHAN_VOLT("bat_therm_400k_pu", 0,
+ SCALE_HW_CALIB_THERM_VOLT)
[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,
diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c
index b03cf584b165..09a13e2b0ef4 100644
--- a/drivers/iio/adc/qcom-vadc-common.c
+++ b/drivers/iio/adc/qcom-vadc-common.c
@@ -309,6 +309,10 @@ 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_therm_volt(
+ 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,
@@ -333,6 +337,7 @@ static int qcom_vadc7_scale_hw_calib_die_temp(
static const 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_THERM_VOLT] = {qcom_vadc_scale_hw_calib_therm_volt},
[SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
[SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
qcom_vadc7_scale_hw_calib_therm},
@@ -583,6 +588,17 @@ static int qcom_vadc_scale_hw_calib_therm(
voltage, result_mdec);
}

+static int qcom_vadc_scale_hw_calib_therm_volt(
+ const struct u32_fract *prescale,
+ const struct adc5_data *data,
+ u16 adc_code, int *result_uv)
+{
+ *result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
+ prescale, data, 1000);
+
+ return 0;
+}
+
static int qcom_vadc_scale_hw_calib_die_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 3bf4c49726a7..ce037994b019 100644
--- a/include/linux/iio/adc/qcom-vadc-common.h
+++ b/include/linux/iio/adc/qcom-vadc-common.h
@@ -93,6 +93,8 @@ struct vadc_linear_graph {
* 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_THERM_VOLT: Returns voltage in uV of a temperature channel.
+ * 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_THERM_100K_PU_PM7: Returns temperature in millidegC using
@@ -114,6 +116,7 @@ enum vadc_scale_fn_type {
SCALE_PMI_CHG_TEMP,
SCALE_HW_CALIB_DEFAULT,
SCALE_HW_CALIB_THERM_100K_PULLUP,
+ SCALE_HW_CALIB_THERM_VOLT,
SCALE_HW_CALIB_XOTHERM,
SCALE_HW_CALIB_THERM_100K_PU_PM7,
SCALE_HW_CALIB_PMIC_THERM,

--
2.53.0