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