iPXE
ath5k_rfkill.c
Go to the documentation of this file.
00001 /*
00002  * RFKILL support for ath5k
00003  *
00004  * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel@gmail.com>
00005  * Lightly modified for iPXE, Sep 2008 by Joshua Oreman <oremanj@rwcr.net>
00006  *
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer,
00014  *    without modification.
00015  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
00016  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
00017  *    redistribution must be conditioned upon including a substantially
00018  *    similar Disclaimer requirement for further binary redistribution.
00019  * 3. Neither the names of the above-listed copyright holders nor the names
00020  *    of any contributors may be used to endorse or promote products derived
00021  *    from this software without specific prior written permission.
00022  *
00023  * NO WARRANTY
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
00027  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00028  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
00029  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00032  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
00034  * THE POSSIBILITY OF SUCH DAMAGES.
00035  */
00036 
00037 FILE_LICENCE ( MIT );
00038 
00039 #include "base.h"
00040 
00041 
00042 static inline void ath5k_rfkill_disable(struct ath5k_softc *sc)
00043 {
00044         DBG("ath5k: rfkill disable (gpio:%d polarity:%d)\n",
00045             sc->rf_kill.gpio, sc->rf_kill.polarity);
00046         ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
00047         ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity);
00048 }
00049 
00050 
00051 static inline void ath5k_rfkill_enable(struct ath5k_softc *sc)
00052 {
00053         DBG("ath5k: rfkill enable (gpio:%d polarity:%d)\n",
00054             sc->rf_kill.gpio, sc->rf_kill.polarity);
00055         ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
00056         ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity);
00057 }
00058 
00059 static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, int enable)
00060 {
00061         struct ath5k_hw *ah = sc->ah;
00062         u32 curval;
00063 
00064         ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio);
00065         curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
00066         ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ?
00067                                !!curval : !curval);
00068 }
00069 
00070 static int __unused
00071 ath5k_is_rfkill_set(struct ath5k_softc *sc)
00072 {
00073         /* configuring GPIO for input for some reason disables rfkill */
00074         /*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/
00075         return (ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) ==
00076                 sc->rf_kill.polarity);
00077 }
00078 
00079 void
00080 ath5k_rfkill_hw_start(struct ath5k_hw *ah)
00081 {
00082         struct ath5k_softc *sc = ah->ah_sc;
00083 
00084         /* read rfkill GPIO configuration from EEPROM header */
00085         sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
00086         sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
00087 
00088         ath5k_rfkill_disable(sc);
00089 
00090         /* enable interrupt for rfkill switch */
00091         if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
00092                 ath5k_rfkill_set_intr(sc, 1);
00093 }
00094 
00095 
00096 void
00097 ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
00098 {
00099         struct ath5k_softc *sc = ah->ah_sc;
00100 
00101         /* disable interrupt for rfkill switch */
00102         if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
00103                 ath5k_rfkill_set_intr(sc, 0);
00104 
00105         /* enable RFKILL when stopping HW so Wifi LED is turned off */
00106         ath5k_rfkill_enable(sc);
00107 }