xref: /dflybsd-src/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_gpio.c (revision 249483dfec1fb7a8da1e2094624856a84033a5b0)
1b7d5e03cSMatthew Dillon /*
2b7d5e03cSMatthew Dillon  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3b7d5e03cSMatthew Dillon  *
4b7d5e03cSMatthew Dillon  * Permission to use, copy, modify, and/or distribute this software for any
5b7d5e03cSMatthew Dillon  * purpose with or without fee is hereby granted, provided that the above
6b7d5e03cSMatthew Dillon  * copyright notice and this permission notice appear in all copies.
7b7d5e03cSMatthew Dillon  *
8b7d5e03cSMatthew Dillon  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9b7d5e03cSMatthew Dillon  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10b7d5e03cSMatthew Dillon  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11b7d5e03cSMatthew Dillon  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12b7d5e03cSMatthew Dillon  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13b7d5e03cSMatthew Dillon  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14b7d5e03cSMatthew Dillon  * PERFORMANCE OF THIS SOFTWARE.
15b7d5e03cSMatthew Dillon  */
16b7d5e03cSMatthew Dillon 
17b7d5e03cSMatthew Dillon #include "opt_ah.h"
18b7d5e03cSMatthew Dillon 
19b7d5e03cSMatthew Dillon #include "ah.h"
20b7d5e03cSMatthew Dillon #include "ah_internal.h"
21b7d5e03cSMatthew Dillon #include "ah_devid.h"
22b7d5e03cSMatthew Dillon #ifdef AH_DEBUG
23b7d5e03cSMatthew Dillon #include "ah_desc.h"                    /* NB: for HAL_PHYERR* */
24b7d5e03cSMatthew Dillon #endif
25b7d5e03cSMatthew Dillon 
26b7d5e03cSMatthew Dillon #include "ar9300/ar9300.h"
27b7d5e03cSMatthew Dillon #include "ar9300/ar9300reg.h"
28b7d5e03cSMatthew Dillon #include "ar9300/ar9300phy.h"
29b7d5e03cSMatthew Dillon 
30b7d5e03cSMatthew Dillon #define AR_GPIO_BIT(_gpio)                      (1 << (_gpio))
31b7d5e03cSMatthew Dillon 
32b7d5e03cSMatthew Dillon /*
33b7d5e03cSMatthew Dillon  * Configure GPIO Output Mux control
34b7d5e03cSMatthew Dillon  */
35b7d5e03cSMatthew Dillon #if UMAC_SUPPORT_SMARTANTENNA
ar9340_soc_gpio_cfg_output_mux(struct ath_hal * ah,u_int32_t gpio,u_int32_t ah_signal_type)36b7d5e03cSMatthew Dillon static void  ar9340_soc_gpio_cfg_output_mux(
37b7d5e03cSMatthew Dillon     struct ath_hal *ah,
38b7d5e03cSMatthew Dillon     u_int32_t gpio,
39b7d5e03cSMatthew Dillon     u_int32_t ah_signal_type)
40b7d5e03cSMatthew Dillon {
41b7d5e03cSMatthew Dillon #define ADDR_READ(addr)      (*((volatile u_int32_t *)(addr)))
42b7d5e03cSMatthew Dillon #define ADDR_WRITE(addr, b)   (void)((*(volatile u_int32_t *) (addr)) = (b))
43b7d5e03cSMatthew Dillon #define AR9340_SOC_GPIO_FUN0    0xB804002c
44b7d5e03cSMatthew Dillon #define AR9340_SOC_GPIO_OE      0xB8040000
45b7d5e03cSMatthew Dillon #if ATH_SMARTANTENNA_DISABLE_JTAG
46b7d5e03cSMatthew Dillon #define AR9340_SOC_GPIO_FUNCTION   (volatile u_int32_t*) 0xB804006c
47b7d5e03cSMatthew Dillon #define WASP_DISABLE_JTAG  0x2
48b7d5e03cSMatthew Dillon #define MAX_JTAG_GPIO_PIN 1
49b7d5e03cSMatthew Dillon #endif
50b7d5e03cSMatthew Dillon     u_int8_t out_func, shift;
51b7d5e03cSMatthew Dillon     u_int32_t  flags;
52b7d5e03cSMatthew Dillon     volatile u_int32_t* address;
53b7d5e03cSMatthew Dillon 
54b7d5e03cSMatthew Dillon     if (!ah_signal_type){
55b7d5e03cSMatthew Dillon         return;
56b7d5e03cSMatthew Dillon     }
57b7d5e03cSMatthew Dillon #if ATH_SMARTANTENNA_DISABLE_JTAG
58b7d5e03cSMatthew Dillon /*
59b7d5e03cSMatthew Dillon  * To use GPIO pins 0 and 1 for controling antennas, JTAG needs to disabled.
60b7d5e03cSMatthew Dillon  */
61b7d5e03cSMatthew Dillon     if (gpio <= MAX_JTAG_GPIO_PIN) {
62b7d5e03cSMatthew Dillon         flags = ADDR_READ(AR9340_SOC_GPIO_FUNCTION);
63b7d5e03cSMatthew Dillon         flags |= WASP_DISABLE_JTAG;
64b7d5e03cSMatthew Dillon         ADDR_WRITE(AR9340_SOC_GPIO_FUNCTION, flags);
65b7d5e03cSMatthew Dillon     }
66b7d5e03cSMatthew Dillon #endif
67b7d5e03cSMatthew Dillon     out_func = gpio / 4;
68b7d5e03cSMatthew Dillon     shift = (gpio % 4);
69b7d5e03cSMatthew Dillon     address = (volatile u_int32_t *)(AR9340_SOC_GPIO_FUN0 + (out_func*4));
70b7d5e03cSMatthew Dillon 
71b7d5e03cSMatthew Dillon     flags = ADDR_READ(address);
72b7d5e03cSMatthew Dillon     flags |= ah_signal_type << (8*shift);
73b7d5e03cSMatthew Dillon     ADDR_WRITE(address, flags);
74b7d5e03cSMatthew Dillon     flags = ADDR_READ(AR9340_SOC_GPIO_OE);
75b7d5e03cSMatthew Dillon     flags &= ~(1 << gpio);
76b7d5e03cSMatthew Dillon     ADDR_WRITE(AR9340_SOC_GPIO_OE, flags);
77b7d5e03cSMatthew Dillon 
78b7d5e03cSMatthew Dillon }
79b7d5e03cSMatthew Dillon #endif
80b7d5e03cSMatthew Dillon 
81b7d5e03cSMatthew Dillon static void
ar9300_gpio_cfg_output_mux(struct ath_hal * ah,u_int32_t gpio,u_int32_t type)82b7d5e03cSMatthew Dillon ar9300_gpio_cfg_output_mux(struct ath_hal *ah, u_int32_t gpio, u_int32_t type)
83b7d5e03cSMatthew Dillon {
84b7d5e03cSMatthew Dillon     int          addr;
85b7d5e03cSMatthew Dillon     u_int32_t    gpio_shift;
86b7d5e03cSMatthew Dillon 
87b7d5e03cSMatthew Dillon     /* each MUX controls 6 GPIO pins */
88b7d5e03cSMatthew Dillon     if (gpio > 11) {
89b7d5e03cSMatthew Dillon         addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX3);
90b7d5e03cSMatthew Dillon     } else if (gpio > 5) {
91b7d5e03cSMatthew Dillon         addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX2);
92b7d5e03cSMatthew Dillon     } else {
93b7d5e03cSMatthew Dillon         addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1);
94b7d5e03cSMatthew Dillon     }
95b7d5e03cSMatthew Dillon 
96b7d5e03cSMatthew Dillon     /*
97b7d5e03cSMatthew Dillon      * 5 bits per GPIO pin.
98b7d5e03cSMatthew Dillon      * Bits 0..4 for 1st pin in that mux,
99b7d5e03cSMatthew Dillon      * bits 5..9 for 2nd pin, etc.
100b7d5e03cSMatthew Dillon      */
101b7d5e03cSMatthew Dillon     gpio_shift = (gpio % 6) * 5;
102b7d5e03cSMatthew Dillon 
103b7d5e03cSMatthew Dillon     OS_REG_RMW(ah, addr, (type << gpio_shift), (0x1f << gpio_shift));
104b7d5e03cSMatthew Dillon }
105b7d5e03cSMatthew Dillon 
106b7d5e03cSMatthew Dillon /*
107b7d5e03cSMatthew Dillon  * Configure GPIO Output lines
108b7d5e03cSMatthew Dillon  */
109b7d5e03cSMatthew Dillon HAL_BOOL
ar9300_gpio_cfg_output(struct ath_hal * ah,u_int32_t gpio,HAL_GPIO_MUX_TYPE hal_signal_type)110b7d5e03cSMatthew Dillon ar9300_gpio_cfg_output(
111b7d5e03cSMatthew Dillon     struct ath_hal *ah,
112b7d5e03cSMatthew Dillon     u_int32_t gpio,
113b7d5e03cSMatthew Dillon     HAL_GPIO_MUX_TYPE hal_signal_type)
114b7d5e03cSMatthew Dillon {
115b7d5e03cSMatthew Dillon     u_int32_t    ah_signal_type;
116b7d5e03cSMatthew Dillon     u_int32_t    gpio_shift;
117b7d5e03cSMatthew Dillon     u_int8_t    smart_ant = 0;
118b7d5e03cSMatthew Dillon     static const u_int32_t    mux_signal_conversion_table[] = {
119b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_OUTPUT             */
120b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
121b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED */
122b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
123b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     */
124b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
125b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    */
126b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
127b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      */
128b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
129b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE        */
130b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL,
131b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME           */
132b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_TX_FRAME,
133b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA      */
134b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA,
135b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK       */
136b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK,
137b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA        */
138b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA,
139b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK         */
140b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK,
141b7d5e03cSMatthew Dillon 	            /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX           */
142b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX,
143b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX           */
144b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX,
145b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX           */
146b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX,
147b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX           */
148b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX,
149b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE      */
150b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE,
151b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA        */
152b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA,
153b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0     */
154b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0,
155b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1     */
156b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1,
157b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2     */
158b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2,
159b7d5e03cSMatthew Dillon                     /* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_SWCOM3    */
160b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_SWCOM3,
161b7d5e03cSMatthew Dillon     };
162b7d5e03cSMatthew Dillon 
163b7d5e03cSMatthew Dillon     HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
164b7d5e03cSMatthew Dillon     if ((gpio == AR9382_GPIO_PIN_8_RESERVED)  ||
165b7d5e03cSMatthew Dillon         (gpio == AR9382_GPIO_9_INPUT_ONLY))
166b7d5e03cSMatthew Dillon     {
167b7d5e03cSMatthew Dillon         return AH_FALSE;
168b7d5e03cSMatthew Dillon     }
169b7d5e03cSMatthew Dillon 
170b7d5e03cSMatthew Dillon     /* Convert HAL signal type definitions to hardware-specific values. */
171b7d5e03cSMatthew Dillon     if ((int) hal_signal_type < ARRAY_LENGTH(mux_signal_conversion_table))
172b7d5e03cSMatthew Dillon     {
173b7d5e03cSMatthew Dillon         ah_signal_type = mux_signal_conversion_table[hal_signal_type];
174b7d5e03cSMatthew Dillon     } else {
175b7d5e03cSMatthew Dillon         return AH_FALSE;
176b7d5e03cSMatthew Dillon     }
177b7d5e03cSMatthew Dillon 
178b7d5e03cSMatthew Dillon     if (gpio <= AR9382_MAX_JTAG_GPIO_PIN_NUM) {
179b7d5e03cSMatthew Dillon         OS_REG_SET_BIT(ah,
180b7d5e03cSMatthew Dillon             AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
181b7d5e03cSMatthew Dillon     }
182b7d5e03cSMatthew Dillon 
183b7d5e03cSMatthew Dillon #if UMAC_SUPPORT_SMARTANTENNA
184b7d5e03cSMatthew Dillon     /* Get the pin and func values for smart antenna */
185b7d5e03cSMatthew Dillon     switch (ah_signal_type)
186b7d5e03cSMatthew Dillon     {
187b7d5e03cSMatthew Dillon         case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0:
188b7d5e03cSMatthew Dillon             gpio = ATH_GPIOPIN_ANTCHAIN0;
189b7d5e03cSMatthew Dillon             ah_signal_type = ATH_GPIOFUNC_ANTCHAIN0;
190b7d5e03cSMatthew Dillon             smart_ant = 1;
191b7d5e03cSMatthew Dillon             break;
192b7d5e03cSMatthew Dillon         case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1:
193b7d5e03cSMatthew Dillon             gpio = ATH_GPIOPIN_ANTCHAIN1;
194b7d5e03cSMatthew Dillon             ah_signal_type = ATH_GPIOFUNC_ANTCHAIN1;
195b7d5e03cSMatthew Dillon             smart_ant = 1;
196b7d5e03cSMatthew Dillon             break;
197b7d5e03cSMatthew Dillon         case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2:
198b7d5e03cSMatthew Dillon             gpio = ATH_GPIOPIN_ANTCHAIN2;
199b7d5e03cSMatthew Dillon             ah_signal_type = ATH_GPIOFUNC_ANTCHAIN2;
200b7d5e03cSMatthew Dillon             smart_ant = 1;
201b7d5e03cSMatthew Dillon             break;
202b7d5e03cSMatthew Dillon #if ATH_SMARTANTENNA_ROUTE_SWCOM_TO_GPIO
203b7d5e03cSMatthew Dillon         case AR_GPIO_OUTPUT_MUX_AS_SWCOM3:
204b7d5e03cSMatthew Dillon             gpio = ATH_GPIOPIN_ROUTE_SWCOM3;
205b7d5e03cSMatthew Dillon             ah_signal_type = ATH_GPIOFUNC_ROUTE_SWCOM3;
206b7d5e03cSMatthew Dillon             smart_ant = 1;
207b7d5e03cSMatthew Dillon             break;
208b7d5e03cSMatthew Dillon #endif
209b7d5e03cSMatthew Dillon         default:
210b7d5e03cSMatthew Dillon             break;
211b7d5e03cSMatthew Dillon     }
212b7d5e03cSMatthew Dillon #endif
213b7d5e03cSMatthew Dillon 
214b7d5e03cSMatthew Dillon     if (smart_ant && (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)))
215b7d5e03cSMatthew Dillon     {
216b7d5e03cSMatthew Dillon #if UMAC_SUPPORT_SMARTANTENNA
217b7d5e03cSMatthew Dillon         ar9340_soc_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
218b7d5e03cSMatthew Dillon #endif
219b7d5e03cSMatthew Dillon         return AH_TRUE;
220b7d5e03cSMatthew Dillon     } else
221b7d5e03cSMatthew Dillon     {
222b7d5e03cSMatthew Dillon         /* Configure the MUX */
223b7d5e03cSMatthew Dillon         ar9300_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
224b7d5e03cSMatthew Dillon     }
225b7d5e03cSMatthew Dillon 
226b7d5e03cSMatthew Dillon     /* 2 bits per output mode */
227b7d5e03cSMatthew Dillon     gpio_shift = 2 * gpio;
228b7d5e03cSMatthew Dillon 
229b7d5e03cSMatthew Dillon     OS_REG_RMW(ah,
230b7d5e03cSMatthew Dillon                AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
231b7d5e03cSMatthew Dillon                (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
232b7d5e03cSMatthew Dillon                (AR_GPIO_OE_OUT_DRV << gpio_shift));
233b7d5e03cSMatthew Dillon     return AH_TRUE;
234b7d5e03cSMatthew Dillon }
235b7d5e03cSMatthew Dillon 
236b7d5e03cSMatthew Dillon /*
237b7d5e03cSMatthew Dillon  * Configure GPIO Output lines -LED off
238b7d5e03cSMatthew Dillon  */
239b7d5e03cSMatthew Dillon HAL_BOOL
ar9300_gpio_cfg_output_led_off(struct ath_hal * ah,u_int32_t gpio,HAL_GPIO_MUX_TYPE halSignalType)240b7d5e03cSMatthew Dillon ar9300_gpio_cfg_output_led_off(
241b7d5e03cSMatthew Dillon     struct ath_hal *ah,
242b7d5e03cSMatthew Dillon     u_int32_t gpio,
243b7d5e03cSMatthew Dillon     HAL_GPIO_MUX_TYPE halSignalType)
244b7d5e03cSMatthew Dillon {
245b7d5e03cSMatthew Dillon     u_int32_t    ah_signal_type;
246b7d5e03cSMatthew Dillon     u_int32_t    gpio_shift;
247b7d5e03cSMatthew Dillon     u_int8_t    smart_ant = 0;
248b7d5e03cSMatthew Dillon 
249b7d5e03cSMatthew Dillon     static const u_int32_t    mux_signal_conversion_table[] = {
250b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_OUTPUT             */
251b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
252b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED */
253b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
254b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     */
255b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
256b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    */
257b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
258b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      */
259b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
260b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE        */
261b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL,
262b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME           */
263b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_TX_FRAME,
264b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA      */
265b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA,
266b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK       */
267b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK,
268b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA        */
269b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA,
270b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK         */
271b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK,
272b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX           */
273b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX,
274b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX           */
275b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX,
276b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX           */
277b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX,
278b7d5e03cSMatthew Dillon         /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX           */
279b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX,
280b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE,
281b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA,
282b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0,
283b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1,
284b7d5e03cSMatthew Dillon         AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2
285b7d5e03cSMatthew Dillon     };
286*4c53cd68SSascha Wildner     HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
287b7d5e03cSMatthew Dillon 
288b7d5e03cSMatthew Dillon     /* Convert HAL signal type definitions to hardware-specific values. */
289b7d5e03cSMatthew Dillon     if ((int) halSignalType < ARRAY_LENGTH(mux_signal_conversion_table))
290b7d5e03cSMatthew Dillon     {
291b7d5e03cSMatthew Dillon         ah_signal_type = mux_signal_conversion_table[halSignalType];
292b7d5e03cSMatthew Dillon     } else {
293b7d5e03cSMatthew Dillon         return AH_FALSE;
294b7d5e03cSMatthew Dillon     }
295b7d5e03cSMatthew Dillon #if UMAC_SUPPORT_SMARTANTENNA
296b7d5e03cSMatthew Dillon     /* Get the pin and func values for smart antenna */
297b7d5e03cSMatthew Dillon     switch (halSignalType)
298b7d5e03cSMatthew Dillon     {
299b7d5e03cSMatthew Dillon         case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0:
300b7d5e03cSMatthew Dillon             gpio = ATH_GPIOPIN_ANTCHAIN0;
301b7d5e03cSMatthew Dillon             ah_signal_type = ATH_GPIOFUNC_ANTCHAIN0;
302b7d5e03cSMatthew Dillon             smart_ant = 1;
303b7d5e03cSMatthew Dillon             break;
304b7d5e03cSMatthew Dillon         case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1:
305b7d5e03cSMatthew Dillon             gpio = ATH_GPIOPIN_ANTCHAIN1;
306b7d5e03cSMatthew Dillon             ah_signal_type = ATH_GPIOFUNC_ANTCHAIN1;
307b7d5e03cSMatthew Dillon             smart_ant = 1;
308b7d5e03cSMatthew Dillon             break;
309b7d5e03cSMatthew Dillon         case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2:
310b7d5e03cSMatthew Dillon             gpio = ATH_GPIOPIN_ANTCHAIN2;
311b7d5e03cSMatthew Dillon             ah_signal_type = ATH_GPIOFUNC_ANTCHAIN2;
312b7d5e03cSMatthew Dillon             smart_ant = 1;
313b7d5e03cSMatthew Dillon             break;
314b7d5e03cSMatthew Dillon         default:
315b7d5e03cSMatthew Dillon             break;
316b7d5e03cSMatthew Dillon     }
317b7d5e03cSMatthew Dillon #endif
318b7d5e03cSMatthew Dillon 
319b7d5e03cSMatthew Dillon     if (smart_ant && AR_SREV_WASP(ah))
320b7d5e03cSMatthew Dillon     {
321b7d5e03cSMatthew Dillon         return AH_FALSE;
322b7d5e03cSMatthew Dillon     }
323b7d5e03cSMatthew Dillon 
324b7d5e03cSMatthew Dillon     // Configure the MUX
325b7d5e03cSMatthew Dillon     ar9300_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
326b7d5e03cSMatthew Dillon 
327b7d5e03cSMatthew Dillon     // 2 bits per output mode
328b7d5e03cSMatthew Dillon     gpio_shift = 2*gpio;
329b7d5e03cSMatthew Dillon 
330b7d5e03cSMatthew Dillon     OS_REG_RMW(ah,
331b7d5e03cSMatthew Dillon                AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
332b7d5e03cSMatthew Dillon                (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
333b7d5e03cSMatthew Dillon                (AR_GPIO_OE_OUT_DRV << gpio_shift));
334b7d5e03cSMatthew Dillon 
335b7d5e03cSMatthew Dillon     return AH_TRUE;
336b7d5e03cSMatthew Dillon }
337b7d5e03cSMatthew Dillon 
338b7d5e03cSMatthew Dillon /*
339b7d5e03cSMatthew Dillon  * Configure GPIO Input lines
340b7d5e03cSMatthew Dillon  */
341b7d5e03cSMatthew Dillon HAL_BOOL
ar9300_gpio_cfg_input(struct ath_hal * ah,u_int32_t gpio)342b7d5e03cSMatthew Dillon ar9300_gpio_cfg_input(struct ath_hal *ah, u_int32_t gpio)
343b7d5e03cSMatthew Dillon {
344b7d5e03cSMatthew Dillon     u_int32_t    gpio_shift;
345b7d5e03cSMatthew Dillon 
346b7d5e03cSMatthew Dillon     HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
347b7d5e03cSMatthew Dillon     if ((gpio == AR9382_GPIO_PIN_8_RESERVED)  ||
348b7d5e03cSMatthew Dillon         (gpio > AR9382_MAX_GPIO_INPUT_PIN_NUM))
349b7d5e03cSMatthew Dillon     {
350b7d5e03cSMatthew Dillon         return AH_FALSE;
351b7d5e03cSMatthew Dillon     }
352b7d5e03cSMatthew Dillon 
353b7d5e03cSMatthew Dillon     if (gpio <= AR9382_MAX_JTAG_GPIO_PIN_NUM) {
354b7d5e03cSMatthew Dillon         OS_REG_SET_BIT(ah,
355b7d5e03cSMatthew Dillon             AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
356b7d5e03cSMatthew Dillon     }
357b7d5e03cSMatthew Dillon     /* TODO: configure input mux for AR9300 */
358b7d5e03cSMatthew Dillon     /* If configured as input, set output to tristate */
359b7d5e03cSMatthew Dillon     gpio_shift = 2 * gpio;
360b7d5e03cSMatthew Dillon 
361b7d5e03cSMatthew Dillon     OS_REG_RMW(ah,
362b7d5e03cSMatthew Dillon                AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
363b7d5e03cSMatthew Dillon                (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
364b7d5e03cSMatthew Dillon                (AR_GPIO_OE_OUT_DRV << gpio_shift));
365b7d5e03cSMatthew Dillon     return AH_TRUE;
366b7d5e03cSMatthew Dillon }
367b7d5e03cSMatthew Dillon 
368b7d5e03cSMatthew Dillon /*
369b7d5e03cSMatthew Dillon  * Once configured for I/O - set output lines
370b7d5e03cSMatthew Dillon  * output the level of GPio PIN without care work mode
371b7d5e03cSMatthew Dillon  */
372b7d5e03cSMatthew Dillon HAL_BOOL
ar9300_gpio_set(struct ath_hal * ah,u_int32_t gpio,u_int32_t val)373b7d5e03cSMatthew Dillon ar9300_gpio_set(struct ath_hal *ah, u_int32_t gpio, u_int32_t val)
374b7d5e03cSMatthew Dillon {
375b7d5e03cSMatthew Dillon     HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
376b7d5e03cSMatthew Dillon     if ((gpio == AR9382_GPIO_PIN_8_RESERVED)  ||
377b7d5e03cSMatthew Dillon         (gpio == AR9382_GPIO_9_INPUT_ONLY))
378b7d5e03cSMatthew Dillon     {
379b7d5e03cSMatthew Dillon         return AH_FALSE;
380b7d5e03cSMatthew Dillon     }
381b7d5e03cSMatthew Dillon     OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUT),
382b7d5e03cSMatthew Dillon         ((val & 1) << gpio), AR_GPIO_BIT(gpio));
383b7d5e03cSMatthew Dillon 
384b7d5e03cSMatthew Dillon     return AH_TRUE;
385b7d5e03cSMatthew Dillon }
386b7d5e03cSMatthew Dillon 
387b7d5e03cSMatthew Dillon /*
388b7d5e03cSMatthew Dillon  * Once configured for I/O - get input lines
389b7d5e03cSMatthew Dillon  */
390b7d5e03cSMatthew Dillon u_int32_t
ar9300_gpio_get(struct ath_hal * ah,u_int32_t gpio)391b7d5e03cSMatthew Dillon ar9300_gpio_get(struct ath_hal *ah, u_int32_t gpio)
392b7d5e03cSMatthew Dillon {
393b7d5e03cSMatthew Dillon     u_int32_t gpio_in;
394b7d5e03cSMatthew Dillon     HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
395a20e5e51SMatthew Dillon     if (gpio == AR9382_GPIO_PIN_8_RESERVED)
396b7d5e03cSMatthew Dillon     {
397b7d5e03cSMatthew Dillon         return 0xffffffff;
398b7d5e03cSMatthew Dillon     }
399b7d5e03cSMatthew Dillon 
400b7d5e03cSMatthew Dillon     gpio_in = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN));
401b7d5e03cSMatthew Dillon     OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN),
402b7d5e03cSMatthew Dillon         (1 << gpio), AR_GPIO_BIT(gpio));
403b7d5e03cSMatthew Dillon     return (MS(gpio_in, AR_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
404b7d5e03cSMatthew Dillon }
405b7d5e03cSMatthew Dillon 
406b7d5e03cSMatthew Dillon u_int32_t
ar9300_gpio_get_intr(struct ath_hal * ah)407b7d5e03cSMatthew Dillon ar9300_gpio_get_intr(struct ath_hal *ah)
408b7d5e03cSMatthew Dillon {
409b7d5e03cSMatthew Dillon     unsigned int mask = 0;
410b7d5e03cSMatthew Dillon     struct ath_hal_9300 *ahp = AH9300(ah);
411b7d5e03cSMatthew Dillon 
412b7d5e03cSMatthew Dillon     mask = ahp->ah_gpio_cause;
413b7d5e03cSMatthew Dillon     return mask;
414b7d5e03cSMatthew Dillon }
415b7d5e03cSMatthew Dillon 
416b7d5e03cSMatthew Dillon /*
417b7d5e03cSMatthew Dillon  * Set the GPIO Interrupt
418b7d5e03cSMatthew Dillon  * Sync and Async interrupts are both set/cleared.
419b7d5e03cSMatthew Dillon  * Async GPIO interrupts may not be raised when the chip is put to sleep.
420b7d5e03cSMatthew Dillon  */
421b7d5e03cSMatthew Dillon void
ar9300_gpio_set_intr(struct ath_hal * ah,u_int gpio,u_int32_t ilevel)422b7d5e03cSMatthew Dillon ar9300_gpio_set_intr(struct ath_hal *ah, u_int gpio, u_int32_t ilevel)
423b7d5e03cSMatthew Dillon {
424b7d5e03cSMatthew Dillon 
425b7d5e03cSMatthew Dillon 
426b7d5e03cSMatthew Dillon     int i, reg_bit;
427b7d5e03cSMatthew Dillon     u_int32_t reg_val;
428b7d5e03cSMatthew Dillon     u_int32_t regs[2], shifts[2];
429b7d5e03cSMatthew Dillon 
430b7d5e03cSMatthew Dillon #ifdef AH_ASSERT
431b7d5e03cSMatthew Dillon     u_int32_t gpio_mask;
432b7d5e03cSMatthew Dillon     u_int32_t old_field_val = 0, field_val = 0;
433b7d5e03cSMatthew Dillon #endif
434b7d5e03cSMatthew Dillon 
435b7d5e03cSMatthew Dillon #ifdef ATH_GPIO_USE_ASYNC_CAUSE
436b7d5e03cSMatthew Dillon     regs[0] = AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE);
437b7d5e03cSMatthew Dillon     regs[1] = AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK);
438b7d5e03cSMatthew Dillon     shifts[0] = AR_INTR_ASYNC_ENABLE_GPIO_S;
439b7d5e03cSMatthew Dillon     shifts[1] = AR_INTR_ASYNC_MASK_GPIO_S;
440b7d5e03cSMatthew Dillon #else
441b7d5e03cSMatthew Dillon     regs[0] = AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE);
442b7d5e03cSMatthew Dillon     regs[1] = AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK);
443b7d5e03cSMatthew Dillon     shifts[0] = AR_INTR_SYNC_ENABLE_GPIO_S;
444b7d5e03cSMatthew Dillon     shifts[1] = AR_INTR_SYNC_MASK_GPIO_S;
445b7d5e03cSMatthew Dillon #endif
446b7d5e03cSMatthew Dillon 
447b7d5e03cSMatthew Dillon     HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
448b7d5e03cSMatthew Dillon 
449b7d5e03cSMatthew Dillon     if ((gpio == AR9382_GPIO_PIN_8_RESERVED) ||
450b7d5e03cSMatthew Dillon         (gpio > AR9382_MAX_GPIO_INPUT_PIN_NUM))
451b7d5e03cSMatthew Dillon     {
452b7d5e03cSMatthew Dillon         return;
453b7d5e03cSMatthew Dillon     }
454b7d5e03cSMatthew Dillon 
455b7d5e03cSMatthew Dillon #ifdef AH_ASSERT
456b7d5e03cSMatthew Dillon     gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.halNumGpioPins) - 1;
457b7d5e03cSMatthew Dillon #endif
458b7d5e03cSMatthew Dillon     if (ilevel == HAL_GPIO_INTR_DISABLE) {
459b7d5e03cSMatthew Dillon         /* clear this GPIO's bit in the interrupt registers */
460b7d5e03cSMatthew Dillon         for (i = 0; i < ARRAY_LENGTH(regs); i++) {
461b7d5e03cSMatthew Dillon             reg_val = OS_REG_READ(ah, regs[i]);
462b7d5e03cSMatthew Dillon             reg_bit = shifts[i] + gpio;
463b7d5e03cSMatthew Dillon             reg_val &= ~(1 << reg_bit);
464b7d5e03cSMatthew Dillon             OS_REG_WRITE(ah, regs[i], reg_val);
465b7d5e03cSMatthew Dillon 
466b7d5e03cSMatthew Dillon             /* check that each register has same GPIOs enabled */
467b7d5e03cSMatthew Dillon #ifdef AH_ASSERT
468b7d5e03cSMatthew Dillon             field_val = (reg_val >> shifts[i]) & gpio_mask;
469b7d5e03cSMatthew Dillon             HALASSERT(i == 0 || old_field_val == field_val);
470b7d5e03cSMatthew Dillon             old_field_val = field_val;
471b7d5e03cSMatthew Dillon #endif
472b7d5e03cSMatthew Dillon         }
473b7d5e03cSMatthew Dillon 
474b7d5e03cSMatthew Dillon     } else {
475b7d5e03cSMatthew Dillon         reg_val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL));
476b7d5e03cSMatthew Dillon         reg_bit = gpio;
477b7d5e03cSMatthew Dillon         if (ilevel == HAL_GPIO_INTR_HIGH) {
478b7d5e03cSMatthew Dillon             /* 0 == interrupt on pin high */
479b7d5e03cSMatthew Dillon             reg_val &= ~(1 << reg_bit);
480b7d5e03cSMatthew Dillon         } else if (ilevel == HAL_GPIO_INTR_LOW) {
481b7d5e03cSMatthew Dillon             /* 1 == interrupt on pin low */
482b7d5e03cSMatthew Dillon             reg_val |= (1 << reg_bit);
483b7d5e03cSMatthew Dillon         }
484b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), reg_val);
485b7d5e03cSMatthew Dillon 
486b7d5e03cSMatthew Dillon         /* set this GPIO's bit in the interrupt registers */
487b7d5e03cSMatthew Dillon         for (i = 0; i < ARRAY_LENGTH(regs); i++) {
488b7d5e03cSMatthew Dillon             reg_val = OS_REG_READ(ah, regs[i]);
489b7d5e03cSMatthew Dillon             reg_bit = shifts[i] + gpio;
490b7d5e03cSMatthew Dillon             reg_val |= (1 << reg_bit);
491b7d5e03cSMatthew Dillon             OS_REG_WRITE(ah, regs[i], reg_val);
492b7d5e03cSMatthew Dillon 
493b7d5e03cSMatthew Dillon             /* check that each register has same GPIOs enabled */
494b7d5e03cSMatthew Dillon #ifdef AH_ASSERT
495b7d5e03cSMatthew Dillon             field_val = (reg_val >> shifts[i]) & gpio_mask;
496b7d5e03cSMatthew Dillon             HALASSERT(i == 0 || old_field_val == field_val);
497b7d5e03cSMatthew Dillon             old_field_val = field_val;
498b7d5e03cSMatthew Dillon #endif
499b7d5e03cSMatthew Dillon         }
500b7d5e03cSMatthew Dillon     }
501b7d5e03cSMatthew Dillon }
502b7d5e03cSMatthew Dillon 
503b7d5e03cSMatthew Dillon u_int32_t
ar9300_gpio_get_polarity(struct ath_hal * ah)504b7d5e03cSMatthew Dillon ar9300_gpio_get_polarity(struct ath_hal *ah)
505b7d5e03cSMatthew Dillon {
506b7d5e03cSMatthew Dillon     return OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL));
507b7d5e03cSMatthew Dillon 
508b7d5e03cSMatthew Dillon }
509b7d5e03cSMatthew Dillon 
510b7d5e03cSMatthew Dillon void
ar9300_gpio_set_polarity(struct ath_hal * ah,u_int32_t pol_map,u_int32_t changed_mask)511b7d5e03cSMatthew Dillon ar9300_gpio_set_polarity(struct ath_hal *ah, u_int32_t pol_map,
512b7d5e03cSMatthew Dillon                          u_int32_t changed_mask)
513b7d5e03cSMatthew Dillon {
514b7d5e03cSMatthew Dillon     u_int32_t gpio_mask;
515b7d5e03cSMatthew Dillon 
516b7d5e03cSMatthew Dillon     gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.halNumGpioPins) - 1;
517b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), gpio_mask & pol_map);
518b7d5e03cSMatthew Dillon 
519b7d5e03cSMatthew Dillon #ifndef ATH_GPIO_USE_ASYNC_CAUSE
520b7d5e03cSMatthew Dillon     /*
521b7d5e03cSMatthew Dillon      * For SYNC_CAUSE type interrupts, we need to clear the cause register
522b7d5e03cSMatthew Dillon      * explicitly. Otherwise an interrupt with the original polarity setting
523b7d5e03cSMatthew Dillon      * will come up immediately (if there is already an interrupt source),
524b7d5e03cSMatthew Dillon      * which is not what we want usually.
525b7d5e03cSMatthew Dillon      */
526b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR),
527b7d5e03cSMatthew Dillon                  changed_mask << AR_INTR_SYNC_ENABLE_GPIO_S);
528b7d5e03cSMatthew Dillon     OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR));
529b7d5e03cSMatthew Dillon #endif
530b7d5e03cSMatthew Dillon }
531b7d5e03cSMatthew Dillon 
532b7d5e03cSMatthew Dillon /*
533b7d5e03cSMatthew Dillon  * get the GPIO input pin mask
534b7d5e03cSMatthew Dillon  * gpio0 - gpio13
535b7d5e03cSMatthew Dillon  * gpio8, gpio11, regard as reserved by the chip ar9382
536b7d5e03cSMatthew Dillon  */
537b7d5e03cSMatthew Dillon 
538b7d5e03cSMatthew Dillon u_int32_t
ar9300_gpio_get_mask(struct ath_hal * ah)539b7d5e03cSMatthew Dillon ar9300_gpio_get_mask(struct ath_hal *ah)
540b7d5e03cSMatthew Dillon {
541b7d5e03cSMatthew Dillon     u_int32_t mask = (1 << (AR9382_MAX_GPIO_INPUT_PIN_NUM + 1) ) - 1;
542b7d5e03cSMatthew Dillon 
543b7d5e03cSMatthew Dillon     if (AH_PRIVATE(ah)->ah_devid == AR9300_DEVID_AR9380_PCIE) {
544b7d5e03cSMatthew Dillon         mask = (1 << AR9382_MAX_GPIO_PIN_NUM) - 1;
545a20e5e51SMatthew Dillon         mask &= ~(1 << AR9382_GPIO_PIN_8_RESERVED);
546b7d5e03cSMatthew Dillon     }
547b7d5e03cSMatthew Dillon     return mask;
548b7d5e03cSMatthew Dillon }
549b7d5e03cSMatthew Dillon 
550b7d5e03cSMatthew Dillon int
ar9300_gpio_set_mask(struct ath_hal * ah,u_int32_t mask,u_int32_t pol_map)551b7d5e03cSMatthew Dillon ar9300_gpio_set_mask(struct ath_hal *ah, u_int32_t mask, u_int32_t pol_map)
552b7d5e03cSMatthew Dillon {
553b7d5e03cSMatthew Dillon     u_int32_t invalid = ~((1 << (AR9382_MAX_GPIO_INPUT_PIN_NUM + 1)) - 1);
554b7d5e03cSMatthew Dillon 
555b7d5e03cSMatthew Dillon     if (AH_PRIVATE(ah)->ah_devid == AR9300_DEVID_AR9380_PCIE) {
556b7d5e03cSMatthew Dillon         invalid = ~((1 << AR9382_MAX_GPIO_PIN_NUM) - 1);
557a20e5e51SMatthew Dillon         invalid |= 1 << AR9382_GPIO_PIN_8_RESERVED;
558b7d5e03cSMatthew Dillon     }
559b7d5e03cSMatthew Dillon     if (mask & invalid) {
560b7d5e03cSMatthew Dillon         ath_hal_printf(ah, "%s: invalid GPIO mask 0x%x\n", __func__, mask);
561b7d5e03cSMatthew Dillon         return -1;
562b7d5e03cSMatthew Dillon     }
563b7d5e03cSMatthew Dillon     AH9300(ah)->ah_gpio_mask = mask;
564b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), mask & pol_map);
565b7d5e03cSMatthew Dillon 
566b7d5e03cSMatthew Dillon     return 0;
567b7d5e03cSMatthew Dillon }
568b7d5e03cSMatthew Dillon 
569b7d5e03cSMatthew Dillon #ifdef AH_DEBUG
570b7d5e03cSMatthew Dillon void ar9300_gpio_show(struct ath_hal *ah);
ar9300_gpio_show(struct ath_hal * ah)571b7d5e03cSMatthew Dillon void ar9300_gpio_show(struct ath_hal *ah)
572b7d5e03cSMatthew Dillon {
573b7d5e03cSMatthew Dillon     ath_hal_printf(ah, "--- 9382 GPIOs ---(ah=%p)\n", ah );
574b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
575b7d5e03cSMatthew Dillon         "AH9300(_ah)->ah_hostifregs:%p\r\n", &(AH9300(ah)->ah_hostifregs));
576b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
577b7d5e03cSMatthew Dillon         "GPIO_OUT:         0x%08X\n",
578b7d5e03cSMatthew Dillon         OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUT)));
579b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
580b7d5e03cSMatthew Dillon         "GPIO_IN:          0x%08X\n",
581b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN)));
582b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
583b7d5e03cSMatthew Dillon         "GPIO_OE:          0x%08X\n",
584b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT)));
585b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
586b7d5e03cSMatthew Dillon         "GPIO_OE1_OUT:     0x%08X\n",
587b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE1_OUT)));
588b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
589b7d5e03cSMatthew Dillon         "GPIO_INTR_POLAR:  0x%08X\n",
590b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL)));
591b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
592b7d5e03cSMatthew Dillon         "GPIO_INPUT_VALUE: 0x%08X\n",
593b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL)));
594b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
595b7d5e03cSMatthew Dillon         "GPIO_INPUT_MUX1:  0x%08X\n",
596b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_MUX1)));
597b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
598b7d5e03cSMatthew Dillon         "GPIO_INPUT_MUX2:  0x%08X\n",
599b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_MUX2)));
600b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
601b7d5e03cSMatthew Dillon         "GPIO_OUTPUT_MUX1: 0x%08X\n",
602b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1)));
603b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
604b7d5e03cSMatthew Dillon         "GPIO_OUTPUT_MUX2: 0x%08X\n",
605b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX2)));
606b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
607b7d5e03cSMatthew Dillon         "GPIO_OUTPUT_MUX3: 0x%08X\n",
608b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX3)));
609b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
610b7d5e03cSMatthew Dillon         "GPIO_INPUT_STATE: 0x%08X\n",
611b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INPUT_STATE)));
612b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
613b7d5e03cSMatthew Dillon         "GPIO_PDPU:        0x%08X\n",
614b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_PDPU)));
615b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
616b7d5e03cSMatthew Dillon         "GPIO_DS:          0x%08X\n",
617b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_DS)));
618b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
619b7d5e03cSMatthew Dillon         "AR_INTR_ASYNC_ENABLE: 0x%08X\n",
620b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE)));
621b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
622b7d5e03cSMatthew Dillon         "AR_INTR_ASYNC_MASK:   0x%08X\n",
623b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK)));
624b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
625b7d5e03cSMatthew Dillon         "AR_INTR_SYNC_ENABLE:  0x%08X\n",
626b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE)));
627b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
628b7d5e03cSMatthew Dillon         "AR_INTR_SYNC_MASK:    0x%08X\n",
629b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK)));
630b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
631b7d5e03cSMatthew Dillon         "AR_INTR_ASYNC_CAUSE:  0x%08X\n",
632b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE)));
633b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
634b7d5e03cSMatthew Dillon         "AR_INTR_SYNC_CAUSE:   0x%08X\n",
635b7d5e03cSMatthew Dillon          OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)));
636b7d5e03cSMatthew Dillon 
637b7d5e03cSMatthew Dillon }
638b7d5e03cSMatthew Dillon #endif /*AH_DEBUG*/
639