ar9300_gpio.c revision 278762
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 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, 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 */ 239HAL_BOOL 240ar9300_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 */ 343HAL_BOOL 344ar9300_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 */ 374HAL_BOOL 375ar9300_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 */ 392u_int32_t 393ar9300_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 408u_int32_t 409ar9300_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 */ 423void 424ar9300_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 505u_int32_t 506ar9300_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 512void 513ar9300_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 540u_int32_t 541ar9300_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 552int 553ar9300_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 572void ar9300_gpio_show(struct ath_hal *ah); 573void 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