Received: by 10.223.164.202 with SMTP id h10csp310562wrb; Wed, 22 Nov 2017 07:33:46 -0800 (PST) X-Google-Smtp-Source: AGs4zMZeZ4n6R37glSzVideAVcOyUH4lSxjJtkzKZKss0K71Po7ITwHhAnmyJ2Jh91m/Zkw3v1DD X-Received: by 10.101.100.148 with SMTP id e20mr21289040pgv.248.1511364826109; Wed, 22 Nov 2017 07:33:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511364826; cv=none; d=google.com; s=arc-20160816; b=gaTkweAsPZ9sLVAcqQsPUW9vEoiXdvrf0x+iQuLafMyevRHEMZQuqH6z00yJL03IlH t1kTW8h4s0S1gRCdb5KidaxQL8RxskW9Q2kBOEbt3FnbCR8om9BIGScY2wHId/ibX4Xv k5XEUu826O3mrPbGvwYuudTcq7KvbSTo+RscUepYA/fFImy4o3TTLs2ut75VlPvh7cr3 elmAL/4hCOU1HhjksGgmWMnHstXYah+QLKQGV5pA5aMsEJD/lj5XYXezmZt2jT6MRXhY v6YaXW7YWB6fQrBMEHujMIfOqwy+ANf0rXGd0VtQB20ccul5+cmVmFVmPV/MME56Mb9e xrGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:cms-type:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:dkim-filter :arc-authentication-results; bh=6EJ0YtVaGglSlNL3SpHy4VwTDvCfeUaZZWBynMqf+qw=; b=nhcYJ6Ml89rvafNheQwsKtxcrZStfOVYWWUiwKfQMlpTrqKSqTqCdgpne4FgfxxPfG p07CUw9oLMWR7p4ImRJFp5nmnqsuvQnL9bEzxZL/kXmxfFHF/n6BGkUVBlVNVFAsHhJa izffhSEDwlC7zP7yXTlWeeLLETHh4W0fnjpL+svyYbIjulPl1hmK515CbrCSmKeSmu/3 2Bn2Qs5FUpo561NTqRG+sZQThJPsRelenYc5MHUJG9jjsEN0rLIGhc2eMSmFDTPSaxsj 1HJ589PHyjhTp7EW0Eb35wBRw/ok8i3KYosJM50xcgASb1DPXhOzgZTFmq6zz5mdNeb6 lz+Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=p2J1RdFa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q1si2096359plb.29.2017.11.22.07.33.34; Wed, 22 Nov 2017 07:33:46 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=p2J1RdFa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751869AbdKVPc7 (ORCPT + 77 others); Wed, 22 Nov 2017 10:32:59 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:51290 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751753AbdKVPcz (ORCPT ); Wed, 22 Nov 2017 10:32:55 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20171122153253euoutp01752d940eb013ca8ce30a159fdb59a3e4~5ckDscPrG1295312953euoutp01R; Wed, 22 Nov 2017 15:32:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20171122153253euoutp01752d940eb013ca8ce30a159fdb59a3e4~5ckDscPrG1295312953euoutp01R DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1511364773; bh=6EJ0YtVaGglSlNL3SpHy4VwTDvCfeUaZZWBynMqf+qw=; h=From:To:Cc:Subject:Date:In-reply-to:References:From; b=p2J1RdFaXDlalAB+ScUcEzljd86vNRKfkdacdOWydiEEqCNqdYbrUCIDo2Iyn73ol x+vcvnC1m7D/4q8p+QtXdemTp2yVv9FFrXkSv1JNfZZGQp84SM78GSoAlBaqHz9uwD pW2YHxHJXHdIcP07NlfV5qjIiG5yfx0BBdGdbb5s= Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20171122153252eucas1p20691ce38bdf5aff437ff388a0954c205~5ckC27Tap3073630736eucas1p2i; Wed, 22 Nov 2017 15:32:52 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 81.0E.12907.3A8951A5; Wed, 22 Nov 2017 15:32:51 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20171122153251eucas1p2d1e78a6063a964dcf75a23e2c168df3f~5ckCIjNZI2791927919eucas1p21; Wed, 22 Nov 2017 15:32:51 +0000 (GMT) X-AuditID: cbfec7f1-f793a6d00000326b-5e-5a1598a3ede4 Received: from eusync1.samsung.com ( [203.254.199.211]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 3A.26.18832.3A8951A5; Wed, 22 Nov 2017 15:32:51 +0000 (GMT) Received: from AMDC2075.DIGITAL.local ([106.120.51.25]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OZT00FB7SICQ510@eusync1.samsung.com>; Wed, 22 Nov 2017 15:32:51 +0000 (GMT) From: Maciej Purski To: Jonathan Cameron , Stefan Bruens Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Javier Martinez Canillas , Peter Meerwald-Stadler , Lars-Peter Clausen , Hartmut Knaack , Jean Delvare , Guenter Roeck , Marek Szyprowski , Bartlomiej Zolnierkiewicz , Maciej Purski Subject: [PATCH 2/2] hwmon: (ina2xx) Make calibration register value fixed Date: Wed, 22 Nov 2017 16:32:15 +0100 Message-id: <1511364735-16818-3-git-send-email-m.purski@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <1511364735-16818-1-git-send-email-m.purski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrCIsWRmVeSWpSXmKPExsWy7djPc7qLZ4hGGcxbamWxccZ6Vos3b9cw WZydEGjxoGkVk8Wu/2+YLZZMns9q0f56K6PFvCPvWCwu75rDZvFk4RkmiwUvb7FYrD1yl93i 965j7BaNp+awOvB5fPgY57FpVSebx5I3h1g9tvTfZfc433yE0WPn9wYg695bNo++LasYPdZv ucri8XmTXABXFJdNSmpOZllqkb5dAlfG1ycOBTsNKn5vv8rWwHhTrYuRk0NCwETizbNDLBC2 mMSFe+vZQGwhgaWMEhcaI7oYuYDsz4wSD35dZoJpuLz9KBNE0TJGiXntwRBF/xklVn59ytjF yMHBJqAlsaY9HqRGRCBc4uP7VkaQGmaBW8wSv7YvZgZJCAt4SfybchBsM4uAqsTmS3fA4rwC LhLTXu+EWiYncfNcJ1icU8BVoqljEgvIIAmBx2wSP3/2s0IUuUgcvtjHBmELS7w6voUdwpaR 6Ow4CDWoWuLi111QNTUSjbc3QNVYS3yetAVsAbMAn8SkbdOZQR6QEOCV6GgTgijxkJi29Rkj RNhRou2FI8S/MxglWrf9Z5zAKL2AkWEVo0hqaXFuemqxkV5xYm5xaV66XnJ+7iZGYFo4/e/4 xx2M709YHWIU4GBU4uF9YScaJcSaWFZcmXuIUYKDWUmEd1I3UIg3JbGyKrUoP76oNCe1+BCj NAeLkjivbVRbpJBAemJJanZqakFqEUyWiYNTqoGxeOJ9xXXSD4KCihr0gneoZ5fmXnMX9xK5 6OJ5rNx9k9ShiCPt4lt1932ZtmfSVrWfH/WimN5H2otOUVwasrFVpf5zgFr926OemVvN13lu 0d05vbN/ztVd+ZETXiVpzu6IurY71XB5ufW2nMzLrTkKMmc++Lm1HK8IL8i1LU7KXb7J8HzM mitKLMUZiYZazEXFiQDYVEssBwMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrDLMWRmVeSWpSXmKPExsVy+t/xy7qLZ4hGGVyZL2WxccZ6Vos3b9cw WZydEGjxoGkVk8Wu/2+YLZZMns9q0f56K6PFvCPvWCwu75rDZvFk4RkmiwUvb7FYrD1yl93i 965j7BaNp+awOvB5fPgY57FpVSebx5I3h1g9tvTfZfc433yE0WPn9wYg695bNo++LasYPdZv ucri8XmTXABXFJdNSmpOZllqkb5dAlfG1ycOBTsNKn5vv8rWwHhTrYuRk0NCwETi8vajTBC2 mMSFe+vZuhi5OIQEljBKdLxaCuU0Mkks/vMOyOHgYBPQkljTHg/SICIQLrH0zQdmkBpmgXvM Et8Ob2YFSQgLeEn8m3KQBcRmEVCV2HzpDjOIzSvgIjHt9U6obXISN891gsU5BVwlmjomgdUL AdUcvfyTeQIj7wJGhlWMIqmlxbnpucWGesWJucWleel6yfm5mxiBYbzt2M/NOxgvbQw+xCjA wajEwzsjSSRKiDWxrLgy9xCjBAezkgjvpG7RKCHelMTKqtSi/Pii0pzU4kOM0hwsSuK8vXtW RwoJpCeWpGanphakFsFkmTg4pRoYO1cuMDqe+DtM0jST+eeX6khv5oNhYutbztZ+/VrkIMUU tfRG5uNVk778+ul+3mauytINNT4z7YNV6gxsI1UrhEI7soUaHTV5rzv5/zFvfB5umKHZu7x4 6sKmqCdJMRPU9p79OoN3R8ndNxL77tvo5ZpXXn/+jcVDtuoog1Zg4p5oxdLEGexKLMUZiYZa zEXFiQDD06JnXwIAAA== X-CMS-MailID: 20171122153251eucas1p2d1e78a6063a964dcf75a23e2c168df3f X-Msg-Generator: CA CMS-TYPE: 201P X-CMS-RootMailID: 20171122153251eucas1p2d1e78a6063a964dcf75a23e2c168df3f X-RootMTR: 20171122153251eucas1p2d1e78a6063a964dcf75a23e2c168df3f References: <1511364735-16818-1-git-send-email-m.purski@samsung.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Calibration register is used for calculating current register in hardware according to datasheet: current = shunt_volt * calib_register / 2048 (ina 226) current = shunt_volt * calib_register / 4096 (ina 219) Fix calib_register value to 2048 for ina226 and 4096 for ina 219 in order to avoid truncation error and provide best precision allowed by shunt_voltage measurement. Make current scale value follow changes of shunt_resistor from sysfs as calib_register value is now fixed. Power_lsb value should also follow shunt_resistor changes as stated in datasheet: power_lsb = 25 * current_lsb (ina 226) power_lsb = 20 * current_lsb (ina 219) Signed-off-by: Maciej Purski --- drivers/hwmon/ina2xx.c | 87 +++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 62e38fa..e362a93 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -95,18 +95,20 @@ enum ina2xx_ids { ina219, ina226 }; struct ina2xx_config { u16 config_default; - int calibration_factor; + int calibration_value; int registers; int shunt_div; int bus_voltage_shift; int bus_voltage_lsb; /* uV */ - int power_lsb; /* uW */ + int power_lsb_factor; }; struct ina2xx_data { const struct ina2xx_config *config; long rshunt; + long current_lsb_uA; + long power_lsb_uW; struct mutex config_lock; struct regmap *regmap; @@ -116,21 +118,21 @@ struct ina2xx_data { static const struct ina2xx_config ina2xx_config[] = { [ina219] = { .config_default = INA219_CONFIG_DEFAULT, - .calibration_factor = 40960000, + .calibration_value = 4096, .registers = INA219_REGISTERS, .shunt_div = 100, .bus_voltage_shift = 3, .bus_voltage_lsb = 4000, - .power_lsb = 20000, + .power_lsb_factor = 20, }, [ina226] = { .config_default = INA226_CONFIG_DEFAULT, - .calibration_factor = 5120000, + .calibration_value = 2048, .registers = INA226_REGISTERS, .shunt_div = 400, .bus_voltage_shift = 0, .bus_voltage_lsb = 1250, - .power_lsb = 25000, + .power_lsb_factor = 25, }, }; @@ -169,12 +171,16 @@ static u16 ina226_interval_to_reg(int interval) return INA226_SHIFT_AVG(avg_bits); } +/* + * Calibration register is set to the best value, which eliminates + * truncation errors on calculating current register in hardware. + * According to datasheet (eq. 3) the best values are 2048 for + * ina226 and 4096 for ina219. They are hardcoded as calibration_value. + */ static int ina2xx_calibrate(struct ina2xx_data *data) { - u16 val = DIV_ROUND_CLOSEST(data->config->calibration_factor, - data->rshunt); - - return regmap_write(data->regmap, INA2XX_CALIBRATION, val); + return regmap_write(data->regmap, INA2XX_CALIBRATION, + data->config->calibration_value); } /* @@ -187,10 +193,6 @@ static int ina2xx_init(struct ina2xx_data *data) if (ret < 0) return ret; - /* - * Set current LSB to 1mA, shunt is in uOhms - * (equation 13 in datasheet). - */ return ina2xx_calibrate(data); } @@ -268,15 +270,15 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg, val = DIV_ROUND_CLOSEST(val, 1000); break; case INA2XX_POWER: - val = regval * data->config->power_lsb; + val = regval * data->power_lsb_uW; break; case INA2XX_CURRENT: - /* signed register, LSB=1mA (selected), in mA */ - val = (s16)regval; + /* signed register, result in mA */ + val = regval * data->current_lsb_uA; + val = DIV_ROUND_CLOSEST(val, 1000); break; case INA2XX_CALIBRATION: - val = DIV_ROUND_CLOSEST(data->config->calibration_factor, - regval); + val = regval; break; default: /* programmer goofed */ @@ -304,9 +306,32 @@ static ssize_t ina2xx_show_value(struct device *dev, ina2xx_get_value(data, attr->index, regval)); } -static ssize_t ina2xx_set_shunt(struct device *dev, - struct device_attribute *da, - const char *buf, size_t count) +/* + * In order to keep calibration register value fixed, the product + * of current_lsb and shunt_resistor should also be fixed and equal + * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order + * to keep the scale. + */ +static int ina2xx_set_shunt(struct ina2xx_data *data, long val) +{ + unsigned int dividend = DIV_ROUND_CLOSEST(1000000000, + data->config->shunt_div); + if (val <= 0 || val > dividend) + return -EINVAL; + + mutex_lock(&data->config_lock); + data->rshunt = val; + data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val); + data->power_lsb_uW = data->config->power_lsb_factor * + data->current_lsb_uA; + mutex_unlock(&data->config_lock); + + return 0; +} + +static ssize_t ina2xx_store_shunt(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) { unsigned long val; int status; @@ -316,18 +341,9 @@ static ssize_t ina2xx_set_shunt(struct device *dev, if (status < 0) return status; - if (val == 0 || - /* Values greater than the calibration factor make no sense. */ - val > data->config->calibration_factor) - return -EINVAL; - - mutex_lock(&data->config_lock); - data->rshunt = val; - status = ina2xx_calibrate(data); - mutex_unlock(&data->config_lock); + status = ina2xx_set_shunt(data, val); if (status < 0) return status; - return count; } @@ -387,7 +403,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL, /* shunt resistance */ static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR, - ina2xx_show_value, ina2xx_set_shunt, + ina2xx_show_value, ina2xx_store_shunt, INA2XX_CALIBRATION); /* update interval (ina226 only) */ @@ -448,10 +464,7 @@ static int ina2xx_probe(struct i2c_client *client, val = INA2XX_RSHUNT_DEFAULT; } - if (val <= 0 || val > data->config->calibration_factor) - return -ENODEV; - - data->rshunt = val; + ina2xx_set_shunt(data, val); ina2xx_regmap_config.max_register = data->config->registers; -- 2.7.4 From 1585341009345871075@xxx Tue Nov 28 19:56:43 +0000 2017 X-GM-THRID: 1585341009345871075 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread