Skip to content

Commit

Permalink
hwmon: (ntc_thermistor) Improve precision of resistance calculation
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Chris Lesiak authored and Guenter Roeck committed Jun 3, 2015
1 parent 0315253 commit f6725ae
Showing 1 changed file with 10 additions and 13 deletions.
23 changes: 10 additions & 13 deletions drivers/hwmon/ntc_thermistor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
struct ntc_thermistor_platform_data *pdata = data->pdata;
u64 mv = uv / 1000;
u64 pmv = pdata->pullup_uv / 1000;
u32 puv = pdata->pullup_uv;
u64 n, puo, pdo;
puo = pdata->pullup_ohm;
pdo = pdata->pulldown_ohm;

if (mv == 0) {
if (pdata->connect == NTC_CONNECTED_POSITIVE)
return INT_MAX;
return 0;
}
if (mv >= pmv)
if (uv == 0)
return (pdata->connect == NTC_CONNECTED_POSITIVE) ?
INT_MAX : 0;
if (uv >= puv)
return (pdata->connect == NTC_CONNECTED_POSITIVE) ?
0 : INT_MAX;

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)
n = div64_u64_safe(puo * mv, pmv - mv);
n = div_u64(puo * uv, puv - uv);
else if (pdata->connect == NTC_CONNECTED_POSITIVE)
n = div64_u64_safe(pdo * puo * (pmv - mv),
puo * mv - pdo * (pmv - mv));
n = div64_u64_safe(pdo * puo * (puv - uv),
puo * uv - pdo * (puv - uv));
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)
n = INT_MAX;
Expand Down

0 comments on commit f6725ae

Please sign in to comment.