iPXE
ath5k_gpio.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
00003  * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
00004  *
00005  * Lightly modified for iPXE, July 2009, by Joshua Oreman <oremanj@rwcr.net>.
00006  *
00007  * Permission to use, copy, modify, and distribute this software for any
00008  * purpose with or without fee is hereby granted, provided that the above
00009  * copyright notice and this permission notice appear in all copies.
00010  *
00011  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00012  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00013  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00014  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00015  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00016  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00017  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00018  *
00019  */
00020 
00021 FILE_LICENCE ( MIT );
00022 
00023 /****************\
00024   GPIO Functions
00025 \****************/
00026 
00027 #include "ath5k.h"
00028 #include "reg.h"
00029 #include "base.h"
00030 
00031 /*
00032  * Set GPIO inputs
00033  */
00034 int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
00035 {
00036         if (gpio >= AR5K_NUM_GPIO)
00037                 return -EINVAL;
00038 
00039         ath5k_hw_reg_write(ah,
00040                 (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
00041                 | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
00042 
00043         return 0;
00044 }
00045 
00046 /*
00047  * Set GPIO outputs
00048  */
00049 int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
00050 {
00051         if (gpio >= AR5K_NUM_GPIO)
00052                 return -EINVAL;
00053 
00054         ath5k_hw_reg_write(ah,
00055                 (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
00056                 | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
00057 
00058         return 0;
00059 }
00060 
00061 /*
00062  * Get GPIO state
00063  */
00064 u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
00065 {
00066         if (gpio >= AR5K_NUM_GPIO)
00067                 return 0xffffffff;
00068 
00069         /* GPIO input magic */
00070         return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
00071                 0x1;
00072 }
00073 
00074 /*
00075  * Set GPIO state
00076  */
00077 int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
00078 {
00079         u32 data;
00080 
00081         if (gpio >= AR5K_NUM_GPIO)
00082                 return -EINVAL;
00083 
00084         /* GPIO output magic */
00085         data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
00086 
00087         data &= ~(1 << gpio);
00088         data |= (val & 1) << gpio;
00089 
00090         ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
00091 
00092         return 0;
00093 }
00094 
00095 /*
00096  * Initialize the GPIO interrupt (RFKill switch)
00097  */
00098 void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
00099                 u32 interrupt_level)
00100 {
00101         u32 data;
00102 
00103         if (gpio >= AR5K_NUM_GPIO)
00104                 return;
00105 
00106         /*
00107          * Set the GPIO interrupt
00108          */
00109         data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
00110                 ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
00111                 AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
00112                 (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
00113 
00114         ath5k_hw_reg_write(ah, interrupt_level ? data :
00115                 (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
00116 
00117         ah->ah_imr |= AR5K_IMR_GPIO;
00118 
00119         /* Enable GPIO interrupts */
00120         AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
00121 }
00122