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 <[email protected]>
---
 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 aa21b032e861..3ae091fa93d7 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.51.0


Reply via email to