The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/ath/ath_hal/ar9300/ar9300_gpio.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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*/

Cache object: fcfb08c7142256e6e77eff1b8c1beba8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.