diff options
author | 2016-04-11 10:41:07 +0300 | |
---|---|---|
committer | 2016-04-13 08:17:18 +0300 | |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/net/ieee802154/cc2520.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/net/ieee802154/cc2520.c')
-rw-r--r-- | kernel/drivers/net/ieee802154/cc2520.c | 156 |
1 files changed, 130 insertions, 26 deletions
diff --git a/kernel/drivers/net/ieee802154/cc2520.c b/kernel/drivers/net/ieee802154/cc2520.c index f833b8bb6..e65b60591 100644 --- a/kernel/drivers/net/ieee802154/cc2520.c +++ b/kernel/drivers/net/ieee802154/cc2520.c @@ -196,6 +196,7 @@ struct cc2520_private { u8 *buf; /* SPI TX/Rx data buffer */ struct mutex buffer_mutex; /* SPI buffer mutex */ bool is_tx; /* Flag for sync b/w Tx and Rx */ + bool amplified; /* Flag for CC2591 */ int fifo_pin; /* FIFO GPIO pin number */ struct work_struct fifop_irqwork;/* Workqueue for FIFOP */ spinlock_t lock; /* Lock for is_tx*/ @@ -589,22 +590,23 @@ cc2520_filter(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed) { struct cc2520_private *priv = hw->priv; + int ret = 0; if (changed & IEEE802154_AFILT_PANID_CHANGED) { u16 panid = le16_to_cpu(filt->pan_id); dev_vdbg(&priv->spi->dev, "cc2520_filter called for pan id\n"); - cc2520_write_ram(priv, CC2520RAM_PANID, - sizeof(panid), (u8 *)&panid); + ret = cc2520_write_ram(priv, CC2520RAM_PANID, + sizeof(panid), (u8 *)&panid); } if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { dev_vdbg(&priv->spi->dev, "cc2520_filter called for IEEE addr\n"); - cc2520_write_ram(priv, CC2520RAM_IEEEADDR, - sizeof(filt->ieee_addr), - (u8 *)&filt->ieee_addr); + ret = cc2520_write_ram(priv, CC2520RAM_IEEEADDR, + sizeof(filt->ieee_addr), + (u8 *)&filt->ieee_addr); } if (changed & IEEE802154_AFILT_SADDR_CHANGED) { @@ -612,20 +614,113 @@ cc2520_filter(struct ieee802154_hw *hw, dev_vdbg(&priv->spi->dev, "cc2520_filter called for saddr\n"); - cc2520_write_ram(priv, CC2520RAM_SHORTADDR, - sizeof(addr), (u8 *)&addr); + ret = cc2520_write_ram(priv, CC2520RAM_SHORTADDR, + sizeof(addr), (u8 *)&addr); } if (changed & IEEE802154_AFILT_PANC_CHANGED) { dev_vdbg(&priv->spi->dev, "cc2520_filter called for panc change\n"); if (filt->pan_coord) - cc2520_write_register(priv, CC2520_FRMFILT0, 0x02); + ret = cc2520_write_register(priv, CC2520_FRMFILT0, + 0x02); else - cc2520_write_register(priv, CC2520_FRMFILT0, 0x00); + ret = cc2520_write_register(priv, CC2520_FRMFILT0, + 0x00); } - return 0; + return ret; +} + +static inline int cc2520_set_tx_power(struct cc2520_private *priv, s32 mbm) +{ + u8 power; + + switch (mbm) { + case 500: + power = 0xF7; + break; + case 300: + power = 0xF2; + break; + case 200: + power = 0xAB; + break; + case 100: + power = 0x13; + break; + case 0: + power = 0x32; + break; + case -200: + power = 0x81; + break; + case -400: + power = 0x88; + break; + case -700: + power = 0x2C; + break; + case -1800: + power = 0x03; + break; + default: + return -EINVAL; + } + + return cc2520_write_register(priv, CC2520_TXPOWER, power); +} + +static inline int cc2520_cc2591_set_tx_power(struct cc2520_private *priv, + s32 mbm) +{ + u8 power; + + switch (mbm) { + case 1700: + power = 0xF9; + break; + case 1600: + power = 0xF0; + break; + case 1400: + power = 0xA0; + break; + case 1100: + power = 0x2C; + break; + case -100: + power = 0x03; + break; + case -800: + power = 0x01; + break; + default: + return -EINVAL; + } + + return cc2520_write_register(priv, CC2520_TXPOWER, power); +} + +#define CC2520_MAX_TX_POWERS 0x8 +static const s32 cc2520_powers[CC2520_MAX_TX_POWERS + 1] = { + 500, 300, 200, 100, 0, -200, -400, -700, -1800, +}; + +#define CC2520_CC2591_MAX_TX_POWERS 0x5 +static const s32 cc2520_cc2591_powers[CC2520_CC2591_MAX_TX_POWERS + 1] = { + 1700, 1600, 1400, 1100, -100, -800, +}; + +static int +cc2520_set_txpower(struct ieee802154_hw *hw, s32 mbm) +{ + struct cc2520_private *priv = hw->priv; + + if (!priv->amplified) + return cc2520_set_tx_power(priv, mbm); + + return cc2520_cc2591_set_tx_power(priv, mbm); } static const struct ieee802154_ops cc2520_ops = { @@ -636,6 +731,7 @@ static const struct ieee802154_ops cc2520_ops = { .ed = cc2520_ed, .set_channel = cc2520_set_channel, .set_hw_addr_filt = cc2520_filter, + .set_txpower = cc2520_set_txpower, }; static int cc2520_register(struct cc2520_private *priv) @@ -649,13 +745,25 @@ static int cc2520_register(struct cc2520_private *priv) priv->hw->priv = priv; priv->hw->parent = &priv->spi->dev; priv->hw->extra_tx_headroom = 0; - priv->hw->vif_data_size = sizeof(*priv); ieee802154_random_extended_addr(&priv->hw->phy->perm_extended_addr); /* We do support only 2.4 Ghz */ - priv->hw->phy->channels_supported[0] = 0x7FFF800; - priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | - IEEE802154_HW_AFILT; + priv->hw->phy->supported.channels[0] = 0x7FFF800; + priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AFILT; + + priv->hw->phy->flags = WPAN_PHY_FLAG_TXPOWER; + + if (!priv->amplified) { + priv->hw->phy->supported.tx_powers = cc2520_powers; + priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_powers); + priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[4]; + } else { + priv->hw->phy->supported.tx_powers = cc2520_cc2591_powers; + priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_cc2591_powers); + priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[0]; + } + + priv->hw->phy->current_channel = 11; dev_vdbg(&priv->spi->dev, "registered cc2520\n"); ret = ieee802154_register_hw(priv->hw); @@ -725,6 +833,7 @@ static int cc2520_get_platform_data(struct spi_device *spi, if (!spi_pdata) return -ENOENT; *pdata = *spi_pdata; + priv->fifo_pin = pdata->fifo; return 0; } @@ -738,7 +847,9 @@ static int cc2520_get_platform_data(struct spi_device *spi, pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0); pdata->reset = of_get_named_gpio(np, "reset-gpio", 0); - pdata->amplified = of_property_read_bool(np, "amplified"); + /* CC2591 front end for CC2520 */ + if (of_property_read_bool(np, "amplified")) + priv->amplified = true; return 0; } @@ -781,11 +892,7 @@ static int cc2520_hw_init(struct cc2520_private *priv) * amplifier. See section 8 page 17 of TI application note AN065. * http://www.ti.com/lit/an/swra229a/swra229a.pdf */ - if (pdata.amplified) { - ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF9); - if (ret) - goto err_ret; - + if (priv->amplified) { ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x16); if (ret) goto err_ret; @@ -806,10 +913,6 @@ static int cc2520_hw_init(struct cc2520_private *priv) if (ret) goto err_ret; } else { - ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF7); - if (ret) - goto err_ret; - ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11); if (ret) goto err_ret; @@ -904,6 +1007,9 @@ static int cc2520_probe(struct spi_device *spi) spin_lock_init(&priv->lock); init_completion(&priv->tx_complete); + /* Assumption that CC2591 is not connected */ + priv->amplified = false; + /* Request all the gpio's */ if (!gpio_is_valid(pdata.fifo)) { dev_err(&spi->dev, "fifo gpio is not valid\n"); @@ -1046,8 +1152,6 @@ MODULE_DEVICE_TABLE(of, cc2520_of_ids); static struct spi_driver cc2520_driver = { .driver = { .name = "cc2520", - .bus = &spi_bus_type, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(cc2520_of_ids), }, .id_table = cc2520_ids, |