From patchwork Wed Feb 12 10:06:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Anson Huang X-Patchwork-Id: 3635991 X-Patchwork-Delegate: rui.zhang@intel.com Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D65C69F369 for ; Wed, 12 Feb 2014 10:07:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E754B20165 for ; Wed, 12 Feb 2014 10:07:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CE0B620117 for ; Wed, 12 Feb 2014 10:07:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751738AbaBLKHP (ORCPT ); Wed, 12 Feb 2014 05:07:15 -0500 Received: from tx2ehsobe003.messaging.microsoft.com ([65.55.88.13]:55302 "EHLO tx2outboundpool.messaging.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751153AbaBLKHM convert rfc822-to-8bit (ORCPT ); Wed, 12 Feb 2014 05:07:12 -0500 Received: from mail162-tx2-R.bigfish.com (10.9.14.245) by TX2EHSOBE014.bigfish.com (10.9.40.34) with Microsoft SMTP Server id 14.1.225.22; Wed, 12 Feb 2014 10:07:11 +0000 Received: from mail162-tx2 (localhost [127.0.0.1]) by mail162-tx2-R.bigfish.com (Postfix) with ESMTP id 7E4D22028F; Wed, 12 Feb 2014 10:07:11 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 3 X-BigFish: VS3(z3e12hzc89bhzz1f42h2148h208ch1ee6h1de0h1fdah2073h2146h1202h1e76h2189h1d1ah1d2ah1fc6h1082kzdchz1de098h8275bh1de097hz2dh2a8h839h93fhd24he5bhf0ah1288h12a5h12a9h12bdh137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b2fh2222h224fh1fb3h1d0ch1d2eh1d3fh1dc1h1dfeh1dffh1e23h1fe8h1ff5h2218h2216h226dh22d0h24afh2327h2336h2438h2461h2487h24d7h2516h2545h255eh1155h) Received: from mail162-tx2 (localhost.localdomain [127.0.0.1]) by mail162-tx2 (MessageSwitch) id 1392199629180638_13553; Wed, 12 Feb 2014 10:07:09 +0000 (UTC) Received: from TX2EHSMHS040.bigfish.com (unknown [10.9.14.247]) by mail162-tx2.bigfish.com (Postfix) with ESMTP id 18E944A0061; Wed, 12 Feb 2014 10:07:09 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by TX2EHSMHS040.bigfish.com (10.9.99.140) with Microsoft SMTP Server (TLS) id 14.16.227.3; Wed, 12 Feb 2014 10:07:08 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-004.039d.mgd.msft.net (10.84.1.14) with Microsoft SMTP Server (TLS) id 14.3.158.2; Wed, 12 Feb 2014 10:07:08 +0000 Received: from ubuntu.ap.freescale.net (ubuntu-010192242118.ap.freescale.net [10.192.242.118]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id s1CA75Jg022069; Wed, 12 Feb 2014 03:07:06 -0700 From: Anson Huang To: , , CC: Subject: =?UTF-8?q?=5BPATCH=5D=20thermal=3A=20imx=3A=20update=20formula=20for=20thermal=20sensor?= Date: Wed, 12 Feb 2014 18:06:35 +0800 Message-ID: <1392199595-1054-1-git-send-email-b20788@freescale.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Acked-by: Shawn Guo --- drivers/thermal/imx_thermal.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 45af765..a99c631 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -62,12 +62,16 @@ enum imx_thermal_trip { #define IMX_POLLING_DELAY 2000 /* millisecond */ #define IMX_PASSIVE_DELAY 1000 +#define FACTOR0 10000000 +#define FACTOR1 15976 +#define FACTOR2 4297157 + struct imx_thermal_data { struct thermal_zone_device *tz; struct thermal_cooling_device *cdev; enum thermal_device_mode mode; struct regmap *tempmon; - int c1, c2; /* See formula in imx_get_sensor_data() */ + u32 c1, c2; /* See formula in imx_get_sensor_data() */ unsigned long temp_passive; unsigned long temp_critical; unsigned long alarm_temp; @@ -84,7 +88,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data, int alarm_value; data->alarm_temp = alarm_temp; - alarm_value = (alarm_temp - data->c2) / data->c1; + alarm_value = (data->c2 - alarm_temp) / data->c1; regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK); regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value << TEMPSENSE0_ALARM_VALUE_SHIFT); @@ -136,7 +140,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp) n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT; /* See imx_get_sensor_data() for formula derivation */ - *temp = data->c2 + data->c1 * n_meas; + *temp = data->c2 - n_meas * data->c1; /* Update alarm value to next higher trip point */ 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) int t1, t2, n1, n2; int ret; u32 val; + u64 temp64; map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon-data"); @@ -330,6 +335,8 @@ static int imx_get_sensor_data(struct platform_device *pdev) * [31:20] - sensor value @ 25C * [19:8] - sensor value of hot * [7:0] - hot temperature value + * Use universal formula now and only need sensor value @ 25C + * slope = 0.4297157 - (0.0015976 * 25C fuse) */ n1 = val >> 20; n2 = (val & 0xfff00) >> 8; @@ -337,20 +344,26 @@ static int imx_get_sensor_data(struct platform_device *pdev) t1 = 25; /* t1 always 25C */ /* - * Derived from linear interpolation, - * Tmeas = T2 + (Nmeas - N2) * (T1 - T2) / (N1 - N2) + * Derived from linear interpolation: + * slope = 0.4297157 - (0.0015976 * 25C fuse) + * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0 + * (Nmeas - n1) / (Tmeas - t1) = slope * We want to reduce this down to the minimum computation necessary * for each temperature read. Also, we want Tmeas in millicelsius * and we don't want to lose precision from integer division. So... - * milli_Tmeas = 1000 * T2 + 1000 * (Nmeas - N2) * (T1 - T2) / (N1 - N2) - * Let constant c1 = 1000 * (T1 - T2) / (N1 - N2) - * milli_Tmeas = (1000 * T2) + c1 * (Nmeas - N2) - * milli_Tmeas = (1000 * T2) + (c1 * Nmeas) - (c1 * N2) - * Let constant c2 = (1000 * T2) - (c1 * N2) - * milli_Tmeas = c2 + (c1 * Nmeas) + * Tmeas = (Nmeas - n1) / slope + t1 + * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1 + * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1 + * Let constant c1 = (-1000 / slope) + * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1 + * Let constant c2 = n1 *c1 + 1000 * t1 + * milli_Tmeas = c2 - Nmeas * c1 */ - data->c1 = 1000 * (t1 - t2) / (n1 - n2); - data->c2 = 1000 * t2 - data->c1 * n2; + temp64 = FACTOR0; + temp64 *= 1000; + do_div(temp64, FACTOR1 * n1 - FACTOR2); + data->c1 = temp64; + data->c2 = n1 * data->c1 + 1000 * t1; /* * Set the default passive cooling trip point to 20 °C below the