Commit 16b46306 authored by David S. Miller's avatar David S. Miller

Merge branch 'at86rf230-next'

Alexander Aring says:

====================
at86rf230 cleanup

this is the first patch series to cleanup the at86rf230 driver. Later I want
to implement regmap and a asynchron spi handling for transmit and receiving
frames.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7f51531c 18c65049
* AT86RF230 IEEE 802.15.4 *
Required properties:
- compatible: should be "atmel,at86rf230", "atmel,at86rf231",
"atmel,at86rf233" or "atmel,at86rf212"
- spi-max-frequency: maximal bus speed, should be set to 7500000 depends
sync or async operation mode
- reg: the chipselect index
- interrupts: the interrupt generated by the device
Optional properties:
- reset-gpio: GPIO spec for the rstn pin
- sleep-gpio: GPIO spec for the slp_tr pin
Example:
at86rf231@0 {
compatible = "atmel,at86rf231";
spi-max-frequency = <7500000>;
reg = <0>;
interrupts = <19 1>;
interrupt-parent = <&gpio3>;
};
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mutex.h> #include <linux/mutex.h>
...@@ -692,10 +693,7 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) ...@@ -692,10 +693,7 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
if (rc < 0) if (rc < 0)
goto err_rx; goto err_rx;
rc = at86rf230_start(dev); return at86rf230_start(dev);
return rc;
err_rx: err_rx:
at86rf230_start(dev); at86rf230_start(dev);
err: err:
...@@ -963,33 +961,24 @@ static irqreturn_t at86rf230_isr_level(int irq, void *data) ...@@ -963,33 +961,24 @@ static irqreturn_t at86rf230_isr_level(int irq, void *data)
return at86rf230_isr(irq, data); return at86rf230_isr(irq, data);
} }
static int at86rf230_irq_polarity(struct at86rf230_local *lp, int pol)
{
return at86rf230_write_subreg(lp, SR_IRQ_POLARITY, pol);
}
static int at86rf230_hw_init(struct at86rf230_local *lp) static int at86rf230_hw_init(struct at86rf230_local *lp)
{ {
struct at86rf230_platform_data *pdata = lp->spi->dev.platform_data; int rc, irq_pol, irq_type;
int rc, irq_pol; u8 dvdd;
u8 status;
u8 csma_seed[2]; u8 csma_seed[2];
rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
if (rc)
return rc;
rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_FORCE_TRX_OFF); rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_FORCE_TRX_OFF);
if (rc) if (rc)
return rc; return rc;
irq_type = irq_get_trigger_type(lp->spi->irq);
/* configure irq polarity, defaults to high active */ /* configure irq polarity, defaults to high active */
if (pdata->irq_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) if (irq_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
irq_pol = IRQ_ACTIVE_LOW; irq_pol = IRQ_ACTIVE_LOW;
else else
irq_pol = IRQ_ACTIVE_HIGH; irq_pol = IRQ_ACTIVE_HIGH;
rc = at86rf230_irq_polarity(lp, irq_pol); rc = at86rf230_write_subreg(lp, SR_IRQ_POLARITY, irq_pol);
if (rc) if (rc)
return rc; return rc;
...@@ -1017,10 +1006,10 @@ static int at86rf230_hw_init(struct at86rf230_local *lp) ...@@ -1017,10 +1006,10 @@ static int at86rf230_hw_init(struct at86rf230_local *lp)
/* Wait the next SLEEP cycle */ /* Wait the next SLEEP cycle */
msleep(100); msleep(100);
rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &status); rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &dvdd);
if (rc) if (rc)
return rc; return rc;
if (!status) { if (!dvdd) {
dev_err(&lp->spi->dev, "DVDD error\n"); dev_err(&lp->spi->dev, "DVDD error\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1032,7 +1021,6 @@ static struct at86rf230_platform_data * ...@@ -1032,7 +1021,6 @@ static struct at86rf230_platform_data *
at86rf230_get_pdata(struct spi_device *spi) at86rf230_get_pdata(struct spi_device *spi)
{ {
struct at86rf230_platform_data *pdata; struct at86rf230_platform_data *pdata;
const char *irq_type;
if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node) if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node)
return spi->dev.platform_data; return spi->dev.platform_data;
...@@ -1044,19 +1032,6 @@ at86rf230_get_pdata(struct spi_device *spi) ...@@ -1044,19 +1032,6 @@ at86rf230_get_pdata(struct spi_device *spi)
pdata->rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0); pdata->rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0);
pdata->slp_tr = of_get_named_gpio(spi->dev.of_node, "sleep-gpio", 0); pdata->slp_tr = of_get_named_gpio(spi->dev.of_node, "sleep-gpio", 0);
pdata->irq_type = IRQF_TRIGGER_RISING;
of_property_read_string(spi->dev.of_node, "irq-type", &irq_type);
if (!strcmp(irq_type, "level-high"))
pdata->irq_type = IRQF_TRIGGER_HIGH;
else if (!strcmp(irq_type, "level-low"))
pdata->irq_type = IRQF_TRIGGER_LOW;
else if (!strcmp(irq_type, "edge-rising"))
pdata->irq_type = IRQF_TRIGGER_RISING;
else if (!strcmp(irq_type, "edge-falling"))
pdata->irq_type = IRQF_TRIGGER_FALLING;
else
dev_warn(&spi->dev, "wrong irq-type specified using edge-rising\n");
spi->dev.platform_data = pdata; spi->dev.platform_data = pdata;
done: done:
return pdata; return pdata;
...@@ -1071,7 +1046,7 @@ static int at86rf230_probe(struct spi_device *spi) ...@@ -1071,7 +1046,7 @@ static int at86rf230_probe(struct spi_device *spi)
u8 part = 0, version = 0, status; u8 part = 0, version = 0, status;
irq_handler_t irq_handler; irq_handler_t irq_handler;
work_func_t irq_worker; work_func_t irq_worker;
int rc; int rc, irq_type;
const char *chip; const char *chip;
struct ieee802154_ops *ops = NULL; struct ieee802154_ops *ops = NULL;
...@@ -1087,27 +1062,17 @@ static int at86rf230_probe(struct spi_device *spi) ...@@ -1087,27 +1062,17 @@ static int at86rf230_probe(struct spi_device *spi)
} }
if (gpio_is_valid(pdata->rstn)) { if (gpio_is_valid(pdata->rstn)) {
rc = gpio_request(pdata->rstn, "rstn"); rc = devm_gpio_request_one(&spi->dev, pdata->rstn,
GPIOF_OUT_INIT_HIGH, "rstn");
if (rc) if (rc)
return rc; return rc;
} }
if (gpio_is_valid(pdata->slp_tr)) { if (gpio_is_valid(pdata->slp_tr)) {
rc = gpio_request(pdata->slp_tr, "slp_tr"); rc = devm_gpio_request_one(&spi->dev, pdata->slp_tr,
if (rc) GPIOF_OUT_INIT_LOW, "slp_tr");
goto err_slp_tr;
}
if (gpio_is_valid(pdata->rstn)) {
rc = gpio_direction_output(pdata->rstn, 1);
if (rc)
goto err_gpio_dir;
}
if (gpio_is_valid(pdata->slp_tr)) {
rc = gpio_direction_output(pdata->slp_tr, 0);
if (rc) if (rc)
goto err_gpio_dir; return rc;
} }
/* Reset */ /* Reset */
...@@ -1121,13 +1086,12 @@ static int at86rf230_probe(struct spi_device *spi) ...@@ -1121,13 +1086,12 @@ static int at86rf230_probe(struct spi_device *spi)
rc = __at86rf230_detect_device(spi, &man_id, &part, &version); rc = __at86rf230_detect_device(spi, &man_id, &part, &version);
if (rc < 0) if (rc < 0)
goto err_gpio_dir; return rc;
if (man_id != 0x001f) { if (man_id != 0x001f) {
dev_err(&spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n", dev_err(&spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
man_id >> 8, man_id & 0xFF); man_id >> 8, man_id & 0xFF);
rc = -EINVAL; return -EINVAL;
goto err_gpio_dir;
} }
switch (part) { switch (part) {
...@@ -1154,16 +1118,12 @@ static int at86rf230_probe(struct spi_device *spi) ...@@ -1154,16 +1118,12 @@ static int at86rf230_probe(struct spi_device *spi)
} }
dev_info(&spi->dev, "Detected %s chip version %d\n", chip, version); dev_info(&spi->dev, "Detected %s chip version %d\n", chip, version);
if (!ops) { if (!ops)
rc = -ENOTSUPP; return -ENOTSUPP;
goto err_gpio_dir;
}
dev = ieee802154_alloc_device(sizeof(*lp), ops); dev = ieee802154_alloc_device(sizeof(*lp), ops);
if (!dev) { if (!dev)
rc = -ENOMEM; return -ENOMEM;
goto err_gpio_dir;
}
lp = dev->priv; lp = dev->priv;
lp->dev = dev; lp->dev = dev;
...@@ -1176,7 +1136,8 @@ static int at86rf230_probe(struct spi_device *spi) ...@@ -1176,7 +1136,8 @@ static int at86rf230_probe(struct spi_device *spi)
dev->extra_tx_headroom = 0; dev->extra_tx_headroom = 0;
dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK; dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK;
if (pdata->irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { irq_type = irq_get_trigger_type(spi->irq);
if (irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
irq_worker = at86rf230_irqwork; irq_worker = at86rf230_irqwork;
irq_handler = at86rf230_isr; irq_handler = at86rf230_isr;
} else { } else {
...@@ -1202,75 +1163,65 @@ static int at86rf230_probe(struct spi_device *spi) ...@@ -1202,75 +1163,65 @@ static int at86rf230_probe(struct spi_device *spi)
if (rc) if (rc)
goto err_hw_init; goto err_hw_init;
rc = request_irq(spi->irq, irq_handler, /* Read irq status register to reset irq line */
IRQF_SHARED | pdata->irq_type, rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &status);
dev_name(&spi->dev), lp);
if (rc) if (rc)
goto err_hw_init; goto err_hw_init;
/* Read irq status register to reset irq line */ rc = devm_request_irq(&spi->dev, spi->irq, irq_handler, IRQF_SHARED,
rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &status); dev_name(&spi->dev), lp);
if (rc) if (rc)
goto err_irq; goto err_hw_init;
rc = ieee802154_register_device(lp->dev); rc = ieee802154_register_device(lp->dev);
if (rc) if (rc)
goto err_irq; goto err_hw_init;
return rc; return rc;
err_irq:
free_irq(spi->irq, lp);
err_hw_init: err_hw_init:
flush_work(&lp->irqwork); flush_work(&lp->irqwork);
spi_set_drvdata(spi, NULL);
mutex_destroy(&lp->bmux); mutex_destroy(&lp->bmux);
ieee802154_free_device(lp->dev); ieee802154_free_device(lp->dev);
err_gpio_dir:
if (gpio_is_valid(pdata->slp_tr))
gpio_free(pdata->slp_tr);
err_slp_tr:
if (gpio_is_valid(pdata->rstn))
gpio_free(pdata->rstn);
return rc; return rc;
} }
static int at86rf230_remove(struct spi_device *spi) static int at86rf230_remove(struct spi_device *spi)
{ {
struct at86rf230_local *lp = spi_get_drvdata(spi); struct at86rf230_local *lp = spi_get_drvdata(spi);
struct at86rf230_platform_data *pdata = spi->dev.platform_data;
/* mask all at86rf230 irq's */ /* mask all at86rf230 irq's */
at86rf230_write_subreg(lp, SR_IRQ_MASK, 0); at86rf230_write_subreg(lp, SR_IRQ_MASK, 0);
ieee802154_unregister_device(lp->dev); ieee802154_unregister_device(lp->dev);
free_irq(spi->irq, lp);
flush_work(&lp->irqwork); flush_work(&lp->irqwork);
if (gpio_is_valid(pdata->slp_tr))
gpio_free(pdata->slp_tr);
if (gpio_is_valid(pdata->rstn))
gpio_free(pdata->rstn);
mutex_destroy(&lp->bmux); mutex_destroy(&lp->bmux);
ieee802154_free_device(lp->dev); ieee802154_free_device(lp->dev);
dev_dbg(&spi->dev, "unregistered at86rf230\n"); dev_dbg(&spi->dev, "unregistered at86rf230\n");
return 0; return 0;
} }
#if IS_ENABLED(CONFIG_OF) static const struct of_device_id at86rf230_of_match[] = {
static struct of_device_id at86rf230_of_match[] = {
{ .compatible = "atmel,at86rf230", }, { .compatible = "atmel,at86rf230", },
{ .compatible = "atmel,at86rf231", }, { .compatible = "atmel,at86rf231", },
{ .compatible = "atmel,at86rf233", }, { .compatible = "atmel,at86rf233", },
{ .compatible = "atmel,at86rf212", }, { .compatible = "atmel,at86rf212", },
{ }, { },
}; };
#endif MODULE_DEVICE_TABLE(of, at86rf230_of_match);
static const struct spi_device_id at86rf230_device_id[] = {
{ .name = "at86rf230", },
{ .name = "at86rf231", },
{ .name = "at86rf233", },
{ .name = "at86rf212", },
{ },
};
MODULE_DEVICE_TABLE(spi, at86rf230_device_id);
static struct spi_driver at86rf230_driver = { static struct spi_driver at86rf230_driver = {
.id_table = at86rf230_device_id,
.driver = { .driver = {
.of_match_table = of_match_ptr(at86rf230_of_match), .of_match_table = of_match_ptr(at86rf230_of_match),
.name = "at86rf230", .name = "at86rf230",
......
...@@ -26,20 +26,6 @@ struct at86rf230_platform_data { ...@@ -26,20 +26,6 @@ struct at86rf230_platform_data {
int rstn; int rstn;
int slp_tr; int slp_tr;
int dig2; int dig2;
/* Setting the irq_type will configure the driver to request
* the platform irq trigger type according to the given value
* and configure the interrupt polarity of the device to the
* corresponding polarity.
*
* Allowed values are: IRQF_TRIGGER_RISING, IRQF_TRIGGER_FALLING,
* IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW
*
* Setting it to 0, the driver does not touch the trigger type
* configuration of the interrupt and sets the interrupt polarity
* of the device to high active (the default value).
*/
int irq_type;
}; };
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment