diff options
author | Alexander Aring <alex.aring@gmail.com> | 2015-09-21 05:24:40 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-09-22 05:51:23 -0400 |
commit | 00250f78896bc52fd4606c4de7e3fb174e702123 (patch) | |
tree | f3793bb250a3e9e5cb35890034d8b69b1ffc4a2b /drivers/net/ieee802154 | |
parent | e33a0f96ac518d4c7ffcf98d2f030e6e23fab6b3 (diff) |
mrf24j40: add tx power support
This patch supports setting of transmit power for the mrf24j40ma
transceiver only. The mrf24j40mc has some amplifier to change the
transmit power, I am currently not sure how the mapping for this
amplifier looks like.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/net/ieee802154')
-rw-r--r-- | drivers/net/ieee802154/mrf24j40.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index c23936e3dd4f..91687c1a56ce 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c | |||
@@ -864,6 +864,65 @@ static int mrf24j40_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm) | |||
864 | return -EINVAL; | 864 | return -EINVAL; |
865 | } | 865 | } |
866 | 866 | ||
867 | static const s32 mrf24j40ma_powers[] = { | ||
868 | 0, -50, -120, -190, -280, -370, -490, -630, -1000, -1050, -1120, -1190, | ||
869 | -1280, -1370, -1490, -1630, -2000, -2050, -2120, -2190, -2280, -2370, | ||
870 | -2490, -2630, -3000, -3050, -3120, -3190, -3280, -3370, -3490, -3630, | ||
871 | }; | ||
872 | |||
873 | static int mrf24j40_set_txpower(struct ieee802154_hw *hw, s32 mbm) | ||
874 | { | ||
875 | struct mrf24j40 *devrec = hw->priv; | ||
876 | s32 small_scale; | ||
877 | u8 val; | ||
878 | |||
879 | if (0 >= mbm && mbm > -1000) { | ||
880 | val = 0; | ||
881 | small_scale = mbm; | ||
882 | } else if (-1000 >= mbm && mbm > -2000) { | ||
883 | val = 0x40; | ||
884 | small_scale = mbm + 1000; | ||
885 | } else if (-2000 >= mbm && mbm > -3000) { | ||
886 | val = 0x80; | ||
887 | small_scale = mbm + 2000; | ||
888 | } else if (-3000 >= mbm && mbm > -4000) { | ||
889 | val = 0xc0; | ||
890 | small_scale = mbm + 3000; | ||
891 | } else { | ||
892 | return -EINVAL; | ||
893 | } | ||
894 | |||
895 | switch (small_scale) { | ||
896 | case 0: | ||
897 | break; | ||
898 | case -50: | ||
899 | val |= 0x08; | ||
900 | break; | ||
901 | case -120: | ||
902 | val |= 0x10; | ||
903 | break; | ||
904 | case -190: | ||
905 | val |= 0x18; | ||
906 | break; | ||
907 | case -280: | ||
908 | val |= 0x20; | ||
909 | break; | ||
910 | case -370: | ||
911 | val |= 0x28; | ||
912 | break; | ||
913 | case -490: | ||
914 | val |= 0x30; | ||
915 | break; | ||
916 | case -630: | ||
917 | val |= 0x38; | ||
918 | break; | ||
919 | default: | ||
920 | return -EINVAL; | ||
921 | } | ||
922 | |||
923 | return regmap_update_bits(devrec->regmap_long, REG_RFCON3, 0xf8, val); | ||
924 | } | ||
925 | |||
867 | static const struct ieee802154_ops mrf24j40_ops = { | 926 | static const struct ieee802154_ops mrf24j40_ops = { |
868 | .owner = THIS_MODULE, | 927 | .owner = THIS_MODULE, |
869 | .xmit_async = mrf24j40_tx, | 928 | .xmit_async = mrf24j40_tx, |
@@ -875,6 +934,7 @@ static const struct ieee802154_ops mrf24j40_ops = { | |||
875 | .set_csma_params = mrf24j40_csma_params, | 934 | .set_csma_params = mrf24j40_csma_params, |
876 | .set_cca_mode = mrf24j40_set_cca_mode, | 935 | .set_cca_mode = mrf24j40_set_cca_mode, |
877 | .set_cca_ed_level = mrf24j40_set_cca_ed_level, | 936 | .set_cca_ed_level = mrf24j40_set_cca_ed_level, |
937 | .set_txpower = mrf24j40_set_txpower, | ||
878 | }; | 938 | }; |
879 | 939 | ||
880 | static void mrf24j40_intstat_complete(void *context) | 940 | static void mrf24j40_intstat_complete(void *context) |
@@ -1088,6 +1148,17 @@ static void mrf24j40_phy_setup(struct mrf24j40 *devrec) | |||
1088 | devrec->hw->phy->cca_ed_level = -6900; | 1148 | devrec->hw->phy->cca_ed_level = -6900; |
1089 | devrec->hw->phy->supported.cca_ed_levels = mrf24j40_ed_levels; | 1149 | devrec->hw->phy->supported.cca_ed_levels = mrf24j40_ed_levels; |
1090 | devrec->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(mrf24j40_ed_levels); | 1150 | devrec->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(mrf24j40_ed_levels); |
1151 | |||
1152 | switch (spi_get_device_id(devrec->spi)->driver_data) { | ||
1153 | case MRF24J40: | ||
1154 | case MRF24J40MA: | ||
1155 | devrec->hw->phy->supported.tx_powers = mrf24j40ma_powers; | ||
1156 | devrec->hw->phy->supported.tx_powers_size = ARRAY_SIZE(mrf24j40ma_powers); | ||
1157 | devrec->hw->phy->flags |= WPAN_PHY_FLAG_TXPOWER; | ||
1158 | break; | ||
1159 | default: | ||
1160 | break; | ||
1161 | } | ||
1091 | } | 1162 | } |
1092 | 1163 | ||
1093 | static int mrf24j40_probe(struct spi_device *spi) | 1164 | static int mrf24j40_probe(struct spi_device *spi) |