aboutsummaryrefslogtreecommitdiff
path: root/drivers/iio
diff options
context:
space:
mode:
authorDmitry Baryshkov <dmitry.baryshkov@linaro.org>2021-02-05 03:01:18 +0300
committerDaniel Lezcano <daniel.lezcano@linaro.org>2021-02-15 21:28:53 +0100
commitca66dca5eda6bd16b7b27fed2a034f2396df5627 (patch)
tree92e7a4119620f5226d4f6cd3867c6b7b9729b524 /drivers/iio
parente8ffd6c0756bd81f069dd67ea47e6908c791e742 (diff)
thermal: qcom: add support for adc-tm5 PMIC thermal monitor
Add support for Thermal Monitoring part of PMIC5. This part is closely coupled with ADC, using it's channels directly. ADC-TM support generating interrupts on ADC value crossing low or high voltage bounds, which is used to support thermal trip points. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lore.kernel.org/r/20210205000118.493610-3-dmitry.baryshkov@linaro.org
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/adc/qcom-vadc-common.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c
index 8682cf1e213f..14723896aab2 100644
--- a/drivers/iio/adc/qcom-vadc-common.c
+++ b/drivers/iio/adc/qcom-vadc-common.c
@@ -368,6 +368,28 @@ static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts,
return 0;
}
+static s32 qcom_vadc_map_temp_voltage(const struct vadc_map_pt *pts,
+ u32 tablesize, int input)
+{
+ u32 i = 0;
+
+ /*
+ * Table must be sorted, find the interval of 'y' which contains value
+ * 'input' and map it to proper 'x' value
+ */
+ while (i < tablesize && pts[i].y < input)
+ i++;
+
+ if (i == 0)
+ return pts[0].x;
+ if (i == tablesize)
+ return pts[tablesize - 1].x;
+
+ /* interpolate linearly */
+ return fixp_linear_interpolate(pts[i - 1].y, pts[i - 1].x,
+ pts[i].y, pts[i].x, input);
+}
+
static void qcom_vadc_scale_calib(const struct vadc_linear_graph *calib_graph,
u16 adc_code,
bool absolute,
@@ -463,6 +485,21 @@ static int qcom_vadc_scale_chg_temp(const struct vadc_linear_graph *calib_graph,
return 0;
}
+/* convert voltage to ADC code, using 1.875V reference */
+static u16 qcom_vadc_scale_voltage_code(s32 voltage,
+ const struct vadc_prescale_ratio *prescale,
+ const u32 full_scale_code_volt,
+ unsigned int factor)
+{
+ s64 volt = voltage;
+ s64 adc_vdd_ref_mv = 1875; /* reference voltage */
+
+ volt *= prescale->num * factor * full_scale_code_volt;
+ volt = div64_s64(volt, (s64)prescale->den * adc_vdd_ref_mv * 1000);
+
+ return volt;
+}
+
static int qcom_vadc_scale_code_voltage_factor(u16 adc_code,
const struct vadc_prescale_ratio *prescale,
const struct adc5_data *data,
@@ -627,6 +664,19 @@ int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
}
EXPORT_SYMBOL(qcom_vadc_scale);
+u16 qcom_adc_tm5_temp_volt_scale(unsigned int prescale_ratio,
+ u32 full_scale_code_volt, int temp)
+{
+ const struct vadc_prescale_ratio *prescale = &adc5_prescale_ratios[prescale_ratio];
+ s32 voltage;
+
+ voltage = qcom_vadc_map_temp_voltage(adcmap_100k_104ef_104fb_1875_vref,
+ ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
+ temp);
+ return qcom_vadc_scale_voltage_code(voltage, prescale, full_scale_code_volt, 1000);
+}
+EXPORT_SYMBOL(qcom_adc_tm5_temp_volt_scale);
+
int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype,
unsigned int prescale_ratio,
const struct adc5_data *data,