Deleted Added
full compact
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#ifdef AH_SUPPORT_AR9300
20
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 */
37#ifdef UMAC_SUPPORT_SMARTANTENNA
35#if UMAC_SUPPORT_SMARTANTENNA
36static 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
81static void
82ar9300_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 */
109HAL_BOOL
110ar9300_gpio_cfg_output(
111 struct ath_hal *ah,
112 u_int32_t gpio,
115 HAL_GPIO_OUTPUT_MUX_TYPE hal_signal_type)
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
165 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);
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. */
174 if (hal_signal_type < ARRAY_LENGTH(mux_signal_conversion_table))
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 {
219#ifdef UMAC_SUPPORT_SMARTANTENNA
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 */
240HAL_BOOL
241ar9300_gpio_cfg_output_led_off(
242 struct ath_hal *ah,
243 u_int32_t gpio,
246 HAL_GPIO_OUTPUT_MUX_TYPE halSignalType)
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. */
293 if (halSignalType < ARRAY_LENGTH(mux_signal_conversion_table))
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 */
344HAL_BOOL
345ar9300_gpio_cfg_input(struct ath_hal *ah, u_int32_t gpio)
346{
347 u_int32_t gpio_shift;
348
351 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);
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 */
376HAL_BOOL
377ar9300_gpio_set(struct ath_hal *ah, u_int32_t gpio, u_int32_t val)
378{
381 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);
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 */
395u_int32_t
396ar9300_gpio_get(struct ath_hal *ah, u_int32_t gpio)
397{
398 u_int32_t gpio_in;
401 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);
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
412u_int32_t
413ar9300_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 */
427void
428ar9300_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
455 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);
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
465 gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins) - 1;
463 gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.halNumGpioPins) - 1;
464#endif
467
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
510u_int32_t
511ar9300_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
517void
518ar9300_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
526 gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins) - 1;
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
545u_int32_t
546ar9300_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
558int
559ar9300_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
579void ar9300_gpio_show(struct ath_hal *ah);
580void 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*/
651
652#endif /* AH_SUPPORT_AR9300 */