aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k/rfkill.c
diff options
context:
space:
mode:
authorTobias Doerffel <tobias.doerffel@gmail.com>2009-06-09 11:33:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-06-10 13:27:54 -0400
commite6a3b61681dcb963e6465ffbc4330b44824f35e3 (patch)
tree1628eb26f1a79858391686a64e9e72780cd6340a /drivers/net/wireless/ath/ath5k/rfkill.c
parent207ee1621722876bb79828689582bf77fd1be200 (diff)
ath5k: added cfg80211 based rfkill support
This patch introduces initial rfkill support for the ath5k driver based on rfkill support in the cfg80211 framework. All rfkill related code is separated into newly created rfkill.c. Changes to existing code are minimal: * added a new data structure ath5k_rfkill to the ath5k_softc structure * inserted calls to HW rfkill init/deinit routines * ath5k_intr() has been extended to handle AR5K_INT_GPIO interrupts Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/rfkill.c')
-rw-r--r--drivers/net/wireless/ath/ath5k/rfkill.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath5k/rfkill.c b/drivers/net/wireless/ath/ath5k/rfkill.c
new file mode 100644
index 000000000000..492ada92db56
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/rfkill.c
@@ -0,0 +1,121 @@
1/*
2 * RFKILL support for ath5k
3 *
4 * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel@gmail.com>
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
16 * redistribution must be conditioned upon including a substantially
17 * similar Disclaimer requirement for further binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * NO WARRANTY
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
26 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
27 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
28 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
31 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGES.
34 */
35
36#include "base.h"
37
38
39static inline void ath5k_rfkill_disable(struct ath5k_softc *sc)
40{
41 ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n",
42 sc->rf_kill.gpio, sc->rf_kill.polarity);
43 ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
44 ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity);
45}
46
47
48static inline void ath5k_rfkill_enable(struct ath5k_softc *sc)
49{
50 ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n",
51 sc->rf_kill.gpio, sc->rf_kill.polarity);
52 ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
53 ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity);
54}
55
56static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable)
57{
58 struct ath5k_hw *ah = sc->ah;
59 ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio);
60 ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
61 ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ?
62 !!ah->ah_gpio[0] : !ah->ah_gpio[0]);
63}
64
65static bool
66ath5k_is_rfkill_set(struct ath5k_softc *sc)
67{
68 /* configuring GPIO for input for some reason disables rfkill */
69 /*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/
70 return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) ==
71 sc->rf_kill.polarity;
72}
73
74static void
75ath5k_tasklet_rfkill_toggle(unsigned long data)
76{
77 struct ath5k_softc *sc = (void *)data;
78 bool blocked;
79
80 blocked = ath5k_is_rfkill_set(sc);
81 wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked);
82}
83
84
85void
86ath5k_rfkill_hw_start(struct ath5k_hw *ah)
87{
88 struct ath5k_softc *sc = ah->ah_sc;
89
90 /* read rfkill GPIO configuration from EEPROM header */
91 sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
92 sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
93
94 tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle,
95 (unsigned long)sc);
96
97 ath5k_rfkill_disable(sc);
98
99 /* enable interrupt for rfkill switch */
100 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
101 ath5k_rfkill_set_intr(sc, true);
102 }
103}
104
105
106void
107ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
108{
109 struct ath5k_softc *sc = ah->ah_sc;
110
111 /* disable interrupt for rfkill switch */
112 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
113 ath5k_rfkill_set_intr(sc, false);
114 }
115
116 tasklet_kill(&sc->rf_kill.toggleq);
117
118 /* enable RFKILL when stopping HW so Wifi LED is turned off */
119 ath5k_rfkill_enable(sc);
120}
121