Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Chris Lesiak and committed by
Guenter Roeck
f6725ae2 0315253b

+10 -13
+10 -13
drivers/hwmon/ntc_thermistor.c
··· 350 350 static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv) 351 351 { 352 352 struct ntc_thermistor_platform_data *pdata = data->pdata; 353 - u64 mv = uv / 1000; 354 - u64 pmv = pdata->pullup_uv / 1000; 353 + u32 puv = pdata->pullup_uv; 355 354 u64 n, puo, pdo; 356 355 puo = pdata->pullup_ohm; 357 356 pdo = pdata->pulldown_ohm; 358 357 359 - if (mv == 0) { 360 - if (pdata->connect == NTC_CONNECTED_POSITIVE) 361 - return INT_MAX; 362 - return 0; 363 - } 364 - if (mv >= pmv) 358 + if (uv == 0) 359 + return (pdata->connect == NTC_CONNECTED_POSITIVE) ? 360 + INT_MAX : 0; 361 + if (uv >= puv) 365 362 return (pdata->connect == NTC_CONNECTED_POSITIVE) ? 366 363 0 : INT_MAX; 367 364 368 365 if (pdata->connect == NTC_CONNECTED_POSITIVE && puo == 0) 369 - n = div64_u64_safe(pdo * (pmv - mv), mv); 366 + n = div_u64(pdo * (puv - uv), uv); 370 367 else if (pdata->connect == NTC_CONNECTED_GROUND && pdo == 0) 371 - n = div64_u64_safe(puo * mv, pmv - mv); 368 + n = div_u64(puo * uv, puv - uv); 372 369 else if (pdata->connect == NTC_CONNECTED_POSITIVE) 373 - n = div64_u64_safe(pdo * puo * (pmv - mv), 374 - puo * mv - pdo * (pmv - mv)); 370 + n = div64_u64_safe(pdo * puo * (puv - uv), 371 + puo * uv - pdo * (puv - uv)); 375 372 else 376 - n = div64_u64_safe(pdo * puo * mv, pdo * (pmv - mv) - puo * mv); 373 + n = div64_u64_safe(pdo * puo * uv, pdo * (puv - uv) - puo * uv); 377 374 378 375 if (n > INT_MAX) 379 376 n = INT_MAX;