diff options
author | Sascha Herrmann <sascha@ps.nvbi.de> | 2013-04-15 00:33:28 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-16 22:34:07 +0200 |
commit | 43b5abe0640100a9e9424c91298c7993d443ffb7 (patch) | |
tree | be50d3b735590b8c81413266de199d3338a8bf7a /drivers/net/ieee802154 | |
parent | ks8851: Remove unneeded PM_OPS definitions (diff) | |
download | linux-43b5abe0640100a9e9424c91298c7993d443ffb7.tar.xz linux-43b5abe0640100a9e9424c91298c7993d443ffb7.zip |
at86rf230: add irq type configuration option
Add option to at86rf230 platform data to configure the type of the
interrupt used by the driver. The irq polarity of the device will
be configured accordingly.
Signed-off-by: Sascha Herrmann <sascha@ps.nvbi.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ieee802154')
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index fc315ddea61c..cf098889ba64 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -219,6 +219,9 @@ struct at86rf230_local { #define IRQ_PLL_UNL (1 << 1) #define IRQ_PLL_LOCK (1 << 0) +#define IRQ_ACTIVE_HIGH 0 +#define IRQ_ACTIVE_LOW 1 + #define STATE_P_ON 0x00 /* BUSY */ #define STATE_BUSY_RX 0x01 #define STATE_BUSY_TX 0x02 @@ -726,11 +729,16 @@ static irqreturn_t at86rf230_isr(int irq, void *data) return IRQ_HANDLED; } +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) { + struct at86rf230_platform_data *pdata = lp->spi->dev.platform_data; + int rc, irq_pol; u8 status; - int rc; rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status); if (rc) @@ -748,6 +756,16 @@ static int at86rf230_hw_init(struct at86rf230_local *lp) dev_info(&lp->spi->dev, "Status: %02x\n", status); } + /* configure irq polarity, defaults to high active */ + if (pdata->irq_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) + irq_pol = IRQ_ACTIVE_LOW; + else + irq_pol = IRQ_ACTIVE_HIGH; + + rc = at86rf230_irq_polarity(lp, irq_pol); + if (rc) + return rc; + rc = at86rf230_write_subreg(lp, SR_IRQ_MASK, 0xff); /* IRQ_TRX_UR | * IRQ_CCA_ED | * IRQ_TRX_END | @@ -798,37 +816,36 @@ static int at86rf230_hw_init(struct at86rf230_local *lp) return 0; } -static int at86rf230_fill_data(struct spi_device *spi) +static void at86rf230_fill_data(struct spi_device *spi) { struct at86rf230_local *lp = spi_get_drvdata(spi); struct at86rf230_platform_data *pdata = spi->dev.platform_data; - if (!pdata) { - dev_err(&spi->dev, "no platform_data\n"); - return -EINVAL; - } - lp->rstn = pdata->rstn; lp->slp_tr = pdata->slp_tr; lp->dig2 = pdata->dig2; - - return 0; } static int at86rf230_probe(struct spi_device *spi) { + struct at86rf230_platform_data *pdata; struct ieee802154_dev *dev; struct at86rf230_local *lp; u8 man_id_0, man_id_1; - int rc; + int rc, supported = 0; const char *chip; - int supported = 0; if (!spi->irq) { dev_err(&spi->dev, "no IRQ specified\n"); return -EINVAL; } + pdata = spi->dev.platform_data; + if (!pdata) { + dev_err(&spi->dev, "no platform_data\n"); + return -EINVAL; + } + dev = ieee802154_alloc_device(sizeof(*lp), &at86rf230_ops); if (!dev) return -ENOMEM; @@ -851,9 +868,7 @@ static int at86rf230_probe(struct spi_device *spi) spi_set_drvdata(spi, lp); - rc = at86rf230_fill_data(spi); - if (rc) - goto err_fill; + at86rf230_fill_data(spi); rc = gpio_request(lp->rstn, "rstn"); if (rc) @@ -928,7 +943,8 @@ static int at86rf230_probe(struct spi_device *spi) if (rc) goto err_gpio_dir; - rc = request_irq(spi->irq, at86rf230_isr, IRQF_SHARED, + rc = request_irq(spi->irq, at86rf230_isr, + IRQF_SHARED | pdata->irq_type, dev_name(&spi->dev), lp); if (rc) goto err_gpio_dir; @@ -948,7 +964,6 @@ err_gpio_dir: err_slp_tr: gpio_free(lp->rstn); err_rstn: -err_fill: spi_set_drvdata(spi, NULL); mutex_destroy(&lp->bmux); ieee802154_free_device(lp->dev); |