From patchwork Mon Dec 18 08:43:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maciej Purski X-Patchwork-Id: 10118461 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 E27B66057F for ; Mon, 18 Dec 2017 08:44:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D0C1A2888B for ; Mon, 18 Dec 2017 08:44:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C572528E37; Mon, 18 Dec 2017 08:44:15 +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=unavailable 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 47A8928E14 for ; Mon, 18 Dec 2017 08:44:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758097AbdLRIoO (ORCPT ); Mon, 18 Dec 2017 03:44:14 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:51538 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757935AbdLRIoM (ORCPT ); Mon, 18 Dec 2017 03:44:12 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20171218084409euoutp01b7eee1924f1aeefe92a5d4fbdbc81f1a~BVwnwDSIU2152021520euoutp011; Mon, 18 Dec 2017 08:44:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20171218084409euoutp01b7eee1924f1aeefe92a5d4fbdbc81f1a~BVwnwDSIU2152021520euoutp011 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1513586650; bh=/2YJ1f3R9yRczbXkGv/UU4V45q2x10gPYCJPYtPAAv0=; h=From:To:Cc:Subject:Date:References:From; b=YGfqpRJ4SU1Qs3rn0gMkj6Z8b7JkeAKJO3qB9Fc2s5IsA76FhsZ1s6SEjFZRaWO5D d54mnyv1nvqL3fbE4uZmH0ew8QBf73SN34/ROC3UntnvHh07c4Z/r/0cvvN2s/Q7SZ gpXOOjCId+3a/+ipF39eRgGRlfg1Aaj5/v4mGyxE= Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20171218084409eucas1p12f4297d41f704e217d5a4bd84f02b474~BVwnIS4uq2242322423eucas1p1X; Mon, 18 Dec 2017 08:44:09 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 1B.48.12907.8DF773A5; Mon, 18 Dec 2017 08:44:09 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20171218084408eucas1p16889c413d8d983e70b43732347f22e01~BVwmV8Dw72207722077eucas1p1I; Mon, 18 Dec 2017 08:44:08 +0000 (GMT) X-AuditID: cbfec7f1-f793a6d00000326b-94-5a377fd83d86 Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id BE.8F.20118.8DF773A5; Mon, 18 Dec 2017 08:44:08 +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 <0P150035HEXDV940@eusync2.samsung.com>; Mon, 18 Dec 2017 08:44:08 +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 v4] iio: adc: ina2xx: Make calibration register value fixed Date: Mon, 18 Dec 2017 09:43:58 +0100 Message-id: <1513586638-6036-1-git-send-email-m.purski@samsung.com> X-Mailer: git-send-email 2.7.4 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrAIsWRmVeSWpSXmKPExsWy7djPc7o3682jDF4/YbTYOGM9q8XZCYEW D5pWMVns+v+G2WLJ5PmsFu2vtzJazDvyjsXi8q45bBZPFp5hsljw8haLxdojd9ktfu86xm7R eGoOqwOvx4ePcR6bVnWyeSx5c4jV43zzEUaPnd8b2D3O33vL5tG3ZRWjx/otV1k8Pm+SC+CM 4rJJSc3JLEst0rdL4MrYO7GTvaBVs+Lq4p/MDYzrFLoYOTkkBEwkfrfcY4awxSQu3FvP1sXI xSEksJRRYtfXU+wQzmdGie1HFjDBdCza1s8EkVjGKNHw7glU1X9GiW03prJ2MXJwsAloSaxp jwdpEBEIl/j4vpURpIZZYCmzxOfZD8D2CQt4S0x7doURxGYRUJX43/QPzOYVcJY4ufANK8Q2 OYmb5zqZQZolBA6wSXyY3cgIkXCRmPdiK1SRsMSr41vYIWwZicuTu1kg7GqJi193sUHYNRKN tzdA1VhLfJ60BewIZgE+iUnbpjODHC0hwCvR0SYEUeIhce33fahyR4nnU9aA/SUkECvRsJh7 AqPUAkaGVYwiqaXFuempxUZ6xYm5xaV56XrJ+bmbGIHxfvrf8Y87GN+fsDrEKMDBqMTDW3DR LEqINbGsuDL3EKMEB7OSCG9qsXmUEG9KYmVValF+fFFpTmrxIUZpDhYlcV7bqLZIIYH0xJLU 7NTUgtQimCwTB6dUA+Mk1fnOes4hl9aacHGqeqrG5P1TVzk4T80l8kBQ7qKtwdq9S4sONC9h XtptlcWeJTMpQdvWck3USj3XrKxs0d7VrR9f3xB+vsd5Q0IiQ+WqaaeDNns+9s6TYUjWTXJa 3P3wwN8ZT9UetR9dPSGYYXb9Kra8L95f+LVrXEszmU+Gh52QmvHBQomlOCPRUIu5qDgRAMs5 TarzAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrNLMWRmVeSWpSXmKPExsVy+t/xK7o36s2jDA7+kLTYOGM9q8XZCYEW D5pWMVns+v+G2WLJ5PmsFu2vtzJazDvyjsXi8q45bBZPFp5hsljw8haLxdojd9ktfu86xm7R eGoOqwOvx4ePcR6bVnWyeSx5c4jV43zzEUaPnd8b2D3O33vL5tG3ZRWjx/otV1k8Pm+SC+CM 4rJJSc3JLEst0rdL4MrYO7GTvaBVs+Lq4p/MDYzrFLoYOTkkBEwkFm3rZ4KwxSQu3FvP1sXI xSEksIRR4snlTSwQTiOTxNIzZxi7GDk42AS0JNa0x4M0iAiESyx984EZpIZZYDmzxJHubawg CWEBb4lpz64wgtgsAqoS/5v+gdm8As4SJxe+YYXYJidx81wn8wRG7gWMDKsYRVJLi3PTc4uN 9IoTc4tL89L1kvNzNzECg3DbsZ9bdjB2vQs+xCjAwajEw1tw0SxKiDWxrLgy9xCjBAezkghv arF5lBBvSmJlVWpRfnxRaU5q8SFGaQ4WJXHe3j2rI4UE0hNLUrNTUwtSi2CyTBycUg2MK260 dWx1KrnPWb+dJdctMOX0VjOGtOWN925dP/Hett5PeN2N5rkKRbknf6eeOD1nq9XRHUHtM/e5 hFR7PdCoCVzVvtpvfm6Ox0+RgvMv81ebXpK+Uc/jf9yc55kf270Cp9cFqUu2PXJe+rZya1bc /MtTggK7Qqzmqd5vn+R4JuutxN2FdVMclFiKMxINtZiLihMB6RAzaT4CAAA= X-CMS-MailID: 20171218084408eucas1p16889c413d8d983e70b43732347f22e01 X-Msg-Generator: CA CMS-TYPE: 201P X-CMS-RootMailID: 20171218084408eucas1p16889c413d8d983e70b43732347f22e01 X-RootMTR: 20171218084408eucas1p16889c413d8d983e70b43732347f22e01 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 Reviewed-by: Stefan BrĂ¼ns --- Changes in v4: - fix comments 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 | 64 +++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index ddf8781..9e8ca12 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -124,11 +124,12 @@ 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 */ + /* fixed relation between current and power lsb, uW/uA */ + int power_lsb_factor; enum ina2xx_ids chip_id; }; @@ -149,20 +150,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, }, }; @@ -227,16 +228,26 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, *val2 = 1000; return IIO_VAL_FRACTIONAL; - case INA2XX_POWER: - /* processed (mW) = raw*lsb (uW) / 1000 */ - *val = chip->config->power_lsb; - *val2 = 1000; + case INA2XX_CURRENT: + /* + * processed (mA) = raw * current_lsb (mA) + * current_lsb (mA) = shunt_voltage_lsb (nV) / + * shunt_resistor (uOhm) + */ + *val = 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; + case INA2XX_POWER: + /* + * processed (mW) = raw * power_lsb (mW) + * power_lsb (mW) = power_lsb_factor (mW/mA) * + * current_lsb (mA) + */ + *val = chip->config->power_lsb_factor * + chip->config->shunt_voltage_lsb; + *val2 = chip->shunt_resistor_uohm; + return IIO_VAL_FRACTIONAL; } case IIO_CHAN_INFO_HARDWAREGAIN: @@ -541,25 +552,21 @@ 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); } 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 +599,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; }