From patchwork Fri Oct 12 16:26:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ben Whitten X-Patchwork-Id: 983169 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="GTHmYYo7"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42WtWx5FYWz9s3Z for ; Sat, 13 Oct 2018 03:26:53 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729009AbeJLX75 (ORCPT ); Fri, 12 Oct 2018 19:59:57 -0400 Received: from mail-wm1-f65.google.com ([209.85.128.65]:34881 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728744AbeJLX75 (ORCPT ); Fri, 12 Oct 2018 19:59:57 -0400 Received: by mail-wm1-f65.google.com with SMTP id e187-v6so13556288wmf.0; Fri, 12 Oct 2018 09:26:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=23da0w/qgoNPD0fMvWjJIhP0dLanI2/jb3uK9EmShR0=; b=GTHmYYo76zzVmg0IFdzJuCHVTlJnlsMx2i6nbPcBzxMUJZyy9OlwdxvaUfKifFWKh6 ZrqkbDfz4QQ0+Qbe5vme6LtJv05as9e5wr6rHVOR5uxjlFo7PXDnm6kf5SdHZBT3Sh7K 1krDTktJdoPNQjopQVZvuC4D6PKOrL1RygWT/wSj/rFv0n5h9GR1/NJx4YWLd8MU9U0Z i1oxAhozu4Ek9T+j+RhXd6vacYI5RUM9u1IXqE5QFnt/8jfrlvhtKpMNsXX0Ugix5QZK 9uqPoSY12RkLkPyP2O5gSjARE6kxUq93KYb7UxaH+Q/Bv+YSw9PgQNrNVo1+SsdoRQLt Rcaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=23da0w/qgoNPD0fMvWjJIhP0dLanI2/jb3uK9EmShR0=; b=lvvVkWeZf6hgAuHVNo7b2SPOkQL93HKqRIPmZNO5Eul350KcgJnGZulGUMAXqMYEIR 45Ib2EhPto3TLfawTK4t2Uqo6j2qR/HsURJPr7G6p1FObWU5qukEKMAy4ZOnSzfIcKdt oJ8Vo39xVTFSmBCqvkVtakmJrfbGVsVpEpSoKsm8xiHWvlWBD18Pb00jwCJtU8tUBorU JNqX4ZgamFeWVp5G3gnEoQlm2T2l3fj5jYgnwUD4i25s8otUQFhYhoTrFf0vFHllQDXW 2t94+FmAC0xXM0wrsRaDtpj3B04ii7qjuKec15EkAlKf/tqfYQrOTf6UpbR3oAPadAOL OC5Q== X-Gm-Message-State: ABuFfoh+ucSndhQE557aHtjCwbSxLTyVcAHXxJVnBS+Vh9xzfC3/9yQS 4+X9COs7IJ+X9j6bexm/x3Q= X-Google-Smtp-Source: ACcGV63mviExopDVadMYJuZqJC3WsWiIoTw6FNcHjWi1sKeSKbINQi/v8D1ug6OEbE+uOm2o72kwBw== X-Received: by 2002:a1c:91cd:: with SMTP id t196-v6mr5440240wmd.63.1539361599071; Fri, 12 Oct 2018 09:26:39 -0700 (PDT) Received: from Sarah.corp.lairdtech.com ([109.174.151.67]) by smtp.gmail.com with ESMTPSA id t198-v6sm1736842wmd.9.2018.10.12.09.26.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 12 Oct 2018 09:26:38 -0700 (PDT) From: Ben Whitten X-Google-Original-From: Ben Whitten To: afaerber@suse.de Cc: starnight@g.ncu.edu.tw, hasnain.virk@arm.com, netdev@vger.kernel.org, liuxuenetmail@gmail.com, shess@hessware.de, Ben Whitten , Mark Brown , Greg Kroah-Hartman , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH v3 lora-next 1/5] regmap: Add regmap_noinc_write API Date: Fri, 12 Oct 2018 17:26:02 +0100 Message-Id: <1539361567-3602-2-git-send-email-ben.whitten@lairdtech.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> References: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The regmap API had a noinc_read function added for instances where devices supported returning data from an internal FIFO in a single read. This commit adds the noinc_write variant to allow writing to a non incrementing register, this is used in devices such as the sx1301 for loading firmware. Signed-off-by: Ben Whitten Reviewed-by: Andreas Färber --- drivers/base/regmap/internal.h | 3 ++ drivers/base/regmap/regmap.c | 77 ++++++++++++++++++++++++++++++++++++++++++ include/linux/regmap.h | 19 +++++++++++ 3 files changed, 99 insertions(+) diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index a6bf34d63..404f123 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -94,11 +94,13 @@ struct regmap { bool (*readable_reg)(struct device *dev, unsigned int reg); bool (*volatile_reg)(struct device *dev, unsigned int reg); bool (*precious_reg)(struct device *dev, unsigned int reg); + bool (*writeable_noinc_reg)(struct device *dev, unsigned int reg); bool (*readable_noinc_reg)(struct device *dev, unsigned int reg); const struct regmap_access_table *wr_table; const struct regmap_access_table *rd_table; const struct regmap_access_table *volatile_table; const struct regmap_access_table *precious_table; + const struct regmap_access_table *wr_noinc_table; const struct regmap_access_table *rd_noinc_table; int (*reg_read)(void *context, unsigned int reg, unsigned int *val); @@ -183,6 +185,7 @@ bool regmap_writeable(struct regmap *map, unsigned int reg); bool regmap_readable(struct regmap *map, unsigned int reg); bool regmap_volatile(struct regmap *map, unsigned int reg); bool regmap_precious(struct regmap *map, unsigned int reg); +bool regmap_writeable_noinc(struct regmap *map, unsigned int reg); bool regmap_readable_noinc(struct regmap *map, unsigned int reg); int _regmap_write(struct regmap *map, unsigned int reg, diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 0360a90..d4f1fc6 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -168,6 +168,17 @@ bool regmap_precious(struct regmap *map, unsigned int reg) return false; } +bool regmap_writeable_noinc(struct regmap *map, unsigned int reg) +{ + if (map->writeable_noinc_reg) + return map->writeable_noinc_reg(map->dev, reg); + + if (map->wr_noinc_table) + return regmap_check_range_table(map, reg, map->wr_noinc_table); + + return true; +} + bool regmap_readable_noinc(struct regmap *map, unsigned int reg) { if (map->readable_noinc_reg) @@ -777,11 +788,13 @@ struct regmap *__regmap_init(struct device *dev, map->rd_table = config->rd_table; map->volatile_table = config->volatile_table; map->precious_table = config->precious_table; + map->wr_noinc_table = config->wr_noinc_table; map->rd_noinc_table = config->rd_noinc_table; map->writeable_reg = config->writeable_reg; map->readable_reg = config->readable_reg; map->volatile_reg = config->volatile_reg; map->precious_reg = config->precious_reg; + map->writeable_noinc_reg = config->writeable_noinc_reg; map->readable_noinc_reg = config->readable_noinc_reg; map->cache_type = config->cache_type; @@ -1298,6 +1311,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) map->readable_reg = config->readable_reg; map->volatile_reg = config->volatile_reg; map->precious_reg = config->precious_reg; + map->writeable_noinc_reg = config->writeable_noinc_reg; map->readable_noinc_reg = config->readable_noinc_reg; map->cache_type = config->cache_type; @@ -1898,6 +1912,69 @@ int regmap_raw_write(struct regmap *map, unsigned int reg, EXPORT_SYMBOL_GPL(regmap_raw_write); /** + * regmap_noinc_write(): Write data from a register without incrementing the + * register number + * + * @map: Register map to write to + * @reg: Register to write to + * @val: Pointer to data buffer + * @val_len: Length of output buffer in bytes. + * + * The regmap API usually assumes that bulk bus write operations will write a + * range of registers. Some devices have certain registers for which a write + * operation can write to an internal FIFO. + * + * The target register must be volatile but registers after it can be + * completely unrelated cacheable registers. + * + * This will attempt multiple writes as required to write val_len bytes. + * + * A value of zero will be returned on success, a negative errno will be + * returned in error cases. + */ +int regmap_noinc_write(struct regmap *map, unsigned int reg, + const void *val, size_t val_len) +{ + size_t write_len; + int ret; + + if (!map->bus) + return -EINVAL; + if (!map->bus->write) + return -ENOTSUPP; + if (val_len % map->format.val_bytes) + return -EINVAL; + if (!IS_ALIGNED(reg, map->reg_stride)) + return -EINVAL; + if (val_len == 0) + return -EINVAL; + + map->lock(map->lock_arg); + + if (!regmap_volatile(map, reg) || !regmap_writeable_noinc(map, reg)) { + ret = -EINVAL; + goto out_unlock; + } + + while (val_len) { + if (map->max_raw_write && map->max_raw_write < val_len) + write_len = map->max_raw_write; + else + write_len = val_len; + ret = _regmap_raw_write(map, reg, val, write_len); + if (ret) + goto out_unlock; + val = ((u8 *)val) + write_len; + val_len -= write_len; + } + +out_unlock: + map->unlock(map->lock_arg); + return ret; +} +EXPORT_SYMBOL_GPL(regmap_noinc_write); + +/** * regmap_field_update_bits_base() - Perform a read/modify/write cycle a * register field. * diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 379505a..de04dc4 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -268,6 +268,13 @@ typedef void (*regmap_unlock)(void *); * field is NULL but precious_table (see below) is not, the * check is performed on such table (a register is precious if * it belongs to one of the ranges specified by precious_table). + * @writeable_noinc_reg: Optional callback returning true if the register + * supports multiple write operations without incrementing + * the register number. If this field is NULL but + * wr_noinc_table (see below) is not, the check is + * performed on such table (a register is no increment + * writeable if it belongs to one of the ranges specified + * by wr_noinc_table). * @readable_noinc_reg: Optional callback returning true if the register * supports multiple read operations without incrementing * the register number. If this field is NULL but @@ -302,6 +309,7 @@ typedef void (*regmap_unlock)(void *); * @rd_table: As above, for read access. * @volatile_table: As above, for volatile registers. * @precious_table: As above, for precious registers. + * @wr_noinc_table: As above, for no increment writeable registers. * @rd_noinc_table: As above, for no increment readable registers. * @reg_defaults: Power on reset values for registers (for use with * register cache support). @@ -352,6 +360,7 @@ struct regmap_config { bool (*readable_reg)(struct device *dev, unsigned int reg); bool (*volatile_reg)(struct device *dev, unsigned int reg); bool (*precious_reg)(struct device *dev, unsigned int reg); + bool (*writeable_noinc_reg)(struct device *dev, unsigned int reg); bool (*readable_noinc_reg)(struct device *dev, unsigned int reg); bool disable_locking; @@ -369,6 +378,7 @@ struct regmap_config { const struct regmap_access_table *rd_table; const struct regmap_access_table *volatile_table; const struct regmap_access_table *precious_table; + const struct regmap_access_table *wr_noinc_table; const struct regmap_access_table *rd_noinc_table; const struct reg_default *reg_defaults; unsigned int num_reg_defaults; @@ -979,6 +989,8 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val); int regmap_write_async(struct regmap *map, unsigned int reg, unsigned int val); int regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len); +int regmap_noinc_write(struct regmap *map, unsigned int reg, + const void *val, size_t val_len); int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, size_t val_count); int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs, @@ -1222,6 +1234,13 @@ static inline int regmap_raw_write_async(struct regmap *map, unsigned int reg, return -EINVAL; } +static inline int regmap_noinc_write(struct regmap *map, unsigned int reg, + const void *val, size_t val_len) +{ + WARN_ONCE(1, "regmap API is disabled"); + return -EINVAL; +} + static inline int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, size_t val_count) { From patchwork Fri Oct 12 16:26:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Whitten X-Patchwork-Id: 983175 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ns7HCyyi"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42WtXY3zKVz9s3Z for ; Sat, 13 Oct 2018 03:27:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729125AbeJMAAI (ORCPT ); Fri, 12 Oct 2018 20:00:08 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:46363 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729086AbeJMAAH (ORCPT ); Fri, 12 Oct 2018 20:00:07 -0400 Received: by mail-wr1-f67.google.com with SMTP id n11-v6so13987861wru.13; Fri, 12 Oct 2018 09:26:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=mat2nPClyH8OZFkoDv8q+tL0+LVOi6YVRjAlX7dy2ug=; b=Ns7HCyyikkEuSK7L1GUt/jf4gkOJsg1yjjKmZYgWP8c2UAXtQiaoPiN9OqF/cnxEqD /5jXAs7JMVfPy5k1j2cJWx8esMMQO8Mu3Y+wfKPUrDxGYVRD5spA4Oxs1zOcWw+T8aMA 7sh5M2I6VNBayxsNzme4V7Wp/prXDNwh35mf3YinVV1eJ+MENYmELX1LaLjep9Z/zFKi JI14GgaLn10E1ky/5ZzT7a6wuBIauSeIwxQ/nHxe4XeUHvHp+ODN20WmD5IB31XweIxX IYlu47wY+aPdRKgYgL3DHL8k6UDdTix4OeI79PI3PqESjiqkyiCljWH7PUrNAUgin6Vd K/+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=mat2nPClyH8OZFkoDv8q+tL0+LVOi6YVRjAlX7dy2ug=; b=K625ZqSu3/yLS7/xpFrV9cSSCrPbKYBpDdUjDgJIA2WruYN0lGs1P3VAaW1XVoZ2U7 S4vL8kiHQp898geHFaDY6GwLdx6vGhK3FXTLkXeTMmTifRcINECK3gnJM0dnci8CteHa fJVDa3Q+dZrNxd1LVR2rEeOLHJPdONUGn303BFIogFwbUO73vqYYOBz4dFJUpNmT3oqc nyGrgfQlHCeXme70iFQYxhYflyVCJ2i7xlP89kX5GTBZn5O27th1hk/JC1anzMwQm+dF 8Abs/07ILw/Z8/MaJpysesd7f4CLKUtggRZSdnXlGSqtloyxcu81QnFOo8pL0jQ0ya4A XZkQ== X-Gm-Message-State: ABuFfojvWbYvtVSQlOZQz+j6iIWjOWL6n8RZYmeys0mvrz6eBawyGR4u NjF2TWmQJLMfJ/2qDQes1EY= X-Google-Smtp-Source: ACcGV63SWRCq7z7Oyas0cDpn/T0b+k2uYffJ6Wo9mMqhtAozmawsowhpjgzpsgygbfq9Cj8a+o67fw== X-Received: by 2002:a5d:694c:: with SMTP id r12-v6mr5581651wrw.170.1539361610284; Fri, 12 Oct 2018 09:26:50 -0700 (PDT) Received: from Sarah.corp.lairdtech.com ([109.174.151.67]) by smtp.gmail.com with ESMTPSA id t198-v6sm1736842wmd.9.2018.10.12.09.26.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 12 Oct 2018 09:26:49 -0700 (PDT) From: Ben Whitten X-Google-Original-From: Ben Whitten To: afaerber@suse.de Cc: starnight@g.ncu.edu.tw, hasnain.virk@arm.com, netdev@vger.kernel.org, liuxuenetmail@gmail.com, shess@hessware.de, Ben Whitten , "David S. Miller" , linux-kernel@vger.kernel.org Subject: [PATCH v3 lora-next 2/5] net: lora: sx1301: replace burst spi functions with regmap_noinc Date: Fri, 12 Oct 2018 17:26:03 +0100 Message-Id: <1539361567-3602-3-git-send-email-ben.whitten@lairdtech.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> References: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org We can now use to regmap_noinc API to allow reading and writing to the internal FIFO register which controls processor memory. We also remove the now defunct spi element from the structure as this completes the move to regmap. Signed-off-by: Ben Whitten --- drivers/net/lora/sx1301.c | 22 ++-------------------- drivers/net/lora/sx1301.h | 2 -- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/net/lora/sx1301.c b/drivers/net/lora/sx1301.c index fd29258..9c85fe7 100644 --- a/drivers/net/lora/sx1301.c +++ b/drivers/net/lora/sx1301.c @@ -74,23 +74,6 @@ static struct regmap_config sx1301_regmap_config = { .max_register = SX1301_MAX_REGISTER, }; -static int sx1301_read_burst(struct sx1301_priv *priv, u8 reg, u8 *val, size_t len) -{ - u8 addr = reg & 0x7f; - return spi_write_then_read(priv->spi, &addr, 1, val, len); -} - -static int sx1301_write_burst(struct sx1301_priv *priv, u8 reg, const u8 *val, size_t len) -{ - u8 addr = reg | BIT(7); - struct spi_transfer xfr[2] = { - { .tx_buf = &addr, .len = 1 }, - { .tx_buf = val, .len = len }, - }; - - return spi_sync_transfer(priv->spi, xfr, 2); -} - static int sx1301_soft_reset(struct sx1301_priv *priv) { return regmap_write(priv->regmap, SX1301_PAGE, REG_PAGE_RESET_SOFT_RESET); @@ -180,7 +163,7 @@ static int sx1301_load_firmware(struct sx1301_priv *priv, int mcu, const struct return ret; } - ret = sx1301_write_burst(priv, SX1301_MPD, fw->data, fw->size); + ret = regmap_noinc_write(priv->regmap, SX1301_MPD, fw->data, fw->size); if (ret) { dev_err(priv->dev, "MCU prom data write failed\n"); return ret; @@ -196,7 +179,7 @@ static int sx1301_load_firmware(struct sx1301_priv *priv, int mcu, const struct if (!buf) return -ENOMEM; - ret = sx1301_read_burst(priv, SX1301_MPD, buf, fw->size); + ret = regmap_noinc_read(priv->regmap, SX1301_MPD, buf, fw->size); if (ret) { dev_err(priv->dev, "MCU prom data read failed\n"); kfree(buf); @@ -566,7 +549,6 @@ static int sx1301_probe(struct spi_device *spi) spi_set_drvdata(spi, netdev); priv->dev = &spi->dev; - priv->spi = spi; priv->regmap = devm_regmap_init_spi(spi, &sx1301_regmap_config); if (IS_ERR(priv->regmap)) { diff --git a/drivers/net/lora/sx1301.h b/drivers/net/lora/sx1301.h index e939c02..e6400f8 100644 --- a/drivers/net/lora/sx1301.h +++ b/drivers/net/lora/sx1301.h @@ -12,7 +12,6 @@ #include #include #include -#include #define SX1301_CHIP_VERSION 103 @@ -64,7 +63,6 @@ struct sx1301_priv { struct lora_dev_priv lora; struct device *dev; - struct spi_device *spi; struct gpio_desc *rst_gpio; struct regmap *regmap; }; From patchwork Fri Oct 12 16:26:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Whitten X-Patchwork-Id: 983170 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="uYGLTF06"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42WtX052mQz9s3Z for ; Sat, 13 Oct 2018 03:26:56 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729208AbeJMAAL (ORCPT ); Fri, 12 Oct 2018 20:00:11 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:37575 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729086AbeJMAAK (ORCPT ); Fri, 12 Oct 2018 20:00:10 -0400 Received: by mail-wr1-f68.google.com with SMTP id y11-v6so14067994wrd.4; Fri, 12 Oct 2018 09:26:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=wWtu2dMp8UhwRbU3BwxSI2ynqCJj/uyJ/bC0hrHmYd4=; b=uYGLTF06V16IxrpB9a6SmyEad5qA6BmGLIWclTHvAprwtNAnR2PWMy8h5qUdLyOHNu T/VCQanlyTWpW1f6+hphzjp/FHqA7ULogm9BCIdujstG98Pjm/pRmUdSjfyeZJmw1WsM ZCOmXxVTON29efKbk9yGBahwwMMaMQdvQzEQuYFW/Q9+BcAbyK/22Yqi3UbxDA1O55ut Wi6jwNerPWTNt1S+HCUPkSE1TTI54Cj8g+7hCkgBKNtzVu7ghUrsF2vjxTOcmHVnKusj gOayEC5g0l2Dk7JI3UaqfVDB+dpHKOQEy+Kl9vPZhjpBb0zydL+n6+SaOlGqQfky7NqK SzYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=wWtu2dMp8UhwRbU3BwxSI2ynqCJj/uyJ/bC0hrHmYd4=; b=Zj4cLLKrKCRSFj8CqtI7xylexjy3bV40kzM8zsFCCAjKdy4ThnwamqIDJyGEAgT55z LyatHSIOkHtS8QgVEPmfcygtdOYd91psxjHiz0xFxlVCkJVR/rbyrHw+/O0dDaLL0ve+ TGxGs8r6fXzKlc2LM4LZsUmRwr0QWXihOBagTtqRqDfPHpWQttoyeVf0Zctl4TjPCYNp ZWoabGtstlXRh9qhvBgRgXsQXmh325Jmmrc13L3KA9O1eHe8wZuQRdQNc/s/DWS+KS9S qWfFwIxQKUkzpZjquKO+J4R8DtQgAtADh2IBbGOgZc0J2bjbDLBjnyMFY0k+vuAiUGwf sx8Q== X-Gm-Message-State: ABuFfogOMt0Vf/8npkUVY5DsVTzrEj8sWmHW9kX9aBRGPhjjxe4L7gE6 w9lNQMRm5ITJJL+Vx4Lej+4= X-Google-Smtp-Source: ACcGV63KlATn71/5w4Jx+FJEajc9HpYakzvYxor9tbQZwdhzTaQ1snvrILH6aX1cWyqoKFk0UUkxOQ== X-Received: by 2002:a5d:5649:: with SMTP id j9-v6mr5540943wrw.41.1539361612168; Fri, 12 Oct 2018 09:26:52 -0700 (PDT) Received: from Sarah.corp.lairdtech.com ([109.174.151.67]) by smtp.gmail.com with ESMTPSA id t198-v6sm1736842wmd.9.2018.10.12.09.26.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 12 Oct 2018 09:26:51 -0700 (PDT) From: Ben Whitten X-Google-Original-From: Ben Whitten To: afaerber@suse.de Cc: starnight@g.ncu.edu.tw, hasnain.virk@arm.com, netdev@vger.kernel.org, liuxuenetmail@gmail.com, shess@hessware.de, Ben Whitten , "David S. Miller" , linux-kernel@vger.kernel.org Subject: [PATCH v3 lora-next 3/5] net: lora: sx1301: convert to using regmap fields for bit ops Date: Fri, 12 Oct 2018 17:26:04 +0100 Message-Id: <1539361567-3602-4-git-send-email-ben.whitten@lairdtech.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> References: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ben Whitten We convert to using regmap fields to allow bit access to the registers where regmap handles the read update write. Signed-off-by: Ben Whitten --- drivers/net/lora/sx1301.c | 234 +++++++++++++--------------------------------- drivers/net/lora/sx1301.h | 46 +++++++++ 2 files changed, 110 insertions(+), 170 deletions(-) diff --git a/drivers/net/lora/sx1301.c b/drivers/net/lora/sx1301.c index 9c85fe7..339f8d9 100644 --- a/drivers/net/lora/sx1301.c +++ b/drivers/net/lora/sx1301.c @@ -24,27 +24,6 @@ #include "sx1301.h" -#define REG_PAGE_RESET_SOFT_RESET BIT(7) - -#define REG_16_GLOBAL_EN BIT(3) - -#define REG_17_CLK32M_EN BIT(0) - -#define REG_0_105_FORCE_HOST_RADIO_CTRL BIT(1) -#define REG_0_105_FORCE_HOST_FE_CTRL BIT(2) -#define REG_0_105_FORCE_DEC_FILTER_GAIN BIT(3) - -#define REG_0_MCU_RST_0 BIT(0) -#define REG_0_MCU_RST_1 BIT(1) -#define REG_0_MCU_SELECT_MUX_0 BIT(2) -#define REG_0_MCU_SELECT_MUX_1 BIT(3) - -#define REG_2_43_RADIO_A_EN BIT(0) -#define REG_2_43_RADIO_B_EN BIT(1) -#define REG_2_43_RADIO_RST BIT(2) - -#define REG_EMERGENCY_FORCE_HOST_CTRL BIT(0) - static const struct regmap_range_cfg sx1301_regmap_ranges[] = { { .name = "Pages", @@ -74,9 +53,10 @@ static struct regmap_config sx1301_regmap_config = { .max_register = SX1301_MAX_REGISTER, }; -static int sx1301_soft_reset(struct sx1301_priv *priv) +static int sx1301_field_write(struct sx1301_priv *priv, + enum sx1301_fields field_id, u8 val) { - return regmap_write(priv->regmap, SX1301_PAGE, REG_PAGE_RESET_SOFT_RESET); + return regmap_field_write(priv->regmap_fields[field_id], val); } static int sx1301_agc_ram_read(struct sx1301_priv *priv, u8 addr, unsigned int *val) @@ -120,7 +100,7 @@ static int sx1301_arb_ram_read(struct sx1301_priv *priv, u8 addr, unsigned int * static int sx1301_load_firmware(struct sx1301_priv *priv, int mcu, const struct firmware *fw) { u8 *buf; - u8 rst, select_mux; + enum sx1301_fields rst, select_mux; unsigned int val; int ret; @@ -131,29 +111,26 @@ static int sx1301_load_firmware(struct sx1301_priv *priv, int mcu, const struct switch (mcu) { case 0: - rst = REG_0_MCU_RST_0; - select_mux = REG_0_MCU_SELECT_MUX_0; + rst = F_MCU_RST_0; + select_mux = F_MCU_SELECT_MUX_0; break; case 1: - rst = REG_0_MCU_RST_1; - select_mux = REG_0_MCU_SELECT_MUX_1; + rst = F_MCU_RST_1; + select_mux = F_MCU_SELECT_MUX_1; break; default: return -EINVAL; } - ret = regmap_read(priv->regmap, SX1301_MCU_CTRL, &val); + ret = sx1301_field_write(priv, rst, 1); if (ret) { - dev_err(priv->dev, "MCU read failed\n"); + dev_err(priv->dev, "MCU reset failed\n"); return ret; } - val |= rst; - val &= ~select_mux; - - ret = regmap_write(priv->regmap, SX1301_MCU_CTRL, val); + ret = sx1301_field_write(priv, select_mux, 0); if (ret) { - dev_err(priv->dev, "MCU reset / select mux write failed\n"); + dev_err(priv->dev, "MCU RAM select mux failed\n"); return ret; } @@ -194,17 +171,9 @@ static int sx1301_load_firmware(struct sx1301_priv *priv, int mcu, const struct kfree(buf); - ret = regmap_read(priv->regmap, SX1301_MCU_CTRL, &val); - if (ret) { - dev_err(priv->dev, "MCU read (1) failed\n"); - return ret; - } - - val |= select_mux; - - ret = regmap_write(priv->regmap, SX1301_MCU_CTRL, val); + ret = sx1301_field_write(priv, select_mux, 1); if (ret) { - dev_err(priv->dev, "MCU reset / select mux write (1) failed\n"); + dev_err(priv->dev, "MCU RAM release mux failed\n"); return ret; } @@ -230,17 +199,9 @@ static int sx1301_agc_calibrate(struct sx1301_priv *priv) return ret; } - ret = regmap_read(priv->regmap, SX1301_FORCE_CTRL, &val); - if (ret) { - dev_err(priv->dev, "0|105 read failed\n"); - return ret; - } - - val &= ~REG_0_105_FORCE_HOST_RADIO_CTRL; - - ret = regmap_write(priv->regmap, SX1301_FORCE_CTRL, val); + ret = sx1301_field_write(priv, F_FORCE_HOST_RADIO_CTRL, 0); if (ret) { - dev_err(priv->dev, "0|105 write failed\n"); + dev_err(priv->dev, "force host control failed\n"); return ret; } @@ -254,17 +215,9 @@ static int sx1301_agc_calibrate(struct sx1301_priv *priv) return ret; } - ret = regmap_read(priv->regmap, SX1301_MCU_CTRL, &val); - if (ret) { - dev_err(priv->dev, "MCU read (0) failed\n"); - return ret; - } - - val &= ~REG_0_MCU_RST_1; - - ret = regmap_write(priv->regmap, SX1301_MCU_CTRL, val); + ret = sx1301_field_write(priv, F_MCU_RST_1, 0); if (ret) { - dev_err(priv->dev, "MCU write (0) failed\n"); + dev_err(priv->dev, "MCU 1 reset failed\n"); return ret; } @@ -282,34 +235,18 @@ static int sx1301_agc_calibrate(struct sx1301_priv *priv) return -ENXIO; } - ret = regmap_read(priv->regmap, SX1301_EMERGENCY_FORCE_HOST_CTRL, &val); - if (ret) { - dev_err(priv->dev, "emergency force read failed\n"); - return ret; - } - - val &= ~REG_EMERGENCY_FORCE_HOST_CTRL; - - ret = regmap_write(priv->regmap, SX1301_EMERGENCY_FORCE_HOST_CTRL, val); + ret = sx1301_field_write(priv, F_EMERGENCY_FORCE_HOST_CTRL, 0); if (ret) { - dev_err(priv->dev, "emergency force write failed\n"); + dev_err(priv->dev, "emergency force failed\n"); return ret; } dev_err(priv->dev, "starting calibration...\n"); msleep(2300); - ret = regmap_read(priv->regmap, SX1301_EMERGENCY_FORCE_HOST_CTRL, &val); - if (ret) { - dev_err(priv->dev, "emergency force read (1) failed\n"); - return ret; - } - - val |= REG_EMERGENCY_FORCE_HOST_CTRL; - - ret = regmap_write(priv->regmap, SX1301_EMERGENCY_FORCE_HOST_CTRL, val); + ret = sx1301_field_write(priv, F_EMERGENCY_FORCE_HOST_CTRL, 1); if (ret) { - dev_err(priv->dev, "emergency force write (1) failed\n"); + dev_err(priv->dev, "emergency force release failed\n"); return ret; } @@ -356,19 +293,15 @@ static int sx1301_load_all_firmware(struct sx1301_priv *priv) if (ret) return ret; - ret = regmap_read(priv->regmap, SX1301_FORCE_CTRL, &val); - if (ret) { - dev_err(priv->dev, "0|105 read failed\n"); + ret = sx1301_field_write(priv, F_FORCE_HOST_RADIO_CTRL, 0); + if (ret) return ret; - } - - val &= ~(REG_0_105_FORCE_HOST_RADIO_CTRL | REG_0_105_FORCE_HOST_FE_CTRL | REG_0_105_FORCE_DEC_FILTER_GAIN); - - ret = regmap_write(priv->regmap, SX1301_FORCE_CTRL, val); - if (ret) { - dev_err(priv->dev, "0|105 write failed\n"); + ret = sx1301_field_write(priv, F_FORCE_HOST_FE_CTRL, 0); + if (ret) + return ret; + ret = sx1301_field_write(priv, F_FORCE_DEC_FILTER_GAIN, 0); + if (ret) return ret; - } ret = regmap_write(priv->regmap, SX1301_CHRS, 0); if (ret) { @@ -376,17 +309,15 @@ static int sx1301_load_all_firmware(struct sx1301_priv *priv) return ret; } - ret = regmap_read(priv->regmap, SX1301_MCU_CTRL, &val); + ret = sx1301_field_write(priv, F_MCU_RST_0, 0); if (ret) { - dev_err(priv->dev, "MCU read (0) failed\n"); + dev_err(priv->dev, "MCU 0 release failed\n"); return ret; } - val &= ~(REG_0_MCU_RST_1 | REG_0_MCU_RST_0); - - ret = regmap_write(priv->regmap, SX1301_MCU_CTRL, val); + ret = sx1301_field_write(priv, F_MCU_RST_1, 0); if (ret) { - dev_err(priv->dev, "MCU write (0) failed\n"); + dev_err(priv->dev, "MCU 1 release failed\n"); return ret; } @@ -438,7 +369,6 @@ static netdev_tx_t sx130x_loradev_start_xmit(struct sk_buff *skb, struct net_dev static int sx130x_loradev_open(struct net_device *netdev) { struct sx1301_priv *priv = netdev_priv(netdev); - unsigned int val; int ret; netdev_dbg(netdev, "%s", __func__); @@ -448,31 +378,15 @@ static int sx130x_loradev_open(struct net_device *netdev) return -ENXIO; } - ret = regmap_read(priv->regmap, SX1301_GEN, &val); - if (ret) { - netdev_err(netdev, "16 read (1) failed\n"); - return ret; - } - - val |= REG_16_GLOBAL_EN; - - ret = regmap_write(priv->regmap, SX1301_GEN, val); - if (ret) { - netdev_err(netdev, "16 write (1) failed\n"); - return ret; - } - - ret = regmap_read(priv->regmap, SX1301_CKEN, &val); + ret = sx1301_field_write(priv, F_GLOBAL_EN, 1); if (ret) { - netdev_err(netdev, "17 read (1) failed\n"); + dev_err(priv->dev, "enable global clocks failed\n"); return ret; } - val |= REG_17_CLK32M_EN; - - ret = regmap_write(priv->regmap, SX1301_CKEN, val); + ret = sx1301_field_write(priv, F_CLK32M_EN, 1); if (ret) { - netdev_err(netdev, "17 write (1) failed\n"); + dev_err(priv->dev, "enable 32M clock failed\n"); return ret; } @@ -519,6 +433,7 @@ static int sx1301_probe(struct spi_device *spi) struct sx1301_priv *priv; struct gpio_desc *rst; int ret; + int i; unsigned int ver; unsigned int val; @@ -557,6 +472,19 @@ static int sx1301_probe(struct spi_device *spi) return ret; } + for (i = 0; i < ARRAY_SIZE(sx1301_regmap_fields); i++) { + const struct reg_field *reg_fields = sx1301_regmap_fields; + + priv->regmap_fields[i] = devm_regmap_field_alloc(&spi->dev, + priv->regmap, + reg_fields[i]); + if (IS_ERR(priv->regmap_fields[i])) { + ret = PTR_ERR(priv->regmap_fields[i]); + dev_err(&spi->dev, "Cannot allocate regmap field: %d\n", ret); + return ret; + } + } + ret = regmap_read(priv->regmap, SX1301_VER, &ver); if (ret) { dev_err(&spi->dev, "version read failed\n"); @@ -574,83 +502,49 @@ static int sx1301_probe(struct spi_device *spi) return ret; } - ret = sx1301_soft_reset(priv); + ret = sx1301_field_write(priv, F_SOFT_RESET, 1); if (ret) { dev_err(&spi->dev, "soft reset failed\n"); return ret; } - ret = regmap_read(priv->regmap, SX1301_GEN, &val); + ret = sx1301_field_write(priv, F_GLOBAL_EN, 0); if (ret) { - dev_err(&spi->dev, "16 read failed\n"); + dev_err(&spi->dev, "gate global clocks failed\n"); return ret; } - val &= ~REG_16_GLOBAL_EN; - - ret = regmap_write(priv->regmap, SX1301_GEN, val); + ret = sx1301_field_write(priv, F_CLK32M_EN, 0); if (ret) { - dev_err(&spi->dev, "16 write failed\n"); + dev_err(&spi->dev, "gate 32M clock failed\n"); return ret; } - ret = regmap_read(priv->regmap, SX1301_CKEN, &val); + ret = sx1301_field_write(priv, F_RADIO_A_EN, 1); if (ret) { - dev_err(&spi->dev, "17 read failed\n"); + dev_err(&spi->dev, "radio a enable failed\n"); return ret; } - val &= ~REG_17_CLK32M_EN; - - ret = regmap_write(priv->regmap, SX1301_CKEN, val); + ret = sx1301_field_write(priv, F_RADIO_B_EN, 1); if (ret) { - dev_err(&spi->dev, "17 write failed\n"); - return ret; - } - - ret = regmap_read(priv->regmap, SX1301_RADIO_CFG, &val); - if (ret) { - dev_err(&spi->dev, "2|43 read failed\n"); - return ret; - } - - val |= REG_2_43_RADIO_B_EN | REG_2_43_RADIO_A_EN; - - ret = regmap_write(priv->regmap, SX1301_RADIO_CFG, val); - if (ret) { - dev_err(&spi->dev, "2|43 write failed\n"); + dev_err(&spi->dev, "radio b enable failed\n"); return ret; } msleep(500); - ret = regmap_read(priv->regmap, SX1301_RADIO_CFG, &val); + ret = sx1301_field_write(priv, F_RADIO_RST, 1); if (ret) { - dev_err(&spi->dev, "2|43 read failed\n"); - return ret; - } - - val |= REG_2_43_RADIO_RST; - - ret = regmap_write(priv->regmap, SX1301_RADIO_CFG, val); - if (ret) { - dev_err(&spi->dev, "2|43 write failed\n"); + dev_err(&spi->dev, "radio asert reset failed\n"); return ret; } msleep(5); - ret = regmap_read(priv->regmap, SX1301_RADIO_CFG, &val); - if (ret) { - dev_err(&spi->dev, "2|43 read failed\n"); - return ret; - } - - val &= ~REG_2_43_RADIO_RST; - - ret = regmap_write(priv->regmap, SX1301_RADIO_CFG, val); + ret = sx1301_field_write(priv, F_RADIO_RST, 0); if (ret) { - dev_err(&spi->dev, "2|43 write failed\n"); + dev_err(&spi->dev, "radio deasert reset failed\n"); return ret; } diff --git a/drivers/net/lora/sx1301.h b/drivers/net/lora/sx1301.h index e6400f8..0bbd948 100644 --- a/drivers/net/lora/sx1301.h +++ b/drivers/net/lora/sx1301.h @@ -60,11 +60,57 @@ #define SX1301_MAX_REGISTER (SX1301_PAGE_BASE(3) + 0x7F) +enum sx1301_fields { + F_SOFT_RESET, + F_GLOBAL_EN, + F_CLK32M_EN, + F_RADIO_A_EN, + F_RADIO_B_EN, + F_RADIO_RST, + + F_MCU_RST_0, + F_MCU_RST_1, + F_MCU_SELECT_MUX_0, + F_MCU_SELECT_MUX_1, + + F_FORCE_HOST_RADIO_CTRL, + F_FORCE_HOST_FE_CTRL, + F_FORCE_DEC_FILTER_GAIN, + + F_EMERGENCY_FORCE_HOST_CTRL, +}; + +static const struct reg_field sx1301_regmap_fields[] = { + /* PAGE */ + [F_SOFT_RESET] = REG_FIELD(SX1301_PAGE, 7, 7), + /* GEN */ + [F_GLOBAL_EN] = REG_FIELD(SX1301_GEN, 3, 3), + /* CKEN */ + [F_CLK32M_EN] = REG_FIELD(SX1301_CKEN, 0, 0), + /* RADIO_CFG */ + [F_RADIO_A_EN] = REG_FIELD(SX1301_RADIO_CFG, 0, 0), + [F_RADIO_B_EN] = REG_FIELD(SX1301_RADIO_CFG, 1, 1), + [F_RADIO_RST] = REG_FIELD(SX1301_RADIO_CFG, 2, 2), + /* MCU_CTRL */ + [F_MCU_RST_0] = REG_FIELD(SX1301_MCU_CTRL, 0, 0), + [F_MCU_RST_1] = REG_FIELD(SX1301_MCU_CTRL, 1, 1), + [F_MCU_SELECT_MUX_0] = REG_FIELD(SX1301_MCU_CTRL, 2, 2), + [F_MCU_SELECT_MUX_1] = REG_FIELD(SX1301_MCU_CTRL, 3, 3), + /* FORCE_CTRL */ + [F_FORCE_HOST_RADIO_CTRL] = REG_FIELD(SX1301_FORCE_CTRL, 1, 1), + [F_FORCE_HOST_FE_CTRL] = REG_FIELD(SX1301_FORCE_CTRL, 2, 2), + [F_FORCE_DEC_FILTER_GAIN] = REG_FIELD(SX1301_FORCE_CTRL, 3, 3), + /* EMERGENCY_FORCE_HOST_CTRL */ + [F_EMERGENCY_FORCE_HOST_CTRL] = + REG_FIELD(SX1301_EMERGENCY_FORCE_HOST_CTRL, 0, 0), +}; + struct sx1301_priv { struct lora_dev_priv lora; struct device *dev; struct gpio_desc *rst_gpio; struct regmap *regmap; + struct regmap_field *regmap_fields[ARRAY_SIZE(sx1301_regmap_fields)]; }; int __init sx130x_radio_init(void); From patchwork Fri Oct 12 16:26:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Whitten X-Patchwork-Id: 983171 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="SW5yjW2t"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42WtX16T5Kz9s4Z for ; Sat, 13 Oct 2018 03:26:57 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729245AbeJMAAM (ORCPT ); Fri, 12 Oct 2018 20:00:12 -0400 Received: from mail-wr1-f65.google.com ([209.85.221.65]:36803 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729154AbeJMAAL (ORCPT ); Fri, 12 Oct 2018 20:00:11 -0400 Received: by mail-wr1-f65.google.com with SMTP id y16so14084498wrw.3; Fri, 12 Oct 2018 09:26:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=vykvvw6z8KbAShDoVOxsMwloQTTl5qXhoxhjAjE5d9g=; b=SW5yjW2tEaz8ZRidld3eD8NjfVzgHQ2zZVrFnomqu9BFeMBMyZJUFY6SIXWmHaYLxv HZ1Ni2YxY/hUUhBSuWuwt5HVXx8JS67OE7Vwk9gan0n671FWoi9fVQz0Y7SanQvwU1et C+wnkzy07upy+c2jzQQRaebnhWoCHl6cKKCSEyrP6Zuszxlkrf4fo/dFX3TAtxj15Urn LjokB7mTlI2K10lqOpqTeNWU2n29sCqtkN+pd12R1vzuTcdB5iofmMEmsqYLNKHjiH6C /gUDZrjmrzW56QGuuTqy3Ht7d0waHa92g6UT7TVZLZSxz/8cg3qFUBWZef8J9Df48qK/ lSAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=vykvvw6z8KbAShDoVOxsMwloQTTl5qXhoxhjAjE5d9g=; b=fCc3Nj8KQT4aOmUp8k6dzK9n1ly+sbrVtmzwc5E6nueWXFTrmv3HaUUaAq09n5q23R nFGkOlw4WQltyguPPzmeMxL4OL3r59YfxR/p7DZPF93RvzBSo+RFzO+zWUMkPTJ5rZH9 b3RUkyo+f6oQWh7n5u3ZsZKLdg1bMznrXB15Pewa7Q14EoPu+E8FG1se+ls0OBi7iPUH BykU1l7/2Em9fMU6S4zK9+dSiGB8v7uWZGmfPNIHFY5AvegN5xXE8Zz7YVCMXd5NtvvC BbirMLrZsUjZ5BpvwZiHUNB85VSZiUt2+DsKqlqmX4ak3evGWFjtPK18hT79ZQR90hu5 C8uw== X-Gm-Message-State: ABuFfohnwIuwfD6VnhvFbaRwmplquZxr8mdMhRwtlP0gNwnZQ+BhRtKC V6AwIsm7H7HSeCuLmqEAI+M= X-Google-Smtp-Source: ACcGV61x0fa6UCmycpq05UXgdsZ+okuw+mzhgZNv1Nn2nput+CBbvgs68nZq3aQPxC/gsx+U0FE7pg== X-Received: by 2002:adf:fe0f:: with SMTP id n15-v6mr5628051wrr.71.1539361613746; Fri, 12 Oct 2018 09:26:53 -0700 (PDT) Received: from Sarah.corp.lairdtech.com ([109.174.151.67]) by smtp.gmail.com with ESMTPSA id t198-v6sm1736842wmd.9.2018.10.12.09.26.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 12 Oct 2018 09:26:52 -0700 (PDT) From: Ben Whitten X-Google-Original-From: Ben Whitten To: afaerber@suse.de Cc: starnight@g.ncu.edu.tw, hasnain.virk@arm.com, netdev@vger.kernel.org, liuxuenetmail@gmail.com, shess@hessware.de, Ben Whitten , "David S. Miller" , linux-kernel@vger.kernel.org Subject: [PATCH v3 lora-next 4/5] net: lora: sx125x: convert to regmap fields Date: Fri, 12 Oct 2018 17:26:05 +0100 Message-Id: <1539361567-3602-5-git-send-email-ben.whitten@lairdtech.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> References: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ben Whitten We convert to using regmap fields to allow regmap to take care of read modify writes and bit shifting for ofset fields. Signed-off-by: Ben Whitten --- drivers/net/lora/sx125x.c | 59 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/drivers/net/lora/sx125x.c b/drivers/net/lora/sx125x.c index dc13d1a..36b61b1 100644 --- a/drivers/net/lora/sx125x.c +++ b/drivers/net/lora/sx125x.c @@ -25,11 +25,25 @@ #include "sx125x.h" -#define REG_CLK_SELECT_TX_DAC_CLK_SELECT_CLK_IN BIT(0) -#define REG_CLK_SELECT_CLK_OUT BIT(1) +enum sx125x_fields { + F_CLK_OUT, + F_TX_DAC_CLK_SEL, + F_SX1257_XOSC_GM_STARTUP, + F_SX1257_XOSC_DISABLE_CORE, +}; + +static const struct reg_field sx125x_regmap_fields[] = { + /* CLK_SELECT */ + [F_CLK_OUT] = REG_FIELD(SX125X_CLK_SELECT, 1, 1), + [F_TX_DAC_CLK_SEL] = REG_FIELD(SX125X_CLK_SELECT, 0, 0), + /* XOSC */ /* TODO maybe make this dynamic */ + [F_SX1257_XOSC_GM_STARTUP] = REG_FIELD(SX1257_XOSC, 0, 3), + [F_SX1257_XOSC_DISABLE_CORE] = REG_FIELD(SX1257_XOSC, 5, 5), +}; struct sx125x_priv { struct regmap *regmap; + struct regmap_field *regmap_fields[ARRAY_SIZE(sx125x_regmap_fields)]; }; static struct regmap_config __maybe_unused sx125x_regmap_config = { @@ -44,11 +58,18 @@ static struct regmap_config __maybe_unused sx125x_regmap_config = { .max_register = SX125X_MAX_REGISTER, }; +static int sx125x_field_write(struct sx125x_priv *priv, + enum sx125x_fields field_id, u8 val) +{ + return regmap_field_write(priv->regmap_fields[field_id], val); +} + static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap *regmap, unsigned int radio) { struct sx125x_priv *priv; unsigned int val; int ret; + int i; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -56,6 +77,18 @@ static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap dev_set_drvdata(dev, priv); priv->regmap = regmap; + for (i = 0; i < ARRAY_SIZE(sx125x_regmap_fields); i++) { + const struct reg_field *reg_fields = sx125x_regmap_fields; + + priv->regmap_fields[i] = devm_regmap_field_alloc(dev, + priv->regmap, + reg_fields[i]); + if (IS_ERR(priv->regmap_fields[i])) { + ret = PTR_ERR(priv->regmap_fields[i]); + dev_err(dev, "Cannot allocate regmap field: %d\n", ret); + return ret; + } + } if (true) { ret = regmap_read(priv->regmap, SX1255_VERSION, &val); @@ -66,24 +99,34 @@ static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap dev_info(dev, "SX125x version: %02x\n", val); } - val = REG_CLK_SELECT_TX_DAC_CLK_SELECT_CLK_IN; if (radio == 1) { /* HACK */ - val |= REG_CLK_SELECT_CLK_OUT; + ret = sx125x_field_write(priv, F_CLK_OUT, 1); + if (ret) { + dev_err(dev, "enabling clock output failed\n"); + return ret; + } + dev_info(dev, "enabling clock output\n"); } - ret = regmap_write(priv->regmap, SX125X_CLK_SELECT, val); + ret = sx125x_field_write(priv, F_TX_DAC_CLK_SEL, 1); if (ret) { - dev_err(dev, "clk write failed\n"); + dev_err(dev, "clock select failed\n"); return ret; } dev_dbg(dev, "clk written\n"); if (true) { - ret = regmap_write(priv->regmap, SX1257_XOSC, 13 + 2 * 16); + ret = sx125x_field_write(priv, F_SX1257_XOSC_DISABLE_CORE, 1); + if (ret) { + dev_err(dev, "xosc disable failed\n"); + return ret; + } + + ret = sx125x_field_write(priv, F_SX1257_XOSC_GM_STARTUP, 13); if (ret) { - dev_err(dev, "xosc write failed\n"); + dev_err(dev, "xosc startup adjust failed\n"); return ret; } } From patchwork Fri Oct 12 16:26:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Whitten X-Patchwork-Id: 983173 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="NGgZwsjN"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42WtX926krz9s3Z for ; Sat, 13 Oct 2018 03:27:05 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729262AbeJMAAO (ORCPT ); Fri, 12 Oct 2018 20:00:14 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:41295 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729086AbeJMAAO (ORCPT ); Fri, 12 Oct 2018 20:00:14 -0400 Received: by mail-wr1-f68.google.com with SMTP id x12-v6so14061526wru.8; Fri, 12 Oct 2018 09:26:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=w12L7T6g553XEV/giTLwwktg3hGh8fmkUvYnpNP+utI=; b=NGgZwsjNnI8T7BA+qTgHU90f7mKDw/kRKL95eonQRn+zm1wcmsLAytkfGLp783Hkng L5utnftQQIf7EQovlSsxIlOyj8ee375pW+qS7SmLXlv3YL5aBdc0X8KDPwvEyG4ibRXk L2RVPTJ0xxydMW1mJOEcp+9ySG80TvbcApBc5/fW5PRdQgONjuQVMuCFZ+4cHsVBQxYj RrA2M+wAPpiGPkeuCDyeb7h30F0h2dykW+TWsytyB0DEQvyzLDJ2mYuH7+NJkDt5k2Se yk9dUErtAtd2w7bTiPN8LxLPm3g4BOLgjebvkmktTYBl1PqbxQpqgOH/eH6rJNYZtkvS 9zXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=w12L7T6g553XEV/giTLwwktg3hGh8fmkUvYnpNP+utI=; b=bNSEGdfAMJMTfsAyFpCMQ2O8TFjZPlQu0NZMxCSNYf3UuMW7bcWzxGl0dKO8yuLEXC TP32vHf+4yYew8QYgnHHsSlKR+9adVcZaYOCeS8RwntwWlfg41I0Q6dms+WFHNSirrkk pHuJpOV+cFDuMQuTSbt5dbBvk34kZtcSb5qIER0X5uEXJRX58343kQmKlOorUgHBG+FO z7B9rxarR8EtBGbpIGfffXiINa+tMeQqn2vpJrPiN/ZpDfRScg6KrQ8389g3wHQDRyuc qzmYI0vYMsm0pOsP8dNk3omjC/G6zKZTiMKofd8VyUd/q6khKZTWpUK/lmWcoYQUs8LU efkw== X-Gm-Message-State: ABuFfohG+g81R3GBK92dcQFCfZOBdMgIv3268+JHO+EXNXxngjm4Xa/T 7kGqZDblOAfPfr0mtZP+Rm0= X-Google-Smtp-Source: ACcGV60eGPqo1wshNB7bxWHSGY1WYpkIhXZgveS4toq6VgN+whw6Aa9Xaps/gGJke+pbfLtbeaN8fQ== X-Received: by 2002:adf:e403:: with SMTP id g3-v6mr5613288wrm.96.1539361615641; Fri, 12 Oct 2018 09:26:55 -0700 (PDT) Received: from Sarah.corp.lairdtech.com ([109.174.151.67]) by smtp.gmail.com with ESMTPSA id t198-v6sm1736842wmd.9.2018.10.12.09.26.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 12 Oct 2018 09:26:54 -0700 (PDT) From: Ben Whitten X-Google-Original-From: Ben Whitten To: afaerber@suse.de Cc: starnight@g.ncu.edu.tw, hasnain.virk@arm.com, netdev@vger.kernel.org, liuxuenetmail@gmail.com, shess@hessware.de, Ben Whitten , "David S. Miller" , linux-kernel@vger.kernel.org Subject: [PATCH v3 lora-next 5/5] net: lora: sx125x sx1301: allow radio to register as a clk provider Date: Fri, 12 Oct 2018 17:26:06 +0100 Message-Id: <1539361567-3602-6-git-send-email-ben.whitten@lairdtech.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> References: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ben Whitten The 32M is run from the radio, before we just enabled it based on the radio number but now we can use the clk framework to request the clk is started when we need it. The 32M clock produced from the radio is really a gated version of tcxo which is a fixed clock provided by hardware, and isn't captured in this patch. The sx1301 brings the clock up prior to calibration once the radios have probed themselves. A sample dts showing the clk link: sx1301: sx1301@0 { ... clocks = <&radio1 0>; clock-names = "clk32m"; radio-spi { radio0: radio-a@0 { ... }; radio1: radio-b@1 { #clock-cells = <0>; clock-output-names = "clk32m"; }; }; }; Signed-off-by: Ben Whitten --- drivers/net/lora/sx125x.c | 112 ++++++++++++++++++++++++++++++++++++++++++---- drivers/net/lora/sx1301.c | 13 ++++++ drivers/net/lora/sx1301.h | 2 + 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/drivers/net/lora/sx125x.c b/drivers/net/lora/sx125x.c index 36b61b1..b7ca782 100644 --- a/drivers/net/lora/sx125x.c +++ b/drivers/net/lora/sx125x.c @@ -9,6 +9,8 @@ * Copyright (c) 2013 Semtech-Cycleo */ +#include +#include #include #include #include @@ -42,10 +44,16 @@ static const struct reg_field sx125x_regmap_fields[] = { }; struct sx125x_priv { + struct clk *clkout; + struct clk_hw clkout_hw; + + struct device *dev; struct regmap *regmap; struct regmap_field *regmap_fields[ARRAY_SIZE(sx125x_regmap_fields)]; }; +#define to_clkout(_hw) container_of(_hw, struct sx125x_priv, clkout_hw) + static struct regmap_config __maybe_unused sx125x_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -64,6 +72,96 @@ static int sx125x_field_write(struct sx125x_priv *priv, return regmap_field_write(priv->regmap_fields[field_id], val); } +static int sx125x_field_read(struct sx125x_priv *priv, + enum sx125x_fields field_id, unsigned int *val) +{ + return regmap_field_read(priv->regmap_fields[field_id], val); +} + +static int sx125x_clkout_enable(struct clk_hw *hw) +{ + struct sx125x_priv *priv = to_clkout(hw); + + dev_info(priv->dev, "enabling clkout\n"); + return sx125x_field_write(priv, F_CLK_OUT, 1); +} + +static void sx125x_clkout_disable(struct clk_hw *hw) +{ + struct sx125x_priv *priv = to_clkout(hw); + int ret; + + dev_info(priv->dev, "disabling clkout\n"); + ret = sx125x_field_write(priv, F_CLK_OUT, 0); + if (ret) + dev_err(priv->dev, "error disabling clkout\n"); +} + +static int sx125x_clkout_is_enabled(struct clk_hw *hw) +{ + struct sx125x_priv *priv = to_clkout(hw); + unsigned int enabled; + int ret; + + ret = sx125x_field_read(priv, F_CLK_OUT, &enabled); + if (ret) { + dev_err(priv->dev, "error reading clk enable\n"); + return 0; + } + return enabled; +} + +static const struct clk_ops sx125x_clkout_ops = { + .enable = sx125x_clkout_enable, + .disable = sx125x_clkout_disable, + .is_enabled = sx125x_clkout_is_enabled, +}; + +static int sx125x_register_clock_provider(struct sx125x_priv *priv) +{ + struct device *dev = priv->dev; + struct clk_init_data init; + const char *parent; + int ret; + + /* Disable CLKOUT */ + ret = sx125x_field_write(priv, F_CLK_OUT, 0); + if (ret) { + dev_err(dev, "unable to disable clkout\n"); + return ret; + } + + /* Register clock provider if expected in DTB */ + if (!of_find_property(dev->of_node, "#clock-cells", NULL)) + return 0; + + dev_info(dev, "registering clkout\n"); + + parent = of_clk_get_parent_name(dev->of_node, 0); + if (!parent) { + dev_err(dev, "Unable to find parent clk\n"); + return -ENODEV; + } + + init.ops = &sx125x_clkout_ops; + init.flags = CLK_IS_BASIC; + init.parent_names = &parent; + init.num_parents = 1; + priv->clkout_hw.init = &init; + + of_property_read_string_index(dev->of_node, "clock-output-names", 0, + &init.name); + + priv->clkout = devm_clk_register(dev, &priv->clkout_hw); + if (IS_ERR(priv->clkout)) { + dev_err(dev, "failed to register clkout\n"); + return PTR_ERR(priv->clkout); + } + ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, + &priv->clkout_hw); + return ret; +} + static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap *regmap, unsigned int radio) { struct sx125x_priv *priv; @@ -76,6 +174,7 @@ static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap return -ENOMEM; dev_set_drvdata(dev, priv); + priv->dev = dev; priv->regmap = regmap; for (i = 0; i < ARRAY_SIZE(sx125x_regmap_fields); i++) { const struct reg_field *reg_fields = sx125x_regmap_fields; @@ -99,16 +198,13 @@ static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap dev_info(dev, "SX125x version: %02x\n", val); } - if (radio == 1) { /* HACK */ - ret = sx125x_field_write(priv, F_CLK_OUT, 1); - if (ret) { - dev_err(dev, "enabling clock output failed\n"); - return ret; - } - - dev_info(dev, "enabling clock output\n"); + ret = sx125x_register_clock_provider(priv); + if (ret) { + dev_err(dev, "failed to register clkout provider: %d\n", ret); + return ret; } + /* TODO Only needs setting on radio on the TX path */ ret = sx125x_field_write(priv, F_TX_DAC_CLK_SEL, 1); if (ret) { dev_err(dev, "clock select failed\n"); diff --git a/drivers/net/lora/sx1301.c b/drivers/net/lora/sx1301.c index 339f8d9..23cbddc3 100644 --- a/drivers/net/lora/sx1301.c +++ b/drivers/net/lora/sx1301.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -378,6 +379,18 @@ static int sx130x_loradev_open(struct net_device *netdev) return -ENXIO; } + priv->clk32m = devm_clk_get(priv->dev, "clk32m"); + if (IS_ERR(priv->clk32m)) { + dev_err(priv->dev, "failed to get clk32m\n"); + return PTR_ERR(priv->clk32m); + } + + ret = clk_prepare_enable(priv->clk32m); + if (ret) { + dev_err(priv->dev, "failed to enable clk32m: %d\n", ret); + return ret; + } + ret = sx1301_field_write(priv, F_GLOBAL_EN, 1); if (ret) { dev_err(priv->dev, "enable global clocks failed\n"); diff --git a/drivers/net/lora/sx1301.h b/drivers/net/lora/sx1301.h index 0bbd948..a1a2e38 100644 --- a/drivers/net/lora/sx1301.h +++ b/drivers/net/lora/sx1301.h @@ -9,6 +9,7 @@ #ifndef _SX1301_ #define _SX1301_ +#include #include #include #include @@ -108,6 +109,7 @@ static const struct reg_field sx1301_regmap_fields[] = { struct sx1301_priv { struct lora_dev_priv lora; struct device *dev; + struct clk *clk32m; struct gpio_desc *rst_gpio; struct regmap *regmap; struct regmap_field *regmap_fields[ARRAY_SIZE(sx1301_regmap_fields)];