From patchwork Fri Dec 15 07:59:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maciej Purski X-Patchwork-Id: 10114169 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E5BE960327 for ; Fri, 15 Dec 2017 07:59:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D697529F1B for ; Fri, 15 Dec 2017 07:59:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C9E3529F12; Fri, 15 Dec 2017 07:59:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EF64229F12 for ; Fri, 15 Dec 2017 07:59:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754369AbdLOH7k (ORCPT ); Fri, 15 Dec 2017 02:59:40 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:36051 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753605AbdLOH7i (ORCPT ); Fri, 15 Dec 2017 02:59:38 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20171215075935euoutp01a298f6b3a59e1bbd47dda76e891da2e5~AaN2hbG0H1710417104euoutp01f; Fri, 15 Dec 2017 07:59:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20171215075935euoutp01a298f6b3a59e1bbd47dda76e891da2e5~AaN2hbG0H1710417104euoutp01f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1513324775; bh=215BK7nqg7xCRRJgLjd6q9j4RH/qkJKbe6mkqGS+4ic=; h=From:To:Cc:Subject:Date:References:From; b=Avo6Bv4YNzTkgKAB62579sXZNFwKTLRBMG2GGEFpCn89gUqbkG293QcSfgn33M3Hf PCne7sCnLxbd270T+exz0O+GbFGFZSf6GGVihAUKAR2c0SwJJHV257yT65nmZ7Q5MI 07lTJgacZso7bNf4j3aFUk43PLQNqV6y41YvVHF8= Received: from eusmges5.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20171215075935eucas1p11f33649cb21f7e50b03a1c8a977c27e6~AaN12e_7V2193421934eucas1p12; Fri, 15 Dec 2017 07:59:35 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges5.samsung.com (EUCPMTA) with SMTP id 4A.8F.12743.6E0833A5; Fri, 15 Dec 2017 07:59:34 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20171215075934eucas1p17dd876ffdc654ee4714bbd20a9c3abdb~AaN1OOsVG1422414224eucas1p1n; Fri, 15 Dec 2017 07:59:34 +0000 (GMT) X-AuditID: cbfec7f5-f79d06d0000031c7-fd-5a3380e6737d Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 67.BB.18832.6E0833A5; Fri, 15 Dec 2017 07:59:34 +0000 (GMT) Received: from AMDC2075.DIGITAL.local ([106.120.51.25]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0P0Z004V4SV1LK60@eusync2.samsung.com>; Fri, 15 Dec 2017 07:59:34 +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, Peter Meerwald-Stadler , Lars-Peter Clausen , Hartmut Knaack , Jean Delvare , Guenter Roeck , Marek Szyprowski , Bartlomiej Zolnierkiewicz , Maciej Purski Subject: [PATCH v3] iio: adc: ina2xx: Make calibration register value fixed Date: Fri, 15 Dec 2017 08:59:23 +0100 Message-id: <1513324763-21541-1-git-send-email-m.purski@samsung.com> X-Mailer: git-send-email 2.7.4 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrAIsWRmVeSWpSXmKPExsWy7djPc7rPGoyjDL49MrfYOGM9q8XZCYEW D5pWMVns+v+G2WLJ5PmsFu2vtzJazDvyjsXi8q45bBZPFp5hsljw8haLxdojd9ktfu86xm7R eGoOqwOvx4ePcR6bVnWyeSx5c4jV43zzEUaPnd8b2D3O33vL5tG3ZRWjx/otV1k8Pm+SC+CM 4rJJSc3JLEst0rdL4Mp48HYhc8EL9Ypzy+cyNzC+ke9i5OSQEDCRuHr4CiuELSZx4d56ti5G Lg4hgaWMEg8OLodyPjNKfLh9jwmm41tvLytEYhmjxNOXU6Cq/jNKvHkxg7GLkYODTUBLYk17 PEiDiEC4xMf3rYwgNcwCS5klPs9+wAySEBbwltjRcpARxGYRUJV4tbsBbAOvgIvEq+arUDfJ Sdw818kM0iwhsIdNYub81VBnuEjs7mlkh7CFJV4d3wJly0h0dhyEqqmWuPh1FxuEXSPReHsD VI21xOdJW8COYBbgk5i0bTozyNESArwSHW1CECUeEg9fdUKVO0q8nneYCaRESCBW4saCygmM UgsYGVYxiqSWFuempxab6hUn5haX5qXrJefnbmIExvvpf8e/7mBceszqEKMAB6MSD69Fm1GU EGtiWXFl7iFGCQ5mJRHee27GUUK8KYmVValF+fFFpTmpxYcYpTlYlMR5baPaIoUE0hNLUrNT UwtSi2CyTBycUg2MGTuanmgkbv8YETrJyk+jvfik/4Sf0cckgr8znb/8rPtVY4idx9TGKW/P VExfePVvQEvJ861uz40nrL7lrb/TM1ZvQ+PhvKuNxW/aFbmLFx5acXu+9gzTR/VT8lUf8L47 9tHfa1/HrKTbCt+rfvFOmWE6RcS+S2Ry351ZhtXiS9OuMgm9i7D+psRSnJFoqMVcVJwIANhi fCrzAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrFLMWRmVeSWpSXmKPExsVy+t/xK7rPGoyjDHr7ZS02zljPanF2QqDF g6ZVTBa7/r9htlgyeT6rRfvrrYwW8468Y7G4vGsOm8WThWeYLBa8vMVisfbIXXaL37uOsVs0 nprD6sDr8eFjnMemVZ1sHkveHGL1ON98hNFj5/cGdo/z996yefRtWcXosX7LVRaPz5vkAjij uGxSUnMyy1KL9O0SuDIevF3IXPBCveLc8rnMDYxv5LsYOTkkBEwkvvX2skLYYhIX7q1nA7GF BJYwSjSfsOli5AKyG5kkGpbuYuli5OBgE9CSWNMeD1IjIhAusfTNB2aQGmaB5cwSR7q3gQ0S FvCW2NFykBHEZhFQlXi1u4EJxOYVcJF41XwVapmcxM1zncwTGLkXMDKsYhRJLS3OTc8tNtQr TswtLs1L10vOz93ECAzBbcd+bt7BeGlj8CFGAQ5GJR5eizajKCHWxLLiytxDjBIczEoivPfc jKOEeFMSK6tSi/Lji0pzUosPMUpzsCiJ8/buWR0pJJCeWJKanZpakFoEk2Xi4JRqYJytfXTR m7CgqHcxyfIJyl//OiQuKZx7fUb3XYeQ7OKGNE22d5VzH7odzr0Tve5drOS12rO1V0tNWz8K uGvrymosEc+OjsttMg78U9MddyEgRETq8bkrp62+b85LUHyn7HAm4/ivWe6iOcd15vDLbsle x//T8vCr3QWTNkYIp8bJvV53cJ5PqhJLcUaioRZzUXEiAEnX+EY9AgAA X-CMS-MailID: 20171215075934eucas1p17dd876ffdc654ee4714bbd20a9c3abdb X-Msg-Generator: CA CMS-TYPE: 201P X-CMS-RootMailID: 20171215075934eucas1p17dd876ffdc654ee4714bbd20a9c3abdb X-RootMTR: 20171215075934eucas1p17dd876ffdc654ee4714bbd20a9c3abdb References: Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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) This is a part of the patchset: https://lkml.org/lkml/2017/11/22/394 Signed-off-by: Maciej Purski --- Changes in v3: - remove variable current_lsb and calculate it on each read of current and power scale value - update comments Changes in v2: - rebase on top of the latest next - remove a redundant variable - power_lsb_uW - fix comments --- drivers/iio/adc/ina2xx-adc.c | 56 +++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index ddf8781..3488100 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -124,11 +124,11 @@ enum ina2xx_ids { ina219, ina226 }; struct ina2xx_config { u16 config_default; - int calibration_factor; + int calibration_value; int shunt_voltage_lsb; /* nV */ int bus_voltage_shift; /* position of lsb */ int bus_voltage_lsb; /* uV */ - int power_lsb; /* uW */ + int power_lsb_factor; enum ina2xx_ids chip_id; }; @@ -149,20 +149,20 @@ struct ina2xx_chip_info { static const struct ina2xx_config ina2xx_config[] = { [ina219] = { .config_default = INA219_CONFIG_DEFAULT, - .calibration_factor = 40960000, + .calibration_value = 4096, .shunt_voltage_lsb = 10000, .bus_voltage_shift = INA219_BUS_VOLTAGE_SHIFT, .bus_voltage_lsb = 4000, - .power_lsb = 20000, + .power_lsb_factor = 20, .chip_id = ina219, }, [ina226] = { .config_default = INA226_CONFIG_DEFAULT, - .calibration_factor = 5120000, + .calibration_value = 2048, .shunt_voltage_lsb = 2500, .bus_voltage_shift = 0, .bus_voltage_lsb = 1250, - .power_lsb = 25000, + .power_lsb_factor = 25, .chip_id = ina226, }, }; @@ -228,15 +228,17 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, return IIO_VAL_FRACTIONAL; case INA2XX_POWER: - /* processed (mW) = raw*lsb (uW) / 1000 */ - *val = chip->config->power_lsb; - *val2 = 1000; + /* processed (mW) = raw * factor * current_lsb (mW)*/ + *val = chip->config->power_lsb_factor * + chip->config->shunt_voltage_lsb; + *val2 = chip->shunt_resistor_uohm; return IIO_VAL_FRACTIONAL; case INA2XX_CURRENT: - /* processed (mA) = raw (mA) */ - *val = 1; - return IIO_VAL_INT; + /* processed (mA) = raw * lsb ([nV] / [uOhm] = [mA]) */ + *val = chip->config->shunt_voltage_lsb; + *val2 = chip->shunt_resistor_uohm; + return IIO_VAL_FRACTIONAL; } case IIO_CHAN_INFO_HARDWAREGAIN: @@ -541,25 +543,26 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, } /* - * Set current LSB to 1mA, shunt is in uOhms - * (equation 13 in datasheet). We hardcode a Current_LSB - * of 1.0 x10-3. The only remaining parameter is RShunt. - * There is no need to expose the CALIBRATION register - * to the user for now. But we need to reset this register - * if the user updates RShunt after driver init, e.g upon - * reading an EEPROM/Probe-type value. + * Calibration register is set to the best value, which eliminates + * truncation errors on calculating current register in hardware. + * According to datasheet (INA 226: eq. 3, INA219: eq. 4) the best values + * are 2048 for ina226 and 4096 for ina219. They are hardcoded as + * calibration_value. */ static int ina2xx_set_calibration(struct ina2xx_chip_info *chip) { - u16 regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, - chip->shunt_resistor_uohm); - - return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); + return regmap_write(chip->regmap, INA2XX_CALIBRATION, + chip->config->calibration_value); } +/* + * As the calibration register is fixed, the product of current_lsb + * and shunt_resistor should also be fixed and equal + * to shunt_voltage_lsb. Current_lsb will be calculated in read_raw() + */ static int set_shunt_resistor(struct ina2xx_chip_info *chip, unsigned int val) { - if (val <= 0 || val > chip->config->calibration_factor) + if (val == 0 || val > INT_MAX) return -EINVAL; chip->shunt_resistor_uohm = val; @@ -592,11 +595,6 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, if (ret) return ret; - /* Update the Calibration register */ - ret = ina2xx_set_calibration(chip); - if (ret) - return ret; - return len; }