The AT86RF231-based ATBEN board does not connect the /RST line and
uses power cycling to reset the transceiver. For this, I added a
platform-specific reset function to the at86rf230 driver.

Does this look okay ?

There are more parts involved in properly supporting that board.
I've described them in the following thread:
http://lists.en.qi-hardware.com/pipermail/discussion/2013-April/010123.html

- Werner

--------------------------------- cut here ---------------------------------

Some platforms may not connect the /RST line directly to a GPIO, or they
may not connect it at all and instead use power cycling to reset the
transceiver.

An example of the latter type is the ATBEN board on the Ben NanoNote.

This patch adds support for a platform-specific reset function to the
AT86RF230/1 driver. If the platform provides a reset function, "rstn"
is ignored and no GPIO is allocated for it.
---
 drivers/net/ieee802154/at86rf230.c |   45 +++++++++++++++++++++++++------------
 include/linux/spi/at86rf230.h      |    9 ++++++-
 2 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/include/linux/spi/at86rf230.h b/include/linux/spi/at86rf230.h
index aa327a8..9fd1b29 100644
--- a/include/linux/spi/at86rf230.h
+++ b/include/linux/spi/at86rf230.h
@@ -23,7 +23,7 @@
 #define AT86RF230_H
 
 struct at86rf230_platform_data {
-       int rstn;
+       int rstn;       /* only used if "reset" (below) is NULL */
        int slp_tr;
        int dig2;
 
@@ -40,6 +40,13 @@ struct at86rf230_platform_data {
         * of the device to high active (the default value).
         */
        int irq_type;
+
+       /* Platform-specific transceiver reset function, e.g., to use
+        * power cycling instead of the reset line. If "reset" is NULL,
+        * the driver resets the transceiver through the "rstn" GPIO.
+        */
+       void (*reset)(void *reset_data);
+       void *reset_data;
 };
 
 #endif
diff --git a/drivers/net/ieee802154/at86rf230.c 
b/drivers/net/ieee802154/at86rf230.c
index 6f10b49..7fa32f2 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -834,6 +834,21 @@ static void at86rf230_fill_data(struct spi_device *spi)
        lp->dig2 = pdata->dig2;
 }
 
+static void at86rf230_reset(struct at86rf230_local *lp)
+{
+       struct at86rf230_platform_data *pdata = lp->spi->dev.platform_data;
+
+       if (pdata->reset) {
+               pdata->reset(pdata->reset_data);
+       } else {
+               msleep(1);
+               gpio_set_value(lp->rstn, 0);
+               msleep(1);
+               gpio_set_value(lp->rstn, 1);
+       }
+       msleep(1);
+}
+
 static int at86rf230_probe(struct spi_device *spi)
 {
        struct at86rf230_platform_data *pdata;
@@ -888,9 +903,11 @@ static int at86rf230_probe(struct spi_device *spi)
 
        at86rf230_fill_data(spi);
 
-       rc = gpio_request(lp->rstn, "rstn");
-       if (rc)
-               goto err_rstn;
+       if (!pdata->reset) {
+               rc = gpio_request(lp->rstn, "rstn");
+               if (rc)
+                       goto err_rstn;
+       }
 
        if (gpio_is_valid(lp->slp_tr)) {
                rc = gpio_request(lp->slp_tr, "slp_tr");
@@ -898,9 +915,11 @@ static int at86rf230_probe(struct spi_device *spi)
                        goto err_slp_tr;
        }
 
-       rc = gpio_direction_output(lp->rstn, 1);
-       if (rc)
-               goto err_gpio_dir;
+       if (!pdata->reset) {
+               rc = gpio_direction_output(lp->rstn, 1);
+               if (rc)
+                       goto err_gpio_dir;
+       }
 
        if (gpio_is_valid(lp->slp_tr)) {
                rc = gpio_direction_output(lp->slp_tr, 0);
@@ -908,12 +927,7 @@ static int at86rf230_probe(struct spi_device *spi)
                        goto err_gpio_dir;
        }
 
-       /* Reset */
-       msleep(1);
-       gpio_set_value(lp->rstn, 0);
-       msleep(1);
-       gpio_set_value(lp->rstn, 1);
-       msleep(1);
+       at86rf230_reset(lp);
 
        rc = at86rf230_read_subreg(lp, SR_MAN_ID_0, &man_id_0);
        if (rc)
@@ -985,7 +999,8 @@ err_gpio_dir:
        if (gpio_is_valid(lp->slp_tr))
                gpio_free(lp->slp_tr);
 err_slp_tr:
-       gpio_free(lp->rstn);
+       if (!pdata->reset)
+               gpio_free(lp->rstn);
 err_rstn:
        spi_set_drvdata(spi, NULL);
        mutex_destroy(&lp->bmux);
@@ -995,6 +1010,7 @@ err_rstn:
 
 static int at86rf230_remove(struct spi_device *spi)
 {
+       struct at86rf230_platform_data *pdata = spi->dev.platform_data;
        struct at86rf230_local *lp = spi_get_drvdata(spi);
 
        ieee802154_unregister_device(lp->dev);
@@ -1004,7 +1020,8 @@ static int at86rf230_remove(struct spi_device *spi)
 
        if (gpio_is_valid(lp->slp_tr))
                gpio_free(lp->slp_tr);
-       gpio_free(lp->rstn);
+       if (!pdata->reset)
+               gpio_free(lp->rstn);
 
        spi_set_drvdata(spi, NULL);
        mutex_destroy(&lp->bmux);

------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to