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*/
return 0;
}
+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 = {
.owner = THIS_MODULE,
.start = cc2520_start,
.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)
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->phy->supported.channels[0] = 0x7FFF800;
priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
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];
+ }
+
dev_vdbg(&priv->spi->dev, "registered cc2520\n");
ret = ieee802154_register_hw(priv->hw);
if (ret)
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;
}
* 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;
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;
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");