Skip to contentSkip to conversation

Add CC2591 Support

PATCH In review Brad Campbell 3 participants 5 messages Mar 17, 2015 – Mar 18, 2015

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

v3 cover Add CC2591 Support

Hi,

I fixed the two issues that Alex pointed out and updated the commit message.

Brad

Brad Campbell (2):
cc2520: Do not store platform_data in spi_device
cc2520: Add support for CC2591 amplifier.

 .../devicetree/bindings/net/ieee802154/cc2520.txt  |   4 +
 drivers/net/ieee802154/cc2520.c                    | 150 +++++++++++++--------
 include/linux/spi/cc2520.h                         |   1 +
 3 files changed, 98 insertions(+), 57 deletions(-)
Signature · 1 line
2.3.2
#1 lore raw

PATCH v3 1/2 cc2520: Do not store platform_data in spi_device

Storing the platform_data struct inside of the SPI struct when using the device tree allows for a later function to edit the content of that struct. This patch refactors the cc2520_get_platformat_data function to accept a pointer to a cc2520_platform_data struct and populates the fields inside of it.

This change mirrors commit aaa1c4d226e4cd730075d3dac99a6d599a0190c7 ("at86rf230: copy pdata to driver allocated space").

---
 drivers/net/ieee802154/cc2520.c | 95 ++++++++++++++++++++---------------------
 1 file changed, 46 insertions(+), 49 deletions(-)
drivers/net/ieee802154/cc2520.c +46 -49
index 181b349..233b6c6 100644
@@ -714,6 +714,33 @@ static irqreturn_t cc2520_sfd_isr(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static int cc2520_get_platform_data(struct spi_device *spi,
+				    struct cc2520_platform_data *pdata)
+{
+	struct device_node *np = spi->dev.of_node;
+	struct cc2520_private *priv = spi_get_drvdata(spi);
+
+	if (!np) {
+		struct cc2520_platform_data *spi_pdata = spi->dev.platform_data;
+		if (!spi_pdata)
+			return -ENOENT;
+		*pdata = *spi_pdata;
+		return 0;
+	}
+
+	pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0);
+	priv->fifo_pin = pdata->fifo;
+
+	pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0);
+
+	pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0);
+	pdata->cca = of_get_named_gpio(np, "cca-gpio", 0);
+	pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0);
+	pdata->reset = of_get_named_gpio(np, "reset-gpio", 0);
+
+	return 0;
+}
+
 static int cc2520_hw_init(struct cc2520_private *priv)
 {
 	u8 status = 0, state = 0xff;
@@ -808,40 +835,10 @@ err_ret:
 	return ret;
 }
 
-static struct cc2520_platform_data *
-cc2520_get_platform_data(struct spi_device *spi)
-{
-	struct cc2520_platform_data *pdata;
-	struct device_node *np = spi->dev.of_node;
-	struct cc2520_private *priv = spi_get_drvdata(spi);
-
-	if (!np)
-		return spi->dev.platform_data;
-
-	pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata)
-		goto done;
-
-	pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0);
-	priv->fifo_pin = pdata->fifo;
-
-	pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0);
-
-	pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0);
-	pdata->cca = of_get_named_gpio(np, "cca-gpio", 0);
-	pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0);
-	pdata->reset = of_get_named_gpio(np, "reset-gpio", 0);
-
-	spi->dev.platform_data = pdata;
-
-done:
-	return pdata;
-}
-
 static int cc2520_probe(struct spi_device *spi)
 {
 	struct cc2520_private *priv;
-	struct cc2520_platform_data *pdata;
+	struct cc2520_platform_data pdata;
 	int ret;
 
 	priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
@@ -850,8 +847,8 @@ static int cc2520_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, priv);
 
-	pdata = cc2520_get_platform_data(spi);
-	if (!pdata) {
+	ret = cc2520_get_platform_data(spi, &pdata);
+	if (ret < 0) {
 		dev_err(&spi->dev, "no platform data\n");
 		return -EINVAL;
 	}
@@ -869,76 +866,76 @@ static int cc2520_probe(struct spi_device *spi)
 	init_completion(&priv->tx_complete);
 
 	/* Request all the gpio's */
-	if (!gpio_is_valid(pdata->fifo)) {
+	if (!gpio_is_valid(pdata.fifo)) {
 		dev_err(&spi->dev, "fifo gpio is not valid\n");
 		ret = -EINVAL;
 		goto err_hw_init;
 	}
 
-	ret = devm_gpio_request_one(&spi->dev, pdata->fifo,
+	ret = devm_gpio_request_one(&spi->dev, pdata.fifo,
 				    GPIOF_IN, "fifo");
 	if (ret)
 		goto err_hw_init;
 
-	if (!gpio_is_valid(pdata->cca)) {
+	if (!gpio_is_valid(pdata.cca)) {
 		dev_err(&spi->dev, "cca gpio is not valid\n");
 		ret = -EINVAL;
 		goto err_hw_init;
 	}
 
-	ret = devm_gpio_request_one(&spi->dev, pdata->cca,
+	ret = devm_gpio_request_one(&spi->dev, pdata.cca,
 				    GPIOF_IN, "cca");
 	if (ret)
 		goto err_hw_init;
 
-	if (!gpio_is_valid(pdata->fifop)) {
+	if (!gpio_is_valid(pdata.fifop)) {
 		dev_err(&spi->dev, "fifop gpio is not valid\n");
 		ret = -EINVAL;
 		goto err_hw_init;
 	}
 
-	ret = devm_gpio_request_one(&spi->dev, pdata->fifop,
+	ret = devm_gpio_request_one(&spi->dev, pdata.fifop,
 				    GPIOF_IN, "fifop");
 	if (ret)
 		goto err_hw_init;
 
-	if (!gpio_is_valid(pdata->sfd)) {
+	if (!gpio_is_valid(pdata.sfd)) {
 		dev_err(&spi->dev, "sfd gpio is not valid\n");
 		ret = -EINVAL;
 		goto err_hw_init;
 	}
 
-	ret = devm_gpio_request_one(&spi->dev, pdata->sfd,
+	ret = devm_gpio_request_one(&spi->dev, pdata.sfd,
 				    GPIOF_IN, "sfd");
 	if (ret)
 		goto err_hw_init;
 
-	if (!gpio_is_valid(pdata->reset)) {
+	if (!gpio_is_valid(pdata.reset)) {
 		dev_err(&spi->dev, "reset gpio is not valid\n");
 		ret = -EINVAL;
 		goto err_hw_init;
 	}
 
-	ret = devm_gpio_request_one(&spi->dev, pdata->reset,
+	ret = devm_gpio_request_one(&spi->dev, pdata.reset,
 				    GPIOF_OUT_INIT_LOW, "reset");
 	if (ret)
 		goto err_hw_init;
 
-	if (!gpio_is_valid(pdata->vreg)) {
+	if (!gpio_is_valid(pdata.vreg)) {
 		dev_err(&spi->dev, "vreg gpio is not valid\n");
 		ret = -EINVAL;
 		goto err_hw_init;
 	}
 
-	ret = devm_gpio_request_one(&spi->dev, pdata->vreg,
+	ret = devm_gpio_request_one(&spi->dev, pdata.vreg,
 				    GPIOF_OUT_INIT_LOW, "vreg");
 	if (ret)
 		goto err_hw_init;
 
-	gpio_set_value(pdata->vreg, HIGH);
+	gpio_set_value(pdata.vreg, HIGH);
 	usleep_range(100, 150);
 
-	gpio_set_value(pdata->reset, HIGH);
+	gpio_set_value(pdata.reset, HIGH);
 	usleep_range(200, 250);
 
 	ret = cc2520_hw_init(priv);
@@ -947,7 +944,7 @@ static int cc2520_probe(struct spi_device *spi)
 
 	/* Set up fifop interrupt */
 	ret = devm_request_irq(&spi->dev,
-			       gpio_to_irq(pdata->fifop),
+			       gpio_to_irq(pdata.fifop),
 			       cc2520_fifop_isr,
 			       IRQF_TRIGGER_RISING,
 			       dev_name(&spi->dev),
@@ -959,7 +956,7 @@ static int cc2520_probe(struct spi_device *spi)
 
 	/* Set up sfd interrupt */
 	ret = devm_request_irq(&spi->dev,
-			       gpio_to_irq(pdata->sfd),
+			       gpio_to_irq(pdata.sfd),
 			       cc2520_sfd_isr,
 			       IRQF_TRIGGER_FALLING,
 			       dev_name(&spi->dev),
Signature · 1 line
2.3.2
#2 lore raw

PATCH v3 2/2 cc2520: Add support for CC2591 amplifier.

In reply to Brad Campbell

The TI CC2521 is an RF power amplifier that is designed to interface with the CC2520. Conveniently, it directly interfaces with the CC2520 and does not require any pins to be connected to a microcontroller/processor. Adding a CC2591 increases the CC2520's range, which is useful for border router and other wall-powered applications.

Using the CC2591 with the CC2520 requires configuring the CC2520 GPIOs that are connected to the CC2591 to correctly set the CC2591 into TX and RX modes. Further, TI recommends that the CC2520_TXPOWER and CC2520_AGCCTRL1 registers are set differently to maximize the CC2591's performance. These settings are covered in TI Application Note AN065.

This patch adds an optional amplified field to the cc2520 entry in the device tree. If present, the CC2520 will be configured to operate with a CC2591.

The expected pin mapping is:
CC2520 GPIO0 --> CC2591 EN
CC2520 GPIO5 --> CC2591 PAEN

---
 .../devicetree/bindings/net/ieee802154/cc2520.txt  |  4 ++
 drivers/net/ieee802154/cc2520.c                    | 55 ++++++++++++++++++----
 include/linux/spi/cc2520.h                         |  1 +
 3 files changed, 52 insertions(+), 8 deletions(-)
Documentation/devicetree/bindings/net/ieee802154/cc2520.txt +4 -0
index 0071883..fb6d49f 100644
@@ -13,11 +13,15 @@ Required properties:
 	- cca-gpio:		GPIO spec for the CCA pin
 	- vreg-gpio:		GPIO spec for the VREG pin
 	- reset-gpio:		GPIO spec for the RESET pin
+Optional properties:
+	- amplified:		include if the CC2520 is connected to a CC2591 amplifier
+
 Example:
 	cc2520@0 {
 		compatible = "ti,cc2520";
 		reg = <0>;
 		spi-max-frequency = <4000000>;
+		amplified;
 		pinctrl-names = "default";
 		pinctrl-0 = <&cc2520_cape_pins>;
 		fifo-gpio = <&gpio1 18 0>;
drivers/net/ieee802154/cc2520.c +47 -8

80 lines not on this page · raw message

include/linux/spi/cc2520.h +1 -0
index 85b8ee6..e741e8b 100644
@@ -21,6 +21,7 @@ struct cc2520_platform_data {
 	int sfd;
 	int reset;
 	int vreg;
+	bool amplified;
 };
 
 #endif
Signature · 1 line
2.3.2
Acked-by on the v3 series
#3 lore raw
In reply to Brad Campbell
Quoted 7 lines · Brad Campbell

Hi,

I fixed the two issues that Alex pointed out and updated the commit message.

Brad

Quoted 9 lines

Brad Campbell (2):
cc2520: Do not store platform_data in spi_device
cc2520: Add support for CC2591 amplifier.

  .../devicetree/bindings/net/ieee802154/cc2520.txt  |   4 +
  drivers/net/ieee802154/cc2520.c                    | 150 +++++++++++++--------
  include/linux/spi/cc2520.h                         |   1 +
  3 files changed, 98 insertions(+), 57 deletions(-)

For the two patches..

Signature · 1 line
Varka Bhadram
#4 lore raw
In reply to Brad Campbell

Hi Brad,

Quoted 5 lines

I fixed the two issues that Alex pointed out and updated the commit message.

Brad

Quoted 8 lines

Brad Campbell (2):
cc2520: Do not store platform_data in spi_device
cc2520: Add support for CC2591 amplifier.

.../devicetree/bindings/net/ieee802154/cc2520.txt  |   4 +
drivers/net/ieee802154/cc2520.c                    | 150 +++++++++++++--------
include/linux/spi/cc2520.h                         |   1 +
3 files changed, 98 insertions(+), 57 deletions(-)

both patches have been applied to bluetooth-next tree.

Regards

Marcel