summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorVarka Bhadram <varkabhadram@gmail.com>2015-05-29 01:26:56 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-05-31 07:40:53 -0400
commite10c1674e31558807fcccfbf3dbebbc1cad9099c (patch)
tree0651109d821e609fe14f7367e89fb8d5381197fd /drivers/net
parent1a1bc59c5f7657387d1a4b45d63248fed55ab88c (diff)
cc2520: add set transmit power setting support
This patch adds support for seeting tx power values for cc2520 and also for the combination of CC2520-CC2591. Signed-off-by: Varka Bhadram <varkab@cdac.in> Cc: Brad Campbell <bradjc5@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ieee802154/cc2520.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
index 0d9353756598..36a4f312cc7c 100644
--- a/drivers/net/ieee802154/cc2520.c
+++ b/drivers/net/ieee802154/cc2520.c
@@ -629,6 +629,97 @@ cc2520_filter(struct ieee802154_hw *hw,
629 return 0; 629 return 0;
630} 630}
631 631
632static inline int cc2520_set_tx_power(struct cc2520_private *priv, s32 mbm)
633{
634 u8 power;
635
636 switch (mbm) {
637 case 500:
638 power = 0xF7;
639 break;
640 case 300:
641 power = 0xF2;
642 break;
643 case 200:
644 power = 0xAB;
645 break;
646 case 100:
647 power = 0x13;
648 break;
649 case 0:
650 power = 0x32;
651 break;
652 case -200:
653 power = 0x81;
654 break;
655 case -400:
656 power = 0x88;
657 break;
658 case -700:
659 power = 0x2C;
660 break;
661 case -1800:
662 power = 0x03;
663 break;
664 default:
665 return -EINVAL;
666 }
667
668 return cc2520_write_register(priv, CC2520_TXPOWER, power);
669}
670
671static inline int cc2520_cc2591_set_tx_power(struct cc2520_private *priv,
672 s32 mbm)
673{
674 u8 power;
675
676 switch (mbm) {
677 case 1700:
678 power = 0xF9;
679 break;
680 case 1600:
681 power = 0xF0;
682 break;
683 case 1400:
684 power = 0xA0;
685 break;
686 case 1100:
687 power = 0x2C;
688 break;
689 case -100:
690 power = 0x03;
691 break;
692 case -800:
693 power = 0x01;
694 break;
695 default:
696 return -EINVAL;
697 }
698
699 return cc2520_write_register(priv, CC2520_TXPOWER, power);
700}
701
702#define CC2520_MAX_TX_POWERS 0x8
703static const s32 cc2520_powers[CC2520_MAX_TX_POWERS + 1] = {
704 500, 300, 200, 100, 0, -200, -400, -700, -1800,
705};
706
707#define CC2520_CC2591_MAX_TX_POWERS 0x5
708static const s32 cc2520_cc2591_powers[CC2520_CC2591_MAX_TX_POWERS + 1] = {
709 1700, 1600, 1400, 1100, -100, -800,
710};
711
712static int
713cc2520_set_txpower(struct ieee802154_hw *hw, s32 mbm)
714{
715 struct cc2520_private *priv = hw->priv;
716
717 if (!priv->amplified)
718 return cc2520_set_tx_power(priv, mbm);
719
720 return cc2520_cc2591_set_tx_power(priv, mbm);
721}
722
632static const struct ieee802154_ops cc2520_ops = { 723static const struct ieee802154_ops cc2520_ops = {
633 .owner = THIS_MODULE, 724 .owner = THIS_MODULE,
634 .start = cc2520_start, 725 .start = cc2520_start,
@@ -637,6 +728,7 @@ static const struct ieee802154_ops cc2520_ops = {
637 .ed = cc2520_ed, 728 .ed = cc2520_ed,
638 .set_channel = cc2520_set_channel, 729 .set_channel = cc2520_set_channel,
639 .set_hw_addr_filt = cc2520_filter, 730 .set_hw_addr_filt = cc2520_filter,
731 .set_txpower = cc2520_set_txpower,
640}; 732};
641 733
642static int cc2520_register(struct cc2520_private *priv) 734static int cc2520_register(struct cc2520_private *priv)
@@ -658,6 +750,16 @@ static int cc2520_register(struct cc2520_private *priv)
658 priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | 750 priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
659 IEEE802154_HW_AFILT; 751 IEEE802154_HW_AFILT;
660 752
753 priv->hw->phy->flags = WPAN_PHY_FLAG_TXPOWER;
754
755 if (!priv->amplified) {
756 priv->hw->phy->supported.tx_powers = cc2520_powers;
757 priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_powers);
758 } else {
759 priv->hw->phy->supported.tx_powers = cc2520_cc2591_powers;
760 priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_cc2591_powers);
761 }
762
661 dev_vdbg(&priv->spi->dev, "registered cc2520\n"); 763 dev_vdbg(&priv->spi->dev, "registered cc2520\n");
662 ret = ieee802154_register_hw(priv->hw); 764 ret = ieee802154_register_hw(priv->hw);
663 if (ret) 765 if (ret)