ar9300_gpio.c revision 250003
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 21#include "ah.h" 22#include "ah_internal.h" 23#include "ah_devid.h" 24#ifdef AH_DEBUG 25#include "ah_desc.h" /* NB: for HAL_PHYERR* */ 26#endif 27 28#include "ar9300/ar9300.h" 29#include "ar9300/ar9300reg.h" 30#include "ar9300/ar9300phy.h" 31 32#define AR_GPIO_BIT(_gpio) (1 << (_gpio)) 33 34/* 35 * Configure GPIO Output Mux control 36 */ 37#ifdef UMAC_SUPPORT_SMARTANTENNA 38static void ar9340_soc_gpio_cfg_output_mux( 39 struct ath_hal *ah, 40 u_int32_t gpio, 41 u_int32_t ah_signal_type) 42{ 43#define ADDR_READ(addr) (*((volatile u_int32_t *)(addr))) 44#define ADDR_WRITE(addr, b) (void)((*(volatile u_int32_t *) (addr)) = (b)) 45#define AR9340_SOC_GPIO_FUN0 0xB804002c 46#define AR9340_SOC_GPIO_OE 0xB8040000 47#if ATH_SMARTANTENNA_DISABLE_JTAG 48#define AR9340_SOC_GPIO_FUNCTION (volatile u_int32_t*) 0xB804006c 49#define WASP_DISABLE_JTAG 0x2 50#define MAX_JTAG_GPIO_PIN 1 51#endif 52 u_int8_t out_func, shift; 53 u_int32_t flags; 54 volatile u_int32_t* address; 55 56 if (!ah_signal_type){ 57 return; 58 } 59#if ATH_SMARTANTENNA_DISABLE_JTAG 60/* 61 * To use GPIO pins 0 and 1 for controling antennas, JTAG needs to disabled. 62 */ 63 if (gpio <= MAX_JTAG_GPIO_PIN) { 64 flags = ADDR_READ(AR9340_SOC_GPIO_FUNCTION); 65 flags |= WASP_DISABLE_JTAG; 66 ADDR_WRITE(AR9340_SOC_GPIO_FUNCTION, flags); 67 } 68#endif 69 out_func = gpio / 4; 70 shift = (gpio % 4); 71 address = (volatile u_int32_t *)(AR9340_SOC_GPIO_FUN0 + (out_func*4)); 72 73 flags = ADDR_READ(address); 74 flags |= ah_signal_type << (8*shift); 75 ADDR_WRITE(address, flags); 76 flags = ADDR_READ(AR9340_SOC_GPIO_OE); 77 flags &= ~(1 << gpio); 78 ADDR_WRITE(AR9340_SOC_GPIO_OE, flags); 79 80} 81#endif 82 83static void 84ar9300_gpio_cfg_output_mux(struct ath_hal *ah, u_int32_t gpio, u_int32_t type) 85{ 86 int addr; 87 u_int32_t gpio_shift; 88 89 /* each MUX controls 6 GPIO pins */ 90 if (gpio > 11) { 91 addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX3); 92 } else if (gpio > 5) { 93 addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX2); 94 } else { 95 addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1); 96 } 97 98 /* 99 * 5 bits per GPIO pin. 100 * Bits 0..4 for 1st pin in that mux, 101 * bits 5..9 for 2nd pin, etc. 102 */ 103 gpio_shift = (gpio % 6) * 5; 104 105 OS_REG_RMW(ah, addr, (type << gpio_shift), (0x1f << gpio_shift)); 106} 107 108/* 109 * Configure GPIO Output lines 110 */ 111HAL_BOOL 112ar9300_gpio_cfg_output( 113 struct ath_hal *ah, 114 u_int32_t gpio, 115 HAL_GPIO_OUTPUT_MUX_TYPE hal_signal_type) 116{ 117 u_int32_t ah_signal_type; 118 u_int32_t gpio_shift; 119 u_int8_t smart_ant = 0; 120 static const u_int32_t mux_signal_conversion_table[] = { 121 /* HAL_GPIO_OUTPUT_MUX_AS_OUTPUT */ 122 AR_GPIO_OUTPUT_MUX_AS_OUTPUT, 123 /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED */ 124 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED, 125 /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED */ 126 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED, 127 /* HAL_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED */ 128 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED, 129 /* HAL_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED */ 130 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED, 131 /* HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE */ 132 AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL, 133 /* HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME */ 134 AR_GPIO_OUTPUT_MUX_AS_TX_FRAME, 135 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA */ 136 AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA, 137 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK */ 138 AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK, 139 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA */ 140 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA, 141 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK */ 142 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK, 143 /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX */ 144 AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX, 145 /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX */ 146 AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX, 147 /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX */ 148 AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX, 149 /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX */ 150 AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX, 151 /* HAL_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE */ 152 AR_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE, 153 /* HAL_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA */ 154 AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA, 155 /* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0 */ 156 AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0, 157 /* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1 */ 158 AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1, 159 /* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2 */ 160 AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2, 161 /* HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_SWCOM3 */ 162 AR_GPIO_OUTPUT_MUX_AS_SWCOM3, 163 }; 164 165 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins); 166 if ((gpio == AR9382_GPIO_PIN_8_RESERVED) || 167 (gpio == AR9382_GPIO_PIN_11_RESERVED) || 168 (gpio == AR9382_GPIO_9_INPUT_ONLY)) 169 { 170 return AH_FALSE; 171 } 172 173 /* Convert HAL signal type definitions to hardware-specific values. */ 174 if (hal_signal_type < ARRAY_LENGTH(mux_signal_conversion_table)) 175 { 176 ah_signal_type = mux_signal_conversion_table[hal_signal_type]; 177 } else { 178 return AH_FALSE; 179 } 180 181 if (gpio <= AR9382_MAX_JTAG_GPIO_PIN_NUM) { 182 OS_REG_SET_BIT(ah, 183 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE); 184 } 185 186#if UMAC_SUPPORT_SMARTANTENNA 187 /* Get the pin and func values for smart antenna */ 188 switch (ah_signal_type) 189 { 190 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0: 191 gpio = ATH_GPIOPIN_ANTCHAIN0; 192 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN0; 193 smart_ant = 1; 194 break; 195 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1: 196 gpio = ATH_GPIOPIN_ANTCHAIN1; 197 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN1; 198 smart_ant = 1; 199 break; 200 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2: 201 gpio = ATH_GPIOPIN_ANTCHAIN2; 202 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN2; 203 smart_ant = 1; 204 break; 205#if ATH_SMARTANTENNA_ROUTE_SWCOM_TO_GPIO 206 case AR_GPIO_OUTPUT_MUX_AS_SWCOM3: 207 gpio = ATH_GPIOPIN_ROUTE_SWCOM3; 208 ah_signal_type = ATH_GPIOFUNC_ROUTE_SWCOM3; 209 smart_ant = 1; 210 break; 211#endif 212 default: 213 break; 214 } 215#endif 216 217 if (smart_ant && (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah))) 218 { 219#ifdef UMAC_SUPPORT_SMARTANTENNA 220 ar9340_soc_gpio_cfg_output_mux(ah, gpio, ah_signal_type); 221#endif 222 return AH_TRUE; 223 } else 224 { 225 /* Configure the MUX */ 226 ar9300_gpio_cfg_output_mux(ah, gpio, ah_signal_type); 227 } 228 229 /* 2 bits per output mode */ 230 gpio_shift = 2 * gpio; 231 232 OS_REG_RMW(ah, 233 AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT), 234 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), 235 (AR_GPIO_OE_OUT_DRV << gpio_shift)); 236 return AH_TRUE; 237} 238 239/* 240 * Configure GPIO Output lines -LED off 241 */ 242HAL_BOOL 243ar9300_gpio_cfg_output_led_off( 244 struct ath_hal *ah, 245 u_int32_t gpio, 246 HAL_GPIO_OUTPUT_MUX_TYPE halSignalType) 247{ 248#define N(a) (sizeof(a) / sizeof(a[0])) 249 u_int32_t ah_signal_type; 250 u_int32_t gpio_shift; 251 u_int8_t smart_ant = 0; 252 253 static const u_int32_t mux_signal_conversion_table[] = { 254 /* HAL_GPIO_OUTPUT_MUX_AS_OUTPUT */ 255 AR_GPIO_OUTPUT_MUX_AS_OUTPUT, 256 /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED */ 257 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED, 258 /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED */ 259 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED, 260 /* HAL_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED */ 261 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED, 262 /* HAL_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED */ 263 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED, 264 /* HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE */ 265 AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL, 266 /* HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME */ 267 AR_GPIO_OUTPUT_MUX_AS_TX_FRAME, 268 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA */ 269 AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA, 270 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK */ 271 AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK, 272 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA */ 273 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA, 274 /* HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK */ 275 AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK, 276 /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX */ 277 AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX, 278 /* HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX */ 279 AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX, 280 /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX */ 281 AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX, 282 /* HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX */ 283 AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX, 284 AR_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE, 285 AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA, 286 AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0, 287 AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1, 288 AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2 289 }; 290 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins); 291 292 /* Convert HAL signal type definitions to hardware-specific values. */ 293 if (halSignalType < ARRAY_LENGTH(mux_signal_conversion_table)) 294 { 295 ah_signal_type = mux_signal_conversion_table[halSignalType]; 296 } else { 297 return AH_FALSE; 298 } 299#if UMAC_SUPPORT_SMARTANTENNA 300 /* Get the pin and func values for smart antenna */ 301 switch (halSignalType) 302 { 303 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0: 304 gpio = ATH_GPIOPIN_ANTCHAIN0; 305 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN0; 306 smart_ant = 1; 307 break; 308 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1: 309 gpio = ATH_GPIOPIN_ANTCHAIN1; 310 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN1; 311 smart_ant = 1; 312 break; 313 case AR_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2: 314 gpio = ATH_GPIOPIN_ANTCHAIN2; 315 ah_signal_type = ATH_GPIOFUNC_ANTCHAIN2; 316 smart_ant = 1; 317 break; 318 default: 319 break; 320 } 321#endif 322 323 if (smart_ant && AR_SREV_WASP(ah)) 324 { 325 return AH_FALSE; 326 } 327 328 // Configure the MUX 329 ar9300_gpio_cfg_output_mux(ah, gpio, ah_signal_type); 330 331 // 2 bits per output mode 332 gpio_shift = 2*gpio; 333 334 OS_REG_RMW(ah, 335 AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT), 336 (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), 337 (AR_GPIO_OE_OUT_DRV << gpio_shift)); 338 339 return AH_TRUE; 340#undef N 341} 342 343/* 344 * Configure GPIO Input lines 345 */ 346HAL_BOOL 347ar9300_gpio_cfg_input(struct ath_hal *ah, u_int32_t gpio) 348{ 349 u_int32_t gpio_shift; 350 351 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins); 352 if ((gpio == AR9382_GPIO_PIN_8_RESERVED) || 353 (gpio == AR9382_GPIO_PIN_11_RESERVED) || 354 (gpio > AR9382_MAX_GPIO_INPUT_PIN_NUM)) 355 { 356 return AH_FALSE; 357 } 358 359 if (gpio <= AR9382_MAX_JTAG_GPIO_PIN_NUM) { 360 OS_REG_SET_BIT(ah, 361 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE); 362 } 363 /* TODO: configure input mux for AR9300 */ 364 /* If configured as input, set output to tristate */ 365 gpio_shift = 2 * gpio; 366 367 OS_REG_RMW(ah, 368 AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT), 369 (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), 370 (AR_GPIO_OE_OUT_DRV << gpio_shift)); 371 return AH_TRUE; 372} 373 374/* 375 * Once configured for I/O - set output lines 376 * output the level of GPio PIN without care work mode 377 */ 378HAL_BOOL 379ar9300_gpio_set(struct ath_hal *ah, u_int32_t gpio, u_int32_t val) 380{ 381 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins); 382 if ((gpio == AR9382_GPIO_PIN_8_RESERVED) || 383 (gpio == AR9382_GPIO_PIN_11_RESERVED) || 384 (gpio == AR9382_GPIO_9_INPUT_ONLY)) 385 { 386 return AH_FALSE; 387 } 388 OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUT), 389 ((val & 1) << gpio), AR_GPIO_BIT(gpio)); 390 391 return AH_TRUE; 392} 393 394/* 395 * Once configured for I/O - get input lines 396 */ 397u_int32_t 398ar9300_gpio_get(struct ath_hal *ah, u_int32_t gpio) 399{ 400 u_int32_t gpio_in; 401 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins); 402 if ((gpio == AR9382_GPIO_PIN_8_RESERVED) || 403 (gpio == AR9382_GPIO_PIN_11_RESERVED)) 404 { 405 return 0xffffffff; 406 } 407 408 gpio_in = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN)); 409 OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN), 410 (1 << gpio), AR_GPIO_BIT(gpio)); 411 return (MS(gpio_in, AR_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0; 412} 413 414u_int32_t 415ar9300_gpio_get_intr(struct ath_hal *ah) 416{ 417 unsigned int mask = 0; 418 struct ath_hal_9300 *ahp = AH9300(ah); 419 420 mask = ahp->ah_gpio_cause; 421 return mask; 422} 423 424/* 425 * Set the GPIO Interrupt 426 * Sync and Async interrupts are both set/cleared. 427 * Async GPIO interrupts may not be raised when the chip is put to sleep. 428 */ 429void 430ar9300_gpio_set_intr(struct ath_hal *ah, u_int gpio, u_int32_t ilevel) 431{ 432 433 434 int i, reg_bit; 435 u_int32_t reg_val; 436 u_int32_t regs[2], shifts[2]; 437 438#ifdef AH_ASSERT 439 u_int32_t gpio_mask; 440 u_int32_t old_field_val = 0, field_val = 0; 441#endif 442 443#ifdef ATH_GPIO_USE_ASYNC_CAUSE 444 regs[0] = AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE); 445 regs[1] = AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK); 446 shifts[0] = AR_INTR_ASYNC_ENABLE_GPIO_S; 447 shifts[1] = AR_INTR_ASYNC_MASK_GPIO_S; 448#else 449 regs[0] = AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE); 450 regs[1] = AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK); 451 shifts[0] = AR_INTR_SYNC_ENABLE_GPIO_S; 452 shifts[1] = AR_INTR_SYNC_MASK_GPIO_S; 453#endif 454 455 HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins); 456 457 if ((gpio == AR9382_GPIO_PIN_8_RESERVED) || 458 (gpio == AR9382_GPIO_PIN_11_RESERVED) || 459 (gpio > AR9382_MAX_GPIO_INPUT_PIN_NUM)) 460 { 461 return; 462 } 463 464#ifdef AH_ASSERT 465 gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins) - 1; 466#endif 467 468 if (ilevel == HAL_GPIO_INTR_DISABLE) { 469 /* clear this GPIO's bit in the interrupt registers */ 470 for (i = 0; i < ARRAY_LENGTH(regs); i++) { 471 reg_val = OS_REG_READ(ah, regs[i]); 472 reg_bit = shifts[i] + gpio; 473 reg_val &= ~(1 << reg_bit); 474 OS_REG_WRITE(ah, regs[i], reg_val); 475 476 /* check that each register has same GPIOs enabled */ 477#ifdef AH_ASSERT 478 field_val = (reg_val >> shifts[i]) & gpio_mask; 479 HALASSERT(i == 0 || old_field_val == field_val); 480 old_field_val = field_val; 481#endif 482 } 483 484 } else { 485 reg_val = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL)); 486 reg_bit = gpio; 487 if (ilevel == HAL_GPIO_INTR_HIGH) { 488 /* 0 == interrupt on pin high */ 489 reg_val &= ~(1 << reg_bit); 490 } else if (ilevel == HAL_GPIO_INTR_LOW) { 491 /* 1 == interrupt on pin low */ 492 reg_val |= (1 << reg_bit); 493 } 494 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), reg_val); 495 496 /* set this GPIO's bit in the interrupt registers */ 497 for (i = 0; i < ARRAY_LENGTH(regs); i++) { 498 reg_val = OS_REG_READ(ah, regs[i]); 499 reg_bit = shifts[i] + gpio; 500 reg_val |= (1 << reg_bit); 501 OS_REG_WRITE(ah, regs[i], reg_val); 502 503 /* check that each register has same GPIOs enabled */ 504#ifdef AH_ASSERT 505 field_val = (reg_val >> shifts[i]) & gpio_mask; 506 HALASSERT(i == 0 || old_field_val == field_val); 507 old_field_val = field_val; 508#endif 509 } 510 } 511} 512 513u_int32_t 514ar9300_gpio_get_polarity(struct ath_hal *ah) 515{ 516 return OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL)); 517 518} 519 520void 521ar9300_gpio_set_polarity(struct ath_hal *ah, u_int32_t pol_map, 522 u_int32_t changed_mask) 523{ 524 u_int32_t gpio_mask; 525 526 gpio_mask = (1 << AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins) - 1; 527 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), gpio_mask & pol_map); 528 529#ifndef ATH_GPIO_USE_ASYNC_CAUSE 530 /* 531 * For SYNC_CAUSE type interrupts, we need to clear the cause register 532 * explicitly. Otherwise an interrupt with the original polarity setting 533 * will come up immediately (if there is already an interrupt source), 534 * which is not what we want usually. 535 */ 536 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR), 537 changed_mask << AR_INTR_SYNC_ENABLE_GPIO_S); 538 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR)); 539#endif 540} 541 542/* 543 * get the GPIO input pin mask 544 * gpio0 - gpio13 545 * gpio8, gpio11, regard as reserved by the chip ar9382 546 */ 547 548u_int32_t 549ar9300_gpio_get_mask(struct ath_hal *ah) 550{ 551 u_int32_t mask = (1 << (AR9382_MAX_GPIO_INPUT_PIN_NUM + 1) ) - 1; 552 553 if (AH_PRIVATE(ah)->ah_devid == AR9300_DEVID_AR9380_PCIE) { 554 mask = (1 << AR9382_MAX_GPIO_PIN_NUM) - 1; 555 mask &= ~(1 << AR9382_GPIO_PIN_8_RESERVED | 556 1 << AR9382_GPIO_PIN_11_RESERVED); 557 } 558 return mask; 559} 560 561int 562ar9300_gpio_set_mask(struct ath_hal *ah, u_int32_t mask, u_int32_t pol_map) 563{ 564 u_int32_t invalid = ~((1 << (AR9382_MAX_GPIO_INPUT_PIN_NUM + 1)) - 1); 565 566 if (AH_PRIVATE(ah)->ah_devid == AR9300_DEVID_AR9380_PCIE) { 567 invalid = ~((1 << AR9382_MAX_GPIO_PIN_NUM) - 1); 568 invalid |= 1 << AR9382_GPIO_PIN_8_RESERVED | 569 1 << AR9382_GPIO_PIN_11_RESERVED; 570 } 571 if (mask & invalid) { 572 ath_hal_printf(ah, "%s: invalid GPIO mask 0x%x\n", __func__, mask); 573 return -1; 574 } 575 AH9300(ah)->ah_gpio_mask = mask; 576 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL), mask & pol_map); 577 578 return 0; 579} 580 581#ifdef AH_DEBUG 582void ar9300_gpio_show(struct ath_hal *ah); 583void ar9300_gpio_show(struct ath_hal *ah) 584{ 585 ath_hal_printf(ah, "--- 9382 GPIOs ---(ah=%p)\n", ah ); 586 ath_hal_printf(ah, 587 "AH9300(_ah)->ah_hostifregs:%p\r\n", &(AH9300(ah)->ah_hostifregs)); 588 ath_hal_printf(ah, 589 "GPIO_OUT: 0x%08X\n", 590 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUT))); 591 ath_hal_printf(ah, 592 "GPIO_IN: 0x%08X\n", 593 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_IN))); 594 ath_hal_printf(ah, 595 "GPIO_OE: 0x%08X\n", 596 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT))); 597 ath_hal_printf(ah, 598 "GPIO_OE1_OUT: 0x%08X\n", 599 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OE1_OUT))); 600 ath_hal_printf(ah, 601 "GPIO_INTR_POLAR: 0x%08X\n", 602 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INTR_POL))); 603 ath_hal_printf(ah, 604 "GPIO_INPUT_VALUE: 0x%08X\n", 605 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL))); 606 ath_hal_printf(ah, 607 "GPIO_INPUT_MUX1: 0x%08X\n", 608 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_MUX1))); 609 ath_hal_printf(ah, 610 "GPIO_INPUT_MUX2: 0x%08X\n", 611 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_INPUT_MUX2))); 612 ath_hal_printf(ah, 613 "GPIO_OUTPUT_MUX1: 0x%08X\n", 614 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1))); 615 ath_hal_printf(ah, 616 "GPIO_OUTPUT_MUX2: 0x%08X\n", 617 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX2))); 618 ath_hal_printf(ah, 619 "GPIO_OUTPUT_MUX3: 0x%08X\n", 620 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX3))); 621 ath_hal_printf(ah, 622 "GPIO_INPUT_STATE: 0x%08X\n", 623 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INPUT_STATE))); 624 ath_hal_printf(ah, 625 "GPIO_PDPU: 0x%08X\n", 626 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_PDPU))); 627 ath_hal_printf(ah, 628 "GPIO_DS: 0x%08X\n", 629 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_GPIO_DS))); 630 ath_hal_printf(ah, 631 "AR_INTR_ASYNC_ENABLE: 0x%08X\n", 632 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE))); 633 ath_hal_printf(ah, 634 "AR_INTR_ASYNC_MASK: 0x%08X\n", 635 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK))); 636 ath_hal_printf(ah, 637 "AR_INTR_SYNC_ENABLE: 0x%08X\n", 638 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE))); 639 ath_hal_printf(ah, 640 "AR_INTR_SYNC_MASK: 0x%08X\n", 641 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK))); 642 ath_hal_printf(ah, 643 "AR_INTR_ASYNC_CAUSE: 0x%08X\n", 644 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE))); 645 ath_hal_printf(ah, 646 "AR_INTR_SYNC_CAUSE: 0x%08X\n", 647 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE))); 648 649} 650#endif /*AH_DEBUG*/ 651 652#endif /* AH_SUPPORT_AR9300 */ 653