From patchwork Sat Dec 23 17:16:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 10131641 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 B3B146019D for ; Sat, 23 Dec 2017 17:16:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EBE81292C4 for ; Sat, 23 Dec 2017 17:16:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E027C292E1; Sat, 23 Dec 2017 17:16:54 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI 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 EEBEB292C4 for ; Sat, 23 Dec 2017 17:16:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756877AbdLWRQy (ORCPT ); Sat, 23 Dec 2017 12:16:54 -0500 Received: from mail-wm0-f68.google.com ([74.125.82.68]:38053 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753091AbdLWRQx (ORCPT ); Sat, 23 Dec 2017 12:16:53 -0500 Received: by mail-wm0-f68.google.com with SMTP id 64so26483988wme.3 for ; Sat, 23 Dec 2017 09:16:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=d2q5EijypgbP8RPUI8Fi78iUSsZjT0pRfKnSe01jIso=; b=KY/3voEZHalocLeCE35Sl+NrlKN+Lb6rSF3g/gV+6sxVu0TUvbmCJyPL23ljHeGltY BoVyxyyn6I8yizsZURLxYGOdiyFvzPfDceYv0NWEhCBftc/zPGQa4FwwRnnhEAUWN9uo 9g+M0BHNctfvLhrSnGRw2hERT466lg6tre9y9bb0oYwwNX4Ku5+xjUg5d9K96snGJr+D O4n1qonoK5PuMC813POoWfIj1SGLLWXAclJX7z+5EHoklUBdKGVB97LGu62TctPM5QHe Jv++jlcJ5zxhs6V6kV+czcfiLjHECmP/QvUY/kHhdHWkj8EfkSYy7kB02ca0ryNKjJlb 5DwQ== X-Gm-Message-State: AKGB3mK/GPoU/5UW40fgAmSOGtxD2iAdQaEKwIR+RHsds9EmbmZ3lkGT MedrooeiZl5ZIoa7SR1dbbwcEzGAfm8= X-Google-Smtp-Source: ACJfBouOriVYQ7vLnNmpgQYuxpl2OFzDWHDOgwH8tT5122qRDaX7lUODpN+ne8nuC4EbH/4wd9MgXw== X-Received: by 10.80.216.202 with SMTP id y10mr20047510edj.221.1514049412072; Sat, 23 Dec 2017 09:16:52 -0800 (PST) Received: from localhost.net ([95.232.21.242]) by smtp.gmail.com with ESMTPSA id y3sm22980643edb.37.2017.12.23.09.16.50 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 23 Dec 2017 09:16:51 -0800 (PST) From: Lorenzo Bianconi To: jic23@kernel.org Cc: linux-iio@vger.kernel.org Subject: [PATCH 2/2] iio: humidity: hts221: add regmap API support Date: Sat, 23 Dec 2017 18:16:21 +0100 Message-Id: X-Mailer: git-send-email 2.13.6 In-Reply-To: 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 Introduce regmap API support to access to i2c/spi bus instead of using a custom support. Remove lock mutex since concurrency is already managed by regmap API Signed-off-by: Lorenzo Bianconi --- drivers/iio/humidity/Kconfig | 2 + drivers/iio/humidity/hts221.h | 27 ++++-------- drivers/iio/humidity/hts221_buffer.c | 20 ++++----- drivers/iio/humidity/hts221_core.c | 84 ++++++++++-------------------------- drivers/iio/humidity/hts221_i2c.c | 64 ++++++++------------------- drivers/iio/humidity/hts221_spi.c | 79 ++++++++------------------------- 6 files changed, 76 insertions(+), 200 deletions(-) diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig index 2c0fc9a400b8..1a0d458e4f4e 100644 --- a/drivers/iio/humidity/Kconfig +++ b/drivers/iio/humidity/Kconfig @@ -68,10 +68,12 @@ config HTS221 config HTS221_I2C tristate depends on HTS221 + select REGMAP_I2C config HTS221_SPI tristate depends on HTS221 + select REGMAP_SPI config HTU21 tristate "Measurement Specialties HTU21 humidity & temperature sensor" diff --git a/drivers/iio/humidity/hts221.h b/drivers/iio/humidity/hts221.h index c581af8c0f5d..00596879010e 100644 --- a/drivers/iio/humidity/hts221.h +++ b/drivers/iio/humidity/hts221.h @@ -15,21 +15,8 @@ #include -#define HTS221_RX_MAX_LENGTH 8 -#define HTS221_TX_MAX_LENGTH 8 - #define HTS221_DATA_SIZE 2 -struct hts221_transfer_buffer { - u8 rx_buf[HTS221_RX_MAX_LENGTH]; - u8 tx_buf[HTS221_TX_MAX_LENGTH] ____cacheline_aligned; -}; - -struct hts221_transfer_function { - int (*read)(struct device *dev, u8 addr, int len, u8 *data); - int (*write)(struct device *dev, u8 addr, int len, u8 *data); -}; - enum hts221_sensor_type { HTS221_SENSOR_H, HTS221_SENSOR_T, @@ -44,8 +31,8 @@ struct hts221_sensor { struct hts221_hw { const char *name; struct device *dev; + struct regmap *regmap; - struct mutex lock; struct iio_trigger *trig; int irq; @@ -53,16 +40,18 @@ struct hts221_hw { bool enabled; u8 odr; - - const struct hts221_transfer_function *tf; - struct hts221_transfer_buffer tb; }; extern const struct dev_pm_ops hts221_pm_ops; -int hts221_write_with_mask(struct hts221_hw *hw, u8 addr, u8 mask, u8 val); +static inline int hts221_write_with_mask(struct hts221_hw *hw, u8 addr, + u8 mask, u8 val) +{ + return regmap_update_bits(hw->regmap, addr, mask, val << __ffs(mask)); +} + int hts221_probe(struct device *dev, int irq, const char *name, - const struct hts221_transfer_function *tf_ops); + struct regmap *regmap); int hts221_set_enable(struct hts221_hw *hw, bool enable); int hts221_allocate_buffers(struct hts221_hw *hw); int hts221_allocate_trigger(struct hts221_hw *hw); diff --git a/drivers/iio/humidity/hts221_buffer.c b/drivers/iio/humidity/hts221_buffer.c index e971ea425268..b1141acfd100 100644 --- a/drivers/iio/humidity/hts221_buffer.c +++ b/drivers/iio/humidity/hts221_buffer.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -38,12 +39,9 @@ static int hts221_trig_set_state(struct iio_trigger *trig, bool state) { struct iio_dev *iio_dev = iio_trigger_get_drvdata(trig); struct hts221_hw *hw = iio_priv(iio_dev); - int err; - err = hts221_write_with_mask(hw, HTS221_REG_DRDY_EN_ADDR, + return hts221_write_with_mask(hw, HTS221_REG_DRDY_EN_ADDR, HTS221_REG_DRDY_EN_MASK, state); - - return err < 0 ? err : 0; } static const struct iio_trigger_ops hts221_trigger_ops = { @@ -53,11 +51,9 @@ static const struct iio_trigger_ops hts221_trigger_ops = { static irqreturn_t hts221_trigger_handler_thread(int irq, void *private) { struct hts221_hw *hw = private; - u8 status; - int err; + int err, status; - err = hw->tf->read(hw->dev, HTS221_REG_STATUS_ADDR, sizeof(status), - &status); + err = regmap_read(hw->regmap, HTS221_REG_STATUS_ADDR, &status); if (err < 0) return IRQ_HANDLED; @@ -171,15 +167,15 @@ static irqreturn_t hts221_buffer_handler_thread(int irq, void *p) /* humidity data */ ch = &iio_dev->channels[HTS221_SENSOR_H]; - err = hw->tf->read(hw->dev, ch->address, HTS221_DATA_SIZE, - buffer); + err = regmap_bulk_read(hw->regmap, ch->address, + buffer, HTS221_DATA_SIZE); if (err < 0) goto out; /* temperature data */ ch = &iio_dev->channels[HTS221_SENSOR_T]; - err = hw->tf->read(hw->dev, ch->address, HTS221_DATA_SIZE, - buffer + HTS221_DATA_SIZE); + err = regmap_bulk_read(hw->regmap, ch->address, + buffer + HTS221_DATA_SIZE, HTS221_DATA_SIZE); if (err < 0) goto out; diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c index d3f7904766bd..b9665846b26f 100644 --- a/drivers/iio/humidity/hts221_core.c +++ b/drivers/iio/humidity/hts221_core.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "hts221.h" @@ -131,38 +132,11 @@ static const struct iio_chan_spec hts221_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(2), }; -int hts221_write_with_mask(struct hts221_hw *hw, u8 addr, u8 mask, u8 val) -{ - u8 data; - int err; - - mutex_lock(&hw->lock); - - err = hw->tf->read(hw->dev, addr, sizeof(data), &data); - if (err < 0) { - dev_err(hw->dev, "failed to read %02x register\n", addr); - goto unlock; - } - - data = (data & ~mask) | ((val << __ffs(mask)) & mask); - - err = hw->tf->write(hw->dev, addr, sizeof(data), &data); - if (err < 0) - dev_err(hw->dev, "failed to write %02x register\n", addr); - -unlock: - mutex_unlock(&hw->lock); - - return err; -} - static int hts221_check_whoami(struct hts221_hw *hw) { - u8 data; - int err; + int err, data; - err = hw->tf->read(hw->dev, HTS221_REG_WHOAMI_ADDR, sizeof(data), - &data); + err = regmap_read(hw->regmap, HTS221_REG_WHOAMI_ADDR, &data); if (err < 0) { dev_err(hw->dev, "failed to read whoami register\n"); return err; @@ -286,35 +260,31 @@ int hts221_set_enable(struct hts221_hw *hw, bool enable) static int hts221_parse_temp_caldata(struct hts221_hw *hw) { - int err, *slope, *b_gen; + int err, *slope, *b_gen, cal0, cal1; s16 cal_x0, cal_x1, cal_y0, cal_y1; - u8 cal0, cal1; - err = hw->tf->read(hw->dev, HTS221_REG_0T_CAL_Y_H, - sizeof(cal0), &cal0); + err = regmap_read(hw->regmap, HTS221_REG_0T_CAL_Y_H, &cal0); if (err < 0) return err; - err = hw->tf->read(hw->dev, HTS221_REG_T1_T0_CAL_Y_H, - sizeof(cal1), &cal1); + err = regmap_read(hw->regmap, HTS221_REG_T1_T0_CAL_Y_H, &cal1); if (err < 0) return err; cal_y0 = (le16_to_cpu(cal1 & 0x3) << 8) | cal0; - err = hw->tf->read(hw->dev, HTS221_REG_1T_CAL_Y_H, - sizeof(cal0), &cal0); + err = regmap_read(hw->regmap, HTS221_REG_1T_CAL_Y_H, &cal0); if (err < 0) return err; cal_y1 = (((cal1 & 0xc) >> 2) << 8) | cal0; - err = hw->tf->read(hw->dev, HTS221_REG_0T_CAL_X_L, sizeof(cal_x0), - (u8 *)&cal_x0); + err = regmap_bulk_read(hw->regmap, HTS221_REG_0T_CAL_X_L, + &cal_x0, sizeof(cal_x0)); if (err < 0) return err; cal_x0 = le16_to_cpu(cal_x0); - err = hw->tf->read(hw->dev, HTS221_REG_1T_CAL_X_L, sizeof(cal_x1), - (u8 *)&cal_x1); + err = regmap_bulk_read(hw->regmap, HTS221_REG_1T_CAL_X_L, + &cal_x1, sizeof(cal_x1)); if (err < 0) return err; cal_x1 = le16_to_cpu(cal_x1); @@ -332,30 +302,27 @@ static int hts221_parse_temp_caldata(struct hts221_hw *hw) static int hts221_parse_rh_caldata(struct hts221_hw *hw) { - int err, *slope, *b_gen; + int err, *slope, *b_gen, data; s16 cal_x0, cal_x1, cal_y0, cal_y1; - u8 data; - err = hw->tf->read(hw->dev, HTS221_REG_0RH_CAL_Y_H, sizeof(data), - &data); + err = regmap_read(hw->regmap, HTS221_REG_0RH_CAL_Y_H, &data); if (err < 0) return err; cal_y0 = data; - err = hw->tf->read(hw->dev, HTS221_REG_1RH_CAL_Y_H, sizeof(data), - &data); + err = regmap_read(hw->regmap, HTS221_REG_1RH_CAL_Y_H, &data); if (err < 0) return err; cal_y1 = data; - err = hw->tf->read(hw->dev, HTS221_REG_0RH_CAL_X_H, sizeof(cal_x0), - (u8 *)&cal_x0); + err = regmap_bulk_read(hw->regmap, HTS221_REG_0RH_CAL_X_H, + &cal_x0, sizeof(cal_x0)); if (err < 0) return err; cal_x0 = le16_to_cpu(cal_x0); - err = hw->tf->read(hw->dev, HTS221_REG_1RH_CAL_X_H, sizeof(cal_x1), - (u8 *)&cal_x1); + err = regmap_bulk_read(hw->regmap, HTS221_REG_1RH_CAL_X_H, + &cal_x1, sizeof(cal_x1)); if (err < 0) return err; cal_x1 = le16_to_cpu(cal_x1); @@ -440,7 +407,7 @@ static int hts221_read_oneshot(struct hts221_hw *hw, u8 addr, int *val) msleep(50); - err = hw->tf->read(hw->dev, addr, sizeof(data), data); + err = regmap_bulk_read(hw->regmap, addr, data, sizeof(data)); if (err < 0) return err; @@ -582,7 +549,7 @@ static const struct iio_info hts221_info = { static const unsigned long hts221_scan_masks[] = {0x3, 0x0}; int hts221_probe(struct device *dev, int irq, const char *name, - const struct hts221_transfer_function *tf_ops) + struct regmap *regmap) { struct iio_dev *iio_dev; struct hts221_hw *hw; @@ -599,9 +566,7 @@ int hts221_probe(struct device *dev, int irq, const char *name, hw->name = name; hw->dev = dev; hw->irq = irq; - hw->tf = tf_ops; - - mutex_init(&hw->lock); + hw->regmap = regmap; err = hts221_check_whoami(hw); if (err < 0) @@ -673,12 +638,9 @@ static int __maybe_unused hts221_suspend(struct device *dev) { struct iio_dev *iio_dev = dev_get_drvdata(dev); struct hts221_hw *hw = iio_priv(iio_dev); - int err; - - err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR, - HTS221_ENABLE_MASK, false); - return err < 0 ? err : 0; + return hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR, + HTS221_ENABLE_MASK, false); } static int __maybe_unused hts221_resume(struct device *dev) diff --git a/drivers/iio/humidity/hts221_i2c.c b/drivers/iio/humidity/hts221_i2c.c index 2c97350a0f76..b5b3f408a658 100644 --- a/drivers/iio/humidity/hts221_i2c.c +++ b/drivers/iio/humidity/hts221_i2c.c @@ -13,61 +13,33 @@ #include #include #include -#include "hts221.h" - -#define I2C_AUTO_INCREMENT 0x80 - -static int hts221_i2c_read(struct device *dev, u8 addr, int len, u8 *data) -{ - struct i2c_msg msg[2]; - struct i2c_client *client = to_i2c_client(dev); - - if (len > 1) - addr |= I2C_AUTO_INCREMENT; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].len = 1; - msg[0].buf = &addr; - - msg[1].addr = client->addr; - msg[1].flags = client->flags | I2C_M_RD; - msg[1].len = len; - msg[1].buf = data; - - return i2c_transfer(client->adapter, msg, 2); -} +#include -static int hts221_i2c_write(struct device *dev, u8 addr, int len, u8 *data) -{ - u8 send[len + 1]; - struct i2c_msg msg; - struct i2c_client *client = to_i2c_client(dev); - - if (len > 1) - addr |= I2C_AUTO_INCREMENT; - - send[0] = addr; - memcpy(&send[1], data, len * sizeof(u8)); - - msg.addr = client->addr; - msg.flags = client->flags; - msg.len = len + 1; - msg.buf = send; +#include "hts221.h" - return i2c_transfer(client->adapter, &msg, 1); -} +#define HTS221_I2C_AUTO_INCREMENT BIT(7) -static const struct hts221_transfer_function hts221_transfer_fn = { - .read = hts221_i2c_read, - .write = hts221_i2c_write, +static const struct regmap_config hts221_i2c_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .write_flag_mask = HTS221_I2C_AUTO_INCREMENT, + .read_flag_mask = HTS221_I2C_AUTO_INCREMENT, }; static int hts221_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct regmap *regmap; + + regmap = devm_regmap_init_i2c(client, &hts221_i2c_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&client->dev, "Failed to register i2c regmap %d\n", + (int)PTR_ERR(regmap)); + return PTR_ERR(regmap); + } + return hts221_probe(&client->dev, client->irq, - client->name, &hts221_transfer_fn); + client->name, regmap); } static const struct acpi_device_id hts221_acpi_match[] = { diff --git a/drivers/iio/humidity/hts221_spi.c b/drivers/iio/humidity/hts221_spi.c index 55b29b53b9d1..ea3aaec54035 100644 --- a/drivers/iio/humidity/hts221_spi.c +++ b/drivers/iio/humidity/hts221_spi.c @@ -12,76 +12,31 @@ #include #include #include -#include "hts221.h" - -#define SENSORS_SPI_READ 0x80 -#define SPI_AUTO_INCREMENT 0x40 - -static int hts221_spi_read(struct device *dev, u8 addr, int len, u8 *data) -{ - int err; - struct spi_device *spi = to_spi_device(dev); - struct iio_dev *iio_dev = spi_get_drvdata(spi); - struct hts221_hw *hw = iio_priv(iio_dev); - - struct spi_transfer xfers[] = { - { - .tx_buf = hw->tb.tx_buf, - .bits_per_word = 8, - .len = 1, - }, - { - .rx_buf = hw->tb.rx_buf, - .bits_per_word = 8, - .len = len, - } - }; - - if (len > 1) - addr |= SPI_AUTO_INCREMENT; - hw->tb.tx_buf[0] = addr | SENSORS_SPI_READ; - - err = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers)); - if (err < 0) - return err; - - memcpy(data, hw->tb.rx_buf, len * sizeof(u8)); +#include - return len; -} - -static int hts221_spi_write(struct device *dev, u8 addr, int len, u8 *data) -{ - struct spi_device *spi = to_spi_device(dev); - struct iio_dev *iio_dev = spi_get_drvdata(spi); - struct hts221_hw *hw = iio_priv(iio_dev); - - struct spi_transfer xfers = { - .tx_buf = hw->tb.tx_buf, - .bits_per_word = 8, - .len = len + 1, - }; - - if (len >= HTS221_TX_MAX_LENGTH) - return -ENOMEM; - - if (len > 1) - addr |= SPI_AUTO_INCREMENT; - hw->tb.tx_buf[0] = addr; - memcpy(&hw->tb.tx_buf[1], data, len); +#include "hts221.h" - return spi_sync_transfer(spi, &xfers, 1); -} +#define HTS221_SPI_AUTO_INCREMENT BIT(6) -static const struct hts221_transfer_function hts221_transfer_fn = { - .read = hts221_spi_read, - .write = hts221_spi_write, +static const struct regmap_config hts221_spi_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .write_flag_mask = HTS221_SPI_AUTO_INCREMENT, + .read_flag_mask = HTS221_SPI_AUTO_INCREMENT, }; static int hts221_spi_probe(struct spi_device *spi) { + struct regmap *regmap; + + regmap = devm_regmap_init_spi(spi, &hts221_spi_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&spi->dev, "Failed to register spi regmap %d\n", + (int)PTR_ERR(regmap)); + return PTR_ERR(regmap); + } return hts221_probe(&spi->dev, spi->irq, - spi->modalias, &hts221_transfer_fn); + spi->modalias, regmap); } static const struct of_device_id hts221_spi_of_match[] = {