Beispiel #1
0
/*
 * Once configured for I/O - set output lines
 */
HAL_BOOL
ar9300GpioSet(struct ath_hal *ah, u_int32_t gpio, u_int32_t val)
{
    HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);

    OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUT), ((val&1) << gpio), AR_GPIO_BIT(gpio));

    return AH_TRUE;
}
Beispiel #2
0
/*
 * Once configured for I/O - set output lines
 */
HAL_BOOL
ar7010GpioSet(struct ath_hal *ah, u_int32_t gpio, u_int32_t val)
{
    HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);

    OS_REG_RMW(ah, AR7010_GPIO_OUT, ((val&1) << gpio), AR_GPIO_BIT(gpio));

    return AH_TRUE;
}
Beispiel #3
0
/*
 * Configure GPIO Output lines
 */
HAL_BOOL
ar9300GpioCfgOutput(
    struct ath_hal *ah,
    u_int32_t gpio,
    HAL_GPIO_OUTPUT_MUX_TYPE halSignalType)
{
#define N(a)    (sizeof(a) / sizeof(a[0]))
#ifndef AR9340_EMULATION
    u_int32_t    ah_signal_type;
    u_int32_t    gpio_shift;

    static const u_int32_t    MuxSignalConversionTable[] = {
        /* HAL_GPIO_OUTPUT_MUX_AS_OUTPUT             */
        AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
        /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED */
        AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
        /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     */
        AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
        /* HAL_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    */
        AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
        /* HAL_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      */
        AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
        /* HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE        */
        AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL,
        /* HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME           */
        AR_GPIO_OUTPUT_MUX_AS_TX_FRAME,
    };

    HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);

    // Convert HAL signal type definitions to hardware-specific values.
    if ((halSignalType >= 0) && (halSignalType < N(MuxSignalConversionTable)))
    {
        ah_signal_type = MuxSignalConversionTable[halSignalType];
    }
    else
    {
        return AH_FALSE;
    }

    // Configure the MUX
    ar9300GpioCfgOutputMux(ah, gpio, ah_signal_type);

    // 2 bits per output mode
    gpio_shift = 2*gpio;

    OS_REG_RMW(ah,
               AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
               (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
               (AR_GPIO_OE_OUT_DRV << gpio_shift));

#endif
    return AH_TRUE;
#undef N
}
Beispiel #4
0
/*
 * Write 16 bits of data from data to the specified EEPROM offset.
 */
HAL_BOOL
ar5416EepromWrite(struct ath_hal *ah, u_int off, u_int16_t data)
{
    u_int32_t status;
    u_int32_t write_to = 50000;      /* write timeout */
    u_int32_t eepromValue;

    eepromValue = (u_int32_t)data & 0xffff;

    /* Setup EEPROM device to write */
    OS_REG_RMW(ah, AR_GPIO_OUTPUT_MUX1, 0, 0x1f << 15);   /* Mux GPIO-3 as GPIO */
    OS_DELAY(1);
    OS_REG_RMW(ah, AR_GPIO_OE_OUT, 0xc0, 0xc0);     /* Configure GPIO-3 as output */
    OS_DELAY(1);
    OS_REG_RMW(ah, AR_GPIO_IN_OUT, 0, 1 << 3);       /* drive GPIO-3 low */
    OS_DELAY(1);

    /* Send write data, as 32 bit data */
    OS_REG_WRITE(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S), eepromValue);

    /* check busy bit to see if eeprom write succeeded */
    while (write_to > 0) {
        status = OS_REG_READ(ah, AR_EEPROM_STATUS_DATA) &
                                    (AR_EEPROM_STATUS_DATA_BUSY |
                                     AR_EEPROM_STATUS_DATA_BUSY_ACCESS |
                                     AR_EEPROM_STATUS_DATA_PROT_ACCESS |
                                     AR_EEPROM_STATUS_DATA_ABSENT_ACCESS);
        if (status == 0) {
            OS_REG_RMW(ah, AR_GPIO_IN_OUT, 1<<3, 1<<3);       /* drive GPIO-3 hi */
            return AH_TRUE;
        }
        OS_DELAY(1);
        write_to--;
    }

    OS_REG_RMW(ah, AR_GPIO_IN_OUT, 1<<3, 1<<3);       /* drive GPIO-3 hi */
    return AH_FALSE;
}
static void
ar9300_setup_test_addac_mode(struct ath_hal *ah)
{
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
    /* byteswap Rx/Tx buffer to ensure correct layout */
    HDPRINTF(ah, HAL_DBG_RF_PARAM,
        "%s: big endian - set AR_CFG_SWTB/AR_CFG_SWRB\n", 
             __func__);
    OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0);
#else
    /* Rx/Tx buffer should not be byteswaped */
    if (OS_REG_READ(ah, AR_CFG) & (AR_CFG_SWTB | AR_CFG_SWRB)) {
        HDPRINTF(ah, HAL_DBG_UNMASKABLE, 
            "%s: **WARNING: little endian but AR_CFG_SWTB/AR_CFG_SWRB set!\n", 
            __func__);
    }
#endif

    OS_REG_WRITE(ah, AR_PHY_TEST, 0);
    OS_REG_WRITE(ah, AR_PHY_TEST_CTL_STATUS, 0);

    /* cf_bbb_obs_sel=4'b0001 */
    OS_REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 0x1);

    /* cf_rx_obs_sel=5'b00000, this is the 5th bit */
    OS_REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);

    /* cf_tx_obs_sel=3'b111 */
    OS_REG_RMW_FIELD(
        ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_TX_OBS_SEL, 0x7);

    /* cf_tx_obs_mux_sel=2'b11 */
    OS_REG_RMW_FIELD(
        ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_TX_OBS_MUX_SEL, 0x3);

    /* enable TSTADC */
    OS_REG_SET_BIT(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_TSTDAC_EN);

    /* cf_rx_obs_sel=5'b00000, these are the first 4 bits */
    OS_REG_RMW_FIELD(
        ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0x0);

    /* tstdac_out_sel=2'b01 */
    OS_REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_CHAIN_SEL, 0x1);
}
Beispiel #6
0
/*
 * Configure GPIO Output Mux control
 */
static void
cfgOutputMux(struct ath_hal *ah, uint32_t gpio, uint32_t type)
{
	int addr;
	uint32_t gpio_shift, tmp;

	HALDEBUG(ah, HAL_DEBUG_GPIO, "%s: gpio=%d, type=%d\n",
	    __func__, gpio, type);

	/* each MUX controls 6 GPIO pins */
	if (gpio > 11)
		addr = AR_GPIO_OUTPUT_MUX3;
	else if (gpio > 5)
		addr = AR_GPIO_OUTPUT_MUX2;
	else
		addr = AR_GPIO_OUTPUT_MUX1;

	/*
	 * 5 bits per GPIO pin. Bits 0..4 for 1st pin in that mux,
	 * bits 5..9 for 2nd pin, etc.
	 */
	gpio_shift = (gpio % 6) * 5;

	/*
	 * From Owl to Merlin 1.0, the value read from MUX1 bit 4 to bit
	 * 9 are wrong.  Here is hardware's coding:
	 * PRDATA[4:0] <= gpio_output_mux[0];
	 * PRDATA[9:4] <= gpio_output_mux[1];
	 *	<==== Bit 4 is used by both gpio_output_mux[0] [1].
	 * Currently the max value for gpio_output_mux[] is 6. So bit 4
	 * will never be used.  So it should be fine that bit 4 won't be
	 * able to recover.
	 */
	if (AR_SREV_MERLIN_20_OR_LATER(ah) ||
	    (addr != AR_GPIO_OUTPUT_MUX1)) {
		OS_REG_RMW(ah, addr, (type << gpio_shift),
		    (0x1f << gpio_shift));
	} else {
		tmp = OS_REG_READ(ah, addr);
		tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
		tmp &= ~(0x1f << gpio_shift);
		tmp |= type << gpio_shift;
		OS_REG_WRITE(ah, addr, tmp);
	}
}
Beispiel #7
0
/*
 * Configure GPIO Input lines
 */
HAL_BOOL
ar7010GpioCfgInput(struct ath_hal *ah, u_int32_t gpio)
{
    u_int32_t    gpio_shift;

    HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);

    /* If configured as input, set output to tristate */
    gpio_shift = gpio;

    /* Per bit output enable. 1: enable the input driver */
    OS_REG_RMW(ah, 
               AR7010_GPIO_OE, 
               (AR7010_GPIO_OE_AS_INPUT << gpio_shift), 
               (AR7010_GPIO_OE_MASK << gpio_shift));

    return AH_TRUE;
}
Beispiel #8
0
/*
 * Configure GPIO Input lines
 */
HAL_BOOL
ar5416GpioCfgInput(struct ath_hal *ah, u_int32_t gpio)
{
    u_int32_t    gpio_shift;

    HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);

    /* TODO: configure input mux for AR5416 */
    /* If configured as input, set output to tristate */
    gpio_shift = 2*gpio;

    OS_REG_RMW(ah, 
               AR_GPIO_OE_OUT, 
               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), 
               (AR_GPIO_OE_OUT_DRV << gpio_shift));

    return AH_TRUE;
}
Beispiel #9
0
/*
 * Configure GPIO Input lines
 */
HAL_BOOL
ar9300GpioCfgInput(struct ath_hal *ah, u_int32_t gpio)
{
#ifndef AR9340_EMULATION
    u_int32_t    gpio_shift;

    HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);

    /* TODO: configure input mux for AR9300 */
    /* If configured as input, set output to tristate */
    gpio_shift = 2*gpio;

    OS_REG_RMW(ah,
               AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
               (AR_GPIO_OE_OUT_DRV << gpio_shift));

#endif
    return AH_TRUE;
}
Beispiel #10
0
/*
 * Configure GPIO Output Mux control
 */
static void
ar5416GpioCfgOutputMux(struct ath_hal *ah, u_int32_t gpio, u_int32_t type)
{
    int          addr;
    u_int32_t    gpio_shift, tmp;

    // each MUX controls 6 GPIO pins
    if (gpio > 11) {
        addr = AR_GPIO_OUTPUT_MUX3;
    } else if (gpio > 5) {
        addr = AR_GPIO_OUTPUT_MUX2;
    } else {
        addr = AR_GPIO_OUTPUT_MUX1;
    }

    // 5 bits per GPIO pin. Bits 0..4 for 1st pin in that mux, bits 5..9 for 2nd pin, etc.
    gpio_shift = (gpio % 6) * 5;

    /*
     * From Owl to Merlin 1.0, the value read from MUX1 bit 4 to bit 9 are wrong.
     * Here is hardware's coding:
     * PRDATA[4:0] <= gpio_output_mux[0];
     * PRDATA[9:4] <= gpio_output_mux[1]; <==== Bit 4 is used by both gpio_output_mux[0] [1].
     * Currently the max value for gpio_output_mux[] is 6. So bit 4 will never be used.
     * So it should be fine that bit 4 won't be able to recover.
     */

    if (AR_SREV_MERLIN_20_OR_LATER(ah) || (addr != AR_GPIO_OUTPUT_MUX1)) {
        OS_REG_RMW(ah, addr, (type << gpio_shift), (0x1f << gpio_shift));
    }
    else {
        tmp = OS_REG_READ(ah, addr);
        tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
        tmp &= ~(0x1f << gpio_shift);
        tmp |= (type << gpio_shift);
        OS_REG_WRITE(ah, addr, tmp);
    }
}
Beispiel #11
0
/*
 * Configure GPIO Output lines
 */
HAL_BOOL
ar7010GpioCfgOutput(struct ath_hal *ah, u_int32_t gpio, HAL_GPIO_OUTPUT_MUX_TYPE halSignalType)
{
    u_int32_t    gpio_shift;

    HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.hal_num_gpio_pins);

    /* Magpie only support GPIO normal output */
    if (halSignalType > HAL_GPIO_OUTPUT_MUX_AS_OUTPUT)
    {
        return AH_FALSE;
    }

    /* 1 bits per output mode */
    gpio_shift = gpio;

    /* Per bit output enable. 0: enable the output driver */
    OS_REG_RMW(ah, 
               AR7010_GPIO_OE, 
               (AR7010_GPIO_OE_AS_OUTPUT<< gpio_shift), 
               (AR7010_GPIO_OE_MASK << gpio_shift));

    return AH_TRUE;
}
Beispiel #12
0
static void
ar9300GpioCfgOutputMux(struct ath_hal *ah, u_int32_t gpio, u_int32_t type)
{
    int          addr;
    u_int32_t    gpio_shift;

    // each MUX controls 6 GPIO pins
    if (gpio > 11) {
        addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX3);
    } else if (gpio > 5) {
        addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX2);
    } else {
        addr = AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1);
    }

    /*
     * 5 bits per GPIO pin.
     * Bits 0..4 for 1st pin in that mux,
     * bits 5..9 for 2nd pin, etc.
     */
    gpio_shift = (gpio % 6) * 5;

    OS_REG_RMW(ah, addr, (type << gpio_shift), (0x1f << gpio_shift));
}
Beispiel #13
0
/*
 * This is specific to Kite.
 *
 * Kiwi and others don't have antenna diversity like this.
 */
void
ar9285BTCoexAntennaDiversity(struct ath_hal *ah)
{
    struct ath_hal_5416 *ahp = AH5416(ah);
    u_int32_t regVal;
    u_int8_t ant_div_control1, ant_div_control2;

    if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ALLOW) ||
            (AH5212(ah)->ah_diversity != HAL_ANT_VARIABLE)) {
        if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ENABLE) &&
                (AH5212(ah)->ah_diversity == HAL_ANT_VARIABLE)) {
            /* Enable antenna diversity */
            ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_ENABLE;
            ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_ENABLE;

            /* Don't disable BT ant to allow BB to control SWCOM */
            ahp->ah_btCoexMode2 &= (~(AR_BT_DISABLE_BT_ANT));
            OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);

            /* Program the correct SWCOM table */
            OS_REG_WRITE(ah, AR_PHY_SWITCH_COM,
                         HAL_BT_COEX_ANT_DIV_SWITCH_COM);
            OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
        } else if (AH5212(ah)->ah_diversity == HAL_ANT_FIXED_B) {
            /* Disable antenna diversity. Use antenna B(LNA2) only. */
            ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_B;
            ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_B;

            /* Disable BT ant to allow concurrent BT and WLAN receive */
            ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT;
            OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);

            /* Program SWCOM talbe to make sure RF switch always parks at WLAN side */
            OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, HAL_BT_COEX_ANT_DIV_SWITCH_COM);
            OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0x60000000, 0xf0000000);
        } else {
            /* Disable antenna diversity. Use antenna A(LNA1) only */
            ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_A;
            ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_A;

            /* Disable BT ant to allow concurrent BT and WLAN receive */
            ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT;
            OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);

            /* Program SWCOM talbe to make sure RF switch always parks at BT side */
            OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0);
            OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
        }

        regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
        regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
        /* Clear ant_fast_div_bias [14:9] since for Janus the main LNA is always LNA1. */
        regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS));

        regVal |= SM(ant_div_control1, AR_PHY_9285_ANT_DIV_CTL);
        regVal |= SM(ant_div_control2, AR_PHY_9285_ANT_DIV_ALT_LNACONF);
        regVal |= SM((ant_div_control2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
        regVal |= SM((ant_div_control1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB);
        regVal |= SM((ant_div_control1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
        OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);

        regVal = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
        regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
        regVal |= SM((ant_div_control1 >> 3), AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
        OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
    }
}