aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnson Huang <b20788@freescale.com>2014-02-12 05:06:35 -0500
committerZhang Rui <rui.zhang@intel.com>2014-04-07 21:01:37 -0400
commit749e8be71d6126b9219f17230e6d0c3eef5191a7 (patch)
treec7f0233dbffaaac26b7f2bfde41184b6b6b0a21e
parent455c6fdbd219161bd09b1165f11699d6d73de11c (diff)
thermal: imx: update formula for thermal sensor
Thermal sensor used to need two calibration points which are in fuse map to get a slope for converting thermal sensor's raw data to real temperature in degree C. Due to the chip calibration limitation, hardware team provides an universal formula to get real temperature from internal thermal sensor raw data: Slope = 0.4297157 - (0.0015976 * 25C fuse); Update the formula, as there will be no hot point calibration data in fuse map from now on. Signed-off-by: Anson Huang <b20788@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
-rw-r--r--drivers/thermal/imx_thermal.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 45af765a3198..a99c63152b8d 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -62,12 +62,16 @@ enum imx_thermal_trip {
62#define IMX_POLLING_DELAY 2000 /* millisecond */ 62#define IMX_POLLING_DELAY 2000 /* millisecond */
63#define IMX_PASSIVE_DELAY 1000 63#define IMX_PASSIVE_DELAY 1000
64 64
65#define FACTOR0 10000000
66#define FACTOR1 15976
67#define FACTOR2 4297157
68
65struct imx_thermal_data { 69struct imx_thermal_data {
66 struct thermal_zone_device *tz; 70 struct thermal_zone_device *tz;
67 struct thermal_cooling_device *cdev; 71 struct thermal_cooling_device *cdev;
68 enum thermal_device_mode mode; 72 enum thermal_device_mode mode;
69 struct regmap *tempmon; 73 struct regmap *tempmon;
70 int c1, c2; /* See formula in imx_get_sensor_data() */ 74 u32 c1, c2; /* See formula in imx_get_sensor_data() */
71 unsigned long temp_passive; 75 unsigned long temp_passive;
72 unsigned long temp_critical; 76 unsigned long temp_critical;
73 unsigned long alarm_temp; 77 unsigned long alarm_temp;
@@ -84,7 +88,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data,
84 int alarm_value; 88 int alarm_value;
85 89
86 data->alarm_temp = alarm_temp; 90 data->alarm_temp = alarm_temp;
87 alarm_value = (alarm_temp - data->c2) / data->c1; 91 alarm_value = (data->c2 - alarm_temp) / data->c1;
88 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK); 92 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK);
89 regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value << 93 regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value <<
90 TEMPSENSE0_ALARM_VALUE_SHIFT); 94 TEMPSENSE0_ALARM_VALUE_SHIFT);
@@ -136,7 +140,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp)
136 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT; 140 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT;
137 141
138 /* See imx_get_sensor_data() for formula derivation */ 142 /* See imx_get_sensor_data() for formula derivation */
139 *temp = data->c2 + data->c1 * n_meas; 143 *temp = data->c2 - n_meas * data->c1;
140 144
141 /* Update alarm value to next higher trip point */ 145 /* Update alarm value to next higher trip point */
142 if (data->alarm_temp == data->temp_passive && *temp >= data->temp_passive) 146 if (data->alarm_temp == data->temp_passive && *temp >= data->temp_passive)
@@ -305,6 +309,7 @@ static int imx_get_sensor_data(struct platform_device *pdev)
305 int t1, t2, n1, n2; 309 int t1, t2, n1, n2;
306 int ret; 310 int ret;
307 u32 val; 311 u32 val;
312 u64 temp64;
308 313
309 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 314 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
310 "fsl,tempmon-data"); 315 "fsl,tempmon-data");
@@ -330,6 +335,8 @@ static int imx_get_sensor_data(struct platform_device *pdev)
330 * [31:20] - sensor value @ 25C 335 * [31:20] - sensor value @ 25C
331 * [19:8] - sensor value of hot 336 * [19:8] - sensor value of hot
332 * [7:0] - hot temperature value 337 * [7:0] - hot temperature value
338 * Use universal formula now and only need sensor value @ 25C
339 * slope = 0.4297157 - (0.0015976 * 25C fuse)
333 */ 340 */
334 n1 = val >> 20; 341 n1 = val >> 20;
335 n2 = (val & 0xfff00) >> 8; 342 n2 = (val & 0xfff00) >> 8;
@@ -337,20 +344,26 @@ static int imx_get_sensor_data(struct platform_device *pdev)
337 t1 = 25; /* t1 always 25C */ 344 t1 = 25; /* t1 always 25C */
338 345
339 /* 346 /*
340 * Derived from linear interpolation, 347 * Derived from linear interpolation:
341 * Tmeas = T2 + (Nmeas - N2) * (T1 - T2) / (N1 - N2) 348 * slope = 0.4297157 - (0.0015976 * 25C fuse)
349 * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
350 * (Nmeas - n1) / (Tmeas - t1) = slope
342 * We want to reduce this down to the minimum computation necessary 351 * We want to reduce this down to the minimum computation necessary
343 * for each temperature read. Also, we want Tmeas in millicelsius 352 * for each temperature read. Also, we want Tmeas in millicelsius
344 * and we don't want to lose precision from integer division. So... 353 * and we don't want to lose precision from integer division. So...
345 * milli_Tmeas = 1000 * T2 + 1000 * (Nmeas - N2) * (T1 - T2) / (N1 - N2) 354 * Tmeas = (Nmeas - n1) / slope + t1
346 * Let constant c1 = 1000 * (T1 - T2) / (N1 - N2) 355 * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
347 * milli_Tmeas = (1000 * T2) + c1 * (Nmeas - N2) 356 * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
348 * milli_Tmeas = (1000 * T2) + (c1 * Nmeas) - (c1 * N2) 357 * Let constant c1 = (-1000 / slope)
349 * Let constant c2 = (1000 * T2) - (c1 * N2) 358 * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
350 * milli_Tmeas = c2 + (c1 * Nmeas) 359 * Let constant c2 = n1 *c1 + 1000 * t1
360 * milli_Tmeas = c2 - Nmeas * c1
351 */ 361 */
352 data->c1 = 1000 * (t1 - t2) / (n1 - n2); 362 temp64 = FACTOR0;
353 data->c2 = 1000 * t2 - data->c1 * n2; 363 temp64 *= 1000;
364 do_div(temp64, FACTOR1 * n1 - FACTOR2);
365 data->c1 = temp64;
366 data->c2 = n1 * data->c1 + 1000 * t1;
354 367
355 /* 368 /*
356 * Set the default passive cooling trip point to 20 °C below the 369 * Set the default passive cooling trip point to 20 °C below the