aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaesar Wang <wxt@rock-chips.com>2015-01-24 21:11:11 -0500
committerEduardo Valentin <edubezval@gmail.com>2015-01-24 22:38:36 -0500
commit1e9a1aea7a05a1c8a7ece72b02d8077089f9e4d5 (patch)
tree719fd65616eefd8a963e5e3b5bce888b1506f773
parent1fd2273f966a095ff825cb20304878fdf14a6b45 (diff)
thermal: rockchip: make temperature reporting much more accurate
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>
-rw-r--r--drivers/thermal/rockchip_thermal.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 9c6ce548e363..3aa46ac7cdbc 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -193,19 +193,20 @@ static u32 rk_tsadcv2_temp_to_code(long temp)
193 193
194static long rk_tsadcv2_code_to_temp(u32 code) 194static long rk_tsadcv2_code_to_temp(u32 code)
195{ 195{
196 int high, low, mid; 196 unsigned int low = 0;
197 197 unsigned int high = ARRAY_SIZE(v2_code_table) - 1;
198 low = 0; 198 unsigned int mid = (low + high) / 2;
199 high = ARRAY_SIZE(v2_code_table) - 1; 199 unsigned int num;
200 mid = (high + low) / 2; 200 unsigned long denom;
201 201
202 if (code > v2_code_table[low].code || code < v2_code_table[high].code) 202 /* Invalid code, return -EAGAIN */
203 return 125000; /* No code available, return max temperature */ 203 if (code > TSADCV2_DATA_MASK)
204 return -EAGAIN;
204 205
205 while (low <= high) { 206 while (low <= high && mid) {
206 if (code >= v2_code_table[mid].code && code < 207 if (code >= v2_code_table[mid].code &&
207 v2_code_table[mid - 1].code) 208 code < v2_code_table[mid - 1].code)
208 return v2_code_table[mid].temp; 209 break;
209 else if (code < v2_code_table[mid].code) 210 else if (code < v2_code_table[mid].code)
210 low = mid + 1; 211 low = mid + 1;
211 else 212 else
@@ -213,7 +214,16 @@ static long rk_tsadcv2_code_to_temp(u32 code)
213 mid = (low + high) / 2; 214 mid = (low + high) / 2;
214 } 215 }
215 216
216 return 125000; 217 /*
218 * The 5C granularity provided by the table is too much. Let's
219 * assume that the relationship between sensor readings and
220 * temperature between 2 table entries is linear and interpolate
221 * to produce less granular result.
222 */
223 num = v2_code_table[mid].temp - v2_code_table[mid - 1].temp;
224 num *= v2_code_table[mid - 1].code - code;
225 denom = v2_code_table[mid - 1].code - v2_code_table[mid].code;
226 return v2_code_table[mid - 1].temp + (num / denom);
217} 227}
218 228
219/** 229/**