Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_gpio.c
48526 views
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_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
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
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
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
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
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
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
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
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
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
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);
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
642