1 /* 2 * Copyright (c) 2004-2008 Reyk Floeter <reyk (at) openbsd.org> 3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm (at) gmail.com> 4 * 5 * Lightly modified for gPXE, July 2009, by Joshua Oreman <oremanj (at) rwcr.net>. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 * 19 */ 20 21 FILE_LICENCE ( MIT ); 22 23 /****************\ 24 GPIO Functions 25 \****************/ 26 27 #include "ath5k.h" 28 #include "reg.h" 29 #include "base.h" 30 31 /* 32 * Set GPIO inputs 33 */ 34 int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) 35 { 36 if (gpio >= AR5K_NUM_GPIO) 37 return -EINVAL; 38 39 ath5k_hw_reg_write(ah, 40 (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio)) 41 | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR); 42 43 return 0; 44 } 45 46 /* 47 * Set GPIO outputs 48 */ 49 int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) 50 { 51 if (gpio >= AR5K_NUM_GPIO) 52 return -EINVAL; 53 54 ath5k_hw_reg_write(ah, 55 (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio)) 56 | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR); 57 58 return 0; 59 } 60 61 /* 62 * Get GPIO state 63 */ 64 u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) 65 { 66 if (gpio >= AR5K_NUM_GPIO) 67 return 0xffffffff; 68 69 /* GPIO input magic */ 70 return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) & 71 0x1; 72 } 73 74 /* 75 * Set GPIO state 76 */ 77 int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val) 78 { 79 u32 data; 80 81 if (gpio >= AR5K_NUM_GPIO) 82 return -EINVAL; 83 84 /* GPIO output magic */ 85 data = ath5k_hw_reg_read(ah, AR5K_GPIODO); 86 87 data &= ~(1 << gpio); 88 data |= (val & 1) << gpio; 89 90 ath5k_hw_reg_write(ah, data, AR5K_GPIODO); 91 92 return 0; 93 } 94 95 /* 96 * Initialize the GPIO interrupt (RFKill switch) 97 */ 98 void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, 99 u32 interrupt_level) 100 { 101 u32 data; 102 103 if (gpio >= AR5K_NUM_GPIO) 104 return; 105 106 /* 107 * Set the GPIO interrupt 108 */ 109 data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & 110 ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH | 111 AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) | 112 (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA); 113 114 ath5k_hw_reg_write(ah, interrupt_level ? data : 115 (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR); 116 117 ah->ah_imr |= AR5K_IMR_GPIO; 118 119 /* Enable GPIO interrupts */ 120 AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO); 121 } 122 123