mirror of https://gitee.com/openkylin/linux.git
hwmon: (ntc_thermistor) Improve precision of resistance calculation
The function get_ohm_of_thermistor has both the measured voltage and the pullup voltage available in microvolts. But it was promptly converting both to millivolts before using them to calculate the thermistor resistance. That conversion unnecessarily hurt the precision of the calculation. For example, take the ncpXXwb473 connected to 5000 mV and pulled down through a 47000 ohm resistor. At 25 C, the resistance of the thermistor is 47000 ohms. The measured voltage will be 2500 mV. If we measure instead 2501 mV, then the calculated resistance will be 46962 ohms -- a difference of 38 ohms. So the precision of the resistance estimate could be increased by 38X by doing the calculations in microvolts. Signed-off-by: Chris Lesiak <chris.lesiak@licor.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
0315253b19
commit
f6725ae2f1
|
@ -350,30 +350,27 @@ static inline u64 div64_u64_safe(u64 dividend, u64 divisor)
|
||||||
static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv)
|
static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv)
|
||||||
{
|
{
|
||||||
struct ntc_thermistor_platform_data *pdata = data->pdata;
|
struct ntc_thermistor_platform_data *pdata = data->pdata;
|
||||||
u64 mv = uv / 1000;
|
u32 puv = pdata->pullup_uv;
|
||||||
u64 pmv = pdata->pullup_uv / 1000;
|
|
||||||
u64 n, puo, pdo;
|
u64 n, puo, pdo;
|
||||||
puo = pdata->pullup_ohm;
|
puo = pdata->pullup_ohm;
|
||||||
pdo = pdata->pulldown_ohm;
|
pdo = pdata->pulldown_ohm;
|
||||||
|
|
||||||
if (mv == 0) {
|
if (uv == 0)
|
||||||
if (pdata->connect == NTC_CONNECTED_POSITIVE)
|
return (pdata->connect == NTC_CONNECTED_POSITIVE) ?
|
||||||
return INT_MAX;
|
INT_MAX : 0;
|
||||||
return 0;
|
if (uv >= puv)
|
||||||
}
|
|
||||||
if (mv >= pmv)
|
|
||||||
return (pdata->connect == NTC_CONNECTED_POSITIVE) ?
|
return (pdata->connect == NTC_CONNECTED_POSITIVE) ?
|
||||||
0 : INT_MAX;
|
0 : INT_MAX;
|
||||||
|
|
||||||
if (pdata->connect == NTC_CONNECTED_POSITIVE && puo == 0)
|
if (pdata->connect == NTC_CONNECTED_POSITIVE && puo == 0)
|
||||||
n = div64_u64_safe(pdo * (pmv - mv), mv);
|
n = div_u64(pdo * (puv - uv), uv);
|
||||||
else if (pdata->connect == NTC_CONNECTED_GROUND && pdo == 0)
|
else if (pdata->connect == NTC_CONNECTED_GROUND && pdo == 0)
|
||||||
n = div64_u64_safe(puo * mv, pmv - mv);
|
n = div_u64(puo * uv, puv - uv);
|
||||||
else if (pdata->connect == NTC_CONNECTED_POSITIVE)
|
else if (pdata->connect == NTC_CONNECTED_POSITIVE)
|
||||||
n = div64_u64_safe(pdo * puo * (pmv - mv),
|
n = div64_u64_safe(pdo * puo * (puv - uv),
|
||||||
puo * mv - pdo * (pmv - mv));
|
puo * uv - pdo * (puv - uv));
|
||||||
else
|
else
|
||||||
n = div64_u64_safe(pdo * puo * mv, pdo * (pmv - mv) - puo * mv);
|
n = div64_u64_safe(pdo * puo * uv, pdo * (puv - uv) - puo * uv);
|
||||||
|
|
||||||
if (n > INT_MAX)
|
if (n > INT_MAX)
|
||||||
n = INT_MAX;
|
n = INT_MAX;
|
||||||
|
|
Loading…
Reference in New Issue