From patchwork Wed Aug 22 11:02:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Whitten X-Patchwork-Id: 960905 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="W0mnw3+i"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41wPm466Y9z9s7c for ; Wed, 22 Aug 2018 21:03:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728743AbeHVO1k (ORCPT ); Wed, 22 Aug 2018 10:27:40 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:35336 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728261AbeHVO1k (ORCPT ); Wed, 22 Aug 2018 10:27:40 -0400 Received: by mail-wr1-f68.google.com with SMTP id j26-v6so1273488wre.2 for ; Wed, 22 Aug 2018 04:03:12 -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; bh=ZPTSDzOWMuMjkPb7VxLUvxP04cUQeXCSUZVyVZ0FE10=; b=W0mnw3+iEl6wMNVGkTcXFd7vI/PUUb90NrdMbvxKq2jxgLhFT3KpqwM3zERrHrsHTg lJgwlPA4jUejEwYvqC+Z+tyPxjbibrjKXEobCwAWFBK7j1h/dhiy04KMcYC81URcnc9G 0pcp2H7v1D0kwl+Kp5/w5fk8sERo+sP1Z+hw85XAlaExDp0cFVlnmNttfFedZOAV3HWn oGfEUZqyhIhJbr7Ixqdcyqkt4QdgaqkYRPGN02rgArOaMMaX5ikZjbp8UZc5uQ6qFQF5 MIFlyLFMwKKnE4WWRqunWsOJHYCDOGG7tcd9SeL9XyBf5TI7vJDUQjNsXpkBl3SvFjjQ tJrQ== 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; bh=ZPTSDzOWMuMjkPb7VxLUvxP04cUQeXCSUZVyVZ0FE10=; b=Sy0xWSWTrzMgGM0OtqcNxx3dgrhzPxrQkL5xsqGV486e0orzPUsjLin0cs7r4Du2Zx VpiZriMr9xidAcSxkQtGZFPkfIEnuVQVxX4/i6kD16B2beB4cx0jBy7/J/CEJV4/ANFG CfF0TgEVHE/ESJ77tzJzoW3t1wAaeLMgDtZbNi6D7fBRYJok4QgX+8u3sU2zvdeXg5Wx erUxdAUm1P+QGMNX21RIogDABoGkA0S+6LwoY5hYGJGF8aH9sxzdreVFsTBIvW8Db2oN aH2HnKhNDzeYSsLJ5RN0TxwZpQIVU6oVYKM/9xQO2GfpUWu9NtvQ6aCYEuPljoduD0sY C+eA== X-Gm-Message-State: APzg51Bm0hj6Y0jYbqJxDXiLFe+/sNF8abWn6vZ1dtlG7Dn0CMC8O0s3 yaeFS1dxO8oDVHCj8XcSQ9s= X-Google-Smtp-Source: ANB0VdYvHw0mPJGA/YW3AhA2l6Zo2WrhXThgCD23p8+GVzYsLpXBiNwJKEtw7dvob+UBKgwq/hF2SQ== X-Received: by 2002:a5d:6150:: with SMTP id y16-v6mr7242759wrt.141.1534935791505; Wed, 22 Aug 2018 04:03:11 -0700 (PDT) Received: from Sarah.corp.lairdtech.com ([109.174.151.67]) by smtp.gmail.com with ESMTPSA id j6-v6sm548890wru.64.2018.08.22.04.03.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 22 Aug 2018 04:03:10 -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 Subject: [PATCH lora-next 1/3] net: lora: sx1301: convert to using regmap fields for bit ops Date: Wed, 22 Aug 2018 12:02:39 +0100 Message-Id: <1534935761-12738-1-git-send-email-ben.whitten@lairdtech.com> X-Mailer: git-send-email 2.7.4 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 | 240 +++++++++++++--------------------------------- drivers/net/lora/sx1301.h | 46 +++++++++ 2 files changed, 113 insertions(+), 173 deletions(-) diff --git a/drivers/net/lora/sx1301.c b/drivers/net/lora/sx1301.c index 971d234..8aad331 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,6 +53,12 @@ static struct regmap_config sx1301_regmap_config = { .max_register = SX1301_MAX_REGISTER, }; +static int sx1301_field_write(struct sx1301_priv *priv, + enum sx1301_fields field_id, u8 val) +{ + return regmap_field_write(priv->regmap_fields[field_id], val); +} + static int sx1301_read_burst(struct sx1301_priv *priv, u8 reg, u8 *val, size_t len) { u8 addr = reg & 0x7f; @@ -91,11 +76,6 @@ static int sx1301_write_burst(struct sx1301_priv *priv, u8 reg, const u8 *val, s 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); -} - static int sx1301_agc_ram_read(struct sx1301_priv *priv, u8 addr, unsigned int *val) { int ret; @@ -137,7 +117,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; @@ -148,29 +128,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; } @@ -211,17 +188,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); + ret = sx1301_field_write(priv, select_mux, 1); 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); - 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; } @@ -247,17 +216,9 @@ static int sx1301_agc_calibrate(struct sx1301_priv *priv) return ret; } - ret = regmap_read(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 read failed\n"); - return ret; - } - - val &= ~REG_0_105_FORCE_HOST_RADIO_CTRL; - - ret = regmap_write(priv->regmap, SX1301_FORCE_CTRL, val); - if (ret) { - dev_err(priv->dev, "0|105 write failed\n"); + dev_err(priv->dev, "force host control failed\n"); return ret; } @@ -271,17 +232,9 @@ static int sx1301_agc_calibrate(struct sx1301_priv *priv) return ret; } - ret = regmap_read(priv->regmap, SX1301_MCU_CTRL, &val); + ret = sx1301_field_write(priv, F_MCU_RST_1, 0); 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); - if (ret) { - dev_err(priv->dev, "MCU write (0) failed\n"); + dev_err(priv->dev, "MCU 1 reset failed\n"); return ret; } @@ -299,34 +252,18 @@ static int sx1301_agc_calibrate(struct sx1301_priv *priv) return -ENXIO; } - ret = regmap_read(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 read failed\n"); - return ret; - } - - val &= ~REG_EMERGENCY_FORCE_HOST_CTRL; - - ret = regmap_write(priv->regmap, SX1301_EMERGENCY_FORCE_HOST_CTRL, val); - 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; } @@ -373,19 +310,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) { @@ -393,17 +326,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; } @@ -455,7 +386,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__); @@ -465,31 +395,15 @@ static int sx130x_loradev_open(struct net_device *netdev) return -ENXIO; } - ret = regmap_read(priv->regmap, SX1301_GEN, &val); + ret = sx1301_field_write(priv, F_GLOBAL_EN, 1); if (ret) { - netdev_err(netdev, "16 read (1) failed\n"); + dev_err(priv->dev, "enable 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, 1); if (ret) { - netdev_err(netdev, "16 write (1) failed\n"); - return ret; - } - - ret = regmap_read(priv->regmap, SX1301_CKEN, &val); - if (ret) { - netdev_err(netdev, "17 read (1) failed\n"); - return ret; - } - - val |= REG_17_CLK32M_EN; - - ret = regmap_write(priv->regmap, SX1301_CKEN, val); - if (ret) { - netdev_err(netdev, "17 write (1) failed\n"); + dev_err(priv->dev, "enable 32M clock failed\n"); return ret; } @@ -536,6 +450,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; @@ -572,6 +487,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"); @@ -589,83 +517,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); - if (ret) { - dev_err(&spi->dev, "16 write failed\n"); - return ret; - } - - ret = regmap_read(priv->regmap, SX1301_CKEN, &val); + ret = sx1301_field_write(priv, F_CLK32M_EN, 0); if (ret) { - dev_err(&spi->dev, "17 read failed\n"); + dev_err(&spi->dev, "gate 32M clock failed\n"); return ret; } - val &= ~REG_17_CLK32M_EN; - - ret = regmap_write(priv->regmap, SX1301_CKEN, val); + ret = sx1301_field_write(priv, F_RADIO_A_EN, 1); if (ret) { - dev_err(&spi->dev, "17 write failed\n"); + dev_err(&spi->dev, "radio a enable 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); + ret = sx1301_field_write(priv, F_RADIO_B_EN, 1); 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 e939c02..59fcb2c 100644 --- a/drivers/net/lora/sx1301.h +++ b/drivers/net/lora/sx1301.h @@ -61,12 +61,58 @@ #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 spi_device *spi; 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 Wed Aug 22 11:02:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Whitten X-Patchwork-Id: 960904 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="ce3es/Fo"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41wPm40byxz9s7X for ; Wed, 22 Aug 2018 21:03:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728675AbeHVO1j (ORCPT ); Wed, 22 Aug 2018 10:27:39 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:34265 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727016AbeHVO1j (ORCPT ); Wed, 22 Aug 2018 10:27:39 -0400 Received: by mail-wr1-f67.google.com with SMTP id g33-v6so1266677wrd.1 for ; Wed, 22 Aug 2018 04:03:13 -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=L4Aco+Hgld1lzsxdfDOnoCr2URwuAJdUHe5/uk+pT7o=; b=ce3es/FoGvTNph8IqSp+Wf/Q5f7PcO/K65NQOTvzhH7WOlja90rTPzqiDzQMrMXj44 8Q5HWKgdY4wSBy41ay5WKlyjTu3ws/or7D96v2OlRDu/+g8R3PqZHZRUEex013sQg55X yBzvBnTPT05laDVKWwEinacDxfgDnROXLIEDh3WSLmDToJnrS8wsaA5Usdsi7r3sgKjD n/XVkdD3Vi7HA9C8DqZ4udnq8xtfxX1BaIK0CYyceAEkDbQe9c4l8JO7PR224r3LM22c cYC6srQjeCz5Yu4TJnBRjfp8cI9YWFIgLTlxiC85QIfyG1BzmgIxVSH9jvpU8Gv/Oq1D ILzA== 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=L4Aco+Hgld1lzsxdfDOnoCr2URwuAJdUHe5/uk+pT7o=; b=Xy34Uk6LQveVLVb2tuwGlU0fDyfj0IAyovJLS/SpO4jdUyR5zRMsYM60euMcWNTBp1 RW4QWd8ZRUyqm/5DjjpCWwdWZAubcyu1oMlYvCEy2Kxq+D6plBO87BsGh0NF+lG7Ihza 8+X6vCrtm90XCCYWPWCiRxGpMgbVq5ujXEHigJi080DGGGKi9fy5mbKbOQDsFmNgfo4d 1faHUn4A294oSsMhF819omfGIiWE9mpWPHbzCMbAAB0/H+ugFK7gxoCqkXe7lKATQvRg Xg8R0QGsboahoDz6CoAnJTNmNE1PNbCqguKj8ebCIAk/Ba+jmvXc4z2Mdf0nsFSTKoU+ 0GEg== X-Gm-Message-State: APzg51Bz65XbVA4OX9+Z/poJGmdQ9dbn4uY3VXABDceIl4o1yMpzsbov lC6hp7V9a8WfpCF2A3eivDo= X-Google-Smtp-Source: ANB0VdYduPGcYg8I+5bIRFy2aJd1VEstu8XmIb0VbqDsAJmI21PG4bXTHnn4ARy0Y9SpvdOK+i2oTQ== X-Received: by 2002:adf:9464:: with SMTP id 91-v6mr8783050wrq.231.1534935793029; Wed, 22 Aug 2018 04:03:13 -0700 (PDT) Received: from Sarah.corp.lairdtech.com ([109.174.151.67]) by smtp.gmail.com with ESMTPSA id j6-v6sm548890wru.64.2018.08.22.04.03.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 22 Aug 2018 04:03:11 -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 Subject: [PATCH lora-next 2/3] net: lora: sx125x: convert to regmap fields Date: Wed, 22 Aug 2018 12:02:40 +0100 Message-Id: <1534935761-12738-2-git-send-email-ben.whitten@lairdtech.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1534935761-12738-1-git-send-email-ben.whitten@lairdtech.com> References: <1534935761-12738-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 3476a59..b5517e4 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 (false) { 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 Wed Aug 22 11:02:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Whitten X-Patchwork-Id: 960906 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="Fzl4hpOK"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41wPmF5hDmz9s7X for ; Wed, 22 Aug 2018 21:03:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728787AbeHVO1n (ORCPT ); Wed, 22 Aug 2018 10:27:43 -0400 Received: from mail-wr1-f66.google.com ([209.85.221.66]:34267 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728261AbeHVO1m (ORCPT ); Wed, 22 Aug 2018 10:27:42 -0400 Received: by mail-wr1-f66.google.com with SMTP id g33-v6so1266759wrd.1 for ; Wed, 22 Aug 2018 04:03:15 -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=ZK5wc0e6pC/BDxRtG2xsWKuSpORyr2ZAGQr/4cODbLQ=; b=Fzl4hpOKSPZ+3/OJcy9e/tzPNQOXhpP7nqa8UULru9dbFp6s89ITj3aRLtoeaErJcX oVCsMG2jbisKCq+g5Cet9i408juw1KwQbHQhIsB1e7UB+bLU668X6NMdJdXGGBcSszmE rmlf8nwzGow/CXD7abpuEIrHG2vv36sjtsddexol4q3VJ4vT8kPg9WMlC4goqxF9jwIK /+T+NUEC7HSW0VQCIc3F0o+m2VFRDH63vhwZmBjQcBqejx4d0tD9RrNPbKU46HZ28DqL h9qMwATwjb4PH4A4EdVpxcTPY1vNV2R4t7CzUo3Jab3ValJQ3qFpr6DKLK2jH7RI19Uw KC6Q== 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=ZK5wc0e6pC/BDxRtG2xsWKuSpORyr2ZAGQr/4cODbLQ=; b=Q4K0bHDezTEPh7gPb4rgr6IM3mAUXoQ3q25na1QM8Ee2u5xOAXTA0wDxPV6GCgKdNm iV1ppCCRVtj+W6gGTT8GVW7fOrd0wqc8BibTLKXeAWLv1oHZIWAy+uQSWa2/nyPr4Qzt 8gCwyeHQbXePU0FjuNxojf1ybPqAlj7AlMuPDDhOpRbWdEX/Yht3VoUN9ltf4t7lBld/ AfcFLXbpTSL20XAiAZKCSyOHrBgI9sbMEUJYrmmoIT6vcb6bQJeq1R0RSvOFpEWZ4mt/ fG6c+RzahjmF1Zg+r2tR+X8kL6mkvsbnpfWhRaS52U4eHmJ0mBX82mqqXWLMvgD/c+zR BBYg== X-Gm-Message-State: AOUpUlFU9um/A03wlnqHRzZizeGNlWYNdyFU4IBpe/Gf08Fuu9eTMCtw hyKT2ItEugUF+iW+t7vhYwE= X-Google-Smtp-Source: AA+uWPyzJudtl/HYQsk1rNEPskyhJR01GqvKh4TlB8PnFghxJAhe1N7HhtFnsmEKdNhyDkYayiqW+A== X-Received: by 2002:adf:9142:: with SMTP id j60-v6mr35176055wrj.180.1534935794893; Wed, 22 Aug 2018 04:03:14 -0700 (PDT) Received: from Sarah.corp.lairdtech.com ([109.174.151.67]) by smtp.gmail.com with ESMTPSA id j6-v6sm548890wru.64.2018.08.22.04.03.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 22 Aug 2018 04:03:13 -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 Subject: [PATCH lora-next 3/3] net: lora: sx125x sx1301: allow radio to register as a clk provider Date: Wed, 22 Aug 2018 12:02:41 +0100 Message-Id: <1534935761-12738-3-git-send-email-ben.whitten@lairdtech.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1534935761-12738-1-git-send-email-ben.whitten@lairdtech.com> References: <1534935761-12738-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 b5517e4..5989157 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 8aad331..0a710d7 100644 --- a/drivers/net/lora/sx1301.c +++ b/drivers/net/lora/sx1301.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -395,6 +396,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 59fcb2c..4b1abd1 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 @@ -109,6 +110,7 @@ static const struct reg_field sx1301_regmap_fields[] = { struct sx1301_priv { struct lora_dev_priv lora; struct device *dev; + struct clk *clk32m; struct spi_device *spi; struct gpio_desc *rst_gpio; struct regmap *regmap;