xref: /freebsd/sys/dev/ath/ath_hal/ar5416/ar5416_btcoex.c (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1*6e778a7eSPedro F. Giffuni /*-
2*6e778a7eSPedro F. Giffuni  * SPDX-License-Identifier: ISC
3*6e778a7eSPedro F. Giffuni  *
46479ef78SAdrian Chadd  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
56479ef78SAdrian Chadd  * Copyright (c) 2002-2005 Atheros Communications, Inc.
66479ef78SAdrian Chadd  * Copyright (c) 2008-2010, Atheros Communications Inc.
76479ef78SAdrian Chadd  *
86479ef78SAdrian Chadd  * Permission to use, copy, modify, and/or distribute this software for any
96479ef78SAdrian Chadd  * purpose with or without fee is hereby granted, provided that the above
106479ef78SAdrian Chadd  * copyright notice and this permission notice appear in all copies.
116479ef78SAdrian Chadd  *
126479ef78SAdrian Chadd  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
136479ef78SAdrian Chadd  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
146479ef78SAdrian Chadd  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
156479ef78SAdrian Chadd  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
166479ef78SAdrian Chadd  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
176479ef78SAdrian Chadd  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
186479ef78SAdrian Chadd  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
196479ef78SAdrian Chadd  */
206479ef78SAdrian Chadd 
216479ef78SAdrian Chadd #include "opt_ah.h"
226479ef78SAdrian Chadd 
236479ef78SAdrian Chadd #include "ah.h"
246479ef78SAdrian Chadd #include "ah_internal.h"
256479ef78SAdrian Chadd #include "ah_devid.h"
266479ef78SAdrian Chadd #ifdef	AH_DEBUG
276479ef78SAdrian Chadd #include "ah_desc.h"                    /* NB: for HAL_PHYERR* */
286479ef78SAdrian Chadd #endif
296479ef78SAdrian Chadd 
306479ef78SAdrian Chadd #include "ar5416/ar5416.h"
316479ef78SAdrian Chadd #include "ar5416/ar5416reg.h"
326479ef78SAdrian Chadd #include "ar5416/ar5416phy.h"
336479ef78SAdrian Chadd #include "ar5416/ar5416desc.h" /* AR5416_CONTTXMODE */
346479ef78SAdrian Chadd #include "ar5416/ar5416_btcoex.h"
356479ef78SAdrian Chadd 
366479ef78SAdrian Chadd void
ar5416SetBTCoexInfo(struct ath_hal * ah,HAL_BT_COEX_INFO * btinfo)376479ef78SAdrian Chadd ar5416SetBTCoexInfo(struct ath_hal *ah, HAL_BT_COEX_INFO *btinfo)
386479ef78SAdrian Chadd {
396479ef78SAdrian Chadd 	struct ath_hal_5416 *ahp = AH5416(ah);
406479ef78SAdrian Chadd 
416479ef78SAdrian Chadd 	ahp->ah_btModule = btinfo->bt_module;
426479ef78SAdrian Chadd 	ahp->ah_btCoexConfigType = btinfo->bt_coex_config;
436479ef78SAdrian Chadd 	ahp->ah_btActiveGpioSelect = btinfo->bt_gpio_bt_active;
446479ef78SAdrian Chadd 	ahp->ah_btPriorityGpioSelect = btinfo->bt_gpio_bt_priority;
456479ef78SAdrian Chadd 	ahp->ah_wlanActiveGpioSelect = btinfo->bt_gpio_wlan_active;
466479ef78SAdrian Chadd 	ahp->ah_btActivePolarity = btinfo->bt_active_polarity;
476479ef78SAdrian Chadd 	ahp->ah_btCoexSingleAnt = btinfo->bt_single_ant;
486479ef78SAdrian Chadd 	ahp->ah_btWlanIsolation = btinfo->bt_isolation;
496479ef78SAdrian Chadd }
506479ef78SAdrian Chadd 
516479ef78SAdrian Chadd void
ar5416BTCoexConfig(struct ath_hal * ah,HAL_BT_COEX_CONFIG * btconf)526479ef78SAdrian Chadd ar5416BTCoexConfig(struct ath_hal *ah, HAL_BT_COEX_CONFIG *btconf)
536479ef78SAdrian Chadd {
546479ef78SAdrian Chadd 	struct ath_hal_5416 *ahp = AH5416(ah);
556479ef78SAdrian Chadd 	HAL_BOOL rxClearPolarity = btconf->bt_rxclear_polarity;
566479ef78SAdrian Chadd 
576479ef78SAdrian Chadd 	/*
586479ef78SAdrian Chadd 	 * For Kiwi and Osprey, the polarity of rx_clear is active high.
596479ef78SAdrian Chadd 	 * The bt_rxclear_polarity flag from ath(4) needs to be inverted.
606479ef78SAdrian Chadd 	 */
616479ef78SAdrian Chadd 	if (AR_SREV_KIWI(ah)) {
626479ef78SAdrian Chadd 		rxClearPolarity = !btconf->bt_rxclear_polarity;
636479ef78SAdrian Chadd 	}
646479ef78SAdrian Chadd 
656479ef78SAdrian Chadd 	ahp->ah_btCoexMode = (ahp->ah_btCoexMode & AR_BT_QCU_THRESH) |
666479ef78SAdrian Chadd 	    SM(btconf->bt_time_extend, AR_BT_TIME_EXTEND) |
676479ef78SAdrian Chadd 	    SM(btconf->bt_txstate_extend, AR_BT_TXSTATE_EXTEND) |
686479ef78SAdrian Chadd 	    SM(btconf->bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
696479ef78SAdrian Chadd 	    SM(btconf->bt_mode, AR_BT_MODE) |
706479ef78SAdrian Chadd 	    SM(btconf->bt_quiet_collision, AR_BT_QUIET) |
716479ef78SAdrian Chadd 	    SM(rxClearPolarity, AR_BT_RX_CLEAR_POLARITY) |
726479ef78SAdrian Chadd 	    SM(btconf->bt_priority_time, AR_BT_PRIORITY_TIME) |
736479ef78SAdrian Chadd 	    SM(btconf->bt_first_slot_time, AR_BT_FIRST_SLOT_TIME);
746479ef78SAdrian Chadd 
756479ef78SAdrian Chadd 	ahp->ah_btCoexMode2 |= SM(btconf->bt_hold_rxclear,
766479ef78SAdrian Chadd 	    AR_BT_HOLD_RX_CLEAR);
776479ef78SAdrian Chadd 
786479ef78SAdrian Chadd 	if (ahp->ah_btCoexSingleAnt == AH_FALSE) {
796479ef78SAdrian Chadd 		/* Enable ACK to go out even though BT has higher priority. */
806479ef78SAdrian Chadd 		ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT;
816479ef78SAdrian Chadd 	}
826479ef78SAdrian Chadd }
836479ef78SAdrian Chadd 
846479ef78SAdrian Chadd void
ar5416BTCoexSetQcuThresh(struct ath_hal * ah,int qnum)856479ef78SAdrian Chadd ar5416BTCoexSetQcuThresh(struct ath_hal *ah, int qnum)
866479ef78SAdrian Chadd {
876479ef78SAdrian Chadd 	struct ath_hal_5416 *ahp = AH5416(ah);
886479ef78SAdrian Chadd 
896479ef78SAdrian Chadd 	ahp->ah_btCoexMode |= SM(qnum, AR_BT_QCU_THRESH);
906479ef78SAdrian Chadd }
916479ef78SAdrian Chadd 
926479ef78SAdrian Chadd void
ar5416BTCoexSetWeights(struct ath_hal * ah,u_int32_t stompType)936479ef78SAdrian Chadd ar5416BTCoexSetWeights(struct ath_hal *ah, u_int32_t stompType)
946479ef78SAdrian Chadd {
956479ef78SAdrian Chadd 	struct ath_hal_5416 *ahp = AH5416(ah);
966479ef78SAdrian Chadd 
976479ef78SAdrian Chadd 	if (AR_SREV_KIWI_10_OR_LATER(ah)) {
98f6b6084bSPedro F. Giffuni 		/* TODO: TX RX separate is not enabled. */
996479ef78SAdrian Chadd 		switch (stompType) {
1008132a45dSAdrian Chadd 		case HAL_BT_COEX_STOMP_AUDIO:
1018132a45dSAdrian Chadd 			/* XXX TODO */
1026479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_ALL:
1036479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1046479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight = AR5416_STOMP_ALL_WLAN_WGHT;
1056479ef78SAdrian Chadd 			break;
1066479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_LOW:
1076479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1086479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight = AR5416_STOMP_LOW_WLAN_WGHT;
1096479ef78SAdrian Chadd 			break;
1106479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_ALL_FORCE:
1116479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1126479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight =
1136479ef78SAdrian Chadd 			    AR5416_STOMP_ALL_FORCE_WLAN_WGHT;
1146479ef78SAdrian Chadd 			break;
1156479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_LOW_FORCE:
1166479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1176479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight =
1186479ef78SAdrian Chadd 			    AR5416_STOMP_LOW_FORCE_WLAN_WGHT;
1196479ef78SAdrian Chadd 			break;
1206479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_NONE:
1216479ef78SAdrian Chadd 		case HAL_BT_COEX_NO_STOMP:
1226479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1236479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight = AR5416_STOMP_NONE_WLAN_WGHT;
1246479ef78SAdrian Chadd 			break;
1256479ef78SAdrian Chadd 		default:
1266479ef78SAdrian Chadd 			/* There is a forceWeight from registry */
1276479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = stompType & 0xffff;
1286479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight = stompType >> 16;
1296479ef78SAdrian Chadd 			break;
1306479ef78SAdrian Chadd 		}
1316479ef78SAdrian Chadd 	} else {
1326479ef78SAdrian Chadd 		switch (stompType) {
1338132a45dSAdrian Chadd 		case HAL_BT_COEX_STOMP_AUDIO:
1348132a45dSAdrian Chadd 			/* XXX TODO */
1356479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_ALL:
1366479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1376479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight = AR5416_STOMP_ALL_WLAN_WGHT;
1386479ef78SAdrian Chadd 			break;
1396479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_LOW:
1406479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1416479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight = AR5416_STOMP_LOW_WLAN_WGHT;
1426479ef78SAdrian Chadd 			break;
1436479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_ALL_FORCE:
1446479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1456479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight =
1466479ef78SAdrian Chadd 			    AR5416_STOMP_ALL_FORCE_WLAN_WGHT;
1476479ef78SAdrian Chadd 			break;
1486479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_LOW_FORCE:
1496479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1506479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight =
1516479ef78SAdrian Chadd 			    AR5416_STOMP_LOW_FORCE_WLAN_WGHT;
1526479ef78SAdrian Chadd 			break;
1536479ef78SAdrian Chadd 		case HAL_BT_COEX_STOMP_NONE:
1546479ef78SAdrian Chadd 		case HAL_BT_COEX_NO_STOMP:
1556479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = AR5416_BT_WGHT;
1566479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight = AR5416_STOMP_NONE_WLAN_WGHT;
1576479ef78SAdrian Chadd 			break;
1586479ef78SAdrian Chadd 		default:
1596479ef78SAdrian Chadd 			/* There is a forceWeight from registry */
1606479ef78SAdrian Chadd 			ahp->ah_btCoexBTWeight = stompType & 0xffff;
1616479ef78SAdrian Chadd 			ahp->ah_btCoexWLANWeight = stompType >> 16;
1626479ef78SAdrian Chadd 			break;
1636479ef78SAdrian Chadd 		}
1646479ef78SAdrian Chadd 	}
1656479ef78SAdrian Chadd }
1666479ef78SAdrian Chadd 
1676479ef78SAdrian Chadd void
ar5416BTCoexSetupBmissThresh(struct ath_hal * ah,u_int32_t thresh)1686479ef78SAdrian Chadd ar5416BTCoexSetupBmissThresh(struct ath_hal *ah, u_int32_t thresh)
1696479ef78SAdrian Chadd {
1706479ef78SAdrian Chadd 	struct ath_hal_5416 *ahp = AH5416(ah);
1716479ef78SAdrian Chadd 
1726479ef78SAdrian Chadd 	ahp->ah_btCoexMode2 |= SM(thresh, AR_BT_BCN_MISS_THRESH);
1736479ef78SAdrian Chadd }
1746479ef78SAdrian Chadd 
1756479ef78SAdrian Chadd /*
1766479ef78SAdrian Chadd  * There is no antenna diversity for Owl, Kiwi, etc.
1776479ef78SAdrian Chadd  *
1786479ef78SAdrian Chadd  * Kite will override this particular method.
1796479ef78SAdrian Chadd  */
180e89812c3SAdrian Chadd void
ar5416BTCoexAntennaDiversity(struct ath_hal * ah)1816479ef78SAdrian Chadd ar5416BTCoexAntennaDiversity(struct ath_hal *ah)
1826479ef78SAdrian Chadd {
1836479ef78SAdrian Chadd }
1846479ef78SAdrian Chadd 
1856479ef78SAdrian Chadd void
ar5416BTCoexSetParameter(struct ath_hal * ah,u_int32_t type,u_int32_t value)1866479ef78SAdrian Chadd ar5416BTCoexSetParameter(struct ath_hal *ah, u_int32_t type, u_int32_t value)
1876479ef78SAdrian Chadd {
1886479ef78SAdrian Chadd 	struct ath_hal_5416 *ahp = AH5416(ah);
1896479ef78SAdrian Chadd 
1906479ef78SAdrian Chadd 	switch (type) {
1916479ef78SAdrian Chadd 	case HAL_BT_COEX_SET_ACK_PWR:
1926479ef78SAdrian Chadd 		if (value) {
1936479ef78SAdrian Chadd 			ahp->ah_btCoexFlag |= HAL_BT_COEX_FLAG_LOW_ACK_PWR;
1946479ef78SAdrian Chadd 			OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_LOW_ACK_POWER);
1956479ef78SAdrian Chadd 		} else {
1966479ef78SAdrian Chadd 			ahp->ah_btCoexFlag &= ~HAL_BT_COEX_FLAG_LOW_ACK_PWR;
1976479ef78SAdrian Chadd 			OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_HIGH_ACK_POWER);
1986479ef78SAdrian Chadd 		}
1996479ef78SAdrian Chadd 		break;
2006479ef78SAdrian Chadd 	case HAL_BT_COEX_ANTENNA_DIVERSITY:
2016479ef78SAdrian Chadd 		/* This is overridden for Kite */
2026479ef78SAdrian Chadd 		break;
2036479ef78SAdrian Chadd #if 0
2046479ef78SAdrian Chadd         case HAL_BT_COEX_LOWER_TX_PWR:
2056479ef78SAdrian Chadd             if (value) {
2066479ef78SAdrian Chadd                 if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) == 0) {
2076479ef78SAdrian Chadd                     ahp->ah_btCoexFlag |= HAL_BT_COEX_FLAG_LOWER_TX_PWR;
2086479ef78SAdrian Chadd 		    AH_PRIVATE(ah)->ah_config.ath_hal_desc_tpc = 1;
2096479ef78SAdrian Chadd                     ar5416SetTxPowerLimit(ah, AH_PRIVATE(ah)->ah_power_limit, AH_PRIVATE(ah)->ah_extra_txpow, 0);
2106479ef78SAdrian Chadd                 }
2116479ef78SAdrian Chadd             }
2126479ef78SAdrian Chadd             else {
2136479ef78SAdrian Chadd                 if (ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) {
2146479ef78SAdrian Chadd                     ahp->ah_btCoexFlag &= ~HAL_BT_COEX_FLAG_LOWER_TX_PWR;
2156479ef78SAdrian Chadd 		    AH_PRIVATE(ah)->ah_config.ath_hal_desc_tpc = 0;
2166479ef78SAdrian Chadd                     ar5416SetTxPowerLimit(ah, AH_PRIVATE(ah)->ah_power_limit, AH_PRIVATE(ah)->ah_extra_txpow, 0);
2176479ef78SAdrian Chadd                 }
2186479ef78SAdrian Chadd             }
2196479ef78SAdrian Chadd             break;
2206479ef78SAdrian Chadd #endif
2216479ef78SAdrian Chadd 	default:
2226479ef78SAdrian Chadd 			break;
2236479ef78SAdrian Chadd 	}
2246479ef78SAdrian Chadd }
2256479ef78SAdrian Chadd 
2266479ef78SAdrian Chadd void
ar5416BTCoexDisable(struct ath_hal * ah)2276479ef78SAdrian Chadd ar5416BTCoexDisable(struct ath_hal *ah)
2286479ef78SAdrian Chadd {
2296479ef78SAdrian Chadd 	struct ath_hal_5416 *ahp = AH5416(ah);
2306479ef78SAdrian Chadd 
2316479ef78SAdrian Chadd 	/* Always drive rx_clear_external output as 0 */
2326479ef78SAdrian Chadd 	ar5416GpioSet(ah, ahp->ah_wlanActiveGpioSelect, 0);
2336479ef78SAdrian Chadd 	ar5416GpioCfgOutput(ah, ahp->ah_wlanActiveGpioSelect,
2346479ef78SAdrian Chadd 	    HAL_GPIO_OUTPUT_MUX_AS_OUTPUT);
2356479ef78SAdrian Chadd 
2366479ef78SAdrian Chadd 	if (AR_SREV_9271(ah)) {
2376479ef78SAdrian Chadd 		/*
2386479ef78SAdrian Chadd 		 * Set wlanActiveGpio to input when disabling BT-COEX to
2396479ef78SAdrian Chadd 		 * reduce power consumption
2406479ef78SAdrian Chadd 		 */
2416479ef78SAdrian Chadd 		ar5416GpioCfgInput(ah, ahp->ah_wlanActiveGpioSelect);
2426479ef78SAdrian Chadd 	}
2436479ef78SAdrian Chadd 
2446479ef78SAdrian Chadd 	if (ahp->ah_btCoexSingleAnt == AH_TRUE) {
2456479ef78SAdrian Chadd 		OS_REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE,
2466479ef78SAdrian Chadd 		    1);
2476479ef78SAdrian Chadd 		OS_REG_RMW_FIELD(ah, AR_MISC_MODE, AR_PCU_BT_ANT_PREVENT_RX,
2486479ef78SAdrian Chadd 		    0);
2496479ef78SAdrian Chadd 	}
2506479ef78SAdrian Chadd 
2516479ef78SAdrian Chadd 	OS_REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
2526479ef78SAdrian Chadd 	OS_REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
2536479ef78SAdrian Chadd 	if (AR_SREV_KIWI_10_OR_LATER(ah))
2546479ef78SAdrian Chadd 		OS_REG_WRITE(ah, AR_BT_COEX_WEIGHT2, 0);
2556479ef78SAdrian Chadd 	OS_REG_WRITE(ah, AR_BT_COEX_MODE2, 0);
2566479ef78SAdrian Chadd 
2576479ef78SAdrian Chadd 	ahp->ah_btCoexEnabled = AH_FALSE;
2586479ef78SAdrian Chadd }
2596479ef78SAdrian Chadd 
2606479ef78SAdrian Chadd int
ar5416BTCoexEnable(struct ath_hal * ah)2616479ef78SAdrian Chadd ar5416BTCoexEnable(struct ath_hal *ah)
2626479ef78SAdrian Chadd {
2636479ef78SAdrian Chadd 	struct ath_hal_5416 *ahp = AH5416(ah);
2646479ef78SAdrian Chadd 
2656479ef78SAdrian Chadd 	/* Program coex mode and weight registers to actually enable coex */
2666479ef78SAdrian Chadd 	OS_REG_WRITE(ah, AR_BT_COEX_MODE, ahp->ah_btCoexMode);
2676479ef78SAdrian Chadd 	OS_REG_WRITE(ah, AR_BT_COEX_WEIGHT,
2686479ef78SAdrian Chadd 	    SM(ahp->ah_btCoexWLANWeight & 0xFFFF, AR_BT_WL_WGHT) |
2696479ef78SAdrian Chadd 	    SM(ahp->ah_btCoexBTWeight & 0xFFFF, AR_BT_BT_WGHT));
2706479ef78SAdrian Chadd 	if (AR_SREV_KIWI_10_OR_LATER(ah)) {
2716479ef78SAdrian Chadd 	OS_REG_WRITE(ah, AR_BT_COEX_WEIGHT2,
2726479ef78SAdrian Chadd 	    SM(ahp->ah_btCoexWLANWeight >> 16, AR_BT_WL_WGHT));
2736479ef78SAdrian Chadd 	}
2746479ef78SAdrian Chadd 	OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);
2756479ef78SAdrian Chadd 
2766479ef78SAdrian Chadd 	/* Added Select GPIO5~8 instaed SPI */
2776479ef78SAdrian Chadd 	if (AR_SREV_9271(ah)) {
278978c5ce5SAdrian Chadd 		uint32_t val;
279978c5ce5SAdrian Chadd 
2806479ef78SAdrian Chadd 		val = OS_REG_READ(ah, AR9271_CLOCK_CONTROL);
2816479ef78SAdrian Chadd 		val &= 0xFFFFFEFF;
2826479ef78SAdrian Chadd 		OS_REG_WRITE(ah, AR9271_CLOCK_CONTROL, val);
2836479ef78SAdrian Chadd 	}
2846479ef78SAdrian Chadd 
2856479ef78SAdrian Chadd 	if (ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_LOW_ACK_PWR)
2866479ef78SAdrian Chadd 		OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_LOW_ACK_POWER);
2876479ef78SAdrian Chadd 	else
2886479ef78SAdrian Chadd 		OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_HIGH_ACK_POWER);
2896479ef78SAdrian Chadd 
2906479ef78SAdrian Chadd 	if (ahp->ah_btCoexSingleAnt == AH_TRUE) {
2916479ef78SAdrian Chadd 		OS_REG_RMW_FIELD(ah, AR_QUIET1,
2926479ef78SAdrian Chadd 		    AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
2936479ef78SAdrian Chadd 		/* XXX should update miscMode? */
2946479ef78SAdrian Chadd 		OS_REG_RMW_FIELD(ah, AR_MISC_MODE,
2956479ef78SAdrian Chadd 		    AR_PCU_BT_ANT_PREVENT_RX, 1);
2966479ef78SAdrian Chadd 	} else {
2976479ef78SAdrian Chadd 		OS_REG_RMW_FIELD(ah, AR_QUIET1,
2986479ef78SAdrian Chadd 		    AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
2996479ef78SAdrian Chadd 		/* XXX should update miscMode? */
3006479ef78SAdrian Chadd 		OS_REG_RMW_FIELD(ah, AR_MISC_MODE,
3016479ef78SAdrian Chadd 		    AR_PCU_BT_ANT_PREVENT_RX, 0);
3026479ef78SAdrian Chadd 	}
3036479ef78SAdrian Chadd 
3046479ef78SAdrian Chadd 	if (ahp->ah_btCoexConfigType == HAL_BT_COEX_CFG_3WIRE) {
3056479ef78SAdrian Chadd 		/* For 3-wire, configure the desired GPIO port for rx_clear */
3066479ef78SAdrian Chadd 		ar5416GpioCfgOutput(ah, ahp->ah_wlanActiveGpioSelect,
3076479ef78SAdrian Chadd 		    HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE);
3086479ef78SAdrian Chadd 	} else {
3096479ef78SAdrian Chadd 		/*
3106479ef78SAdrian Chadd 		 * For 2-wire, configure the desired GPIO port
3116479ef78SAdrian Chadd 		 * for TX_FRAME output
3126479ef78SAdrian Chadd 		 */
3136479ef78SAdrian Chadd 		ar5416GpioCfgOutput(ah, ahp->ah_wlanActiveGpioSelect,
3146479ef78SAdrian Chadd 		    HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME);
3156479ef78SAdrian Chadd 	}
3166479ef78SAdrian Chadd 
3176479ef78SAdrian Chadd 	/*
3186479ef78SAdrian Chadd 	 * Enable a weak pull down on BT_ACTIVE.
3196479ef78SAdrian Chadd 	 * When BT device is disabled, BT_ACTIVE might be floating.
3206479ef78SAdrian Chadd 	 */
3216479ef78SAdrian Chadd 	OS_REG_RMW(ah, AR_GPIO_PDPU,
3226479ef78SAdrian Chadd 	    (0x2 << (ahp->ah_btActiveGpioSelect * 2)),
3236479ef78SAdrian Chadd 	    (0x3 << (ahp->ah_btActiveGpioSelect * 2)));
3246479ef78SAdrian Chadd 
3256479ef78SAdrian Chadd 	ahp->ah_btCoexEnabled = AH_TRUE;
3266479ef78SAdrian Chadd 
3276479ef78SAdrian Chadd 	return (0);
3286479ef78SAdrian Chadd }
3296479ef78SAdrian Chadd 
3306479ef78SAdrian Chadd void
ar5416InitBTCoex(struct ath_hal * ah)3316479ef78SAdrian Chadd ar5416InitBTCoex(struct ath_hal *ah)
3326479ef78SAdrian Chadd {
3336479ef78SAdrian Chadd 	struct ath_hal_5416 *ahp = AH5416(ah);
3346479ef78SAdrian Chadd 
3350c20aadbSAdrian Chadd 	HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3360c20aadbSAdrian Chadd 	    "%s: called; configType=%d\n",
3370c20aadbSAdrian Chadd 	    __func__,
3380c20aadbSAdrian Chadd 	    ahp->ah_btCoexConfigType);
3390c20aadbSAdrian Chadd 
3406479ef78SAdrian Chadd 	if (ahp->ah_btCoexConfigType == HAL_BT_COEX_CFG_3WIRE) {
3416479ef78SAdrian Chadd 		OS_REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
3426479ef78SAdrian Chadd 		    (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
3436479ef78SAdrian Chadd 		    AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB));
3446479ef78SAdrian Chadd 
3456479ef78SAdrian Chadd 		/*
3466479ef78SAdrian Chadd 		 * Set input mux for bt_prority_async and
3476479ef78SAdrian Chadd 		 * bt_active_async to GPIO pins
3486479ef78SAdrian Chadd 		 */
3496479ef78SAdrian Chadd 		OS_REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
3506479ef78SAdrian Chadd 		    AR_GPIO_INPUT_MUX1_BT_ACTIVE,
3516479ef78SAdrian Chadd 		    ahp->ah_btActiveGpioSelect);
3526479ef78SAdrian Chadd 		OS_REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
3536479ef78SAdrian Chadd 		    AR_GPIO_INPUT_MUX1_BT_PRIORITY,
3546479ef78SAdrian Chadd 		    ahp->ah_btPriorityGpioSelect);
3556479ef78SAdrian Chadd 
3566479ef78SAdrian Chadd 		/*
3576479ef78SAdrian Chadd 		 * Configure the desired GPIO ports for input
3586479ef78SAdrian Chadd 		 */
3596479ef78SAdrian Chadd 		ar5416GpioCfgInput(ah, ahp->ah_btActiveGpioSelect);
3606479ef78SAdrian Chadd 		ar5416GpioCfgInput(ah, ahp->ah_btPriorityGpioSelect);
3616479ef78SAdrian Chadd 
362e89812c3SAdrian Chadd 		/*
363e89812c3SAdrian Chadd 		 * Configure the antenna diversity setup.
364e89812c3SAdrian Chadd 		 * It's a no-op for AR9287; AR9285 overrides this
365e89812c3SAdrian Chadd 		 * as required.
366e89812c3SAdrian Chadd 		 */
367e89812c3SAdrian Chadd 		AH5416(ah)->ah_btCoexSetDiversity(ah);
3686479ef78SAdrian Chadd 
3696479ef78SAdrian Chadd 		if (ahp->ah_btCoexEnabled)
3706479ef78SAdrian Chadd 			ar5416BTCoexEnable(ah);
3716479ef78SAdrian Chadd 		else
3726479ef78SAdrian Chadd 			ar5416BTCoexDisable(ah);
3736479ef78SAdrian Chadd 	} else if (ahp->ah_btCoexConfigType != HAL_BT_COEX_CFG_NONE) {
3746479ef78SAdrian Chadd 		/* 2-wire */
3756479ef78SAdrian Chadd 		if (ahp->ah_btCoexEnabled) {
3766479ef78SAdrian Chadd 			/* Connect bt_active_async to baseband */
3776479ef78SAdrian Chadd 			OS_REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
3786479ef78SAdrian Chadd 			    (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
3796479ef78SAdrian Chadd 			     AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
3806479ef78SAdrian Chadd 			OS_REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
3816479ef78SAdrian Chadd 			    AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
3826479ef78SAdrian Chadd 
3836479ef78SAdrian Chadd 			/*
3846479ef78SAdrian Chadd 			 * Set input mux for bt_prority_async and
3856479ef78SAdrian Chadd 			 * bt_active_async to GPIO pins
3866479ef78SAdrian Chadd 			 */
3876479ef78SAdrian Chadd 			OS_REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
3886479ef78SAdrian Chadd 			    AR_GPIO_INPUT_MUX1_BT_ACTIVE,
3896479ef78SAdrian Chadd                             ahp->ah_btActiveGpioSelect);
3906479ef78SAdrian Chadd 
3916479ef78SAdrian Chadd 			/* Configure the desired GPIO ports for input */
3926479ef78SAdrian Chadd 			ar5416GpioCfgInput(ah, ahp->ah_btActiveGpioSelect);
3936479ef78SAdrian Chadd 
3946479ef78SAdrian Chadd 			/* Enable coexistence on initialization */
3956479ef78SAdrian Chadd 			ar5416BTCoexEnable(ah);
3966479ef78SAdrian Chadd 		}
3976479ef78SAdrian Chadd 	}
3986479ef78SAdrian Chadd }
399