162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (c) 2015 Qualcomm Atheros Inc. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 562306a36Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 662306a36Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 962306a36Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1062306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1162306a36Sopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1262306a36Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1362306a36Sopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1462306a36Sopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "hw.h" 1862306a36Sopenharmony_ci#include "hw-ops.h" 1962306a36Sopenharmony_ci#include "ar9003_mci.h" 2062306a36Sopenharmony_ci#include "ar9003_aic.h" 2162306a36Sopenharmony_ci#include "ar9003_phy.h" 2262306a36Sopenharmony_ci#include "reg_aic.h" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic const u8 com_att_db_table[ATH_AIC_MAX_COM_ATT_DB_TABLE] = { 2562306a36Sopenharmony_ci 0, 3, 9, 15, 21, 27 2662306a36Sopenharmony_ci}; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic const u16 aic_lin_table[ATH_AIC_MAX_AIC_LIN_TABLE] = { 2962306a36Sopenharmony_ci 8191, 7300, 6506, 5799, 5168, 4606, 4105, 3659, 3062306a36Sopenharmony_ci 3261, 2906, 2590, 2309, 2057, 1834, 1634, 1457, 3162306a36Sopenharmony_ci 1298, 1157, 1031, 919, 819, 730, 651, 580, 3262306a36Sopenharmony_ci 517, 461, 411, 366, 326, 291, 259, 231, 3362306a36Sopenharmony_ci 206, 183, 163, 146, 130, 116, 103, 92, 3462306a36Sopenharmony_ci 82, 73, 65, 58, 52, 46, 41, 37, 3562306a36Sopenharmony_ci 33, 29, 26, 23, 21, 18, 16, 15, 3662306a36Sopenharmony_ci 13, 12, 10, 9, 8, 7, 7, 6, 3762306a36Sopenharmony_ci 5, 5, 4, 4, 3 3862306a36Sopenharmony_ci}; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic bool ar9003_hw_is_aic_enabled(struct ath_hw *ah) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci /* 4562306a36Sopenharmony_ci * Disable AIC for now, until we have all the 4662306a36Sopenharmony_ci * HW code and the driver-layer support ready. 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ci return false; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_AIC) 5162306a36Sopenharmony_ci return false; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci return true; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic int16_t ar9003_aic_find_valid(bool *cal_sram_valid, 5762306a36Sopenharmony_ci bool dir, u8 index) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci int16_t i; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci if (dir) { 6262306a36Sopenharmony_ci for (i = index + 1; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 6362306a36Sopenharmony_ci if (cal_sram_valid[i]) 6462306a36Sopenharmony_ci break; 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci } else { 6762306a36Sopenharmony_ci for (i = index - 1; i >= 0; i--) { 6862306a36Sopenharmony_ci if (cal_sram_valid[i]) 6962306a36Sopenharmony_ci break; 7062306a36Sopenharmony_ci } 7162306a36Sopenharmony_ci } 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci if ((i >= ATH_AIC_MAX_BT_CHANNEL) || (i < 0)) 7462306a36Sopenharmony_ci i = -1; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci return i; 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/* 8062306a36Sopenharmony_ci * type 0: aic_lin_table, 1: com_att_db_table 8162306a36Sopenharmony_ci */ 8262306a36Sopenharmony_cistatic int16_t ar9003_aic_find_index(u8 type, int16_t value) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci int16_t i = -1; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if (type == 0) { 8762306a36Sopenharmony_ci for (i = ATH_AIC_MAX_AIC_LIN_TABLE - 1; i >= 0; i--) { 8862306a36Sopenharmony_ci if (aic_lin_table[i] >= value) 8962306a36Sopenharmony_ci break; 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci } else if (type == 1) { 9262306a36Sopenharmony_ci for (i = 0; i < ATH_AIC_MAX_COM_ATT_DB_TABLE; i++) { 9362306a36Sopenharmony_ci if (com_att_db_table[i] > value) { 9462306a36Sopenharmony_ci i--; 9562306a36Sopenharmony_ci break; 9662306a36Sopenharmony_ci } 9762306a36Sopenharmony_ci } 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci if (i >= ATH_AIC_MAX_COM_ATT_DB_TABLE) 10062306a36Sopenharmony_ci i = -1; 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci return i; 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic void ar9003_aic_gain_table(struct ath_hw *ah) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci u32 aic_atten_word[19], i; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /* Config LNA gain difference */ 11162306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_BT_COEX_4, 0x2c200a00); 11262306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_BT_COEX_5, 0x5c4e4438); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci /* Program gain table */ 11562306a36Sopenharmony_ci aic_atten_word[0] = (0x1 & 0xf) << 14 | (0x1f & 0x1f) << 9 | (0x0 & 0xf) << 5 | 11662306a36Sopenharmony_ci (0x1f & 0x1f); /* -01 dB: 4'd1, 5'd31, 00 dB: 4'd0, 5'd31 */ 11762306a36Sopenharmony_ci aic_atten_word[1] = (0x3 & 0xf) << 14 | (0x1f & 0x1f) << 9 | (0x2 & 0xf) << 5 | 11862306a36Sopenharmony_ci (0x1f & 0x1f); /* -03 dB: 4'd3, 5'd31, -02 dB: 4'd2, 5'd31 */ 11962306a36Sopenharmony_ci aic_atten_word[2] = (0x5 & 0xf) << 14 | (0x1f & 0x1f) << 9 | (0x4 & 0xf) << 5 | 12062306a36Sopenharmony_ci (0x1f & 0x1f); /* -05 dB: 4'd5, 5'd31, -04 dB: 4'd4, 5'd31 */ 12162306a36Sopenharmony_ci aic_atten_word[3] = (0x1 & 0xf) << 14 | (0x1e & 0x1f) << 9 | (0x0 & 0xf) << 5 | 12262306a36Sopenharmony_ci (0x1e & 0x1f); /* -07 dB: 4'd1, 5'd30, -06 dB: 4'd0, 5'd30 */ 12362306a36Sopenharmony_ci aic_atten_word[4] = (0x3 & 0xf) << 14 | (0x1e & 0x1f) << 9 | (0x2 & 0xf) << 5 | 12462306a36Sopenharmony_ci (0x1e & 0x1f); /* -09 dB: 4'd3, 5'd30, -08 dB: 4'd2, 5'd30 */ 12562306a36Sopenharmony_ci aic_atten_word[5] = (0x5 & 0xf) << 14 | (0x1e & 0x1f) << 9 | (0x4 & 0xf) << 5 | 12662306a36Sopenharmony_ci (0x1e & 0x1f); /* -11 dB: 4'd5, 5'd30, -10 dB: 4'd4, 5'd30 */ 12762306a36Sopenharmony_ci aic_atten_word[6] = (0x1 & 0xf) << 14 | (0xf & 0x1f) << 9 | (0x0 & 0xf) << 5 | 12862306a36Sopenharmony_ci (0xf & 0x1f); /* -13 dB: 4'd1, 5'd15, -12 dB: 4'd0, 5'd15 */ 12962306a36Sopenharmony_ci aic_atten_word[7] = (0x3 & 0xf) << 14 | (0xf & 0x1f) << 9 | (0x2 & 0xf) << 5 | 13062306a36Sopenharmony_ci (0xf & 0x1f); /* -15 dB: 4'd3, 5'd15, -14 dB: 4'd2, 5'd15 */ 13162306a36Sopenharmony_ci aic_atten_word[8] = (0x5 & 0xf) << 14 | (0xf & 0x1f) << 9 | (0x4 & 0xf) << 5 | 13262306a36Sopenharmony_ci (0xf & 0x1f); /* -17 dB: 4'd5, 5'd15, -16 dB: 4'd4, 5'd15 */ 13362306a36Sopenharmony_ci aic_atten_word[9] = (0x1 & 0xf) << 14 | (0x7 & 0x1f) << 9 | (0x0 & 0xf) << 5 | 13462306a36Sopenharmony_ci (0x7 & 0x1f); /* -19 dB: 4'd1, 5'd07, -18 dB: 4'd0, 5'd07 */ 13562306a36Sopenharmony_ci aic_atten_word[10] = (0x3 & 0xf) << 14 | (0x7 & 0x1f) << 9 | (0x2 & 0xf) << 5 | 13662306a36Sopenharmony_ci (0x7 & 0x1f); /* -21 dB: 4'd3, 5'd07, -20 dB: 4'd2, 5'd07 */ 13762306a36Sopenharmony_ci aic_atten_word[11] = (0x5 & 0xf) << 14 | (0x7 & 0x1f) << 9 | (0x4 & 0xf) << 5 | 13862306a36Sopenharmony_ci (0x7 & 0x1f); /* -23 dB: 4'd5, 5'd07, -22 dB: 4'd4, 5'd07 */ 13962306a36Sopenharmony_ci aic_atten_word[12] = (0x7 & 0xf) << 14 | (0x7 & 0x1f) << 9 | (0x6 & 0xf) << 5 | 14062306a36Sopenharmony_ci (0x7 & 0x1f); /* -25 dB: 4'd7, 5'd07, -24 dB: 4'd6, 5'd07 */ 14162306a36Sopenharmony_ci aic_atten_word[13] = (0x3 & 0xf) << 14 | (0x3 & 0x1f) << 9 | (0x2 & 0xf) << 5 | 14262306a36Sopenharmony_ci (0x3 & 0x1f); /* -27 dB: 4'd3, 5'd03, -26 dB: 4'd2, 5'd03 */ 14362306a36Sopenharmony_ci aic_atten_word[14] = (0x5 & 0xf) << 14 | (0x3 & 0x1f) << 9 | (0x4 & 0xf) << 5 | 14462306a36Sopenharmony_ci (0x3 & 0x1f); /* -29 dB: 4'd5, 5'd03, -28 dB: 4'd4, 5'd03 */ 14562306a36Sopenharmony_ci aic_atten_word[15] = (0x1 & 0xf) << 14 | (0x1 & 0x1f) << 9 | (0x0 & 0xf) << 5 | 14662306a36Sopenharmony_ci (0x1 & 0x1f); /* -31 dB: 4'd1, 5'd01, -30 dB: 4'd0, 5'd01 */ 14762306a36Sopenharmony_ci aic_atten_word[16] = (0x3 & 0xf) << 14 | (0x1 & 0x1f) << 9 | (0x2 & 0xf) << 5 | 14862306a36Sopenharmony_ci (0x1 & 0x1f); /* -33 dB: 4'd3, 5'd01, -32 dB: 4'd2, 5'd01 */ 14962306a36Sopenharmony_ci aic_atten_word[17] = (0x5 & 0xf) << 14 | (0x1 & 0x1f) << 9 | (0x4 & 0xf) << 5 | 15062306a36Sopenharmony_ci (0x1 & 0x1f); /* -35 dB: 4'd5, 5'd01, -34 dB: 4'd4, 5'd01 */ 15162306a36Sopenharmony_ci aic_atten_word[18] = (0x7 & 0xf) << 14 | (0x1 & 0x1f) << 9 | (0x6 & 0xf) << 5 | 15262306a36Sopenharmony_ci (0x1 & 0x1f); /* -37 dB: 4'd7, 5'd01, -36 dB: 4'd6, 5'd01 */ 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci /* Write to Gain table with auto increment enabled. */ 15562306a36Sopenharmony_ci REG_WRITE(ah, (AR_PHY_AIC_SRAM_ADDR_B0 + 0x3000), 15662306a36Sopenharmony_ci (ATH_AIC_SRAM_AUTO_INCREMENT | 15762306a36Sopenharmony_ci ATH_AIC_SRAM_GAIN_TABLE_OFFSET)); 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci for (i = 0; i < 19; i++) { 16062306a36Sopenharmony_ci REG_WRITE(ah, (AR_PHY_AIC_SRAM_DATA_B0 + 0x3000), 16162306a36Sopenharmony_ci aic_atten_word[i]); 16262306a36Sopenharmony_ci } 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic u8 ar9003_aic_cal_start(struct ath_hw *ah, u8 min_valid_count) 16662306a36Sopenharmony_ci{ 16762306a36Sopenharmony_ci struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; 16862306a36Sopenharmony_ci int i; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci /* Write to Gain table with auto increment enabled. */ 17162306a36Sopenharmony_ci REG_WRITE(ah, (AR_PHY_AIC_SRAM_ADDR_B0 + 0x3000), 17262306a36Sopenharmony_ci (ATH_AIC_SRAM_AUTO_INCREMENT | 17362306a36Sopenharmony_ci ATH_AIC_SRAM_CAL_OFFSET)); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 17662306a36Sopenharmony_ci REG_WRITE(ah, (AR_PHY_AIC_SRAM_DATA_B0 + 0x3000), 0); 17762306a36Sopenharmony_ci aic->aic_sram[i] = 0; 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_CTRL_0_B0, 18162306a36Sopenharmony_ci (SM(0, AR_PHY_AIC_MON_ENABLE) | 18262306a36Sopenharmony_ci SM(127, AR_PHY_AIC_CAL_MAX_HOP_COUNT) | 18362306a36Sopenharmony_ci SM(min_valid_count, AR_PHY_AIC_CAL_MIN_VALID_COUNT) | 18462306a36Sopenharmony_ci SM(37, AR_PHY_AIC_F_WLAN) | 18562306a36Sopenharmony_ci SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) | 18662306a36Sopenharmony_ci SM(0, AR_PHY_AIC_CAL_ENABLE) | 18762306a36Sopenharmony_ci SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) | 18862306a36Sopenharmony_ci SM(0, AR_PHY_AIC_ENABLE))); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_CTRL_0_B1, 19162306a36Sopenharmony_ci (SM(0, AR_PHY_AIC_MON_ENABLE) | 19262306a36Sopenharmony_ci SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) | 19362306a36Sopenharmony_ci SM(0, AR_PHY_AIC_CAL_ENABLE) | 19462306a36Sopenharmony_ci SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) | 19562306a36Sopenharmony_ci SM(0, AR_PHY_AIC_ENABLE))); 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_CTRL_1_B0, 19862306a36Sopenharmony_ci (SM(8, AR_PHY_AIC_CAL_BT_REF_DELAY) | 19962306a36Sopenharmony_ci SM(0, AR_PHY_AIC_BT_IDLE_CFG) | 20062306a36Sopenharmony_ci SM(1, AR_PHY_AIC_STDBY_COND) | 20162306a36Sopenharmony_ci SM(37, AR_PHY_AIC_STDBY_ROT_ATT_DB) | 20262306a36Sopenharmony_ci SM(5, AR_PHY_AIC_STDBY_COM_ATT_DB) | 20362306a36Sopenharmony_ci SM(15, AR_PHY_AIC_RSSI_MAX) | 20462306a36Sopenharmony_ci SM(0, AR_PHY_AIC_RSSI_MIN))); 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_CTRL_1_B1, 20762306a36Sopenharmony_ci (SM(15, AR_PHY_AIC_RSSI_MAX) | 20862306a36Sopenharmony_ci SM(0, AR_PHY_AIC_RSSI_MIN))); 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_CTRL_2_B0, 21162306a36Sopenharmony_ci (SM(44, AR_PHY_AIC_RADIO_DELAY) | 21262306a36Sopenharmony_ci SM(8, AR_PHY_AIC_CAL_STEP_SIZE_CORR) | 21362306a36Sopenharmony_ci SM(12, AR_PHY_AIC_CAL_ROT_IDX_CORR) | 21462306a36Sopenharmony_ci SM(2, AR_PHY_AIC_CAL_CONV_CHECK_FACTOR) | 21562306a36Sopenharmony_ci SM(5, AR_PHY_AIC_ROT_IDX_COUNT_MAX) | 21662306a36Sopenharmony_ci SM(0, AR_PHY_AIC_CAL_SYNTH_TOGGLE) | 21762306a36Sopenharmony_ci SM(0, AR_PHY_AIC_CAL_SYNTH_AFTER_BTRX) | 21862306a36Sopenharmony_ci SM(200, AR_PHY_AIC_CAL_SYNTH_SETTLING))); 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_CTRL_3_B0, 22162306a36Sopenharmony_ci (SM(2, AR_PHY_AIC_MON_MAX_HOP_COUNT) | 22262306a36Sopenharmony_ci SM(1, AR_PHY_AIC_MON_MIN_STALE_COUNT) | 22362306a36Sopenharmony_ci SM(1, AR_PHY_AIC_MON_PWR_EST_LONG) | 22462306a36Sopenharmony_ci SM(2, AR_PHY_AIC_MON_PD_TALLY_SCALING) | 22562306a36Sopenharmony_ci SM(10, AR_PHY_AIC_MON_PERF_THR) | 22662306a36Sopenharmony_ci SM(2, AR_PHY_AIC_CAL_TARGET_MAG_SETTING) | 22762306a36Sopenharmony_ci SM(1, AR_PHY_AIC_CAL_PERF_CHECK_FACTOR) | 22862306a36Sopenharmony_ci SM(1, AR_PHY_AIC_CAL_PWR_EST_LONG))); 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_CTRL_4_B0, 23162306a36Sopenharmony_ci (SM(2, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) | 23262306a36Sopenharmony_ci SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) | 23362306a36Sopenharmony_ci SM(0, AR_PHY_AIC_CAL_ISO_EST_INIT_SETTING) | 23462306a36Sopenharmony_ci SM(2, AR_PHY_AIC_CAL_COM_ATT_DB_BACKOFF) | 23562306a36Sopenharmony_ci SM(1, AR_PHY_AIC_CAL_COM_ATT_DB_FIXED))); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_CTRL_4_B1, 23862306a36Sopenharmony_ci (SM(2, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) | 23962306a36Sopenharmony_ci SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) | 24062306a36Sopenharmony_ci SM(0, AR_PHY_AIC_CAL_ISO_EST_INIT_SETTING) | 24162306a36Sopenharmony_ci SM(2, AR_PHY_AIC_CAL_COM_ATT_DB_BACKOFF) | 24262306a36Sopenharmony_ci SM(1, AR_PHY_AIC_CAL_COM_ATT_DB_FIXED))); 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci ar9003_aic_gain_table(ah); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci /* Need to enable AIC reference signal in BT modem. */ 24762306a36Sopenharmony_ci REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL, 24862306a36Sopenharmony_ci (REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) | 24962306a36Sopenharmony_ci ATH_AIC_BT_AIC_ENABLE)); 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci aic->aic_cal_start_time = REG_READ(ah, AR_TSF_L32); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci /* Start calibration */ 25462306a36Sopenharmony_ci REG_CLR_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_ENABLE); 25562306a36Sopenharmony_ci REG_SET_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_CH_VALID_RESET); 25662306a36Sopenharmony_ci REG_SET_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_ENABLE); 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci aic->aic_caled_chan = 0; 25962306a36Sopenharmony_ci aic->aic_cal_state = AIC_CAL_STATE_STARTED; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci return aic->aic_cal_state; 26262306a36Sopenharmony_ci} 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cistatic bool ar9003_aic_cal_post_process(struct ath_hw *ah) 26562306a36Sopenharmony_ci{ 26662306a36Sopenharmony_ci struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; 26762306a36Sopenharmony_ci bool cal_sram_valid[ATH_AIC_MAX_BT_CHANNEL]; 26862306a36Sopenharmony_ci struct ath_aic_out_info aic_sram[ATH_AIC_MAX_BT_CHANNEL]; 26962306a36Sopenharmony_ci u32 dir_path_gain_idx, quad_path_gain_idx, value; 27062306a36Sopenharmony_ci u32 fixed_com_att_db; 27162306a36Sopenharmony_ci int8_t dir_path_sign, quad_path_sign; 27262306a36Sopenharmony_ci int16_t i; 27362306a36Sopenharmony_ci bool ret = true; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci memset(&cal_sram_valid, 0, sizeof(cal_sram_valid)); 27662306a36Sopenharmony_ci memset(&aic_sram, 0, sizeof(aic_sram)); 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 27962306a36Sopenharmony_ci struct ath_aic_sram_info sram; 28062306a36Sopenharmony_ci value = aic->aic_sram[i]; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci cal_sram_valid[i] = sram.valid = 28362306a36Sopenharmony_ci MS(value, AR_PHY_AIC_SRAM_VALID); 28462306a36Sopenharmony_ci sram.rot_quad_att_db = 28562306a36Sopenharmony_ci MS(value, AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB); 28662306a36Sopenharmony_ci sram.vga_quad_sign = 28762306a36Sopenharmony_ci MS(value, AR_PHY_AIC_SRAM_VGA_QUAD_SIGN); 28862306a36Sopenharmony_ci sram.rot_dir_att_db = 28962306a36Sopenharmony_ci MS(value, AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB); 29062306a36Sopenharmony_ci sram.vga_dir_sign = 29162306a36Sopenharmony_ci MS(value, AR_PHY_AIC_SRAM_VGA_DIR_SIGN); 29262306a36Sopenharmony_ci sram.com_att_6db = 29362306a36Sopenharmony_ci MS(value, AR_PHY_AIC_SRAM_COM_ATT_6DB); 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci if (sram.valid) { 29662306a36Sopenharmony_ci dir_path_gain_idx = sram.rot_dir_att_db + 29762306a36Sopenharmony_ci com_att_db_table[sram.com_att_6db]; 29862306a36Sopenharmony_ci quad_path_gain_idx = sram.rot_quad_att_db + 29962306a36Sopenharmony_ci com_att_db_table[sram.com_att_6db]; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci dir_path_sign = (sram.vga_dir_sign) ? 1 : -1; 30262306a36Sopenharmony_ci quad_path_sign = (sram.vga_quad_sign) ? 1 : -1; 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci aic_sram[i].dir_path_gain_lin = dir_path_sign * 30562306a36Sopenharmony_ci aic_lin_table[dir_path_gain_idx]; 30662306a36Sopenharmony_ci aic_sram[i].quad_path_gain_lin = quad_path_sign * 30762306a36Sopenharmony_ci aic_lin_table[quad_path_gain_idx]; 30862306a36Sopenharmony_ci } 30962306a36Sopenharmony_ci } 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 31262306a36Sopenharmony_ci int16_t start_idx, end_idx; 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci if (cal_sram_valid[i]) 31562306a36Sopenharmony_ci continue; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci start_idx = ar9003_aic_find_valid(cal_sram_valid, 0, i); 31862306a36Sopenharmony_ci end_idx = ar9003_aic_find_valid(cal_sram_valid, 1, i); 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci if (start_idx < 0) { 32162306a36Sopenharmony_ci /* extrapolation */ 32262306a36Sopenharmony_ci start_idx = end_idx; 32362306a36Sopenharmony_ci end_idx = ar9003_aic_find_valid(cal_sram_valid, 1, start_idx); 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci if (end_idx < 0) { 32662306a36Sopenharmony_ci ret = false; 32762306a36Sopenharmony_ci break; 32862306a36Sopenharmony_ci } 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci aic_sram[i].dir_path_gain_lin = 33162306a36Sopenharmony_ci ((aic_sram[start_idx].dir_path_gain_lin - 33262306a36Sopenharmony_ci aic_sram[end_idx].dir_path_gain_lin) * 33362306a36Sopenharmony_ci (start_idx - i) + ((end_idx - i) >> 1)) / 33462306a36Sopenharmony_ci (end_idx - i) + 33562306a36Sopenharmony_ci aic_sram[start_idx].dir_path_gain_lin; 33662306a36Sopenharmony_ci aic_sram[i].quad_path_gain_lin = 33762306a36Sopenharmony_ci ((aic_sram[start_idx].quad_path_gain_lin - 33862306a36Sopenharmony_ci aic_sram[end_idx].quad_path_gain_lin) * 33962306a36Sopenharmony_ci (start_idx - i) + ((end_idx - i) >> 1)) / 34062306a36Sopenharmony_ci (end_idx - i) + 34162306a36Sopenharmony_ci aic_sram[start_idx].quad_path_gain_lin; 34262306a36Sopenharmony_ci } 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci if (end_idx < 0) { 34562306a36Sopenharmony_ci /* extrapolation */ 34662306a36Sopenharmony_ci end_idx = ar9003_aic_find_valid(cal_sram_valid, 0, start_idx); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (end_idx < 0) { 34962306a36Sopenharmony_ci ret = false; 35062306a36Sopenharmony_ci break; 35162306a36Sopenharmony_ci } 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci aic_sram[i].dir_path_gain_lin = 35462306a36Sopenharmony_ci ((aic_sram[start_idx].dir_path_gain_lin - 35562306a36Sopenharmony_ci aic_sram[end_idx].dir_path_gain_lin) * 35662306a36Sopenharmony_ci (i - start_idx) + ((start_idx - end_idx) >> 1)) / 35762306a36Sopenharmony_ci (start_idx - end_idx) + 35862306a36Sopenharmony_ci aic_sram[start_idx].dir_path_gain_lin; 35962306a36Sopenharmony_ci aic_sram[i].quad_path_gain_lin = 36062306a36Sopenharmony_ci ((aic_sram[start_idx].quad_path_gain_lin - 36162306a36Sopenharmony_ci aic_sram[end_idx].quad_path_gain_lin) * 36262306a36Sopenharmony_ci (i - start_idx) + ((start_idx - end_idx) >> 1)) / 36362306a36Sopenharmony_ci (start_idx - end_idx) + 36462306a36Sopenharmony_ci aic_sram[start_idx].quad_path_gain_lin; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci } else if (start_idx >= 0){ 36762306a36Sopenharmony_ci /* interpolation */ 36862306a36Sopenharmony_ci aic_sram[i].dir_path_gain_lin = 36962306a36Sopenharmony_ci (((end_idx - i) * aic_sram[start_idx].dir_path_gain_lin) + 37062306a36Sopenharmony_ci ((i - start_idx) * aic_sram[end_idx].dir_path_gain_lin) + 37162306a36Sopenharmony_ci ((end_idx - start_idx) >> 1)) / 37262306a36Sopenharmony_ci (end_idx - start_idx); 37362306a36Sopenharmony_ci aic_sram[i].quad_path_gain_lin = 37462306a36Sopenharmony_ci (((end_idx - i) * aic_sram[start_idx].quad_path_gain_lin) + 37562306a36Sopenharmony_ci ((i - start_idx) * aic_sram[end_idx].quad_path_gain_lin) + 37662306a36Sopenharmony_ci ((end_idx - start_idx) >> 1))/ 37762306a36Sopenharmony_ci (end_idx - start_idx); 37862306a36Sopenharmony_ci } 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci /* From dir/quad_path_gain_lin to sram. */ 38262306a36Sopenharmony_ci i = ar9003_aic_find_valid(cal_sram_valid, 1, 0); 38362306a36Sopenharmony_ci if (i < 0) { 38462306a36Sopenharmony_ci i = 0; 38562306a36Sopenharmony_ci ret = false; 38662306a36Sopenharmony_ci } 38762306a36Sopenharmony_ci fixed_com_att_db = com_att_db_table[MS(aic->aic_sram[i], 38862306a36Sopenharmony_ci AR_PHY_AIC_SRAM_COM_ATT_6DB)]; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 39162306a36Sopenharmony_ci int16_t rot_dir_path_att_db, rot_quad_path_att_db; 39262306a36Sopenharmony_ci struct ath_aic_sram_info sram; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci sram.vga_dir_sign = 39562306a36Sopenharmony_ci (aic_sram[i].dir_path_gain_lin >= 0) ? 1 : 0; 39662306a36Sopenharmony_ci sram.vga_quad_sign = 39762306a36Sopenharmony_ci (aic_sram[i].quad_path_gain_lin >= 0) ? 1 : 0; 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci rot_dir_path_att_db = 40062306a36Sopenharmony_ci ar9003_aic_find_index(0, abs(aic_sram[i].dir_path_gain_lin)) - 40162306a36Sopenharmony_ci fixed_com_att_db; 40262306a36Sopenharmony_ci rot_quad_path_att_db = 40362306a36Sopenharmony_ci ar9003_aic_find_index(0, abs(aic_sram[i].quad_path_gain_lin)) - 40462306a36Sopenharmony_ci fixed_com_att_db; 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci sram.com_att_6db = 40762306a36Sopenharmony_ci ar9003_aic_find_index(1, fixed_com_att_db); 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci sram.valid = true; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci sram.rot_dir_att_db = 41262306a36Sopenharmony_ci min(max(rot_dir_path_att_db, 41362306a36Sopenharmony_ci (int16_t)ATH_AIC_MIN_ROT_DIR_ATT_DB), 41462306a36Sopenharmony_ci ATH_AIC_MAX_ROT_DIR_ATT_DB); 41562306a36Sopenharmony_ci sram.rot_quad_att_db = 41662306a36Sopenharmony_ci min(max(rot_quad_path_att_db, 41762306a36Sopenharmony_ci (int16_t)ATH_AIC_MIN_ROT_QUAD_ATT_DB), 41862306a36Sopenharmony_ci ATH_AIC_MAX_ROT_QUAD_ATT_DB); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci aic->aic_sram[i] = (SM(sram.vga_dir_sign, 42162306a36Sopenharmony_ci AR_PHY_AIC_SRAM_VGA_DIR_SIGN) | 42262306a36Sopenharmony_ci SM(sram.vga_quad_sign, 42362306a36Sopenharmony_ci AR_PHY_AIC_SRAM_VGA_QUAD_SIGN) | 42462306a36Sopenharmony_ci SM(sram.com_att_6db, 42562306a36Sopenharmony_ci AR_PHY_AIC_SRAM_COM_ATT_6DB) | 42662306a36Sopenharmony_ci SM(sram.valid, 42762306a36Sopenharmony_ci AR_PHY_AIC_SRAM_VALID) | 42862306a36Sopenharmony_ci SM(sram.rot_dir_att_db, 42962306a36Sopenharmony_ci AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB) | 43062306a36Sopenharmony_ci SM(sram.rot_quad_att_db, 43162306a36Sopenharmony_ci AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB)); 43262306a36Sopenharmony_ci } 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci return ret; 43562306a36Sopenharmony_ci} 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_cistatic void ar9003_aic_cal_done(struct ath_hw *ah) 43862306a36Sopenharmony_ci{ 43962306a36Sopenharmony_ci struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci /* Disable AIC reference signal in BT modem. */ 44262306a36Sopenharmony_ci REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL, 44362306a36Sopenharmony_ci (REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) & 44462306a36Sopenharmony_ci ~ATH_AIC_BT_AIC_ENABLE)); 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci if (ar9003_aic_cal_post_process(ah)) 44762306a36Sopenharmony_ci aic->aic_cal_state = AIC_CAL_STATE_DONE; 44862306a36Sopenharmony_ci else 44962306a36Sopenharmony_ci aic->aic_cal_state = AIC_CAL_STATE_ERROR; 45062306a36Sopenharmony_ci} 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_cistatic u8 ar9003_aic_cal_continue(struct ath_hw *ah, bool cal_once) 45362306a36Sopenharmony_ci{ 45462306a36Sopenharmony_ci struct ath_common *common = ath9k_hw_common(ah); 45562306a36Sopenharmony_ci struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; 45662306a36Sopenharmony_ci struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; 45762306a36Sopenharmony_ci int i, num_chan; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci num_chan = MS(mci_hw->config, ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci if (!num_chan) { 46262306a36Sopenharmony_ci aic->aic_cal_state = AIC_CAL_STATE_ERROR; 46362306a36Sopenharmony_ci return aic->aic_cal_state; 46462306a36Sopenharmony_ci } 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci if (cal_once) { 46762306a36Sopenharmony_ci for (i = 0; i < 10000; i++) { 46862306a36Sopenharmony_ci if ((REG_READ(ah, AR_PHY_AIC_CTRL_0_B1) & 46962306a36Sopenharmony_ci AR_PHY_AIC_CAL_ENABLE) == 0) 47062306a36Sopenharmony_ci break; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci udelay(100); 47362306a36Sopenharmony_ci } 47462306a36Sopenharmony_ci } 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci /* 47762306a36Sopenharmony_ci * Use AR_PHY_AIC_CAL_ENABLE bit instead of AR_PHY_AIC_CAL_DONE. 47862306a36Sopenharmony_ci * Sometimes CAL_DONE bit is not asserted. 47962306a36Sopenharmony_ci */ 48062306a36Sopenharmony_ci if ((REG_READ(ah, AR_PHY_AIC_CTRL_0_B1) & 48162306a36Sopenharmony_ci AR_PHY_AIC_CAL_ENABLE) != 0) { 48262306a36Sopenharmony_ci ath_dbg(common, MCI, "AIC cal is not done after 40ms"); 48362306a36Sopenharmony_ci goto exit; 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1, 48762306a36Sopenharmony_ci (ATH_AIC_SRAM_CAL_OFFSET | ATH_AIC_SRAM_AUTO_INCREMENT)); 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 49062306a36Sopenharmony_ci u32 value; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci value = REG_READ(ah, AR_PHY_AIC_SRAM_DATA_B1); 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci if (value & 0x01) { 49562306a36Sopenharmony_ci if (aic->aic_sram[i] == 0) 49662306a36Sopenharmony_ci aic->aic_caled_chan++; 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci aic->aic_sram[i] = value; 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci if (!cal_once) 50162306a36Sopenharmony_ci break; 50262306a36Sopenharmony_ci } 50362306a36Sopenharmony_ci } 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci if ((aic->aic_caled_chan >= num_chan) || cal_once) { 50662306a36Sopenharmony_ci ar9003_aic_cal_done(ah); 50762306a36Sopenharmony_ci } else { 50862306a36Sopenharmony_ci /* Start calibration */ 50962306a36Sopenharmony_ci REG_CLR_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_ENABLE); 51062306a36Sopenharmony_ci REG_SET_BIT(ah, AR_PHY_AIC_CTRL_0_B1, 51162306a36Sopenharmony_ci AR_PHY_AIC_CAL_CH_VALID_RESET); 51262306a36Sopenharmony_ci REG_SET_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_ENABLE); 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ciexit: 51562306a36Sopenharmony_ci return aic->aic_cal_state; 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci} 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ciu8 ar9003_aic_calibration(struct ath_hw *ah) 52062306a36Sopenharmony_ci{ 52162306a36Sopenharmony_ci struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; 52262306a36Sopenharmony_ci u8 cal_ret = AIC_CAL_STATE_ERROR; 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci switch (aic->aic_cal_state) { 52562306a36Sopenharmony_ci case AIC_CAL_STATE_IDLE: 52662306a36Sopenharmony_ci cal_ret = ar9003_aic_cal_start(ah, 1); 52762306a36Sopenharmony_ci break; 52862306a36Sopenharmony_ci case AIC_CAL_STATE_STARTED: 52962306a36Sopenharmony_ci cal_ret = ar9003_aic_cal_continue(ah, false); 53062306a36Sopenharmony_ci break; 53162306a36Sopenharmony_ci case AIC_CAL_STATE_DONE: 53262306a36Sopenharmony_ci cal_ret = AIC_CAL_STATE_DONE; 53362306a36Sopenharmony_ci break; 53462306a36Sopenharmony_ci default: 53562306a36Sopenharmony_ci break; 53662306a36Sopenharmony_ci } 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci return cal_ret; 53962306a36Sopenharmony_ci} 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ciu8 ar9003_aic_start_normal(struct ath_hw *ah) 54262306a36Sopenharmony_ci{ 54362306a36Sopenharmony_ci struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; 54462306a36Sopenharmony_ci int16_t i; 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci if (aic->aic_cal_state != AIC_CAL_STATE_DONE) 54762306a36Sopenharmony_ci return 1; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci ar9003_aic_gain_table(ah); 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1, ATH_AIC_SRAM_AUTO_INCREMENT); 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 55462306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_AIC_SRAM_DATA_B1, aic->aic_sram[i]); 55562306a36Sopenharmony_ci } 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci /* FIXME: Replace these with proper register names */ 55862306a36Sopenharmony_ci REG_WRITE(ah, 0xa6b0, 0x80); 55962306a36Sopenharmony_ci REG_WRITE(ah, 0xa6b4, 0x5b2df0); 56062306a36Sopenharmony_ci REG_WRITE(ah, 0xa6b8, 0x10762cc8); 56162306a36Sopenharmony_ci REG_WRITE(ah, 0xa6bc, 0x1219a4b); 56262306a36Sopenharmony_ci REG_WRITE(ah, 0xa6c0, 0x1e01); 56362306a36Sopenharmony_ci REG_WRITE(ah, 0xb6b4, 0xf0); 56462306a36Sopenharmony_ci REG_WRITE(ah, 0xb6c0, 0x1e01); 56562306a36Sopenharmony_ci REG_WRITE(ah, 0xb6b0, 0x81); 56662306a36Sopenharmony_ci REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX4, 0x40000000); 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci aic->aic_enabled = true; 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci return 0; 57162306a36Sopenharmony_ci} 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ciu8 ar9003_aic_cal_reset(struct ath_hw *ah) 57462306a36Sopenharmony_ci{ 57562306a36Sopenharmony_ci struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci aic->aic_cal_state = AIC_CAL_STATE_IDLE; 57862306a36Sopenharmony_ci return aic->aic_cal_state; 57962306a36Sopenharmony_ci} 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ciu8 ar9003_aic_calibration_single(struct ath_hw *ah) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; 58462306a36Sopenharmony_ci u8 cal_ret; 58562306a36Sopenharmony_ci int num_chan; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci num_chan = MS(mci_hw->config, ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN); 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci (void) ar9003_aic_cal_start(ah, num_chan); 59062306a36Sopenharmony_ci cal_ret = ar9003_aic_cal_continue(ah, true); 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci return cal_ret; 59362306a36Sopenharmony_ci} 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_civoid ar9003_hw_attach_aic_ops(struct ath_hw *ah) 59662306a36Sopenharmony_ci{ 59762306a36Sopenharmony_ci struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci priv_ops->is_aic_enabled = ar9003_hw_is_aic_enabled; 60062306a36Sopenharmony_ci} 601