ar9300_gpio.c revision 250008
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_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 */ 240HAL_BOOL 241ar9300_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 */ 344HAL_BOOL 345ar9300_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 */ 376HAL_BOOL 377ar9300_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 */ 395u_int32_t 396ar9300_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 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 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 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 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*/ 648