* [PATCH bluetooth-next 1/1] drivers: mrf24j40: add support for reset and wake pin
@ 2016-11-15 13:18 smlng
2016-11-15 16:10 ` Stefan Schmidt
0 siblings, 1 reply; 2+ messages in thread
From: smlng @ 2016-11-15 13:18 UTC (permalink / raw)
To: linux-wpan
The mrf24j40 requires a high on the RESET pin, otherwise it will reset
itself over and over. With this patch the driver will ensure that a GPIO
(if connected) will be set to high during device initialization. Details:
- set reset to high on driver probe
- make pin configurable via device tree (overlay)
- similar to the at86rf233 driver
- update devicetree documentation
Signed-off-by: smlng <s@mlng.net>
---
.../bindings/net/ieee802154/mrf24j40.txt | 4 ++
drivers/net/ieee802154/mrf24j40.c | 59 ++++++++++++++++++++--
include/linux/spi/mrf24j40.h | 9 ++++
3 files changed, 69 insertions(+), 3 deletions(-)
create mode 100644 include/linux/spi/mrf24j40.h
diff --git a/Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt b/Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt
index a4ed2efb5b73..2fabba041e48 100644
--- a/Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt
+++ b/Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt
@@ -9,6 +9,10 @@ Required properties:
- reg: the chipselect index
- interrupts: the interrupt generated by the device.
+Optional properties:
+ - reset-gpio: GPIO spec for the rstn pin
+ - wake-gpio: GPIO spec for the wake pin
+
Example:
mrf24j40ma@0 {
diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
index 7b131f8e4093..275b54d6bad3 100644
--- a/drivers/net/ieee802154/mrf24j40.c
+++ b/drivers/net/ieee802154/mrf24j40.c
@@ -16,9 +16,11 @@
*/
#include <linux/spi/spi.h>
+#include <linux/spi/mrf24j40.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/regmap.h>
+#include <linux/of_gpio.h>
#include <linux/ieee802154.h>
#include <linux/irq.h>
#include <net/cfg802154.h>
@@ -1276,16 +1278,67 @@ static void mrf24j40_phy_setup(struct mrf24j40 *devrec)
}
}
+static int
+mrf24j40_get_pdata(struct spi_device *spi, int *rstn, int *wake)
+{
+ struct mrf24j40_platform_data *pdata = spi->dev.platform_data;
+
+ if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node) {
+ if (!pdata)
+ return -ENOENT;
+
+ *rstn = pdata->rstn;
+ *wake = pdata->wake;
+ return 0;
+ }
+
+ *rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0);
+ *wake = of_get_named_gpio(spi->dev.of_node, "wake-gpio", 0);
+ return 0;
+}
+
static int mrf24j40_probe(struct spi_device *spi)
{
int ret = -ENOMEM, irq_type;
+ int rc, rstn, wake;
struct ieee802154_hw *hw;
struct mrf24j40 *devrec;
- dev_info(&spi->dev, "probe(). IRQ: %d\n", spi->irq);
+ if (!spi->irq) {
+ dev_err(&spi->dev, "no IRQ specified\n");
+ return -EINVAL;
+ }
- /* Register with the 802154 subsystem */
+ rc = mrf24j40_get_pdata(spi, &rstn, &wake);
+ if (rc < 0) {
+ dev_err(&spi->dev, "failed to parse platform_data: %d\n", rc);
+ return rc;
+ }
+
+ if (gpio_is_valid(rstn)) {
+ rc = devm_gpio_request_one(&spi->dev, rstn,
+ GPIOF_OUT_INIT_HIGH, "rstn");
+ if (rc)
+ return rc;
+ }
+ if (gpio_is_valid(wake)) {
+ rc = devm_gpio_request_one(&spi->dev, wake,
+ GPIOF_OUT_INIT_LOW, "wake");
+ if (rc)
+ return rc;
+ }
+
+ /* Reset */
+ if (gpio_is_valid(rstn)) {
+ udelay(1);
+ gpio_set_value(rstn, 0);
+ udelay(1);
+ gpio_set_value(rstn, 1);
+ usleep_range(120, 240);
+ }
+
+ /* Register with the 802154 subsystem */
hw = ieee802154_alloc_hw(sizeof(*devrec), &mrf24j40_ops);
if (!hw)
goto err_ret;
@@ -1350,7 +1403,7 @@ static int mrf24j40_probe(struct spi_device *spi)
goto err_register_device;
}
- dev_dbg(printdev(devrec), "registered mrf24j40\n");
+ dev_info(printdev(devrec), "registered mrf24j40\n");
ret = ieee802154_register_hw(devrec->hw);
if (ret)
goto err_register_device;
diff --git a/include/linux/spi/mrf24j40.h b/include/linux/spi/mrf24j40.h
new file mode 100644
index 000000000000..60810194cae9
--- /dev/null
+++ b/include/linux/spi/mrf24j40.h
@@ -0,0 +1,9 @@
+#ifndef _SPI_MRF24J40_H
+#define _SPI_MRF24J40_H
+
+struct mrf24j40_platform_data {
+ int rstn;
+ int wake;
+};
+
+#endif /* _SPI_MRF24J40_H */
--
2.10.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH bluetooth-next 1/1] drivers: mrf24j40: add support for reset and wake pin
2016-11-15 13:18 [PATCH bluetooth-next 1/1] drivers: mrf24j40: add support for reset and wake pin smlng
@ 2016-11-15 16:10 ` Stefan Schmidt
0 siblings, 0 replies; 2+ messages in thread
From: Stefan Schmidt @ 2016-11-15 16:10 UTC (permalink / raw)
To: smlng, linux-wpan; +Cc: Alan Ott
Hello.
On 15/11/16 14:18, smlng wrote:
Please fix your mail from line to have your real name to show up as
patch author.
> The mrf24j40 requires a high on the RESET pin, otherwise it will reset
> itself over and over. With this patch the driver will ensure that a GPIO
> (if connected) will be set to high during device initialization. Details:
>
> - set reset to high on driver probe
> - make pin configurable via device tree (overlay)
> - similar to the at86rf233 driver
> - update devicetree documentation
Thanks for taking the time to submit this patch! This looks good to me
in general. I cc'ed Alan Ott as the driver maintainer now to see what he
thinks about this patch.
What I miss here is a bit of context for the wake pin. The commit
message only covers the reset pin handling. What do we do with the wake
pin here?
> Signed-off-by: smlng <s@mlng.net>
Same as the from line. Please use your real name for the SOB here.
> ---
> .../bindings/net/ieee802154/mrf24j40.txt | 4 ++
> drivers/net/ieee802154/mrf24j40.c | 59 ++++++++++++++++++++--
> include/linux/spi/mrf24j40.h | 9 ++++
> 3 files changed, 69 insertions(+), 3 deletions(-)
> create mode 100644 include/linux/spi/mrf24j40.h
>
> diff --git a/Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt b/Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt
> index a4ed2efb5b73..2fabba041e48 100644
> --- a/Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt
> +++ b/Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt
> @@ -9,6 +9,10 @@ Required properties:
> - reg: the chipselect index
> - interrupts: the interrupt generated by the device.
>
> +Optional properties:
> + - reset-gpio: GPIO spec for the rstn pin
> + - wake-gpio: GPIO spec for the wake pin
> +
> Example:
>
> mrf24j40ma@0 {
> diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
> index 7b131f8e4093..275b54d6bad3 100644
> --- a/drivers/net/ieee802154/mrf24j40.c
> +++ b/drivers/net/ieee802154/mrf24j40.c
> @@ -16,9 +16,11 @@
> */
>
> #include <linux/spi/spi.h>
> +#include <linux/spi/mrf24j40.h>
> #include <linux/interrupt.h>
> #include <linux/module.h>
> #include <linux/regmap.h>
> +#include <linux/of_gpio.h>
> #include <linux/ieee802154.h>
> #include <linux/irq.h>
> #include <net/cfg802154.h>
> @@ -1276,16 +1278,67 @@ static void mrf24j40_phy_setup(struct mrf24j40 *devrec)
> }
> }
>
> +static int
> +mrf24j40_get_pdata(struct spi_device *spi, int *rstn, int *wake)
> +{
> + struct mrf24j40_platform_data *pdata = spi->dev.platform_data;
> +
> + if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node) {
> + if (!pdata)
> + return -ENOENT;
> +
> + *rstn = pdata->rstn;
> + *wake = pdata->wake;
> + return 0;
> + }
> +
> + *rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0);
> + *wake = of_get_named_gpio(spi->dev.of_node, "wake-gpio", 0);
> + return 0;
> +}
> +
> static int mrf24j40_probe(struct spi_device *spi)
> {
> int ret = -ENOMEM, irq_type;
> + int rc, rstn, wake;
> struct ieee802154_hw *hw;
> struct mrf24j40 *devrec;
>
> - dev_info(&spi->dev, "probe(). IRQ: %d\n", spi->irq);
You removed this line entirely. Was that on purpose? Having the IRQ
printed in dmesg might be handy for debugging.
> + if (!spi->irq) {
> + dev_err(&spi->dev, "no IRQ specified\n");
> + return -EINVAL;
> + }
>
> - /* Register with the 802154 subsystem */
> + rc = mrf24j40_get_pdata(spi, &rstn, &wake);
> + if (rc < 0) {
> + dev_err(&spi->dev, "failed to parse platform_data: %d\n", rc);
> + return rc;
> + }
> +
> + if (gpio_is_valid(rstn)) {
> + rc = devm_gpio_request_one(&spi->dev, rstn,
> + GPIOF_OUT_INIT_HIGH, "rstn");
> + if (rc)
> + return rc;
> + }
>
> + if (gpio_is_valid(wake)) {
> + rc = devm_gpio_request_one(&spi->dev, wake,
> + GPIOF_OUT_INIT_LOW, "wake");
> + if (rc)
> + return rc;
> + }
> +
> + /* Reset */
> + if (gpio_is_valid(rstn)) {
> + udelay(1);
> + gpio_set_value(rstn, 0);
> + udelay(1);
> + gpio_set_value(rstn, 1);
> + usleep_range(120, 240);
> + }
> +
> + /* Register with the 802154 subsystem */
> hw = ieee802154_alloc_hw(sizeof(*devrec), &mrf24j40_ops);
> if (!hw)
> goto err_ret;
> @@ -1350,7 +1403,7 @@ static int mrf24j40_probe(struct spi_device *spi)
> goto err_register_device;
> }
>
> - dev_dbg(printdev(devrec), "registered mrf24j40\n");
> + dev_info(printdev(devrec), "registered mrf24j40\n");
Not related to the rest of this patch. The change itself is good though.
Maybe combine this with IRQ printout from above and have this as an
additional patch?
> ret = ieee802154_register_hw(devrec->hw);
> if (ret)
> goto err_register_device;
> diff --git a/include/linux/spi/mrf24j40.h b/include/linux/spi/mrf24j40.h
> new file mode 100644
> index 000000000000..60810194cae9
> --- /dev/null
> +++ b/include/linux/spi/mrf24j40.h
> @@ -0,0 +1,9 @@
> +#ifndef _SPI_MRF24J40_H
> +#define _SPI_MRF24J40_H
> +
> +struct mrf24j40_platform_data {
> + int rstn;
> + int wake;
> +};
> +
> +#endif /* _SPI_MRF24J40_H */
>
Just to clarify this. This header file is needed for the usage of
platform data, right? If not I would argue that we do not create a
header for this in include/spi but have the struct in the driver itself.
I vaguely remember that we need this for the usage of pdata.
regards
Stefan Schmidt
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-11-15 16:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-15 13:18 [PATCH bluetooth-next 1/1] drivers: mrf24j40: add support for reset and wake pin smlng
2016-11-15 16:10 ` Stefan Schmidt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.