Skip to content

Commit

Permalink
thermal: rockchip: make temperature reporting much more accurate
Browse files Browse the repository at this point in the history
In general, the kernel should report temperature readings exactly as
reported by the hardware. The cpu / gpu thermal driver works in 5 degree
increments,but we ought to do more accurate. The temperature will do
linear interpolation between the entries in the table.

Test= $md5sum /dev/zero &
$while true; do grep "" /sys/class/thermal/thermal_zone[1-2]/temp;
sleep .5; done

e.g. We can get the result as follows:
    /sys/class/thermal/thermal_zone1/temp:39994
    /sys/class/thermal/thermal_zone2/temp:39086
    /sys/class/thermal/thermal_zone1/temp:39994
    /sys/class/thermal/thermal_zone2/temp:39540
    /sys/class/thermal/thermal_zone1/temp:39540
    /sys/class/thermal/thermal_zone2/temp:39540
    /sys/class/thermal/thermal_zone1/temp:39540
    /sys/class/thermal/thermal_zone2/temp:39994

Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
  • Loading branch information
Caesar Wang authored and Eduardo Valentin committed Jan 25, 2015
1 parent 1fd2273 commit 1e9a1ae
Showing 1 changed file with 23 additions and 13 deletions.
36 changes: 23 additions & 13 deletions drivers/thermal/rockchip_thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,27 +193,37 @@ static u32 rk_tsadcv2_temp_to_code(long temp)

static long rk_tsadcv2_code_to_temp(u32 code)
{
int high, low, mid;

low = 0;
high = ARRAY_SIZE(v2_code_table) - 1;
mid = (high + low) / 2;

if (code > v2_code_table[low].code || code < v2_code_table[high].code)
return 125000; /* No code available, return max temperature */
unsigned int low = 0;
unsigned int high = ARRAY_SIZE(v2_code_table) - 1;
unsigned int mid = (low + high) / 2;
unsigned int num;
unsigned long denom;

/* Invalid code, return -EAGAIN */
if (code > TSADCV2_DATA_MASK)
return -EAGAIN;

while (low <= high) {
if (code >= v2_code_table[mid].code && code <
v2_code_table[mid - 1].code)
return v2_code_table[mid].temp;
while (low <= high && mid) {
if (code >= v2_code_table[mid].code &&
code < v2_code_table[mid - 1].code)
break;
else if (code < v2_code_table[mid].code)
low = mid + 1;
else
high = mid - 1;
mid = (low + high) / 2;
}

return 125000;
/*
* The 5C granularity provided by the table is too much. Let's
* assume that the relationship between sensor readings and
* temperature between 2 table entries is linear and interpolate
* to produce less granular result.
*/
num = v2_code_table[mid].temp - v2_code_table[mid - 1].temp;
num *= v2_code_table[mid - 1].code - code;
denom = v2_code_table[mid - 1].code - v2_code_table[mid].code;
return v2_code_table[mid - 1].temp + (num / denom);
}

/**
Expand Down

0 comments on commit 1e9a1ae

Please sign in to comment.