ar9285_btcoex.c revision 237611
1237611Sadrian/* 2237611Sadrian * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 3237611Sadrian * Copyright (c) 2002-2005 Atheros Communications, Inc. 4237611Sadrian * Copyright (c) 2008-2010, Atheros Communications Inc. 5237611Sadrian * 6237611Sadrian * Permission to use, copy, modify, and/or distribute this software for any 7237611Sadrian * purpose with or without fee is hereby granted, provided that the above 8237611Sadrian * copyright notice and this permission notice appear in all copies. 9237611Sadrian * 10237611Sadrian * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11237611Sadrian * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12237611Sadrian * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13237611Sadrian * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14237611Sadrian * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15237611Sadrian * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16237611Sadrian * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17237611Sadrian * 18237611Sadrian * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c 237611 2012-06-26 22:16:53Z adrian $ 19237611Sadrian */ 20237611Sadrian 21237611Sadrian#include "opt_ah.h" 22237611Sadrian 23237611Sadrian#include "ah.h" 24237611Sadrian#include "ah_internal.h" 25237611Sadrian#include "ah_devid.h" 26237611Sadrian#ifdef AH_DEBUG 27237611Sadrian#include "ah_desc.h" /* NB: for HAL_PHYERR* */ 28237611Sadrian#endif 29237611Sadrian 30237611Sadrian#include "ar5416/ar5416.h" 31237611Sadrian#include "ar5416/ar5416reg.h" 32237611Sadrian#include "ar5416/ar5416phy.h" 33237611Sadrian#include "ar5416/ar5416desc.h" /* AR5416_CONTTXMODE */ 34237611Sadrian 35237611Sadrian#include "ar9002/ar9285phy.h" 36237611Sadrian#include "ar9002/ar9285.h" 37237611Sadrian 38237611Sadrian/* 39237611Sadrian * This is specific to Kite. 40237611Sadrian * 41237611Sadrian * Kiwi and others don't have antenna diversity like this. 42237611Sadrian */ 43237611Sadrianvoid 44237611Sadrianar9285BTCoexAntennaDiversity(struct ath_hal *ah) 45237611Sadrian{ 46237611Sadrian struct ath_hal_5416 *ahp = AH5416(ah); 47237611Sadrian u_int32_t regVal; 48237611Sadrian u_int8_t ant_div_control1, ant_div_control2; 49237611Sadrian 50237611Sadrian if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ALLOW) || 51237611Sadrian (AH5212(ah)->ah_diversity != HAL_ANT_VARIABLE)) { 52237611Sadrian if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ENABLE) && 53237611Sadrian (AH5212(ah)->ah_diversity == HAL_ANT_VARIABLE)) { 54237611Sadrian /* Enable antenna diversity */ 55237611Sadrian ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_ENABLE; 56237611Sadrian ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_ENABLE; 57237611Sadrian 58237611Sadrian /* Don't disable BT ant to allow BB to control SWCOM */ 59237611Sadrian ahp->ah_btCoexMode2 &= (~(AR_BT_DISABLE_BT_ANT)); 60237611Sadrian OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2); 61237611Sadrian 62237611Sadrian /* Program the correct SWCOM table */ 63237611Sadrian OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 64237611Sadrian HAL_BT_COEX_ANT_DIV_SWITCH_COM); 65237611Sadrian OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000); 66237611Sadrian } else if (AH5212(ah)->ah_diversity == HAL_ANT_FIXED_B) { 67237611Sadrian /* Disable antenna diversity. Use antenna B(LNA2) only. */ 68237611Sadrian ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_B; 69237611Sadrian ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_B; 70237611Sadrian 71237611Sadrian /* Disable BT ant to allow concurrent BT and WLAN receive */ 72237611Sadrian ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT; 73237611Sadrian OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2); 74237611Sadrian 75237611Sadrian /* Program SWCOM talbe to make sure RF switch always parks at WLAN side */ 76237611Sadrian OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, HAL_BT_COEX_ANT_DIV_SWITCH_COM); 77237611Sadrian OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0x60000000, 0xf0000000); 78237611Sadrian } else { 79237611Sadrian /* Disable antenna diversity. Use antenna A(LNA1) only */ 80237611Sadrian ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_A; 81237611Sadrian ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_A; 82237611Sadrian 83237611Sadrian /* Disable BT ant to allow concurrent BT and WLAN receive */ 84237611Sadrian ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT; 85237611Sadrian OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2); 86237611Sadrian 87237611Sadrian /* Program SWCOM talbe to make sure RF switch always parks at BT side */ 88237611Sadrian OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0); 89237611Sadrian OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000); 90237611Sadrian } 91237611Sadrian 92237611Sadrian regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 93237611Sadrian regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL)); 94237611Sadrian /* Clear ant_fast_div_bias [14:9] since for Janus the main LNA is always LNA1. */ 95237611Sadrian regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS)); 96237611Sadrian 97237611Sadrian regVal |= SM(ant_div_control1, AR_PHY_9285_ANT_DIV_CTL); 98237611Sadrian regVal |= SM(ant_div_control2, AR_PHY_9285_ANT_DIV_ALT_LNACONF); 99237611Sadrian regVal |= SM((ant_div_control2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF); 100237611Sadrian regVal |= SM((ant_div_control1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB); 101237611Sadrian regVal |= SM((ant_div_control1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB); 102237611Sadrian OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal); 103237611Sadrian 104237611Sadrian regVal = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 105237611Sadrian regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 106237611Sadrian regVal |= SM((ant_div_control1 >> 3), AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 107237611Sadrian OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal); 108237611Sadrian } 109237611Sadrian} 110237611Sadrian 111237611Sadrianvoid 112237611Sadrianar9285BTCoexSetParameter(struct ath_hal *ah, u_int32_t type, u_int32_t value) 113237611Sadrian{ 114237611Sadrian struct ath_hal_5416 *ahp = AH5416(ah); 115237611Sadrian 116237611Sadrian switch (type) { 117237611Sadrian case HAL_BT_COEX_ANTENNA_DIVERSITY: 118237611Sadrian if (AR_SREV_KITE(ah)) { 119237611Sadrian ahp->ah_btCoexFlag |= HAL_BT_COEX_FLAG_ANT_DIV_ALLOW; 120237611Sadrian if (value) 121237611Sadrian ahp->ah_btCoexFlag |= 122237611Sadrian HAL_BT_COEX_FLAG_ANT_DIV_ENABLE; 123237611Sadrian else 124237611Sadrian ahp->ah_btCoexFlag &= 125237611Sadrian ~HAL_BT_COEX_FLAG_ANT_DIV_ENABLE; 126237611Sadrian ar9285BTCoexAntennaDiversity(ah); 127237611Sadrian } 128237611Sadrian break; 129237611Sadrian default: 130237611Sadrian ar5416BTCoexSetParameter(ah, type, value); 131237611Sadrian break; 132237611Sadrian } 133237611Sadrian} 134237611Sadrian 135237611Sadrian 136