0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include "ath5k.h"
0037
0038
0039 static inline void ath5k_rfkill_disable(struct ath5k_hw *ah)
0040 {
0041 ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n",
0042 ah->rf_kill.gpio, ah->rf_kill.polarity);
0043 ath5k_hw_set_gpio_output(ah, ah->rf_kill.gpio);
0044 ath5k_hw_set_gpio(ah, ah->rf_kill.gpio, !ah->rf_kill.polarity);
0045 }
0046
0047
0048 static inline void ath5k_rfkill_enable(struct ath5k_hw *ah)
0049 {
0050 ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n",
0051 ah->rf_kill.gpio, ah->rf_kill.polarity);
0052 ath5k_hw_set_gpio_output(ah, ah->rf_kill.gpio);
0053 ath5k_hw_set_gpio(ah, ah->rf_kill.gpio, ah->rf_kill.polarity);
0054 }
0055
0056 static inline void ath5k_rfkill_set_intr(struct ath5k_hw *ah, bool enable)
0057 {
0058 u32 curval;
0059
0060 ath5k_hw_set_gpio_input(ah, ah->rf_kill.gpio);
0061 curval = ath5k_hw_get_gpio(ah, ah->rf_kill.gpio);
0062 ath5k_hw_set_gpio_intr(ah, ah->rf_kill.gpio, enable ?
0063 !!curval : !curval);
0064 }
0065
0066 static bool
0067 ath5k_is_rfkill_set(struct ath5k_hw *ah)
0068 {
0069
0070
0071 return ath5k_hw_get_gpio(ah, ah->rf_kill.gpio) ==
0072 ah->rf_kill.polarity;
0073 }
0074
0075 static void
0076 ath5k_tasklet_rfkill_toggle(struct tasklet_struct *t)
0077 {
0078 struct ath5k_hw *ah = from_tasklet(ah, t, rf_kill.toggleq);
0079 bool blocked;
0080
0081 blocked = ath5k_is_rfkill_set(ah);
0082 wiphy_rfkill_set_hw_state(ah->hw->wiphy, blocked);
0083 }
0084
0085
0086 void
0087 ath5k_rfkill_hw_start(struct ath5k_hw *ah)
0088 {
0089
0090 ah->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
0091 ah->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
0092
0093 tasklet_setup(&ah->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle);
0094
0095 ath5k_rfkill_disable(ah);
0096
0097
0098 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
0099 ath5k_rfkill_set_intr(ah, true);
0100 }
0101
0102
0103 void
0104 ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
0105 {
0106
0107 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
0108 ath5k_rfkill_set_intr(ah, false);
0109
0110 tasklet_kill(&ah->rf_kill.toggleq);
0111
0112
0113 ath5k_rfkill_enable(ah);
0114 }
0115