diff options
author | Dmitry Baryshkov <dmitry.baryshkov@linaro.org> | 2021-02-05 03:01:18 +0300 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2021-02-15 21:28:53 +0100 |
commit | ca66dca5eda6bd16b7b27fed2a034f2396df5627 (patch) | |
tree | 92e7a4119620f5226d4f6cd3867c6b7b9729b524 /drivers/iio | |
parent | e8ffd6c0756bd81f069dd67ea47e6908c791e742 (diff) | |
download | linux-ca66dca5eda6bd16b7b27fed2a034f2396df5627.tar.bz2 |
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.c | 50 |
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, |