ar5416_gpio.c (203159) | ar5416_gpio.c (228836) |
---|---|
1/* 2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3 * Copyright (c) 2002-2008 Atheros Communications, Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * | 1/* 2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3 * Copyright (c) 2002-2008 Atheros Communications, Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * |
17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c 203159 2010-01-29 10:10:14Z rpaulo $ | 17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c 228836 2011-12-23 08:53:22Z adrian $ |
18 */ 19#include "opt_ah.h" 20 21#include "ah.h" 22#include "ah_internal.h" 23#include "ah_devid.h" 24 25#include "ar5416/ar5416.h" --- 4 unchanged lines hidden (view full) --- 30 31/* 32 * Configure GPIO Output Mux control 33 */ 34static void 35cfgOutputMux(struct ath_hal *ah, uint32_t gpio, uint32_t type) 36{ 37 int addr; | 18 */ 19#include "opt_ah.h" 20 21#include "ah.h" 22#include "ah_internal.h" 23#include "ah_devid.h" 24 25#include "ar5416/ar5416.h" --- 4 unchanged lines hidden (view full) --- 30 31/* 32 * Configure GPIO Output Mux control 33 */ 34static void 35cfgOutputMux(struct ath_hal *ah, uint32_t gpio, uint32_t type) 36{ 37 int addr; |
38 uint32_t gpio_shift, reg; | 38 uint32_t gpio_shift, tmp; |
39 | 39 |
40 HALDEBUG(ah, HAL_DEBUG_GPIO, "%s: gpio=%d, type=%d\n", 41 __func__, gpio, type); 42 |
|
40 /* each MUX controls 6 GPIO pins */ 41 if (gpio > 11) 42 addr = AR_GPIO_OUTPUT_MUX3; 43 else if (gpio > 5) 44 addr = AR_GPIO_OUTPUT_MUX2; 45 else 46 addr = AR_GPIO_OUTPUT_MUX1; 47 --- 8 unchanged lines hidden (view full) --- 56 * 9 are wrong. Here is hardware's coding: 57 * PRDATA[4:0] <= gpio_output_mux[0]; 58 * PRDATA[9:4] <= gpio_output_mux[1]; 59 * <==== Bit 4 is used by both gpio_output_mux[0] [1]. 60 * Currently the max value for gpio_output_mux[] is 6. So bit 4 61 * will never be used. So it should be fine that bit 4 won't be 62 * able to recover. 63 */ | 43 /* each MUX controls 6 GPIO pins */ 44 if (gpio > 11) 45 addr = AR_GPIO_OUTPUT_MUX3; 46 else if (gpio > 5) 47 addr = AR_GPIO_OUTPUT_MUX2; 48 else 49 addr = AR_GPIO_OUTPUT_MUX1; 50 --- 8 unchanged lines hidden (view full) --- 59 * 9 are wrong. Here is hardware's coding: 60 * PRDATA[4:0] <= gpio_output_mux[0]; 61 * PRDATA[9:4] <= gpio_output_mux[1]; 62 * <==== Bit 4 is used by both gpio_output_mux[0] [1]. 63 * Currently the max value for gpio_output_mux[] is 6. So bit 4 64 * will never be used. So it should be fine that bit 4 won't be 65 * able to recover. 66 */ |
64 reg = OS_REG_READ(ah, addr); 65 if (addr == AR_GPIO_OUTPUT_MUX1 && !AR_SREV_MERLIN_20_OR_LATER(ah)) 66 reg = ((reg & 0x1F0) << 1) | (reg & ~0x1F0); 67 reg &= ~(0x1f << gpio_shift); 68 reg |= type << gpio_shift; 69 OS_REG_WRITE(ah, addr, reg); | 67 if (AR_SREV_MERLIN_20_OR_LATER(ah) || 68 (addr != AR_GPIO_OUTPUT_MUX1)) { 69 OS_REG_RMW(ah, addr, (type << gpio_shift), 70 (0x1f << gpio_shift)); 71 } else { 72 tmp = OS_REG_READ(ah, addr); 73 tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0); 74 tmp &= ~(0x1f << gpio_shift); 75 tmp |= type << gpio_shift; 76 OS_REG_WRITE(ah, addr, tmp); 77 } |
70} 71 72/* 73 * Configure GPIO Output lines 74 */ 75HAL_BOOL 76ar5416GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type) 77{ 78 uint32_t gpio_shift, reg; 79 80 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins); 81 | 78} 79 80/* 81 * Configure GPIO Output lines 82 */ 83HAL_BOOL 84ar5416GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type) 85{ 86 uint32_t gpio_shift, reg; 87 88 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins); 89 |
90 HALDEBUG(ah, HAL_DEBUG_GPIO, 91 "%s: gpio=%d, type=%d\n", __func__, gpio, type); 92 |
|
82 /* NB: type maps directly to hardware */ | 93 /* NB: type maps directly to hardware */ |
94 /* XXX this may not actually be the case, for anything but output */ |
|
83 cfgOutputMux(ah, gpio, type); 84 gpio_shift = gpio << 1; /* 2 bits per output mode */ 85 86 reg = OS_REG_READ(ah, AR_GPIO_OE_OUT); 87 reg &= ~(AR_GPIO_OE_OUT_DRV << gpio_shift); | 95 cfgOutputMux(ah, gpio, type); 96 gpio_shift = gpio << 1; /* 2 bits per output mode */ 97 98 reg = OS_REG_READ(ah, AR_GPIO_OE_OUT); 99 reg &= ~(AR_GPIO_OE_OUT_DRV << gpio_shift); |
100 /* Always drive, rather than tristate/drive low/drive high */ |
|
88 reg |= AR_GPIO_OE_OUT_DRV_ALL << gpio_shift; 89 OS_REG_WRITE(ah, AR_GPIO_OE_OUT, reg); 90 91 return AH_TRUE; 92} 93 94/* 95 * Configure GPIO Input lines 96 */ 97HAL_BOOL 98ar5416GpioCfgInput(struct ath_hal *ah, uint32_t gpio) 99{ 100 uint32_t gpio_shift, reg; 101 102 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins); 103 | 101 reg |= AR_GPIO_OE_OUT_DRV_ALL << gpio_shift; 102 OS_REG_WRITE(ah, AR_GPIO_OE_OUT, reg); 103 104 return AH_TRUE; 105} 106 107/* 108 * Configure GPIO Input lines 109 */ 110HAL_BOOL 111ar5416GpioCfgInput(struct ath_hal *ah, uint32_t gpio) 112{ 113 uint32_t gpio_shift, reg; 114 115 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins); 116 |
117 HALDEBUG(ah, HAL_DEBUG_GPIO, "%s: gpio=%d\n", __func__, gpio); 118 |
|
104 /* TODO: configure input mux for AR5416 */ 105 /* If configured as input, set output to tristate */ 106 gpio_shift = gpio << 1; 107 108 reg = OS_REG_READ(ah, AR_GPIO_OE_OUT); 109 reg &= ~(AR_GPIO_OE_OUT_DRV << gpio_shift); 110 reg |= AR_GPIO_OE_OUT_DRV_ALL << gpio_shift; 111 OS_REG_WRITE(ah, AR_GPIO_OE_OUT, reg); --- 5 unchanged lines hidden (view full) --- 117 * Once configured for I/O - set output lines 118 */ 119HAL_BOOL 120ar5416GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val) 121{ 122 uint32_t reg; 123 124 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins); | 119 /* TODO: configure input mux for AR5416 */ 120 /* If configured as input, set output to tristate */ 121 gpio_shift = gpio << 1; 122 123 reg = OS_REG_READ(ah, AR_GPIO_OE_OUT); 124 reg &= ~(AR_GPIO_OE_OUT_DRV << gpio_shift); 125 reg |= AR_GPIO_OE_OUT_DRV_ALL << gpio_shift; 126 OS_REG_WRITE(ah, AR_GPIO_OE_OUT, reg); --- 5 unchanged lines hidden (view full) --- 132 * Once configured for I/O - set output lines 133 */ 134HAL_BOOL 135ar5416GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val) 136{ 137 uint32_t reg; 138 139 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins); |
140 HALDEBUG(ah, HAL_DEBUG_GPIO, 141 "%s: gpio=%d, val=%d\n", __func__, gpio, val); |
|
125 126 reg = OS_REG_READ(ah, AR_GPIO_IN_OUT); 127 if (val & 1) 128 reg |= AR_GPIO_BIT(gpio); 129 else 130 reg &= ~AR_GPIO_BIT(gpio); 131 OS_REG_WRITE(ah, AR_GPIO_IN_OUT, reg); 132 return AH_TRUE; --- 8 unchanged lines hidden (view full) --- 141 uint32_t bits; 142 143 if (gpio >= AH_PRIVATE(ah)->ah_caps.halNumGpioPins) 144 return 0xffffffff; 145 /* 146 * Read output value for all gpio's, shift it, 147 * and verify whether the specific bit is set. 148 */ | 142 143 reg = OS_REG_READ(ah, AR_GPIO_IN_OUT); 144 if (val & 1) 145 reg |= AR_GPIO_BIT(gpio); 146 else 147 reg &= ~AR_GPIO_BIT(gpio); 148 OS_REG_WRITE(ah, AR_GPIO_IN_OUT, reg); 149 return AH_TRUE; --- 8 unchanged lines hidden (view full) --- 158 uint32_t bits; 159 160 if (gpio >= AH_PRIVATE(ah)->ah_caps.halNumGpioPins) 161 return 0xffffffff; 162 /* 163 * Read output value for all gpio's, shift it, 164 * and verify whether the specific bit is set. 165 */ |
166 if (AR_SREV_KIWI_10_OR_LATER(ah)) 167 bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR9287_GPIO_IN_VAL); |
|
149 if (AR_SREV_KITE_10_OR_LATER(ah)) 150 bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR9285_GPIO_IN_VAL); 151 else if (AR_SREV_MERLIN_10_OR_LATER(ah)) 152 bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR928X_GPIO_IN_VAL); 153 else 154 bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL); 155 return ((bits & AR_GPIO_BIT(gpio)) != 0); 156} 157 158/* 159 * Set the GPIO Interrupt Sync and Async interrupts are both set/cleared. 160 * Async GPIO interrupts may not be raised when the chip is put to sleep. 161 */ 162void 163ar5416GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel) 164{ 165 uint32_t val, mask; 166 167 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins); | 168 if (AR_SREV_KITE_10_OR_LATER(ah)) 169 bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR9285_GPIO_IN_VAL); 170 else if (AR_SREV_MERLIN_10_OR_LATER(ah)) 171 bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR928X_GPIO_IN_VAL); 172 else 173 bits = MS(OS_REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL); 174 return ((bits & AR_GPIO_BIT(gpio)) != 0); 175} 176 177/* 178 * Set the GPIO Interrupt Sync and Async interrupts are both set/cleared. 179 * Async GPIO interrupts may not be raised when the chip is put to sleep. 180 */ 181void 182ar5416GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel) 183{ 184 uint32_t val, mask; 185 186 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins); |
187 HALDEBUG(ah, HAL_DEBUG_GPIO, 188 "%s: gpio=%d, ilevel=%d\n", __func__, gpio, ilevel); |
|
168 169 if (ilevel == HAL_GPIO_INTR_DISABLE) { 170 val = MS(OS_REG_READ(ah, AR_INTR_ASYNC_ENABLE), 171 AR_INTR_ASYNC_ENABLE_GPIO) &~ AR_GPIO_BIT(gpio); 172 OS_REG_RMW_FIELD(ah, AR_INTR_ASYNC_ENABLE, 173 AR_INTR_ASYNC_ENABLE_GPIO, val); 174 175 mask = MS(OS_REG_READ(ah, AR_INTR_ASYNC_MASK), --- 56 unchanged lines hidden --- | 189 190 if (ilevel == HAL_GPIO_INTR_DISABLE) { 191 val = MS(OS_REG_READ(ah, AR_INTR_ASYNC_ENABLE), 192 AR_INTR_ASYNC_ENABLE_GPIO) &~ AR_GPIO_BIT(gpio); 193 OS_REG_RMW_FIELD(ah, AR_INTR_ASYNC_ENABLE, 194 AR_INTR_ASYNC_ENABLE_GPIO, val); 195 196 mask = MS(OS_REG_READ(ah, AR_INTR_ASYNC_MASK), --- 56 unchanged lines hidden --- |