Home | History | Annotate | Download | only in ath5k
      1 /*
      2  * RFKILL support for ath5k
      3  *
      4  * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel (at) gmail.com>
      5  * Lightly modified for gPXE, Sep 2008 by Joshua Oreman <oremanj (at) rwcr.net>
      6  *
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer,
     14  *    without modification.
     15  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     16  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
     17  *    redistribution must be conditioned upon including a substantially
     18  *    similar Disclaimer requirement for further binary redistribution.
     19  * 3. Neither the names of the above-listed copyright holders nor the names
     20  *    of any contributors may be used to endorse or promote products derived
     21  *    from this software without specific prior written permission.
     22  *
     23  * NO WARRANTY
     24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     26  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
     27  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
     28  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
     29  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
     32  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     34  * THE POSSIBILITY OF SUCH DAMAGES.
     35  */
     36 
     37 FILE_LICENCE ( MIT );
     38 
     39 #include "base.h"
     40 
     41 
     42 static inline void ath5k_rfkill_disable(struct ath5k_softc *sc)
     43 {
     44 	DBG("ath5k: rfkill disable (gpio:%d polarity:%d)\n",
     45 	    sc->rf_kill.gpio, sc->rf_kill.polarity);
     46 	ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
     47 	ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity);
     48 }
     49 
     50 
     51 static inline void ath5k_rfkill_enable(struct ath5k_softc *sc)
     52 {
     53 	DBG("ath5k: rfkill enable (gpio:%d polarity:%d)\n",
     54 	    sc->rf_kill.gpio, sc->rf_kill.polarity);
     55 	ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
     56 	ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity);
     57 }
     58 
     59 static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, int enable)
     60 {
     61 	struct ath5k_hw *ah = sc->ah;
     62 	u32 curval;
     63 
     64 	ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio);
     65 	curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
     66 	ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ?
     67 			       !!curval : !curval);
     68 }
     69 
     70 static int __unused
     71 ath5k_is_rfkill_set(struct ath5k_softc *sc)
     72 {
     73 	/* configuring GPIO for input for some reason disables rfkill */
     74 	/*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/
     75 	return (ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) ==
     76 		sc->rf_kill.polarity);
     77 }
     78 
     79 void
     80 ath5k_rfkill_hw_start(struct ath5k_hw *ah)
     81 {
     82 	struct ath5k_softc *sc = ah->ah_sc;
     83 
     84 	/* read rfkill GPIO configuration from EEPROM header */
     85 	sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
     86 	sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
     87 
     88 	ath5k_rfkill_disable(sc);
     89 
     90 	/* enable interrupt for rfkill switch */
     91 	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
     92 		ath5k_rfkill_set_intr(sc, 1);
     93 }
     94 
     95 
     96 void
     97 ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
     98 {
     99 	struct ath5k_softc *sc = ah->ah_sc;
    100 
    101 	/* disable interrupt for rfkill switch */
    102 	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
    103 		ath5k_rfkill_set_intr(sc, 0);
    104 
    105 	/* enable RFKILL when stopping HW so Wifi LED is turned off */
    106 	ath5k_rfkill_enable(sc);
    107 }
    108