linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets
@ 2019-01-28 16:12 Ben Whitten
  2019-01-28 16:12 ` [PATCH lora-next 01/11] dt-bindings: net: lora: sx130x: add power lut binding Ben Whitten
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, netdev, linux-kernel

Hello,

This series adds setup nessesary to transmit lora packets from the
SX1301x, it builds on the comments on the RFC [1] to a point where
the card is capable of sending out a LoRa modulated signal using
transmission paramaters from the LORA socket address.

As patches have been refactored and split up extensivly to bite
sized chunks they do not include individual RFC -> v1, this is
covered in this letter.

The setup involves starting the firmware up inside the card by
providing a LUT of its internal gain values calibrated against
the card output. As this information is hardware specific it
is added as a binding in the DT, with documentation to match.
Binding patch is based off a commit of the basic documentation
under review [2]
Not captured here are commands to set this gain table for use
in devices which do not use DT.

As _stat_xmit cannot sleep we spin the tx function to a work queue
so we can write to the SPI backed regmaps.

As proposed [3] as one way of getting lora packet metadata to
the driver is by using the socket address to encode spreading
factor, coding rate, bandwidth etc. The corresponding translation
is added on the driver side, populating the test transmission with
real values and has been tested to show changing bandwidths.
To perform testing a tx_test [4] was used to show changing
parameters on a spectrum analyser.

We also add patches to the defaults in the SX130x to fill in a TODO
in our initialisation.

Thanks,
Ben Whitten

[1] http://lists.infradead.org/pipermail/linux-lpwan/2018-December/000019.html
[2] http://lists.infradead.org/pipermail/linux-lpwan/2019-January/000150.html
[3] https://events.linuxfoundation.org/wp-content/uploads/2017/12/ELCE2018_LoRa_final_Andreas-Farber.pdf slide 16
[4] https://github.com/BWhitten/lora-modules/blob/master/tx_test.c

RFC -> v1
* Split up commits to sensible order and logical block sizes.
* Added DT binding for TX gain LUT.
* Fixed spelling mistakes.
* Converted metadata enums to suggested integers with suitable sizes.
* Fixed out by 1 in test transmission population.

CC: linux-lpwan@lists.infradead.org
CC: netdev@vger.kernel.org
CC: linux-kernel@vger.kernel.org


Ben Whitten (11):
  dt-bindings: net: lora: sx130x: add power lut binding
  net: lora: sx130x: add loading of tx lut from DT
  net: lora: sx130x: add CHRS to volatile register list
  net: lora: sx130x: add helper function for writing to the SX130x MCU
  net: lora: sx130x: initialise AGC
  net: lora: sx130x: add detail to TODO in setup
  net: lora: sx130x: add work queue to tx path
  net: lora: sx130x: add test transmission
  net: lora: introduce lora socket addressing for metadata
  net: lora: sx130x: make use of lora address metadata in transmission
  net: lora: sx130x: add patch to register fields

 .../bindings/net/lora/semtech,sx130x.yaml     |  13 +
 drivers/net/lora/sx130x.c                     | 521 +++++++++++++++++-
 drivers/net/lora/sx130x.h                     |  97 ++++
 include/linux/lora/skb.h                      |   9 +
 include/uapi/linux/lora.h                     |  14 +
 net/lora/dgram.c                              |  45 ++
 6 files changed, 697 insertions(+), 2 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH lora-next 01/11] dt-bindings: net: lora: sx130x: add power lut binding
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
@ 2019-01-28 16:12 ` Ben Whitten
  2019-01-28 18:13   ` Rob Herring
  2019-01-28 16:12 ` [PATCH lora-next 02/11] net: lora: sx130x: add loading of tx lut from DT Ben Whitten
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
  To: afaerber
  Cc: linux-lpwan, Ben Whitten, David S. Miller, Rob Herring,
	Mark Rutland, netdev, devicetree, linux-kernel

From: Ben Whitten <ben.whitten@gmail.com>

Adding power lookup table for the concentrator specified in DT.

These values are calibrated for the hardware and are unique to hardware
designs and certifications.

First byte is signed power in dBm measured at the rf connector.
Second byte is unsigned value for DIGITAL gain.
Third byte is unsigned value for PA gain, 2 bits only.
Fourth byte is unsigned value for DAC gain, 2 bits only.
Fifth byte is unsigned value for MIXER gain, 4 bits only.

Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
 .../bindings/net/lora/semtech,sx130x.yaml           | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml b/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml
index 24fad1218735..187fa2090a0b 100644
--- a/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml
+++ b/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml
@@ -37,6 +37,15 @@ properties:
     maxItems: 1
     description: A connection of the reset gpio line.
 
+  power-lut:
+    description: Power lookup table for the concentrator.
+      Consisting of maximum 16 entries, each entry having the following format;
+      First byte is signed power in dBm measured at the rf connector.
+      Second byte is unsigned value for DIGITAL gain.
+      Third byte is unsigned value for PA gain, 2 bits only.
+      Fourth byte is unsigned value for DAC gain, 2 bits only.
+      Fifth byte is unsigned value for MIXER gain, 4 bits only.
+
   radio-spi:
     type: object
     description: The concentrator can have two radios connected which are
@@ -83,6 +92,10 @@ examples:
         reset-gpios = <&pioB 27 GPIO_ACTIVE_HIGH>;
         spi-max-frequency = <8000000>;
 
+	power-lut =   [	00 00 00 03 09
+			03 00 00 03 0C
+			04 00 00 03 0D ];
+
         radio-spi {
           #address-cells = <1>;
           #size-cells = <0>;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 02/11] net: lora: sx130x: add loading of tx lut from DT
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
  2019-01-28 16:12 ` [PATCH lora-next 01/11] dt-bindings: net: lora: sx130x: add power lut binding Ben Whitten
@ 2019-01-28 16:12 ` Ben Whitten
  2019-01-28 16:12 ` [PATCH lora-next 03/11] net: lora: sx130x: add CHRS to volatile register list Ben Whitten
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel

From: Ben Whitten <ben.whitten@gmail.com>

The AGC software requires loading of a power lookup table on initialisation
prior to transmission.
The fields required are digital, pa, dac, and mixer gain. These values are
typically hardware specific and calibrated for a particular power output at
the card rf port.
The format of the DT binding is <power(s8) dig(u8) pa(u8) dac(u8) mix(u8)>
a valid entry is 5 bytes, a valid table is up to 16 entries.

Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
 drivers/net/lora/sx130x.c | 29 +++++++++++++++++++++++++++++
 drivers/net/lora/sx130x.h |  2 ++
 2 files changed, 31 insertions(+)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 3174fc695d54..70cfb4532b51 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -51,6 +51,14 @@ static const struct reg_field sx130x_regmap_fields[] = {
 		REG_FIELD(SX1301_EMERGENCY_FORCE_HOST_CTRL, 0, 0),
 };
 
+struct sx130x_tx_gain_lut {
+	s8 power;	/* dBm measured at board connector */
+	u8 dig_gain;
+	u8 pa_gain;
+	u8 dac_gain;
+	u8 mix_gain;
+};
+
 struct sx130x_priv {
 	struct lora_dev_priv	lora;
 	struct device		*dev;
@@ -59,6 +67,8 @@ struct sx130x_priv {
 	struct regmap_field	*regmap_fields[ARRAY_SIZE(sx130x_regmap_fields)];
 	struct mutex		io_lock;
 	void			*drvdata;
+	struct sx130x_tx_gain_lut tx_gain_lut[SX1301_TX_GAIN_LUT_MAX];
+	u8 tx_gain_lut_size;
 };
 
 struct regmap *sx130x_get_regmap(struct device *dev)
@@ -589,6 +599,7 @@ int sx130x_early_probe(struct regmap *regmap, struct gpio_desc *rst)
 	struct device *dev = regmap_get_device(regmap);
 	struct net_device *netdev;
 	struct sx130x_priv *priv;
+	const u8 *power_lut;
 	int ret;
 	int i;
 
@@ -620,6 +631,24 @@ int sx130x_early_probe(struct regmap *regmap, struct gpio_desc *rst)
 			return ret;
 		}
 	}
+
+	if (IS_ENABLED(CONFIG_OF)) {
+		power_lut = of_get_property(dev->of_node, "power-lut", &ret);
+		if (power_lut && (ret % 5)) {
+			dev_err(dev, "Invalid power table\n");
+			return -EINVAL;
+		} else if (power_lut) {
+			priv->tx_gain_lut_size = ret / 5;
+			for (i = 0; i < priv->tx_gain_lut_size; i++) {
+				priv->tx_gain_lut[i].power = *(power_lut++);
+				priv->tx_gain_lut[i].dig_gain = *(power_lut++);
+				priv->tx_gain_lut[i].pa_gain = *(power_lut++) & 0x03;
+				priv->tx_gain_lut[i].dac_gain = *(power_lut++) & 0x03;
+				priv->tx_gain_lut[i].mix_gain = *(power_lut++) & 0x0F;
+			}
+		}
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(sx130x_early_probe);
diff --git a/drivers/net/lora/sx130x.h b/drivers/net/lora/sx130x.h
index abab2ee42512..6330777f4eac 100644
--- a/drivers/net/lora/sx130x.h
+++ b/drivers/net/lora/sx130x.h
@@ -18,6 +18,8 @@
 #define SX1301_MCU_AGC_FW_VERSION 4
 #define SX1301_MCU_AGC_CAL_FW_VERSION 2
 
+#define SX1301_TX_GAIN_LUT_MAX 16
+
 /* Page independent */
 #define SX1301_PAGE     0x00
 #define SX1301_VER      0x01
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 03/11] net: lora: sx130x: add CHRS to volatile register list
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
  2019-01-28 16:12 ` [PATCH lora-next 01/11] dt-bindings: net: lora: sx130x: add power lut binding Ben Whitten
  2019-01-28 16:12 ` [PATCH lora-next 02/11] net: lora: sx130x: add loading of tx lut from DT Ben Whitten
@ 2019-01-28 16:12 ` Ben Whitten
  2019-01-28 16:12 ` [PATCH lora-next 04/11] net: lora: sx130x: add helper function for writing to the SX130x MCU Ben Whitten
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel

From: Ben Whitten <ben.whitten@gmail.com>

The CHRS register is used in transactions to the MCU within the SX130x,
we need to always write to it.

Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
 drivers/net/lora/sx130x.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 70cfb4532b51..529ca6622878 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -134,6 +134,7 @@ static bool sx130x_volatile_reg(struct device *dev, unsigned int reg)
 	case SX1301_MPD:
 	case SX1301_AGCSTS:
 
+	case SX1301_CHRS:
 	case SX1301_MCU_CTRL:
 
 	case SX1301_RADIO_A_SPI_DATA_RB:
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 04/11] net: lora: sx130x: add helper function for writing to the SX130x MCU
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
                   ` (2 preceding siblings ...)
  2019-01-28 16:12 ` [PATCH lora-next 03/11] net: lora: sx130x: add CHRS to volatile register list Ben Whitten
@ 2019-01-28 16:12 ` Ben Whitten
  2019-01-28 16:12 ` [PATCH lora-next 05/11] net: lora: sx130x: initialise AGC Ben Whitten
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel

From: Ben Whitten <ben.whitten@gmail.com>

The transaction to the internal MCU starts with CMD_WAIT to start a
transaction, written to CHRS followed by writing the value, the status of
the command is read back from AGCSTS.

Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
 drivers/net/lora/sx130x.c | 28 ++++++++++++++++++++++++++++
 drivers/net/lora/sx130x.h |  2 ++
 2 files changed, 30 insertions(+)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 529ca6622878..818a1c9192b3 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -337,6 +337,34 @@ static int sx130x_load_firmware(struct sx130x_priv *priv, int mcu, const struct
 	return 0;
 }
 
+static int sx130x_agc_transaction(struct sx130x_priv *priv, unsigned int val,
+				  unsigned int *status)
+{
+	int ret;
+
+	ret = regmap_write(priv->regmap, SX1301_CHRS, SX1301_AGC_CMD_WAIT);
+	if (ret) {
+		dev_err(priv->dev, "AGC transaction start failed\n");
+		return ret;
+	}
+	usleep_range(1000, 2000);
+
+	ret = regmap_write(priv->regmap, SX1301_CHRS, val);
+	if (ret) {
+		dev_err(priv->dev, "AGC transaction value failed\n");
+		return ret;
+	}
+	usleep_range(1000, 2000);
+
+	ret = regmap_read(priv->regmap, SX1301_AGCSTS, status);
+	if (ret) {
+		dev_err(priv->dev, "AGC status read failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int sx130x_agc_calibrate(struct sx130x_priv *priv)
 {
 	const struct firmware *fw;
diff --git a/drivers/net/lora/sx130x.h b/drivers/net/lora/sx130x.h
index 6330777f4eac..69bb9cbd1aba 100644
--- a/drivers/net/lora/sx130x.h
+++ b/drivers/net/lora/sx130x.h
@@ -18,6 +18,8 @@
 #define SX1301_MCU_AGC_FW_VERSION 4
 #define SX1301_MCU_AGC_CAL_FW_VERSION 2
 
+#define SX1301_AGC_CMD_WAIT 16
+
 #define SX1301_TX_GAIN_LUT_MAX 16
 
 /* Page independent */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 05/11] net: lora: sx130x: initialise AGC
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
                   ` (3 preceding siblings ...)
  2019-01-28 16:12 ` [PATCH lora-next 04/11] net: lora: sx130x: add helper function for writing to the SX130x MCU Ben Whitten
@ 2019-01-28 16:12 ` Ben Whitten
  2019-01-28 16:13 ` [PATCH lora-next 06/11] net: lora: sx130x: add detail to TODO in setup Ben Whitten
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel

From: Ben Whitten <ben.whitten@gmail.com>

Initialisation of the AGC firmware requires a couple of steps to be
completed;
- Loading a TX LUT
- Loading the two MSBs for the radio tx synthesizer frequencies,
  (Always 3 if f > 768 for SX1257 and SX1258 or f > 384 for SX1255)
- Loading a firmware option
- Finish initialisation by writing intended value of the radio select
  register.

Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
 drivers/net/lora/sx130x.c | 110 ++++++++++++++++++++++++++++++++++++++
 drivers/net/lora/sx130x.h |   7 +++
 2 files changed, 117 insertions(+)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 818a1c9192b3..18acfc8e934d 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -537,6 +537,111 @@ static int sx130x_load_all_firmware(struct sx130x_priv *priv)
 	return 0;
 }
 
+static int sx130x_load_tx_gain_lut(struct sx130x_priv *priv)
+{
+	struct net_device *netdev = dev_get_drvdata(priv->dev);
+	struct sx130x_tx_gain_lut *lut = priv->tx_gain_lut;
+	unsigned int status, val;
+	int ret, i;
+
+	for (i = 0; i < priv->tx_gain_lut_size; i++) {
+		val = lut->pa_gain << SX1301_PA_GAIN_OFFSET;
+		val |= lut->dac_gain << SX1301_DAC_GAIN_OFFSET;
+		val |= lut->mix_gain;
+
+		netdev_info(netdev, "AGC LUT entry %d dBm: 0x%02x\n", lut->power, val);
+		ret = sx130x_agc_transaction(priv, val, &status);
+		if (ret) {
+			netdev_err(netdev, "AGC LUT load failed\n");
+			return ret;
+		}
+		if (status != (SX1301_AGC_STATUS_SUCCESS | i)) {
+			netdev_err(netdev, "AGC firmware LUT init error: 0x%02x", status);
+			return -ENXIO;
+		}
+		lut++;
+	}
+
+	/* Abort the transaction if there are less then 16 entries */
+	if (priv->tx_gain_lut_size < SX1301_TX_GAIN_LUT_MAX) {
+		ret = sx130x_agc_transaction(priv, SX1301_AGC_CMD_ABORT, &status);
+		if (ret) {
+			netdev_err(netdev, "AGC LUT abort failed\n");
+			return ret;
+		}
+		if (status != SX1301_AGC_STATUS_SUCCESS) {
+			netdev_err(netdev, "AGC firmware LUT abort error: 0x%02x", status);
+			return -ENXIO;
+		}
+	}
+
+	return ret;
+};
+
+static int sx130x_agc_init(struct sx130x_priv *priv)
+{
+	struct net_device *netdev = dev_get_drvdata(priv->dev);
+	unsigned int tx_msb;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(priv->regmap, SX1301_AGCSTS, &val);
+	if (ret) {
+		netdev_err(netdev, "AGC status read failed\n");
+		return ret;
+	}
+	if (val != SX1301_AGC_STATUS_READY) {
+		netdev_err(netdev, "AGC firmware init failure: 0x%02x\n", val);
+		return -ENXIO;
+	}
+
+	ret = sx130x_load_tx_gain_lut(priv);
+	if (ret)
+		return ret;
+
+	/*
+	 * Load Tx freq MSBs
+	 * Always 3 if f > 768 for SX1257 and SX1258 or f > 384 for SX1255
+	 */
+	tx_msb = 3; /* TODO detect radio type */
+
+	ret = sx130x_agc_transaction(priv, tx_msb, &val);
+	if (ret) {
+		netdev_err(netdev, "AGC Tx MSBs load failed\n");
+		return ret;
+	}
+	if (val != (SX1301_AGC_STATUS_SUCCESS | tx_msb)) {
+		netdev_err(netdev, "AGC firmware Tx MSBs error: 0x%02x", val);
+		return -ENXIO;
+	}
+
+	/* Load chan_select firmware option */
+	ret = sx130x_agc_transaction(priv, 0, &val);
+	if (ret) {
+		netdev_err(netdev, "AGC chan select failed\n");
+		return ret;
+	}
+	if (val != (SX1301_AGC_STATUS_SUCCESS | 0)) {
+		netdev_err(netdev, "AGC firmware chan select error: 0x%02x", val);
+		return -ENXIO;
+	}
+
+	/* End AGC firmware init and check status */
+	/* TODO load the intended value of radio_select here
+	 * LORA IF mapping to radio A/B (per bit, 0=A, 1=B) */
+	ret = sx130x_agc_transaction(priv, 0, &val);
+	if (ret) {
+		netdev_err(netdev, "AGC radio select failed\n");
+		return ret;
+	}
+	if (val != SX1301_AGC_STATUS_INITIALISED) {
+		netdev_err(netdev, "AGC firmware init error: 0x%02x", val);
+		return -ENXIO;
+	}
+
+	return ret;
+}
+
 static netdev_tx_t sx130x_loradev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	if (skb->protocol != htons(ETH_P_LORA)) {
@@ -589,6 +694,11 @@ static int sx130x_loradev_open(struct net_device *netdev)
 	if (ret)
 		goto err_firmware;
 
+	usleep_range(1000, 2000);
+	ret = sx130x_agc_init(priv);
+	if (ret)
+		goto err_firmware;
+
 	ret = open_loradev(netdev);
 	if (ret)
 		goto err_open;
diff --git a/drivers/net/lora/sx130x.h b/drivers/net/lora/sx130x.h
index 69bb9cbd1aba..2878dd3cc547 100644
--- a/drivers/net/lora/sx130x.h
+++ b/drivers/net/lora/sx130x.h
@@ -19,8 +19,15 @@
 #define SX1301_MCU_AGC_CAL_FW_VERSION 2
 
 #define SX1301_AGC_CMD_WAIT 16
+#define SX1301_AGC_CMD_ABORT 17
+
+#define SX1301_AGC_STATUS_READY 0x10
+#define SX1301_AGC_STATUS_SUCCESS 0x30
+#define SX1301_AGC_STATUS_INITIALISED 0x40
 
 #define SX1301_TX_GAIN_LUT_MAX 16
+#define SX1301_PA_GAIN_OFFSET 6
+#define SX1301_DAC_GAIN_OFFSET 4
 
 /* Page independent */
 #define SX1301_PAGE     0x00
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 06/11] net: lora: sx130x: add detail to TODO in setup
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
                   ` (4 preceding siblings ...)
  2019-01-28 16:12 ` [PATCH lora-next 05/11] net: lora: sx130x: initialise AGC Ben Whitten
@ 2019-01-28 16:13 ` Ben Whitten
  2019-01-28 16:13 ` [PATCH lora-next 07/11] net: lora: sx130x: add work queue to tx path Ben Whitten
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel

From: Ben Whitten <ben.whitten@gmail.com>

Setup requires a more steps to be complete, call these out specifically
so they are not missed.

Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
 drivers/net/lora/sx130x.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 18acfc8e934d..88932fbbb598 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -688,7 +688,17 @@ static int sx130x_loradev_open(struct net_device *netdev)
 	if (ret)
 		goto err_calibrate;
 
-	/* TODO */
+	/* TODO Load constant adjustments, patches */
+
+	/* TODO Frequency time drift */
+
+	/* TODO Configure lora multi demods, bitfield of active */
+
+	/* TODO Load concentrator multi channel frequencies */
+
+	/* TODO enable the correlator on enabled frequencies */
+
+	/* TODO PPM, and modem enable */
 
 	ret = sx130x_load_all_firmware(priv);
 	if (ret)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 07/11] net: lora: sx130x: add work queue to tx path
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
                   ` (5 preceding siblings ...)
  2019-01-28 16:13 ` [PATCH lora-next 06/11] net: lora: sx130x: add detail to TODO in setup Ben Whitten
@ 2019-01-28 16:13 ` Ben Whitten
  2019-01-28 16:13 ` [PATCH lora-next 08/11] net: lora: sx130x: add test transmission Ben Whitten
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel

As we are not allowed to sleep in _start_xmit, we need to add a work queue
to handle transmission of the packets.

Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
 drivers/net/lora/sx130x.c | 50 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 88932fbbb598..820ec0220e28 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -69,6 +69,10 @@ struct sx130x_priv {
 	void			*drvdata;
 	struct sx130x_tx_gain_lut tx_gain_lut[SX1301_TX_GAIN_LUT_MAX];
 	u8 tx_gain_lut_size;
+
+	struct sk_buff *tx_skb;
+	struct workqueue_struct *wq;
+	struct work_struct tx_work;
 };
 
 struct regmap *sx130x_get_regmap(struct device *dev)
@@ -644,6 +648,8 @@ static int sx130x_agc_init(struct sx130x_priv *priv)
 
 static netdev_tx_t sx130x_loradev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
+	struct sx130x_priv *priv = netdev_priv(netdev);
+
 	if (skb->protocol != htons(ETH_P_LORA)) {
 		kfree_skb(skb);
 		netdev->stats.tx_dropped++;
@@ -651,11 +657,36 @@ static netdev_tx_t sx130x_loradev_start_xmit(struct sk_buff *skb, struct net_dev
 	}
 
 	netif_stop_queue(netdev);
+	priv->tx_skb = skb;
+	queue_work(priv->wq, &priv->tx_work);
 
-	/* TODO */
 	return NETDEV_TX_OK;
 }
 
+static void sx130x_tx_work_handler(struct work_struct *ws)
+{
+	struct sx130x_priv *priv = container_of(ws, struct sx130x_priv, tx_work);
+	struct net_device *netdev = dev_get_drvdata(priv->dev);
+	int ret;
+
+	netdev_dbg(netdev, "%s\n", __func__);
+
+	if (priv->tx_skb) {
+
+		/* TODO actual tx* */
+
+		if (!(netdev->flags & IFF_ECHO) ||
+		    priv->tx_skb->pkt_type != PACKET_LOOPBACK ||
+		    priv->tx_skb->protocol != htons(ETH_P_LORA))
+			kfree_skb(priv->tx_skb);
+
+		priv->tx_skb = NULL;
+	}
+
+	if (netif_queue_stopped(netdev))
+		netif_wake_queue(netdev);
+}
+
 static int sx130x_loradev_open(struct net_device *netdev)
 {
 	struct sx130x_priv *priv = netdev_priv(netdev);
@@ -715,6 +746,12 @@ static int sx130x_loradev_open(struct net_device *netdev)
 
 	mutex_unlock(&priv->io_lock);
 
+	priv->tx_skb = NULL;
+
+	priv->wq = alloc_workqueue("sx130x_wq",
+				   WQ_FREEZABLE | WQ_MEM_RECLAIM, 0);
+	INIT_WORK(&priv->tx_work, sx130x_tx_work_handler);
+
 	netif_start_queue(netdev);
 
 	return 0;
@@ -729,11 +766,22 @@ static int sx130x_loradev_open(struct net_device *netdev)
 
 static int sx130x_loradev_stop(struct net_device *netdev)
 {
+	struct sx130x_priv *priv = netdev_priv(netdev);
+
 	netdev_dbg(netdev, "%s", __func__);
 
 	netif_stop_queue(netdev);
 	close_loradev(netdev);
 
+	destroy_workqueue(priv->wq);
+	priv->wq = NULL;
+
+	if (priv->tx_skb) {
+		netdev->stats.tx_errors++;
+		dev_kfree_skb(priv->tx_skb);
+	}
+	priv->tx_skb = NULL;
+
 	return 0;
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 08/11] net: lora: sx130x: add test transmission
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
                   ` (6 preceding siblings ...)
  2019-01-28 16:13 ` [PATCH lora-next 07/11] net: lora: sx130x: add work queue to tx path Ben Whitten
@ 2019-01-28 16:13 ` Ben Whitten
  2019-01-28 16:13 ` [PATCH lora-next 09/11] net: lora: introduce lora socket addressing for metadata Ben Whitten
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel

First transmission from the SX130x, all metadata values are hardcoded
and will be replaced with a suitable alternative.
Data sent into the socket is sent straight out of the card.

Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
 drivers/net/lora/sx130x.c | 128 +++++++++++++++++++++++++++++++++++++-
 drivers/net/lora/sx130x.h |  11 ++++
 2 files changed, 137 insertions(+), 2 deletions(-)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 820ec0220e28..f96f32d2e1ff 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -49,8 +49,50 @@ static const struct reg_field sx130x_regmap_fields[] = {
 	/* EMERGENCY_FORCE_HOST_CTRL */
 	[F_EMERGENCY_FORCE_HOST_CTRL] =
 		REG_FIELD(SX1301_EMERGENCY_FORCE_HOST_CTRL, 0, 0),
+	/* TX_TRIG */
+	[F_TX_TRIG_IMMEDIATE] = REG_FIELD(SX1301_TX_TRIG, 0, 0),
+	[F_TX_TRIG_DELAYED] = REG_FIELD(SX1301_TX_TRIG, 1, 1),
+	[F_TX_TRIG_GPS] = REG_FIELD(SX1301_TX_TRIG, 2, 2),
 };
 
+struct sx130x_tx_header {
+	u8	tx_freq[3];
+	u32	start;
+	u8	tx_power:4,
+		modulation_type:1,
+		radio_select:1,
+		resered0:2;
+	u8	reserved1;
+
+	union {
+		struct lora_t {
+			u8	sf:4,
+				cr:3,
+				crc16_en:1;
+			u8	payload_len;
+			u8	mod_bw:2,
+				implicit_header:1,
+				ppm_offset:1,
+				invert_pol:1,
+				reserved0:3;
+			u16	preamble;
+			u8	reserved1;
+			u8	reserved2;
+		} lora;
+		struct fsk_t {
+			u8	freq_dev;
+			u8	payload_len;
+			u8	packet_mode:1,
+				crc_en:1,
+				enc_mode:2,
+				crc_mode:1,
+				reserved0:3;
+			u16	preamble;
+			u16	bitrate;
+		} fsk;
+	} u;
+} __packed;
+
 struct sx130x_tx_gain_lut {
 	s8 power;	/* dBm measured at board connector */
 	u8 dig_gain;
@@ -646,6 +688,83 @@ static int sx130x_agc_init(struct sx130x_priv *priv)
 	return ret;
 }
 
+static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
+{
+	int ret, i;
+	u8 buff[256 + 16];
+	struct sx130x_tx_header *hdr = (struct sx130x_tx_header *)buff;
+	struct net_device *netdev = dev_get_drvdata(priv->dev);
+
+	/* TODO general checks to make sure we CAN send */
+
+	/* TODO Enable notch filter for lora 125 */
+
+	/* TODO get start delay for this TX */
+
+	/* TODO interpret tx power, HACK just set max power */
+
+	/* TODO get TX imbalance for this pow index from calibration step */
+
+	/* TODO set the dig gain */
+
+	/* TODO set TX PLL freq based on radio used to TX */
+
+	memset(buff, 0, sizeof(buff));
+
+	/* HACK set to 868MHz */
+	hdr->tx_freq[0] = 217;
+	hdr->tx_freq[1] = 0;
+	hdr->tx_freq[2] = 0;
+
+	hdr->start = 0; /* Start imediatly */
+	hdr->radio_select = 0; /* HACK Radio A transmit */
+	hdr->modulation_type = 0; /* HACK modulation LORA */
+	hdr->tx_power = 15; /* HACK power entry 15 */
+
+	hdr->u.lora.crc16_en = 1; /* Enable CRC16 */
+	hdr->u.lora.cr = 1; /* CR 4/5 */
+	hdr->u.lora.sf = 7; /* SF7 */
+	hdr->u.lora.payload_len = len; /* Set the data len to the skb len */
+	hdr->u.lora.implicit_header = 0; /* No implicit header */
+	hdr->u.lora.mod_bw = 0; /* Set 125KHz BW */
+	hdr->u.lora.ppm_offset = 0; /* TODO no ppm offset? */
+	hdr->u.lora.invert_pol = 0; /* TODO set no inverted polarity */
+
+	hdr->u.lora.preamble = 8; /* Set the standard preamble */
+
+	/* TODO 2 Msb in tx_freq0 for large narrow filtering, unset for now */
+	hdr->tx_freq[0] &= 0x3F;
+
+	/* Copy the TX data into the buffer ready to go */
+
+	memcpy((void *)&buff[16], data, len);
+
+	/* Reset any transmissions */
+	ret = regmap_write(priv->regmap, SX1301_TX_TRIG, 0);
+	if (ret)
+		return ret;
+
+	/* Put the buffer into the tranmit fifo */
+	ret = regmap_write(priv->regmap, SX1301_TX_DATA_BUF_ADDR, 0);
+	if (ret)
+		return ret;
+	ret = regmap_noinc_write(priv->regmap, SX1301_TX_DATA_BUF_DATA, buff,
+				 len + 16);
+	if (ret)
+		return ret;
+
+	/* HACK just go for immediate transfer */
+	ret = sx130x_field_force_write(priv, F_TX_TRIG_IMMEDIATE, 1);
+	if (ret)
+		return ret;
+
+	netdev_dbg(netdev, "Transmitting packet of size %d: ", len);
+	for (i = 0; i < len + 16; i++)
+		netdev_dbg(netdev, "%X", buff[i]);
+
+	return ret;
+}
+
 static netdev_tx_t sx130x_loradev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct sx130x_priv *priv = netdev_priv(netdev);
@@ -672,8 +791,13 @@ static void sx130x_tx_work_handler(struct work_struct *ws)
 	netdev_dbg(netdev, "%s\n", __func__);
 
 	if (priv->tx_skb) {
-
-		/* TODO actual tx* */
+		ret = sx130x_tx(priv, priv->tx_skb->data, priv->tx_skb->len);
+		if (ret) {
+			netdev->stats.tx_errors++;
+		} else {
+			netdev->stats.tx_packets++;
+			netdev->stats.tx_bytes += priv->tx_skb->len;
+		}
 
 		if (!(netdev->flags & IFF_ECHO) ||
 		    priv->tx_skb->pkt_type != PACKET_LOOPBACK ||
diff --git a/drivers/net/lora/sx130x.h b/drivers/net/lora/sx130x.h
index 2878dd3cc547..38f1b58b2165 100644
--- a/drivers/net/lora/sx130x.h
+++ b/drivers/net/lora/sx130x.h
@@ -32,6 +32,10 @@
 /* Page independent */
 #define SX1301_PAGE     0x00
 #define SX1301_VER      0x01
+#define SX1301_RX_DATA_BUF_ADDR 0x02 /* 16 wide */
+#define SX1301_RX_DATA_BUF_DATA 0x04
+#define SX1301_TX_DATA_BUF_ADDR 0x05
+#define SX1301_TX_DATA_BUF_DATA 0x06
 #define SX1301_MPA      0x09
 #define SX1301_MPD      0x0A
 #define SX1301_GEN      0x10
@@ -49,6 +53,9 @@
 #define SX1301_FORCE_CTRL   (SX1301_PAGE_BASE(0) + 0x69)
 #define SX1301_MCU_CTRL     (SX1301_PAGE_BASE(0) + 0x6A)
 
+/* Page 1 */
+#define SX1301_TX_TRIG      (SX1301_PAGE_BASE(1) + 0x21)
+
 /* Page 2 */
 #define SX1301_RADIO_A_SPI_DATA     (SX1301_PAGE_BASE(2) + 0x21)
 #define SX1301_RADIO_A_SPI_DATA_RB  (SX1301_PAGE_BASE(2) + 0x22)
@@ -87,6 +94,10 @@ enum sx130x_fields {
 	F_FORCE_DEC_FILTER_GAIN,
 
 	F_EMERGENCY_FORCE_HOST_CTRL,
+
+	F_TX_TRIG_IMMEDIATE,
+	F_TX_TRIG_DELAYED,
+	F_TX_TRIG_GPS,
 };
 
 struct regmap *sx130x_get_regmap(struct device *dev);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 09/11] net: lora: introduce lora socket addressing for metadata
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
                   ` (7 preceding siblings ...)
  2019-01-28 16:13 ` [PATCH lora-next 08/11] net: lora: sx130x: add test transmission Ben Whitten
@ 2019-01-28 16:13 ` Ben Whitten
  2019-01-28 16:13 ` [PATCH lora-next 10/11] net: lora: sx130x: make use of lora address metadata in transmission Ben Whitten
  2019-01-28 16:13 ` [PATCH lora-next 11/11] net: lora: sx130x: add patch to register fields Ben Whitten
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, linux-kernel, netdev

Information such as spreading factor, coding rate and power are on a per
transmission basis so we can encode this information in the lora socket
address.
In future we may have a different format for receive with additional
fields which get populated.

Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
 include/linux/lora/skb.h  |  9 ++++++++
 include/uapi/linux/lora.h | 14 ++++++++++++
 net/lora/dgram.c          | 45 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)

diff --git a/include/linux/lora/skb.h b/include/linux/lora/skb.h
index 8806741464d0..6abeb39b8b7f 100644
--- a/include/linux/lora/skb.h
+++ b/include/linux/lora/skb.h
@@ -12,6 +12,15 @@
 
 struct lora_skb_priv {
 	int ifindex;
+
+	u64 freq;
+	u8 sf;
+	u8 cr;
+	u16 bw;
+
+	u8 sync;
+
+	s8 power;
 };
 
 static inline struct lora_skb_priv *lora_skb_prv(struct sk_buff *skb)
diff --git a/include/uapi/linux/lora.h b/include/uapi/linux/lora.h
index 4ff00b9c3c20..4c458ee3ed9a 100644
--- a/include/uapi/linux/lora.h
+++ b/include/uapi/linux/lora.h
@@ -10,6 +10,18 @@
 #include <linux/types.h>
 #include <linux/socket.h>
 
+/* TX addressing definition */
+struct tx_addr {
+	__u64 freq;
+	__u8 sf;
+	__u8 cr;
+	__u16 bw;
+
+	__u8 sync;
+
+	__s8 power;
+};
+
 /* particular protocols of the protocol family PF_LORA */
 #define LORA_PROTO_DATAGRAM	0
 #define LORA_NPROTO		1
@@ -17,7 +29,9 @@
 struct sockaddr_lora {
 	__kernel_sa_family_t lora_family;
 	int lora_ifindex;
+	__u8 lora_protocol;
 	union {
+		struct tx_addr	tx;
 	} lora_addr;
 };
 
diff --git a/net/lora/dgram.c b/net/lora/dgram.c
index 4d931fd3778a..1556ad0f8835 100644
--- a/net/lora/dgram.c
+++ b/net/lora/dgram.c
@@ -20,6 +20,15 @@ struct dgram_sock {
 	int ifindex;
 	bool bound;
 	struct notifier_block notifier;
+
+	u64 freq;
+	u8 sf;
+	u8 cr;
+	u16 bw;
+
+	u8 sync;
+
+	s8 power;
 };
 
 static inline struct dgram_sock *dgram_sk(const struct sock *sk)
@@ -69,6 +78,12 @@ static int dgram_bind(struct socket *sock, struct sockaddr *uaddr, int len)
 		ifindex = 0;
 
 	dgram->ifindex = ifindex;
+	dgram->freq = addr->lora_addr.tx.freq;
+	dgram->sf = addr->lora_addr.tx.sf;
+	dgram->cr = addr->lora_addr.tx.cr;
+	dgram->bw = addr->lora_addr.tx.bw;
+	dgram->sync = addr->lora_addr.tx.sync;
+	dgram->power = addr->lora_addr.tx.power;
 	dgram->bound = true;
 
 out:
@@ -118,6 +133,12 @@ static int dgram_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 
 	lora_skb_reserve(skb);
 	lora_skb_prv(skb)->ifindex = netdev->ifindex;
+	lora_skb_prv(skb)->freq = dgram->freq;
+	lora_skb_prv(skb)->sf = dgram->sf;
+	lora_skb_prv(skb)->cr = dgram->cr;
+	lora_skb_prv(skb)->bw = dgram->bw;
+	lora_skb_prv(skb)->sync = dgram->sync;
+	lora_skb_prv(skb)->power = dgram->power;
 
 	ret = memcpy_from_msg(skb_put(skb, size), msg, size);
 	if (ret < 0)
@@ -172,6 +193,12 @@ static int dgram_getname(struct socket *sock, struct sockaddr *uaddr,
 	memset(addr, 0, sizeof(*addr));
 	addr->lora_family = AF_LORA;
 	addr->lora_ifindex = dgram->ifindex;
+	addr->lora_addr.tx.freq = dgram->freq;
+	addr->lora_addr.tx.sf = dgram->sf;
+	addr->lora_addr.tx.cr = dgram->cr;
+	addr->lora_addr.tx.bw = dgram->bw;
+	addr->lora_addr.tx.sync = dgram->sync;
+	addr->lora_addr.tx.power = dgram->power;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
 	return sizeof(*addr);
@@ -198,6 +225,12 @@ static int dgram_release(struct socket *sock)
 	lock_sock(sk);
 
 	dgram->ifindex = 0;
+	dgram->freq = 0;
+	dgram->sf = 0;
+	dgram->cr = 0;
+	dgram->bw = 0;
+	dgram->sync = 0;
+	dgram->power = 0;
 	dgram->bound = false;
 
 	sock_orphan(sk);
@@ -251,6 +284,12 @@ static int dgram_notifier(struct notifier_block *nb, unsigned long msg, void *pt
 		lock_sock(sk);
 
 		dgram->ifindex = 0;
+		dgram->freq = 0;
+		dgram->sf = 0;
+		dgram->cr = 0;
+		dgram->bw = 0;
+		dgram->sync = 0;
+		dgram->power = 0;
 		dgram->bound = false;
 
 		release_sock(sk);
@@ -277,6 +316,12 @@ static int dgram_init(struct sock *sk)
 	pr_debug("lora: %s\n", __func__);
 
 	dgram->bound = false;
+	dgram->freq = 0;
+	dgram->sf = 0;
+	dgram->cr = 0;
+	dgram->bw = 0;
+	dgram->sync = 0;
+	dgram->power = 0;
 	dgram->ifindex = 0;
 
 	dgram->notifier.notifier_call = dgram_notifier;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 10/11] net: lora: sx130x: make use of lora address metadata in transmission
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
                   ` (8 preceding siblings ...)
  2019-01-28 16:13 ` [PATCH lora-next 09/11] net: lora: introduce lora socket addressing for metadata Ben Whitten
@ 2019-01-28 16:13 ` Ben Whitten
  2019-01-28 16:13 ` [PATCH lora-next 11/11] net: lora: sx130x: add patch to register fields Ben Whitten
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel

We take the metadata encoded in the lora address and apply it to the
outgoing transmission.

Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
 drivers/net/lora/sx130x.c | 58 ++++++++++++++++++++++++++++++++-------
 1 file changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index f96f32d2e1ff..428e82b4ccb8 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/gpio/consumer.h>
 #include <linux/lora/dev.h>
+#include <linux/lora/skb.h>
 #include <linux/spi/spi.h>
 
 #include "sx130x.h"
@@ -688,12 +689,13 @@ static int sx130x_agc_init(struct sx130x_priv *priv)
 	return ret;
 }
 
-static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
+static int sx130x_tx(struct sx130x_priv *priv, struct sk_buff *skb)
 {
 	int ret, i;
 	u8 buff[256 + 16];
 	struct sx130x_tx_header *hdr = (struct sx130x_tx_header *)buff;
 	struct net_device *netdev = dev_get_drvdata(priv->dev);
+	u8 sf;
 
 	/* TODO general checks to make sure we CAN send */
 
@@ -722,11 +724,47 @@ static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
 	hdr->tx_power = 15; /* HACK power entry 15 */
 
 	hdr->u.lora.crc16_en = 1; /* Enable CRC16 */
-	hdr->u.lora.cr = 1; /* CR 4/5 */
-	hdr->u.lora.sf = 7; /* SF7 */
-	hdr->u.lora.payload_len = len; /* Set the data len to the skb len */
+
+	switch (lora_skb_prv(skb)->cr) {
+	case 5:
+		hdr->u.lora.cr = 1; /* CR 4/5 */
+		break;
+	case 6:
+		hdr->u.lora.cr = 2; /* CR 4/6 */
+		break;
+	case 7:
+		hdr->u.lora.cr = 3; /* CR 4/7 */
+		break;
+	case 8:
+		hdr->u.lora.cr = 4; /* CR 4/8 */
+		break;
+	default:
+		return -ENXIO;
+	}
+
+	sf = lora_skb_prv(skb)->sf;
+	if ((sf < 6) || (sf > 12))
+		return -ENXIO;
+
+	hdr->u.lora.sf = sf;
+
+	hdr->u.lora.payload_len = skb->len; /* Set the data length */
 	hdr->u.lora.implicit_header = 0; /* No implicit header */
-	hdr->u.lora.mod_bw = 0; /* Set 125KHz BW */
+
+	switch(lora_skb_prv(skb)->bw) {
+	case 125:
+		hdr->u.lora.mod_bw = 0; /* 125KHz BW */
+		break;
+	case 250:
+		hdr->u.lora.mod_bw = 1; /* 250KHz BW */
+		break;
+	case 500:
+		hdr->u.lora.mod_bw = 2; /* 500KHz BW */
+		break;
+	default:
+		return -ENXIO;
+	}
+
 	hdr->u.lora.ppm_offset = 0; /* TODO no ppm offset? */
 	hdr->u.lora.invert_pol = 0; /* TODO set no inverted polarity */
 
@@ -737,7 +775,7 @@ static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
 
 	/* Copy the TX data into the buffer ready to go */
 
-	memcpy((void *)&buff[16], data, len);
+	memcpy((void *)&buff[16], skb->data, skb->len);
 
 	/* Reset any transmissions */
 	ret = regmap_write(priv->regmap, SX1301_TX_TRIG, 0);
@@ -749,7 +787,7 @@ static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
 	if (ret)
 		return ret;
 	ret = regmap_noinc_write(priv->regmap, SX1301_TX_DATA_BUF_DATA, buff,
-				 len + 16);
+				 skb->len + 16);
 	if (ret)
 		return ret;
 
@@ -758,8 +796,8 @@ static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
 	if (ret)
 		return ret;
 
-	netdev_dbg(netdev, "Transmitting packet of size %d: ", len);
-	for (i = 0; i < len + 16; i++)
+	netdev_dbg(netdev, "Transmitting packet of size %d: ", skb->len);
+	for (i = 0; i < skb->len + 16; i++)
 		netdev_dbg(netdev, "%X", buff[i]);
 
 	return ret;
@@ -791,7 +829,7 @@ static void sx130x_tx_work_handler(struct work_struct *ws)
 	netdev_dbg(netdev, "%s\n", __func__);
 
 	if (priv->tx_skb) {
-		ret = sx130x_tx(priv, priv->tx_skb->data, priv->tx_skb->len);
+		ret = sx130x_tx(priv, priv->tx_skb);
 		if (ret) {
 			netdev->stats.tx_errors++;
 		} else {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH lora-next 11/11] net: lora: sx130x: add patch to register fields
  2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
                   ` (9 preceding siblings ...)
  2019-01-28 16:13 ` [PATCH lora-next 10/11] net: lora: sx130x: make use of lora address metadata in transmission Ben Whitten
@ 2019-01-28 16:13 ` Ben Whitten
  10 siblings, 0 replies; 13+ messages in thread
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
  To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel

The SX130x chips require a number of constant adjustments and patches.
We add the fields for the registers which require patches, add patch
values then add a helper to patch fields. Removing one TODO.

Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
 drivers/net/lora/sx130x.c | 131 +++++++++++++++++++++++++++++++++++++-
 drivers/net/lora/sx130x.h |  75 ++++++++++++++++++++++
 2 files changed, 205 insertions(+), 1 deletion(-)

diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 428e82b4ccb8..6e3b42de98a0 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -27,6 +27,63 @@
 
 #include "sx130x.h"
 
+struct sx130x_fields_sequence {
+	enum sx130x_fields field;
+	u8 val;
+};
+
+static const struct sx130x_fields_sequence sx130x_regmap_fields_patch[] = {
+	/* I/Q path setup */
+	{F_RSSI_BB_FILTER_ALPHA,	6},
+	{F_RSSI_DEC_FILTER_ALPHA,	7},
+	{F_RSSI_CHANN_FILTER_ALPHA,	7},
+	{F_RSSI_BB_DEFAULT_VALUE,	23},
+	{F_RSSI_DEC_DEFAULT_VALUE,	85},
+	{F_RSSI_CHANN_DEFAULT_VALUE,	66},
+	{F_DEC_GAIN_OFFSET,		7},
+	{F_CHAN_GAIN_OFFSET,		6},
+
+	/* LoRa 'multi' demodulator setup */
+	{F_SNR_AVG_CST,			3},
+	{F_FRAME_SYNCH_PEAK1_POS,	3}, // Public LoRa network
+	{F_FRAME_SYNCH_PEAK2_POS,	4}, // Public LoRa network
+
+	/* LoRa standalone 'MBWSSF' demodulator setup */
+	{F_MBWSSF_FRAME_SYNCH_PEAK1_POS, 3}, // Public LoRa network
+	{F_MBWSSF_FRAME_SYNCH_PEAK2_POS, 4}, // Public LoRa network
+
+	/* Improvement of ref clock freq error tolerance */
+	{F_ADJUST_MODEM_START_OFFSET_RDX4L, 1},
+	{F_ADJUST_MODEM_START_OFFSET_SF12_RDX4L, (4094 & 0xFF)},
+	{F_ADJUST_MODEM_START_OFFSET_SF12_RDX4H, (4094 >> 8)},
+	{F_CORR_MAC_GAIN,		7},
+
+	/* FSK datapath setup */
+	{F_FSK_RX_INVERT,		1},
+	{F_FSK_MODEM_INVERT_IQ,		1},
+
+	/* FSK demodulator setup */
+	{F_FSK_RSSI_LENGTH,		4},
+	{F_FSK_PKT_MODE,		1},
+	{F_FSK_CRC_EN,			1},
+	{F_FSK_DCFREE_ENC,		2},
+	{F_FSK_ERROR_OSR_TOL,		10},
+	{F_FSK_PKT_LENGTH,		255},
+	{F_FSK_PATTERN_TIMEOUT_CFGL,	128},
+
+	/* TX general parameters */
+	{F_TX_START_DELAYL, (TX_START_DELAY_DEFAULT & 0xFF)},
+	{F_TX_START_DELAYH, (TX_START_DELAY_DEFAULT >> 8)},
+
+	/* TX LoRa */
+	{F_TX_SWAP_IQ,			1},
+	{F_TX_FRAME_SYNCH_PEAK1_POS,	3}, // Public LoRa network
+	{F_TX_FRAME_SYNCH_PEAK2_POS,	4}, // Public LoRa network
+
+	/* TX FSK */
+	{F_FSK_TX_GAUSSIAN_SELECT_BT,	2},
+};
+
 static const struct reg_field sx130x_regmap_fields[] = {
 	/* PAGE */
 	[F_SOFT_RESET]          = REG_FIELD(SX1301_PAGE, 7, 7),
@@ -54,6 +111,59 @@ static const struct reg_field sx130x_regmap_fields[] = {
 	[F_TX_TRIG_IMMEDIATE] = REG_FIELD(SX1301_TX_TRIG, 0, 0),
 	[F_TX_TRIG_DELAYED] = REG_FIELD(SX1301_TX_TRIG, 1, 1),
 	[F_TX_TRIG_GPS] = REG_FIELD(SX1301_TX_TRIG, 2, 2),
+
+	/* RSSI_X_FILTER_ALPHA */
+	[F_RSSI_BB_FILTER_ALPHA] = REG_FIELD(SX1301_RSSI_BB_FILTER_ALPHA, 0, 4),
+	[F_RSSI_DEC_FILTER_ALPHA] = REG_FIELD(SX1301_RSSI_DEC_FILTER_ALPHA, 0, 4),
+	[F_RSSI_CHANN_FILTER_ALPHA]	= REG_FIELD(SX1301_RSSI_CHANN_FILTER_ALPHA, 0, 4),
+	/* RSSI_X_DEFAULT_VALUE */
+	[F_RSSI_BB_DEFAULT_VALUE] = REG_FIELD(SX1301_RSSI_BB_DEFAULT_VALUE, 0, 7),
+	[F_RSSI_DEC_DEFAULT_VALUE] = REG_FIELD(SX1301_RSSI_DEC_DEFAULT_VALUE, 0, 7),
+	[F_RSSI_CHANN_DEFAULT_VALUE] = REG_FIELD(SX1301_RSSI_CHANN_DEFAULT_VALUE, 0, 7),
+	/* GAIN_OFFSET */
+	[F_DEC_GAIN_OFFSET]	= REG_FIELD(SX1301_GAIN_OFFSET, 0, 3),
+	[F_CHAN_GAIN_OFFSET]	= REG_FIELD(SX1301_GAIN_OFFSET, 4, 7),
+
+	[F_SNR_AVG_CST] = REG_FIELD(SX1301_MISC_CFG1, 4, 5),
+	[F_FRAME_SYNCH_PEAK1_POS] = REG_FIELD(SX1301_FRAME_SYNCH, 0, 3),
+	[F_FRAME_SYNCH_PEAK2_POS] = REG_FIELD(SX1301_FRAME_SYNCH, 4, 7),
+
+	[F_MBWSSF_FRAME_SYNCH_PEAK1_POS] = REG_FIELD(SX1301_BHSYNCPOS, 0, 3),
+	[F_MBWSSF_FRAME_SYNCH_PEAK2_POS] = REG_FIELD(SX1301_BHSYNCPOS, 4, 7),
+
+	[F_ADJUST_MODEM_START_OFFSET_RDX4L] =
+		REG_FIELD(SX1301_MODEM_START_RDX4L, 0, 7),  // 12 bits
+	[F_ADJUST_MODEM_START_OFFSET_RDX4H] =
+		REG_FIELD(SX1301_MODEM_START_RDX4H, 0, 3),
+	[F_ADJUST_MODEM_START_OFFSET_SF12_RDX4L] =
+		REG_FIELD(SX1301_MODEM_START_SF12_RDX4L, 0, 7), // 12 bits
+	[F_ADJUST_MODEM_START_OFFSET_SF12_RDX4H] =
+		REG_FIELD(SX1301_MODEM_START_SF12_RDX4H, 0, 3),
+	[F_CORR_MAC_GAIN] = REG_FIELD(SX1301_CORR_CFG, 4, 6),
+
+	[F_FSK_RSSI_LENGTH] = REG_FIELD(SX1301_FSK_CFG1, 3, 5),
+	[F_FSK_RX_INVERT] = REG_FIELD(SX1301_FSK_CFG1, 6, 6),
+	[F_FSK_PKT_MODE] = REG_FIELD(SX1301_FSK_CFG1, 7, 7),
+
+	[F_FSK_MODEM_INVERT_IQ] = REG_FIELD(SX1301_IQCFG, 5, 5),
+
+	[F_FSK_CRC_EN] = REG_FIELD(SX1301_FSK_CFG2, 3, 3),
+	[F_FSK_DCFREE_ENC] = REG_FIELD(SX1301_FSK_CFG2, 4, 5),
+	[F_FSK_ERROR_OSR_TOL] = REG_FIELD(SX1301_FSK_ERROR_OSR_TOL, 0, 4),
+	[F_FSK_PKT_LENGTH] = REG_FIELD(SX1301_FSK_PKT_LENGTH, 0, 7),
+	[F_FSK_PATTERN_TIMEOUT_CFGL] =
+		REG_FIELD(SX1301_FSK_PATTERN_TIMEOUT_CFGL, 0, 7),  // 10 bits
+	[F_FSK_PATTERN_TIMEOUT_CFGH] =
+		REG_FIELD(SX1301_FSK_PATTERN_TIMEOUT_CFGH, 0, 1),
+
+	[F_TX_START_DELAYL] = REG_FIELD(SX1301_TX_START_DELAYL, 0, 7), // 16 bit
+	[F_TX_START_DELAYH] = REG_FIELD(SX1301_TX_START_DELAYH, 0, 7),
+
+	[F_TX_SWAP_IQ] = REG_FIELD(SX1301_TX_CFG2, 7, 7),
+	[F_TX_FRAME_SYNCH_PEAK1_POS] = REG_FIELD(SX1301_TX_FRAME_SYNCH, 0, 3),
+	[F_TX_FRAME_SYNCH_PEAK2_POS] = REG_FIELD(SX1301_TX_FRAME_SYNCH, 4, 7),
+
+	[F_FSK_TX_GAUSSIAN_SELECT_BT] = REG_FIELD(SX1301_FSK_TX, 1, 2),
 };
 
 struct sx130x_tx_header {
@@ -263,6 +373,23 @@ static int sx130x_soft_reset(struct sx130x_priv *priv)
 	return 0;
 }
 
+static int sx130x_fields_patch(struct sx130x_priv *priv)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(sx130x_regmap_fields_patch); i++) {
+		ret = sx130x_field_force_write(priv, sx130x_regmap_fields_patch[i].field,
+					       sx130x_regmap_fields_patch[i].val);
+		if (ret) {
+			dev_err(priv->dev,
+				"Failed to patch regmap field: %d\n", i);
+			break;
+		}
+	}
+
+	return ret;
+}
+
 static int sx130x_agc_ram_read(struct sx130x_priv *priv, u8 addr, unsigned int *val)
 {
 	int ret;
@@ -881,7 +1008,9 @@ static int sx130x_loradev_open(struct net_device *netdev)
 	if (ret)
 		goto err_calibrate;
 
-	/* TODO Load constant adjustments, patches */
+	ret = sx130x_fields_patch(priv);
+	if (ret)
+		return ret;
 
 	/* TODO Frequency time drift */
 
diff --git a/drivers/net/lora/sx130x.h b/drivers/net/lora/sx130x.h
index 38f1b58b2165..121c8a35b5c3 100644
--- a/drivers/net/lora/sx130x.h
+++ b/drivers/net/lora/sx130x.h
@@ -29,6 +29,9 @@
 #define SX1301_PA_GAIN_OFFSET 6
 #define SX1301_DAC_GAIN_OFFSET 4
 
+/* Calibrated value for 500KHz BW and notch filter disabled */
+#define TX_START_DELAY_DEFAULT  1497
+
 /* Page independent */
 #define SX1301_PAGE     0x00
 #define SX1301_VER      0x01
@@ -49,12 +52,39 @@
 #define SX1301_PAGE_BASE(n) (SX1301_VIRT_BASE + (SX1301_PAGE_LEN * n))
 
 /* Page 0 */
+#define SX1301_IQCFG        (SX1301_PAGE_BASE(0) + 0x21)
 #define SX1301_CHRS         (SX1301_PAGE_BASE(0) + 0x23)
+#define SX1301_CORR_CFG     (SX1301_PAGE_BASE(0) + 0x4E)
+#define SX1301_MODEM_START_RDX4L (SX1301_PAGE_BASE(0) + 0x51)
+#define SX1301_MODEM_START_RDX4H (SX1301_PAGE_BASE(0) + 0x52)
+#define SX1301_MODEM_START_SF12_RDX4L (SX1301_PAGE_BASE(0) + 0x53)
+#define SX1301_MODEM_START_SF12_RDX4H (SX1301_PAGE_BASE(0) + 0x54)
+#define SX1301_FRAME_SYNCH  (SX1301_PAGE_BASE(0) + 0x5F)
+#define SX1301_MISC_CFG1    (SX1301_PAGE_BASE(0) + 0x63)
+#define SX1301_GAIN_OFFSET  (SX1301_PAGE_BASE(0) + 0x68)
 #define SX1301_FORCE_CTRL   (SX1301_PAGE_BASE(0) + 0x69)
 #define SX1301_MCU_CTRL     (SX1301_PAGE_BASE(0) + 0x6A)
+#define SX1301_RSSI_BB_DEFAULT_VALUE 	(SX1301_PAGE_BASE(0) + 0x6C)
+#define SX1301_RSSI_DEC_DEFAULT_VALUE 	(SX1301_PAGE_BASE(0) + 0x6D)
+#define SX1301_RSSI_CHANN_DEFAULT_VALUE (SX1301_PAGE_BASE(0) + 0x6E)
+#define SX1301_RSSI_BB_FILTER_ALPHA 	(SX1301_PAGE_BASE(0) + 0x6F)
+#define SX1301_RSSI_DEC_FILTER_ALPHA 	(SX1301_PAGE_BASE(0) + 0x70)
+#define SX1301_RSSI_CHANN_FILTER_ALPHA 	(SX1301_PAGE_BASE(0) + 0x71)
 
 /* Page 1 */
 #define SX1301_TX_TRIG      (SX1301_PAGE_BASE(1) + 0x21)
+#define SX1301_TX_START_DELAYL      (SX1301_PAGE_BASE(1) + 0x22)
+#define SX1301_TX_START_DELAYH      (SX1301_PAGE_BASE(1) + 0x23)
+#define SX1301_TX_FRAME_SYNCH       (SX1301_PAGE_BASE(1) + 0x24)
+#define SX1301_TX_CFG2              (SX1301_PAGE_BASE(1) + 0x2A)
+#define SX1301_BHSYNCPOS            (SX1301_PAGE_BASE(1) + 0x2E)
+#define SX1301_FSK_CFG1             (SX1301_PAGE_BASE(1) + 0x3F)
+#define SX1301_FSK_CFG2             (SX1301_PAGE_BASE(1) + 0x40)
+#define SX1301_FSK_ERROR_OSR_TOL    (SX1301_PAGE_BASE(1) + 0x41)
+#define SX1301_FSK_PKT_LENGTH       (SX1301_PAGE_BASE(1) + 0x4C)
+#define SX1301_FSK_TX               (SX1301_PAGE_BASE(1) + 0x4D)
+#define SX1301_FSK_PATTERN_TIMEOUT_CFGL (SX1301_PAGE_BASE(1) + 0x53)
+#define SX1301_FSK_PATTERN_TIMEOUT_CFGH (SX1301_PAGE_BASE(1) + 0x54)
 
 /* Page 2 */
 #define SX1301_RADIO_A_SPI_DATA     (SX1301_PAGE_BASE(2) + 0x21)
@@ -98,6 +128,51 @@ enum sx130x_fields {
 	F_TX_TRIG_IMMEDIATE,
 	F_TX_TRIG_DELAYED,
 	F_TX_TRIG_GPS,
+
+	F_RSSI_BB_FILTER_ALPHA,
+	F_RSSI_DEC_FILTER_ALPHA,
+	F_RSSI_CHANN_FILTER_ALPHA,
+
+	F_RSSI_BB_DEFAULT_VALUE,
+	F_RSSI_DEC_DEFAULT_VALUE,
+	F_RSSI_CHANN_DEFAULT_VALUE,
+
+	F_DEC_GAIN_OFFSET,
+	F_CHAN_GAIN_OFFSET,
+
+	F_SNR_AVG_CST,
+	F_FRAME_SYNCH_PEAK1_POS,
+	F_FRAME_SYNCH_PEAK2_POS,
+
+	F_MBWSSF_FRAME_SYNCH_PEAK1_POS,
+	F_MBWSSF_FRAME_SYNCH_PEAK2_POS,
+
+	F_ADJUST_MODEM_START_OFFSET_RDX4L,
+	F_ADJUST_MODEM_START_OFFSET_RDX4H,
+	F_ADJUST_MODEM_START_OFFSET_SF12_RDX4L,
+	F_ADJUST_MODEM_START_OFFSET_SF12_RDX4H,
+	F_CORR_MAC_GAIN,
+
+	F_FSK_RX_INVERT,
+	F_FSK_MODEM_INVERT_IQ,
+
+	F_FSK_RSSI_LENGTH,
+	F_FSK_PKT_MODE,
+	F_FSK_CRC_EN,
+	F_FSK_DCFREE_ENC,
+	F_FSK_ERROR_OSR_TOL,
+	F_FSK_PKT_LENGTH,
+	F_FSK_PATTERN_TIMEOUT_CFGL,
+	F_FSK_PATTERN_TIMEOUT_CFGH,
+
+	F_TX_START_DELAYL,
+	F_TX_START_DELAYH,
+
+	F_TX_SWAP_IQ,
+	F_TX_FRAME_SYNCH_PEAK1_POS,
+	F_TX_FRAME_SYNCH_PEAK2_POS,
+
+	F_FSK_TX_GAUSSIAN_SELECT_BT,
 };
 
 struct regmap *sx130x_get_regmap(struct device *dev);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH lora-next 01/11] dt-bindings: net: lora: sx130x: add power lut binding
  2019-01-28 16:12 ` [PATCH lora-next 01/11] dt-bindings: net: lora: sx130x: add power lut binding Ben Whitten
@ 2019-01-28 18:13   ` Rob Herring
  0 siblings, 0 replies; 13+ messages in thread
From: Rob Herring @ 2019-01-28 18:13 UTC (permalink / raw)
  To: Ben Whitten
  Cc: Andreas Färber, linux-lpwan, David S. Miller, Mark Rutland,
	netdev, devicetree, linux-kernel

On Mon, Jan 28, 2019 at 10:13 AM Ben Whitten <ben.whitten@gmail.com> wrote:
>
> From: Ben Whitten <ben.whitten@gmail.com>
>
> Adding power lookup table for the concentrator specified in DT.
>
> These values are calibrated for the hardware and are unique to hardware
> designs and certifications.
>
> First byte is signed power in dBm measured at the rf connector.
> Second byte is unsigned value for DIGITAL gain.
> Third byte is unsigned value for PA gain, 2 bits only.
> Fourth byte is unsigned value for DAC gain, 2 bits only.
> Fifth byte is unsigned value for MIXER gain, 4 bits only.
>
> Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
> ---
>  .../bindings/net/lora/semtech,sx130x.yaml           | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml b/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml
> index 24fad1218735..187fa2090a0b 100644
> --- a/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml
> +++ b/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml
> @@ -37,6 +37,15 @@ properties:
>      maxItems: 1
>      description: A connection of the reset gpio line.
>
> +  power-lut:
> +    description: Power lookup table for the concentrator.
> +      Consisting of maximum 16 entries, each entry having the following format;
> +      First byte is signed power in dBm measured at the rf connector.
> +      Second byte is unsigned value for DIGITAL gain.
> +      Third byte is unsigned value for PA gain, 2 bits only.
> +      Fourth byte is unsigned value for DAC gain, 2 bits only.
> +      Fifth byte is unsigned value for MIXER gain, 4 bits only.

Would you expect this to be a common lora property? If not it should
have a vendor prefix.

Either way, non-standard properties need to reference a type. That
would be 'uint8-matrix' in this case. See the '$ref' in the examples.
Though, I guess I need to add a signed type.

We can write all the free form text above as a schema:

minItems: 1
maxItems: 16
items:
  items:
    - description: ...
      range??
    - description: ...
      range??
    - description: ...
      maximum: 3
    - description: ...
      maximum: 3
    - description: ...
      maximum: 15

> +
>    radio-spi:
>      type: object
>      description: The concentrator can have two radios connected which are
> @@ -83,6 +92,10 @@ examples:
>          reset-gpios = <&pioB 27 GPIO_ACTIVE_HIGH>;
>          spi-max-frequency = <8000000>;
>
> +       power-lut =   [ 00 00 00 03 09
> +                       03 00 00 03 0C
> +                       04 00 00 03 0D ];

You may need to write this with '/bits/ 8' syntax so you can bracket
each 5 byte entry. I don't think we can do that with [] notation.

Rob

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2019-01-28 18:13 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-28 16:12 [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets Ben Whitten
2019-01-28 16:12 ` [PATCH lora-next 01/11] dt-bindings: net: lora: sx130x: add power lut binding Ben Whitten
2019-01-28 18:13   ` Rob Herring
2019-01-28 16:12 ` [PATCH lora-next 02/11] net: lora: sx130x: add loading of tx lut from DT Ben Whitten
2019-01-28 16:12 ` [PATCH lora-next 03/11] net: lora: sx130x: add CHRS to volatile register list Ben Whitten
2019-01-28 16:12 ` [PATCH lora-next 04/11] net: lora: sx130x: add helper function for writing to the SX130x MCU Ben Whitten
2019-01-28 16:12 ` [PATCH lora-next 05/11] net: lora: sx130x: initialise AGC Ben Whitten
2019-01-28 16:13 ` [PATCH lora-next 06/11] net: lora: sx130x: add detail to TODO in setup Ben Whitten
2019-01-28 16:13 ` [PATCH lora-next 07/11] net: lora: sx130x: add work queue to tx path Ben Whitten
2019-01-28 16:13 ` [PATCH lora-next 08/11] net: lora: sx130x: add test transmission Ben Whitten
2019-01-28 16:13 ` [PATCH lora-next 09/11] net: lora: introduce lora socket addressing for metadata Ben Whitten
2019-01-28 16:13 ` [PATCH lora-next 10/11] net: lora: sx130x: make use of lora address metadata in transmission Ben Whitten
2019-01-28 16:13 ` [PATCH lora-next 11/11] net: lora: sx130x: add patch to register fields Ben Whitten

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).