ar9285_btcoex.c revision 243841
1205354Simp/* 2205354Simp * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 3205354Simp * Copyright (c) 2002-2005 Atheros Communications, Inc. 4205354Simp * Copyright (c) 2008-2010, Atheros Communications Inc. 5205354Simp * 6205354Simp * Permission to use, copy, modify, and/or distribute this software for any 7205354Simp * purpose with or without fee is hereby granted, provided that the above 8205354Simp * copyright notice and this permission notice appear in all copies. 9205354Simp * 10205354Simp * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11205354Simp * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12205354Simp * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13205354Simp * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14205354Simp * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15205354Simp * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16205354Simp * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17205354Simp * 18272103Sgavin * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c 243841 2012-12-04 00:01:24Z adrian $ 19205354Simp */ 20205354Simp 21205354Simp#include "opt_ah.h" 22283327Sian 23283327Sian#include "ah.h" 24205354Simp#include "ah_internal.h" 25205354Simp#include "ah_devid.h" 26205354Simp#ifdef AH_DEBUG 27205354Simp#include "ah_desc.h" /* NB: for HAL_PHYERR* */ 28205354Simp#endif 29205354Simp 30205354Simp#include "ar5416/ar5416.h" 31205354Simp#include "ar5416/ar5416reg.h" 32205354Simp#include "ar5416/ar5416phy.h" 33205354Simp#include "ar5416/ar5416desc.h" /* AR5416_CONTTXMODE */ 34205354Simp 35205354Simp#include "ar9002/ar9285phy.h" 36205354Simp#include "ar9002/ar9285.h" 37205354Simp 38205354Simp/* 39205354Simp * This is specific to Kite. 40205354Simp * 41205354Simp * Kiwi and others don't have antenna diversity like this. 42205354Simp */ 43205354Simpvoid 44205354Simpar9285BTCoexAntennaDiversity(struct ath_hal *ah) 45205354Simp{ 46205354Simp struct ath_hal_5416 *ahp = AH5416(ah); 47205354Simp u_int32_t regVal; 48205354Simp u_int8_t ant_div_control1, ant_div_control2; 49205354Simp 50205354Simp if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ALLOW) || 51205354Simp (AH5212(ah)->ah_diversity != HAL_ANT_VARIABLE)) { 52205354Simp if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ENABLE) && 53205354Simp (AH5212(ah)->ah_diversity == HAL_ANT_VARIABLE)) { 54205354Simp /* Enable antenna diversity */ 55205354Simp ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_ENABLE; 56205354Simp ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_ENABLE; 57205354Simp 58205354Simp /* Don't disable BT ant to allow BB to control SWCOM */ 59205354Simp ahp->ah_btCoexMode2 &= (~(AR_BT_DISABLE_BT_ANT)); 60205354Simp OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2); 61 62 /* Program the correct SWCOM table */ 63 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 64 HAL_BT_COEX_ANT_DIV_SWITCH_COM); 65 OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000); 66 } else if (AH5212(ah)->ah_diversity == HAL_ANT_FIXED_B) { 67 /* Disable antenna diversity. Use antenna B(LNA2) only. */ 68 ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_B; 69 ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_B; 70 71 /* Disable BT ant to allow concurrent BT and WLAN receive */ 72 ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT; 73 OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2); 74 75 /* 76 * Program SWCOM table to make sure RF switch always parks 77 * at WLAN side 78 */ 79 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 80 HAL_BT_COEX_ANT_DIV_SWITCH_COM); 81 OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0x60000000, 0xf0000000); 82 } else { 83 /* Disable antenna diversity. Use antenna A(LNA1) only */ 84 ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_A; 85 ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_A; 86 87 /* Disable BT ant to allow concurrent BT and WLAN receive */ 88 ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT; 89 OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2); 90 91 /* 92 * Program SWCOM table to make sure RF switch always 93 * parks at BT side 94 */ 95 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0); 96 OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000); 97 } 98 99 regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 100 regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL)); 101 /* 102 * Clear ant_fast_div_bias [14:9] since for Janus the main LNA is 103 * always LNA1. 104 */ 105 regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS)); 106 107 regVal |= SM(ant_div_control1, AR_PHY_9285_ANT_DIV_CTL); 108 regVal |= SM(ant_div_control2, AR_PHY_9285_ANT_DIV_ALT_LNACONF); 109 regVal |= SM((ant_div_control2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF); 110 regVal |= SM((ant_div_control1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB); 111 regVal |= SM((ant_div_control1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB); 112 OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal); 113 114 regVal = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 115 regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 116 regVal |= SM((ant_div_control1 >> 3), 117 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 118 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal); 119 } 120} 121 122void 123ar9285BTCoexSetParameter(struct ath_hal *ah, u_int32_t type, u_int32_t value) 124{ 125 struct ath_hal_5416 *ahp = AH5416(ah); 126 127 switch (type) { 128 case HAL_BT_COEX_ANTENNA_DIVERSITY: 129 if (AR_SREV_KITE(ah)) { 130 ahp->ah_btCoexFlag |= HAL_BT_COEX_FLAG_ANT_DIV_ALLOW; 131 if (value) 132 ahp->ah_btCoexFlag |= 133 HAL_BT_COEX_FLAG_ANT_DIV_ENABLE; 134 else 135 ahp->ah_btCoexFlag &= 136 ~HAL_BT_COEX_FLAG_ANT_DIV_ENABLE; 137 ar9285BTCoexAntennaDiversity(ah); 138 } 139 break; 140 default: 141 ar5416BTCoexSetParameter(ah, type, value); 142 break; 143 } 144} 145 146 147