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
ar9340_soc_gpio_cfg_output_mux(struct ath_hal * ah,u_int32_t gpio,u_int32_t ah_signal_type)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
ar9300_gpio_cfg_output_mux(struct ath_hal * ah,u_int32_t gpio,u_int32_t type)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
ar9300_gpio_cfg_output(struct ath_hal * ah,u_int32_t gpio,HAL_GPIO_MUX_TYPE hal_signal_type)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_9_INPUT_ONLY))
166 {
167 return AH_FALSE;
168 }
169
170 /* Convert HAL signal type definitions to hardware-specific values. */
171 if ((int) hal_signal_type < ARRAY_LENGTH(mux_signal_conversion_table))
172 {
173 ah_signal_type = mux_signal_conversion_table[hal_signal_type];
174 } else {
175 return AH_FALSE;
176 }
177
178 if (gpio <= AR9382_MAX_JTAG_GPIO_PIN_NUM) {
179 OS_REG_SET_BIT(ah,
180 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
181 }
182
183 #if UMAC_SUPPORT_SMARTANTENNA
184 /* Get the pin and func values for smart antenna */
185 switch (ah_signal_type)
186 {
187 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0:
188 gpio = ATH_GPIOPIN_ANTCHAIN0;
189 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN0;
190 smart_ant = 1;
191 break;
192 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1:
193 gpio = ATH_GPIOPIN_ANTCHAIN1;
194 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN1;
195 smart_ant = 1;
196 break;
197 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2:
198 gpio = ATH_GPIOPIN_ANTCHAIN2;
199 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN2;
200 smart_ant = 1;
201 break;
202 #if ATH_SMARTANTENNA_ROUTE_SWCOM_TO_GPIO
203 case AR_GPIO_OUTPUT_MUX_AS_SWCOM3:
204 gpio = ATH_GPIOPIN_ROUTE_SWCOM3;
205 ah_signal_type = ATH_GPIOFUNC_ROUTE_SWCOM3;
206 smart_ant = 1;
207 break;
208 #endif
209 default:
210 break;
211 }
212 #endif
213
214 if (smart_ant && (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)))
215 {
216 #if UMAC_SUPPORT_SMARTANTENNA
217 ar9340_soc_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
218 #endif
219 return AH_TRUE;
220 } else
221 {
222 /* Configure the MUX */
223 ar9300_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
224 }
225
226 /* 2 bits per output mode */
227 gpio_shift = 2 * gpio;
228
229 OS_REG_RMW(ah,
230 AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
231 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
232 (AR_GPIO_OE_OUT_DRV << gpio_shift));
233 return AH_TRUE;
234 }
235
236 /*
237 * Configure GPIO Output lines -LED off
238 */
239 HAL_BOOL
ar9300_gpio_cfg_output_led_off(struct ath_hal * ah,u_int32_t gpio,HAL_GPIO_MUX_TYPE halSignalType)240 ar9300_gpio_cfg_output_led_off(
241 struct ath_hal *ah,
242 u_int32_t gpio,
243 HAL_GPIO_MUX_TYPE halSignalType)
244 {
245 #define N(a) (sizeof(a) / sizeof(a[0]))
246 u_int32_t ah_signal_type;
247 u_int32_t gpio_shift;
248 u_int8_t smart_ant = 0;
249
250 static const u_int32_t mux_signal_conversion_table[] = {
251 /* HAL_GPIO_OUTPUT_MUX_AS_OUTPUT */
252 AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
253 /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED */
254 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
255 /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED */
256 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
257 /* HAL_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED */
258 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
259 /* HAL_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED */
260 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
261 /* HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE */
262 AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL,
263 /* HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME */
264 AR_GPIO_OUTPUT_MUX_AS_TX_FRAME,
265 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA */
266 AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA,
267 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK */
268 AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK,
269 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA */
270 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA,
271 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK */
272 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK,
273 /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX */
274 AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX,
275 /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX */
276 AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX,
277 /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX */
278 AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX,
279 /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX */
280 AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX,
281 AR_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE,
282 AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA,
283 AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0,
284 AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1,
285 AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2
286 };
287 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);
288
289 /* Convert HAL signal type definitions to hardware-specific values. */
290 if ((int) halSignalType < ARRAY_LENGTH(mux_signal_conversion_table))
291 {
292 ah_signal_type = mux_signal_conversion_table[halSignalType];
293 } else {
294 return AH_FALSE;
295 }
296 #if UMAC_SUPPORT_SMARTANTENNA
297 /* Get the pin and func values for smart antenna */
298 switch (halSignalType)
299 {
300 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0:
301 gpio = ATH_GPIOPIN_ANTCHAIN0;
302 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN0;
303 smart_ant = 1;
304 break;
305 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1:
306 gpio = ATH_GPIOPIN_ANTCHAIN1;
307 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN1;
308 smart_ant = 1;
309 break;
310 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2:
311 gpio = ATH_GPIOPIN_ANTCHAIN2;
312 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN2;
313 smart_ant = 1;
314 break;
315 default:
316 break;
317 }
318 #endif
319
320 if (smart_ant && AR_SREV_WASP(ah))
321 {
322 return AH_FALSE;
323 }
324
325 // Configure the MUX
326 ar9300_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
327
328 // 2 bits per output mode
329 gpio_shift = 2*gpio;
330
331 OS_REG_RMW(ah,
332 AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
333 (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
334 (AR_GPIO_OE_OUT_DRV << gpio_shift));
335
336 return AH_TRUE;
337 #undef N
338 }
339
340 /*
341 * Configure GPIO Input lines
342 */
343 HAL_BOOL
ar9300_gpio_cfg_input(struct ath_hal * ah,u_int32_t gpio)344 ar9300_gpio_cfg_input(struct ath_hal *ah, u_int32_t gpio)
345 {
346 u_int32_t gpio_shift;
347
348 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
349 if ((gpio == AR9382_GPIO_PIN_8_RESERVED) ||
350 (gpio > AR9382_MAX_GPIO_INPUT_PIN_NUM))
351 {
352 return AH_FALSE;
353 }
354
355 if (gpio <= AR9382_MAX_JTAG_GPIO_PIN_NUM) {
356 OS_REG_SET_BIT(ah,
357 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
358 }
359 /* TODO: configure input mux for AR9300 */
360 /* If configured as input, set output to tristate */
361 gpio_shift = 2 * gpio;
362
363 OS_REG_RMW(ah,
364 AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
365 (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
366 (AR_GPIO_OE_OUT_DRV << gpio_shift));
367 return AH_TRUE;
368 }
369
370 /*
371 * Once configured for I/O - set output lines
372 * output the level of GPio PIN without care work mode
373 */
374 HAL_BOOL
ar9300_gpio_set(struct ath_hal * ah,u_int32_t gpio,u_int32_t val)375 ar9300_gpio_set(struct ath_hal *ah, u_int32_t gpio, u_int32_t val)
376 {
377 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
378 if ((gpio == AR9382_GPIO_PIN_8_RESERVED) ||
379 (gpio == AR9382_GPIO_9_INPUT_ONLY))
380 {
381 return AH_FALSE;
382 }
383 OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUT),
384 ((val & 1) << gpio), AR_GPIO_BIT(gpio));
385
386 return AH_TRUE;
387 }
388
389 /*
390 * Once configured for I/O - get input lines
391 */
392 u_int32_t
ar9300_gpio_get(struct ath_hal * ah,u_int32_t gpio)393 ar9300_gpio_get(struct ath_hal *ah, u_int32_t gpio)
394 {
395 u_int32_t gpio_in;
396 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
397 if (gpio == AR9382_GPIO_PIN_8_RESERVED)
398 {
399 return 0xffffffff;
400 }
401
402 gpio_in = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN));
403 OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN),
404 (1 << gpio), AR_GPIO_BIT(gpio));
405 return (MS(gpio_in, AR_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
406 }
407
408 u_int32_t
ar9300_gpio_get_intr(struct ath_hal * ah)409 ar9300_gpio_get_intr(struct ath_hal *ah)
410 {
411 unsigned int mask = 0;
412 struct ath_hal_9300 *ahp = AH9300(ah);
413
414 mask = ahp->ah_gpio_cause;
415 return mask;
416 }
417
418 /*
419 * Set the GPIO Interrupt
420 * Sync and Async interrupts are both set/cleared.
421 * Async GPIO interrupts may not be raised when the chip is put to sleep.
422 */
423 void
ar9300_gpio_set_intr(struct ath_hal * ah,u_int gpio,u_int32_t ilevel)424 ar9300_gpio_set_intr(struct ath_hal *ah, u_int gpio, u_int32_t ilevel)
425 {
426
427
428 int i, reg_bit;
429 u_int32_t reg_val;
430 u_int32_t regs[2], shifts[2];
431
432 #ifdef AH_ASSERT
433 u_int32_t gpio_mask;
434 u_int32_t old_field_val = 0, field_val = 0;
435 #endif
436
437 #ifdef ATH_GPIO_USE_ASYNC_CAUSE
438 regs[0] = AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE);
439 regs[1] = AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK);
440 shifts[0] = AR_INTR_ASYNC_ENABLE_GPIO_S;
441 shifts[1] = AR_INTR_ASYNC_MASK_GPIO_S;
442 #else
443 regs[0] = AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE);
444 regs[1] = AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK);
445 shifts[0] = AR_INTR_SYNC_ENABLE_GPIO_S;
446 shifts[1] = AR_INTR_SYNC_MASK_GPIO_S;
447 #endif
448
449 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
450
451 if ((gpio == AR9382_GPIO_PIN_8_RESERVED) ||
452 (gpio > AR9382_MAX_GPIO_INPUT_PIN_NUM))
453 {
454 return;
455 }
456
457 #ifdef AH_ASSERT
458 gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.halNumGpioPins) - 1;
459 #endif
460 if (ilevel == HAL_GPIO_INTR_DISABLE) {
461 /* clear this GPIO's bit in the interrupt registers */
462 for (i = 0; i < ARRAY_LENGTH(regs); i++) {
463 reg_val = OS_REG_READ(ah, regs[i]);
464 reg_bit = shifts[i] + gpio;
465 reg_val &= ~(1 << reg_bit);
466 OS_REG_WRITE(ah, regs[i], reg_val);
467
468 /* check that each register has same GPIOs enabled */
469 #ifdef AH_ASSERT
470 field_val = (reg_val >> shifts[i]) & gpio_mask;
471 HALASSERT(i == 0 || old_field_val == field_val);
472 old_field_val = field_val;
473 #endif
474 }
475
476 } else {
477 reg_val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL));
478 reg_bit = gpio;
479 if (ilevel == HAL_GPIO_INTR_HIGH) {
480 /* 0 == interrupt on pin high */
481 reg_val &= ~(1 << reg_bit);
482 } else if (ilevel == HAL_GPIO_INTR_LOW) {
483 /* 1 == interrupt on pin low */
484 reg_val |= (1 << reg_bit);
485 }
486 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), reg_val);
487
488 /* set this GPIO's bit in the interrupt registers */
489 for (i = 0; i < ARRAY_LENGTH(regs); i++) {
490 reg_val = OS_REG_READ(ah, regs[i]);
491 reg_bit = shifts[i] + gpio;
492 reg_val |= (1 << reg_bit);
493 OS_REG_WRITE(ah, regs[i], reg_val);
494
495 /* check that each register has same GPIOs enabled */
496 #ifdef AH_ASSERT
497 field_val = (reg_val >> shifts[i]) & gpio_mask;
498 HALASSERT(i == 0 || old_field_val == field_val);
499 old_field_val = field_val;
500 #endif
501 }
502 }
503 }
504
505 u_int32_t
ar9300_gpio_get_polarity(struct ath_hal * ah)506 ar9300_gpio_get_polarity(struct ath_hal *ah)
507 {
508 return OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL));
509
510 }
511
512 void
ar9300_gpio_set_polarity(struct ath_hal * ah,u_int32_t pol_map,u_int32_t changed_mask)513 ar9300_gpio_set_polarity(struct ath_hal *ah, u_int32_t pol_map,
514 u_int32_t changed_mask)
515 {
516 u_int32_t gpio_mask;
517
518 gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.halNumGpioPins) - 1;
519 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), gpio_mask & pol_map);
520
521 #ifndef ATH_GPIO_USE_ASYNC_CAUSE
522 /*
523 * For SYNC_CAUSE type interrupts, we need to clear the cause register
524 * explicitly. Otherwise an interrupt with the original polarity setting
525 * will come up immediately (if there is already an interrupt source),
526 * which is not what we want usually.
527 */
528 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR),
529 changed_mask << AR_INTR_SYNC_ENABLE_GPIO_S);
530 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR));
531 #endif
532 }
533
534 /*
535 * get the GPIO input pin mask
536 * gpio0 - gpio13
537 * gpio8, gpio11, regard as reserved by the chip ar9382
538 */
539
540 u_int32_t
ar9300_gpio_get_mask(struct ath_hal * ah)541 ar9300_gpio_get_mask(struct ath_hal *ah)
542 {
543 u_int32_t mask = (1 << (AR9382_MAX_GPIO_INPUT_PIN_NUM + 1) ) - 1;
544
545 if (AH_PRIVATE(ah)->ah_devid == AR9300_DEVID_AR9380_PCIE) {
546 mask = (1 << AR9382_MAX_GPIO_PIN_NUM) - 1;
547 mask &= ~(1 << AR9382_GPIO_PIN_8_RESERVED);
548 }
549 return mask;
550 }
551
552 int
ar9300_gpio_set_mask(struct ath_hal * ah,u_int32_t mask,u_int32_t pol_map)553 ar9300_gpio_set_mask(struct ath_hal *ah, u_int32_t mask, u_int32_t pol_map)
554 {
555 u_int32_t invalid = ~((1 << (AR9382_MAX_GPIO_INPUT_PIN_NUM + 1)) - 1);
556
557 if (AH_PRIVATE(ah)->ah_devid == AR9300_DEVID_AR9380_PCIE) {
558 invalid = ~((1 << AR9382_MAX_GPIO_PIN_NUM) - 1);
559 invalid |= 1 << AR9382_GPIO_PIN_8_RESERVED;
560 }
561 if (mask & invalid) {
562 ath_hal_printf(ah, "%s: invalid GPIO mask 0x%x\n", __func__, mask);
563 return -1;
564 }
565 AH9300(ah)->ah_gpio_mask = mask;
566 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), mask & pol_map);
567
568 return 0;
569 }
570
571 #ifdef AH_DEBUG
572 void ar9300_gpio_show(struct ath_hal *ah);
ar9300_gpio_show(struct ath_hal * ah)573 void ar9300_gpio_show(struct ath_hal *ah)
574 {
575 ath_hal_printf(ah, "--- 9382 GPIOs ---(ah=%p)\n", ah );
576 ath_hal_printf(ah,
577 "AH9300(_ah)->ah_hostifregs:%p\r\n", &(AH9300(ah)->ah_hostifregs));
578 ath_hal_printf(ah,
579 "GPIO_OUT: 0x%08X\n",
580 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUT)));
581 ath_hal_printf(ah,
582 "GPIO_IN: 0x%08X\n",
583 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN)));
584 ath_hal_printf(ah,
585 "GPIO_OE: 0x%08X\n",
586 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT)));
587 ath_hal_printf(ah,
588 "GPIO_OE1_OUT: 0x%08X\n",
589 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE1_OUT)));
590 ath_hal_printf(ah,
591 "GPIO_INTR_POLAR: 0x%08X\n",
592 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL)));
593 ath_hal_printf(ah,
594 "GPIO_INPUT_VALUE: 0x%08X\n",
595 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL)));
596 ath_hal_printf(ah,
597 "GPIO_INPUT_MUX1: 0x%08X\n",
598 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_MUX1)));
599 ath_hal_printf(ah,
600 "GPIO_INPUT_MUX2: 0x%08X\n",
601 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_MUX2)));
602 ath_hal_printf(ah,
603 "GPIO_OUTPUT_MUX1: 0x%08X\n",
604 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1)));
605 ath_hal_printf(ah,
606 "GPIO_OUTPUT_MUX2: 0x%08X\n",
607 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX2)));
608 ath_hal_printf(ah,
609 "GPIO_OUTPUT_MUX3: 0x%08X\n",
610 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX3)));
611 ath_hal_printf(ah,
612 "GPIO_INPUT_STATE: 0x%08X\n",
613 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INPUT_STATE)));
614 ath_hal_printf(ah,
615 "GPIO_PDPU: 0x%08X\n",
616 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_PDPU)));
617 ath_hal_printf(ah,
618 "GPIO_DS: 0x%08X\n",
619 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_DS)));
620 ath_hal_printf(ah,
621 "AR_INTR_ASYNC_ENABLE: 0x%08X\n",
622 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE)));
623 ath_hal_printf(ah,
624 "AR_INTR_ASYNC_MASK: 0x%08X\n",
625 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK)));
626 ath_hal_printf(ah,
627 "AR_INTR_SYNC_ENABLE: 0x%08X\n",
628 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE)));
629 ath_hal_printf(ah,
630 "AR_INTR_SYNC_MASK: 0x%08X\n",
631 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK)));
632 ath_hal_printf(ah,
633 "AR_INTR_ASYNC_CAUSE: 0x%08X\n",
634 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE)));
635 ath_hal_printf(ah,
636 "AR_INTR_SYNC_CAUSE: 0x%08X\n",
637 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)));
638
639 }
640 #endif /*AH_DEBUG*/
641