diff options
author | Varka Bhadram <varkabhadram@gmail.com> | 2015-05-29 01:26:56 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-05-31 07:40:53 -0400 |
commit | e10c1674e31558807fcccfbf3dbebbc1cad9099c (patch) | |
tree | 0651109d821e609fe14f7367e89fb8d5381197fd /drivers/net | |
parent | 1a1bc59c5f7657387d1a4b45d63248fed55ab88c (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.c | 102 |
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 | ||
632 | static 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 | |||
671 | static 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 | ||
703 | static 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 | ||
708 | static const s32 cc2520_cc2591_powers[CC2520_CC2591_MAX_TX_POWERS + 1] = { | ||
709 | 1700, 1600, 1400, 1100, -100, -800, | ||
710 | }; | ||
711 | |||
712 | static int | ||
713 | cc2520_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 | |||
632 | static const struct ieee802154_ops cc2520_ops = { | 723 | static 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 | ||
642 | static int cc2520_register(struct cc2520_private *priv) | 734 | static 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) |