ath9k patches
v2 cover ath9k patches
From: Sujith Manoharan <[email protected]>
AIC support, for -next.
v2 : Address warning reported by Kalle:
ar9003_aic.c: In function 'ar9003_aic_cal_post_process':
ar9003_aic.c:431:1: warning: the frame size of 1312 bytes is larger than 1024 bytes [-Wframe-larger-than=]Sujith Manoharan (11):
ath9k: Add initial structures for AIC
ath9k: Register private AIC ops
ath9k: Add register definitions for AIC
ath9k: Handle MCI_STATE_AIC_CAL_SINGLE
ath9k: Finish AIC calibration
ath9k: Process the AIC calibration results
ath9k: Disable AIC by default
ath9k: Handle MCI_STATE_AIC_CAL_RESET
ath9k: Handle MCI_STATE_AIC_START
ath9k: Handle MCI_STATE_AIC_CAL
ath9k: Start AIC calibration during MCI reset
drivers/net/wireless/ath/ath9k/Makefile | 3 +- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 599 ++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_aic.h | 61 +++ drivers/net/wireless/ath/ath9k/ar9003_hw.c | 1 + drivers/net/wireless/ath/ath9k/ar9003_mci.c | 20 + drivers/net/wireless/ath/ath9k/ar9003_phy.h | 25 -- drivers/net/wireless/ath/ath9k/btcoex.h | 12 + drivers/net/wireless/ath/ath9k/hw-ops.h | 8 + drivers/net/wireless/ath/ath9k/hw.h | 6 + drivers/net/wireless/ath/ath9k/reg_aic.h | 168 ++++++++ 10 files changed, 877 insertions(+), 26 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_aic.c create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_aic.h create mode 100644 drivers/net/wireless/ath/ath9k/reg_aic.h
Signature · 1 line
2.3.1
PATCH v2 1/11 ath9k: Add initial structures for AIC
From: Sujith Manoharan <[email protected]>
These are necessary for implementing AIC,
supported by chips like WB222.
--- drivers/net/wireless/ath/ath9k/ar9003_aic.h | 49 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/btcoex.h | 11 +++++++ 2 files changed, 60 insertions(+) create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_aic.h
drivers/net/wireless/ath/ath9k/ar9003_aic.h new file +49 -0
@@ -0,0 +1,49 @@ +/* +* Copyright (c) 2015 Qualcomm Atheros Inc. +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef AR9003_AIC_H +#define AR9003_AIC_H + +#define ATH_AIC_MAX_COM_ATT_DB_TABLE 6 +#define ATH_AIC_MAX_AIC_LIN_TABLE 69 +#define ATH_AIC_MIN_ROT_DIR_ATT_DB 0 +#define ATH_AIC_MIN_ROT_QUAD_ATT_DB 0 +#define ATH_AIC_MAX_ROT_DIR_ATT_DB 37 +#define ATH_AIC_MAX_ROT_QUAD_ATT_DB 37 +#define ATH_AIC_SRAM_AUTO_INCREMENT 0x80000000 +#define ATH_AIC_SRAM_GAIN_TABLE_OFFSET 0x280 +#define ATH_AIC_SRAM_CAL_OFFSET 0x140 +#define ATH_AIC_SRAM_OFFSET 0x00 +#define ATH_AIC_MEAS_MAG_THRESH 20 +#define ATH_AIC_BT_JUPITER_CTRL 0x66820 +#define ATH_AIC_BT_AIC_ENABLE 0x02 + +struct ath_aic_sram_info { +bool valid:1 ; +bool vga_quad_sign:1 ; +bool vga_dir_sign:1 ; +u8 rot_quad_att_db; +u8 rot_dir_att_db; +u8 com_att_6db; +}; + +struct ath_aic_out_info { +int16_t dir_path_gain_lin; +int16_t quad_path_gain_lin; +struct ath_aic_sram_info sram; +}; + +#endif /* AR9003_AIC_H */
drivers/net/wireless/ath/ath9k/btcoex.h +11 -0
@@ -44,6 +44,9 @@#define AR9300_NUM_BT_WEIGHTS 4#define AR9300_NUM_WLAN_WEIGHTS 4 + +#define ATH_AIC_MAX_BT_CHANNEL 79 +/* Defines the BT AR_BT_COEX_WGHT used */ enum ath_stomp_type {ATH_BTCOEX_STOMP_ALL ,
@@ -93,6 +96,14 @@ struct ath9k_hw_mci {u32 last_recovery; }; +struct ath9k_hw_aic { +bool aic_enabled; +u8 aic_cal_state; +u8 aic_caled_chan; +u32 aic_sram[ATH_AIC_MAX_BT_CHANNEL ]; +u32 aic_cal_start_time; +}; +struct ath_btcoex_hw {enum ath_btcoex_scheme scheme;struct ath9k_hw_mci mci;
Signature · 1 line
2.3.1
PATCH v2 1/11 ath9k: Add initial structures for AIC
Quoted 7 lines
From: Sujith Manoharan <[email protected]>
These are necessary for implementing AIC,
supported by chips like WB222.Signed-off-by Sujith Manoharan <[email protected]>
Thanks, 11 patches applied to wireless-drivers-next.git:
d3f193ee6538 ath9k: Add initial structures for AIC 637625f2db84 ath9k: Register private AIC ops 6dacafea2d3a ath9k: Add register definitions for AIC b6ab9ae2eed8 ath9k: Handle MCI_STATE_AIC_CAL_SINGLE 716eed4c0dfb ath9k: Finish AIC calibration 188f1a1288d5 ath9k: Process the AIC calibration results 208837eeb925 ath9k: Disable AIC by default 958b6827b781 ath9k: Handle MCI_STATE_AIC_CAL_RESET f2ef792a8085 ath9k: Handle MCI_STATE_AIC_START 60544603b669 ath9k: Handle MCI_STATE_AIC_CAL 7644317bd39c ath9k: Start AIC calibration during MCI reset
Kalle Valo
PATCH v2 2/11 ath9k: Register private AIC ops
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
AIC can be disabled or enabled on a per-card basis using MCI configuration, so register a function to check its status.
--- drivers/net/wireless/ath/ath9k/Makefile | 3 ++- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 37 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_hw.c | 1 + drivers/net/wireless/ath/ath9k/hw-ops.h | 8 +++++++ drivers/net/wireless/ath/ath9k/hw.h | 6 +++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_aic.c
drivers/net/wireless/ath/ath9k/Makefile +2 -1
@@ -46,7 +46,8 @@ ath9k_hw-y:= \ ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ - ar9003_mci.o + ar9003_mci.o \ + ar9003_aic.o ath9k_hw-$(CONFIG_ATH9K_PCOEM) += ar9003_rtt.o
drivers/net/wireless/ath/ath9k/ar9003_aic.c new file +37 -0
@@ -0,0 +1,37 @@ +/* +* Copyright (c) 2015 Qualcomm Atheros Inc. +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "hw.h" +#include "hw-ops.h" +#include "ar9003_mci.h" +#include "ar9003_aic.h" + +static bool ar9003_hw_is_aic_enabled (struct ath_hw *ah) +{ +struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; + +if (mci_hw->config &ATH_MCI_CONFIG_DISABLE_AIC ) +return false; + +return true; +} + +void ar9003_hw_attach_aic_ops (struct ath_hw *ah) +{ +struct ath_hw_private_ops *priv_ops =ath9k_hw_private_ops (ah); + + priv_ops->is_aic_enabled = ar9003_hw_is_aic_enabled; +}
drivers/net/wireless/ath/ath9k/ar9003_hw.c +1 -0
@@ -1180,4 +1180,5 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)ar9003_hw_attach_phy_ops (ah);ar9003_hw_attach_calib_ops (ah);ar9003_hw_attach_mac_ops (ah); +ar9003_hw_attach_aic_ops (ah); }
drivers/net/wireless/ath/ath9k/hw-ops.h +8 -0
@@ -108,6 +108,14 @@ static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) ath9k_hw_ops(ah)->set_bt_ant_diversity(ah, enable); } +static inline bool ath9k_hw_is_aic_enabled (struct ath_hw *ah) +{ +if (ath9k_hw_private_ops (ah)->is_aic_enabled) +return ath9k_hw_private_ops (ah)->is_aic_enabled (ah); + +return false; +} +#endif /* Private hardware call ops */
drivers/net/wireless/ath/ath9k/hw.h +6 -0
@@ -653,6 +653,10 @@ struct ath_hw_private_ops {/* ANI */ void (*ani_cache_ini_regs)(struct ath_hw *ah); + +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT +bool (*is_aic_enabled)(struct ath_hw *ah); +#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ };/**
@@ -1113,6 +1117,8 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah);int ar9002_hw_attach_ops (struct ath_hw *ah);void ar9003_hw_attach_ops (struct ath_hw *ah); +void ar9003_hw_attach_aic_ops (struct ath_hw *ah); +void ar9002_hw_load_ani_reg (struct ath_hw *ah,struct ath9k_channel *chan);void ath9k_ani_reset (struct ath_hw *ah,bool is_scanning);
Signature · 1 line
2.3.1
PATCH v2 2/11 ath9k: Register private AIC ops
Quoted 7 lines · Sujith Manoharan
From: Sujith Manoharan <[email protected]>
AIC can be disabled or enabled on a per-card basis using MCI configuration, so register a function to check its status.
Signed-off-by Sujith Manoharan <[email protected]>
I guess you already saw the error from kbuild:
Quoted 1 line
Quoted 1 line
ERROR: "
ar9003_hw_attach_aic_ops" [drivers/net/wireless/ath/ath9k/ath9k_hw.ko] undefined!
Can you send a fix for this, please?
Signature · 1 line
Kalle Valo
PATCH v2 2/11 ath9k: Register private AIC ops
Quoted 5 lines · Kalle Valo
I guess you already saw the error from kbuild:
Quoted 1 line
Quoted 1 line
ERROR: "
ar9003_hw_attach_aic_ops" [drivers/net/wireless/ath/ath9k/ath9k_hw.ko] undefined!Can you send a fix for this, please?
This slipped through the radar...
I've posted a patch: https://patchwork.kernel.org/patch/6056731/
Sujith
PATCH v2 2/11 ath9k: Register private AIC ops
Quoted 9 lines · Sujith Manoharan
Quoted 5 lines · Kalle Valo
I guess you already saw the error from kbuild:
Quoted 1 line
Quoted 1 line
ERROR: "
ar9003_hw_attach_aic_ops" [drivers/net/wireless/ath/ath9k/ath9k_hw.ko] undefined!Can you send a fix for this, please?
This slipped through the radar...
I've posted a patch: https://patchwork.kernel.org/patch/6056731/
Thanks, I'll apply it soon.
Signature · 1 line
Kalle Valo
PATCH v2 3/11 ath9k: Add register definitions for AIC
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
Various registers to control and check AIC
status.
--- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 1 + drivers/net/wireless/ath/ath9k/ar9003_phy.h | 25 ----- drivers/net/wireless/ath/ath9k/reg_aic.h | 168 ++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 25 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/reg_aic.h
drivers/net/wireless/ath/ath9k/ar9003_aic.c +1 -0
@@ -18,6 +18,7 @@#include "hw-ops.h" #include "ar9003_mci.h" #include "ar9003_aic.h" +#include "reg_aic.h" static bool ar9003_hw_is_aic_enabled (struct ath_hw *ah) {
drivers/net/wireless/ath/ath9k/ar9003_phy.h +0 -25
@@ -640,16 +640,6 @@#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8 -/* AIC Registers */ -#define AR_PHY_AIC_CTRL_0_B0 (AR_SM_BASE + 0x4b0) -#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4) -#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8) -#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc) -#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + 0x4c4)) -#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + 0x4c8)) -#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) -#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) -#define AR_PHY_65NM_CH0_TXRF3 0x16048#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1
@@ -989,21 +979,6 @@#define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c)#define AR_PHY_TX_IQCAL_CORR_COEFF_B1 (_i) (AR_SM1_BASE + 0x450 + ((_i) << 2)) -/* SM 1 AIC Registers */ - -#define AR_PHY_AIC_CTRL_0_B1 (AR_SM1_BASE + 0x4b0) -#define AR_PHY_AIC_CTRL_1_B1 (AR_SM1_BASE + 0x4b4) -#define AR_PHY_AIC_CTRL_2_B1 (AR_SM1_BASE + 0x4b8) -#define AR_PHY_AIC_STAT_0_B1 (AR_SM1_BASE + (AR_SREV_9462_10(ah) ? \ - 0x4c0 : 0x4c4)) -#define AR_PHY_AIC_STAT_1_B1 (AR_SM1_BASE + (AR_SREV_9462_10(ah) ? \ - 0x4c4 : 0x4c8)) -#define AR_PHY_AIC_CTRL_4_B1 (AR_SM1_BASE + 0x4c0) -#define AR_PHY_AIC_STAT_2_B1 (AR_SM1_BASE + 0x4cc) - -#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0) -#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4) -#define AR_PHY_RTT_TABLE_SW_INTF_B (i) (0x384 + ((i) ? \ AR_SM1_BASE : AR_SM_BASE))#define AR_PHY_RTT_TABLE_SW_INTF_1_B (i) (0x388 + ((i) ? \
drivers/net/wireless/ath/ath9k/reg_aic.h new file +168 -0
168 lines not on this page · raw message
Signature · 1 line
2.3.1
PATCH v2 4/11 ath9k: Handle MCI_STATE_AIC_CAL_SINGLE
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
This patch adds routines to handle the MCI
message AIC_CAL_SINGLE, starting the required
HW calibration.
--- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 169 ++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_aic.h | 9 ++ drivers/net/wireless/ath/ath9k/ar9003_mci.c | 4 + drivers/net/wireless/ath/ath9k/btcoex.h | 1 + 4 files changed, 183 insertions(+)
drivers/net/wireless/ath/ath9k/ar9003_aic.c +169 -0
@@ -30,6 +30,175 @@ static bool ar9003_hw_is_aic_enabled(struct ath_hw *ah)return true; } +static void ar9003_aic_gain_table (struct ath_hw *ah) +{ +u32 aic_atten_word[19 ], i; + +/* Config LNA gain difference */ +REG_WRITE (ah,AR_PHY_BT_COEX_4 ,0x2c200a00 ); +REG_WRITE (ah,AR_PHY_BT_COEX_5 ,0x5c4e4438 ); + +/* Program gain table */ + aic_atten_word[0 ] = (0x1 &0xf ) <<14 | (0x1f &0x1f ) <<9 | (0x0 &0xf ) <<5 | + (0x1f &0x1f );/* -01 dB: 4'd1, 5'd31, 00 dB: 4'd0, 5'd31 */ + aic_atten_word[1 ] = (0x3 &0xf ) <<14 | (0x1f &0x1f ) <<9 | (0x2 &0xf ) <<5 | + (0x1f &0x1f );/* -03 dB: 4'd3, 5'd31, -02 dB: 4'd2, 5'd31 */ + aic_atten_word[2 ] = (0x5 &0xf ) <<14 | (0x1f &0x1f ) <<9 | (0x4 &0xf ) <<5 | + (0x1f &0x1f );/* -05 dB: 4'd5, 5'd31, -04 dB: 4'd4, 5'd31 */ + aic_atten_word[3 ] = (0x1 &0xf ) <<14 | (0x1e &0x1f ) <<9 | (0x0 &0xf ) <<5 | + (0x1e &0x1f );/* -07 dB: 4'd1, 5'd30, -06 dB: 4'd0, 5'd30 */ + aic_atten_word[4 ] = (0x3 &0xf ) <<14 | (0x1e &0x1f ) <<9 | (0x2 &0xf ) <<5 | + (0x1e &0x1f );/* -09 dB: 4'd3, 5'd30, -08 dB: 4'd2, 5'd30 */ + aic_atten_word[5 ] = (0x5 &0xf ) <<14 | (0x1e &0x1f ) <<9 | (0x4 &0xf ) <<5 | + (0x1e &0x1f );/* -11 dB: 4'd5, 5'd30, -10 dB: 4'd4, 5'd30 */ + aic_atten_word[6 ] = (0x1 &0xf ) <<14 | (0xf &0x1f ) <<9 | (0x0 &0xf ) <<5 | + (0xf &0x1f );/* -13 dB: 4'd1, 5'd15, -12 dB: 4'd0, 5'd15 */ + aic_atten_word[7 ] = (0x3 &0xf ) <<14 | (0xf &0x1f ) <<9 | (0x2 &0xf ) <<5 | + (0xf &0x1f );/* -15 dB: 4'd3, 5'd15, -14 dB: 4'd2, 5'd15 */ + aic_atten_word[8 ] = (0x5 &0xf ) <<14 | (0xf &0x1f ) <<9 | (0x4 &0xf ) <<5 | + (0xf &0x1f );/* -17 dB: 4'd5, 5'd15, -16 dB: 4'd4, 5'd15 */ + aic_atten_word[9 ] = (0x1 &0xf ) <<14 | (0x7 &0x1f ) <<9 | (0x0 &0xf ) <<5 | + (0x7 &0x1f );/* -19 dB: 4'd1, 5'd07, -18 dB: 4'd0, 5'd07 */ + aic_atten_word[10 ] = (0x3 &0xf ) <<14 | (0x7 &0x1f ) <<9 | (0x2 &0xf ) <<5 | + (0x7 &0x1f );/* -21 dB: 4'd3, 5'd07, -20 dB: 4'd2, 5'd07 */ + aic_atten_word[11 ] = (0x5 &0xf ) <<14 | (0x7 &0x1f ) <<9 | (0x4 &0xf ) <<5 | + (0x7 &0x1f );/* -23 dB: 4'd5, 5'd07, -22 dB: 4'd4, 5'd07 */ + aic_atten_word[12 ] = (0x7 &0xf ) <<14 | (0x7 &0x1f ) <<9 | (0x6 &0xf ) <<5 | + (0x7 &0x1f );/* -25 dB: 4'd7, 5'd07, -24 dB: 4'd6, 5'd07 */ + aic_atten_word[13 ] = (0x3 &0xf ) <<14 | (0x3 &0x1f ) <<9 | (0x2 &0xf ) <<5 | + (0x3 &0x1f );/* -27 dB: 4'd3, 5'd03, -26 dB: 4'd2, 5'd03 */ + aic_atten_word[14 ] = (0x5 &0xf ) <<14 | (0x3 &0x1f ) <<9 | (0x4 &0xf ) <<5 | + (0x3 &0x1f );/* -29 dB: 4'd5, 5'd03, -28 dB: 4'd4, 5'd03 */ + aic_atten_word[15 ] = (0x1 &0xf ) <<14 | (0x1 &0x1f ) <<9 | (0x0 &0xf ) <<5 | + (0x1 &0x1f );/* -31 dB: 4'd1, 5'd01, -30 dB: 4'd0, 5'd01 */ + aic_atten_word[16 ] = (0x3 &0xf ) <<14 | (0x1 &0x1f ) <<9 | (0x2 &0xf ) <<5 | + (0x1 &0x1f );/* -33 dB: 4'd3, 5'd01, -32 dB: 4'd2, 5'd01 */ + aic_atten_word[17 ] = (0x5 &0xf ) <<14 | (0x1 &0x1f ) <<9 | (0x4 &0xf ) <<5 | + (0x1 &0x1f );/* -35 dB: 4'd5, 5'd01, -34 dB: 4'd4, 5'd01 */ + aic_atten_word[18 ] = (0x7 &0xf ) <<14 | (0x1 &0x1f ) <<9 | (0x6 &0xf ) <<5 | + (0x1 &0x1f );/* -37 dB: 4'd7, 5'd01, -36 dB: 4'd6, 5'd01 */ + +/* Write to Gain table with auto increment enabled. */ +REG_WRITE (ah, (AR_PHY_AIC_SRAM_ADDR_B0 +0x3000 ), + (ATH_AIC_SRAM_AUTO_INCREMENT | +ATH_AIC_SRAM_GAIN_TABLE_OFFSET )); + +for (i =0 ; i <19 ; i++) { +REG_WRITE (ah, (AR_PHY_AIC_SRAM_DATA_B0 +0x3000 ), + aic_atten_word[i]); + } +} + +static void ar9003_aic_cal_start (struct ath_hw *ah,u8 min_valid_count) +{ +struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; +int i; + +/* Write to Gain table with auto increment enabled. */ +REG_WRITE (ah, (AR_PHY_AIC_SRAM_ADDR_B0 +0x3000 ), + (ATH_AIC_SRAM_AUTO_INCREMENT | +ATH_AIC_SRAM_CAL_OFFSET )); + +for (i =0 ; i <ATH_AIC_MAX_BT_CHANNEL ; i++) { +REG_WRITE (ah, (AR_PHY_AIC_SRAM_DATA_B0 +0x3000 ),0 ); + aic->aic_sram[i] =0 ; + } + +REG_WRITE (ah,AR_PHY_AIC_CTRL_0_B0 , + (SM (0 ,AR_PHY_AIC_MON_ENABLE ) | +SM (127 ,AR_PHY_AIC_CAL_MAX_HOP_COUNT ) | +SM (min_valid_count,AR_PHY_AIC_CAL_MIN_VALID_COUNT ) | +SM (37 ,AR_PHY_AIC_F_WLAN ) | +SM (1 ,AR_PHY_AIC_CAL_CH_VALID_RESET ) | +SM (0 ,AR_PHY_AIC_CAL_ENABLE ) | +SM (0x40 ,AR_PHY_AIC_BTTX_PWR_THR ) | +SM (0 ,AR_PHY_AIC_ENABLE ))); + +REG_WRITE (ah,AR_PHY_AIC_CTRL_0_B1 , + (SM (0 ,AR_PHY_AIC_MON_ENABLE ) | +SM (1 ,AR_PHY_AIC_CAL_CH_VALID_RESET ) | +SM (0 ,AR_PHY_AIC_CAL_ENABLE ) | +SM (0x40 ,AR_PHY_AIC_BTTX_PWR_THR ) | +SM (0 ,AR_PHY_AIC_ENABLE ))); + +REG_WRITE (ah,AR_PHY_AIC_CTRL_1_B0 , + (SM (8 ,AR_PHY_AIC_CAL_BT_REF_DELAY ) | +SM (0 ,AR_PHY_AIC_BT_IDLE_CFG ) | +SM (1 ,AR_PHY_AIC_STDBY_COND ) | +SM (37 ,AR_PHY_AIC_STDBY_ROT_ATT_DB ) | +SM (5 ,AR_PHY_AIC_STDBY_COM_ATT_DB ) | +SM (15 ,AR_PHY_AIC_RSSI_MAX ) | +SM (0 ,AR_PHY_AIC_RSSI_MIN ))); + +REG_WRITE (ah,AR_PHY_AIC_CTRL_1_B1 , + (SM (15 ,AR_PHY_AIC_RSSI_MAX ) | +SM (0 ,AR_PHY_AIC_RSSI_MIN ))); + +REG_WRITE (ah,AR_PHY_AIC_CTRL_2_B0 , + (SM (44 ,AR_PHY_AIC_RADIO_DELAY ) | +SM (8 ,AR_PHY_AIC_CAL_STEP_SIZE_CORR ) | +SM (12 ,AR_PHY_AIC_CAL_ROT_IDX_CORR ) | +SM (2 ,AR_PHY_AIC_CAL_CONV_CHECK_FACTOR ) | +SM (5 ,AR_PHY_AIC_ROT_IDX_COUNT_MAX ) | +SM (0 ,AR_PHY_AIC_CAL_SYNTH_TOGGLE ) | +SM (0 ,AR_PHY_AIC_CAL_SYNTH_AFTER_BTRX ) | +SM (200 ,AR_PHY_AIC_CAL_SYNTH_SETTLING ))); + +REG_WRITE (ah,AR_PHY_AIC_CTRL_3_B0 , + (SM (2 ,AR_PHY_AIC_MON_MAX_HOP_COUNT ) | +SM (1 ,AR_PHY_AIC_MON_MIN_STALE_COUNT ) | +SM (1 ,AR_PHY_AIC_MON_PWR_EST_LONG ) | +SM (2 ,AR_PHY_AIC_MON_PD_TALLY_SCALING ) | +SM (10 ,AR_PHY_AIC_MON_PERF_THR ) | +SM (2 ,AR_PHY_AIC_CAL_TARGET_MAG_SETTING ) | +SM (1 ,AR_PHY_AIC_CAL_PERF_CHECK_FACTOR ) | +SM (1 ,AR_PHY_AIC_CAL_PWR_EST_LONG ))); + +REG_WRITE (ah,AR_PHY_AIC_CTRL_4_B0 , + (SM (2 ,AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO ) | +SM (3 ,AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO ) | +SM (0 ,AR_PHY_AIC_CAL_ISO_EST_INIT_SETTING ) | +SM (2 ,AR_PHY_AIC_CAL_COM_ATT_DB_BACKOFF ) | +SM (1 ,AR_PHY_AIC_CAL_COM_ATT_DB_FIXED ))); + +REG_WRITE (ah,AR_PHY_AIC_CTRL_4_B1 , + (SM (2 ,AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO ) | +SM (3 ,AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO ) | +SM (0 ,AR_PHY_AIC_CAL_ISO_EST_INIT_SETTING ) | +SM (2 ,AR_PHY_AIC_CAL_COM_ATT_DB_BACKOFF ) | +SM (1 ,AR_PHY_AIC_CAL_COM_ATT_DB_FIXED ))); + +ar9003_aic_gain_table (ah); + +/* Need to enable AIC reference signal in BT modem. */ +REG_WRITE (ah,ATH_AIC_BT_JUPITER_CTRL , + (REG_READ (ah,ATH_AIC_BT_JUPITER_CTRL ) | +ATH_AIC_BT_AIC_ENABLE )); + + aic->aic_cal_start_time =REG_READ (ah,AR_TSF_L32 ); + +/* Start calibration */ +REG_CLR_BIT (ah,AR_PHY_AIC_CTRL_0_B1 ,AR_PHY_AIC_CAL_ENABLE ); +REG_SET_BIT (ah,AR_PHY_AIC_CTRL_0_B1 ,AR_PHY_AIC_CAL_CH_VALID_RESET ); +REG_SET_BIT (ah,AR_PHY_AIC_CTRL_0_B1 ,AR_PHY_AIC_CAL_ENABLE ); + + aic->aic_caled_chan =0 ; + aic->aic_cal_state =AIC_CAL_STATE_STARTED ; +} + +u8 ar9003_aic_calibration_single (struct ath_hw *ah) +{ +struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; +u8 cal_ret =0 ; +int num_chan; + + num_chan =MS (mci_hw->config,ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN ); + +ar9003_aic_cal_start (ah, num_chan); + +return cal_ret; +} +void ar9003_hw_attach_aic_ops (struct ath_hw *ah) {struct ath_hw_private_ops *priv_ops =ath9k_hw_private_ops (ah);
drivers/net/wireless/ath/ath9k/ar9003_aic.h +9 -0
@@ -31,6 +31,13 @@#define ATH_AIC_BT_JUPITER_CTRL 0x66820#define ATH_AIC_BT_AIC_ENABLE 0x02 +enum aic_cal_state { +AIC_CAL_STATE_IDLE =0 , +AIC_CAL_STATE_STARTED , +AIC_CAL_STATE_DONE , +AIC_CAL_STATE_ERROR +}; +struct ath_aic_sram_info {bool valid:1 ;bool vga_quad_sign:1 ;
@@ -46,4 +53,6 @@ struct ath_aic_out_info { struct ath_aic_sram_info sram; }; +u8 ar9003_aic_calibration_single (struct ath_hw *ah); +#endif /* AR9003_AIC_H */
drivers/net/wireless/ath/ath9k/ar9003_mci.c +4 -0
@@ -19,6 +19,7 @@#include "hw-ops.h" #include "ar9003_phy.h" #include "ar9003_mci.h" +#include "ar9003_aic.h" static void ar9003_mci_reset_req_wakeup (struct ath_hw *ah) {
@@ -1362,6 +1363,9 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ?1 :0 ; mci->need_flush_btinfo = false;break ; +case MCI_STATE_AIC_CAL_SINGLE : + value =ar9003_aic_calibration_single (ah); +break ;default :break ; }
drivers/net/wireless/ath/ath9k/btcoex.h +1 -0
@@ -107,6 +107,7 @@ struct ath9k_hw_aic {struct ath_btcoex_hw {enum ath_btcoex_scheme scheme;struct ath9k_hw_mci mci; +struct ath9k_hw_aic aic;bool enabled;u8 wlanactive_gpio;u8 btactive_gpio;
Signature · 1 line
2.3.1
PATCH v2 5/11 ath9k: Finish AIC calibration
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
Set the appropriate bits in the HW after
AIC calibration is done.
--- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 78 ++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath9k/ar9003_aic.c +77 -1
@@ -186,15 +186,91 @@ static void ar9003_aic_cal_start(struct ath_hw *ah, u8 min_valid_count) aic->aic_cal_state =AIC_CAL_STATE_STARTED ; } +static void ar9003_aic_cal_done (struct ath_hw *ah) +{ +/* Disable AIC reference signal in BT modem. */ +REG_WRITE (ah,ATH_AIC_BT_JUPITER_CTRL , + (REG_READ (ah,ATH_AIC_BT_JUPITER_CTRL ) & + ~ATH_AIC_BT_AIC_ENABLE )); +} + +static u8 ar9003_aic_cal_continue (struct ath_hw *ah,bool cal_once) +{ +struct ath_common *common =ath9k_hw_common (ah); +struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; +struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; +int i, num_chan; + + num_chan =MS (mci_hw->config,ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN ); + +if (!num_chan) { + aic->aic_cal_state =AIC_CAL_STATE_ERROR ; +return aic->aic_cal_state; + } + +if (cal_once) { +for (i =0 ; i <10000 ; i++) { +if ((REG_READ (ah,AR_PHY_AIC_CTRL_0_B1 ) & +AR_PHY_AIC_CAL_ENABLE ) ==0 ) +break ; + +udelay (100 ); + } + } + +/* +* Use AR_PHY_AIC_CAL_ENABLE bit instead of AR_PHY_AIC_CAL_DONE. +* Sometimes CAL_DONE bit is not asserted. +*/ +if ((REG_READ (ah,AR_PHY_AIC_CTRL_0_B1 ) & +AR_PHY_AIC_CAL_ENABLE ) !=0 ) { +ath_dbg (common,MCI ,"AIC cal is not done after 40ms" ); + goto exit; + } + +REG_WRITE (ah,AR_PHY_AIC_SRAM_ADDR_B1 , + (ATH_AIC_SRAM_CAL_OFFSET |ATH_AIC_SRAM_AUTO_INCREMENT )); + +for (i =0 ; i <ATH_AIC_MAX_BT_CHANNEL ; i++) { +u32 value; + + value =REG_READ (ah,AR_PHY_AIC_SRAM_DATA_B1 ); + +if (value &0x01 ) { +if (aic->aic_sram[i] ==0 ) + aic->aic_caled_chan++; + + aic->aic_sram[i] = value; + +if (!cal_once) +break ; + } + } + +if ((aic->aic_caled_chan >= num_chan) || cal_once) { +ar9003_aic_cal_done (ah); + }else { +/* Start calibration */ +REG_CLR_BIT (ah,AR_PHY_AIC_CTRL_0_B1 ,AR_PHY_AIC_CAL_ENABLE ); +REG_SET_BIT (ah,AR_PHY_AIC_CTRL_0_B1 , +AR_PHY_AIC_CAL_CH_VALID_RESET ); +REG_SET_BIT (ah,AR_PHY_AIC_CTRL_0_B1 ,AR_PHY_AIC_CAL_ENABLE ); + } +exit: +return aic->aic_cal_state; + +} +u8 ar9003_aic_calibration_single (struct ath_hw *ah) {struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; -u8 cal_ret =0 ; +u8 cal_ret;int num_chan; num_chan =MS (mci_hw->config,ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN );ar9003_aic_cal_start (ah, num_chan); + cal_ret =ar9003_aic_cal_continue (ah, true);return cal_ret; }
Signature · 1 line
2.3.1
PATCH v2 6/11 ath9k: Process the AIC calibration results
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
This patch adds support for post-processing
the AIC calibration results.
--- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 245 ++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+)
drivers/net/wireless/ath/ath9k/ar9003_aic.c +245 -0
@@ -20,6 +20,22 @@#include "ar9003_aic.h" #include "reg_aic.h" +static const u8 com_att_db_table[ATH_AIC_MAX_COM_ATT_DB_TABLE ] = { +0 ,3 ,9 ,15 ,21 ,27 +}; + +static const u16 aic_lin_table[ATH_AIC_MAX_AIC_LIN_TABLE ] = { +8191 ,7300 ,6506 ,5799 ,5168 ,4606 ,4105 ,3659 , +3261 ,2906 ,2590 ,2309 ,2057 ,1834 ,1634 ,1457 , +1298 ,1157 ,1031 ,919 ,819 ,730 ,651 ,580 , +517 ,461 ,411 ,366 ,326 ,291 ,259 ,231 , +206 ,183 ,163 ,146 ,130 ,116 ,103 ,92 , +82 ,73 ,65 ,58 ,52 ,46 ,41 ,37 , +33 ,29 ,26 ,23 ,21 ,18 ,16 ,15 , +13 ,12 ,10 ,9 ,8 ,7 ,7 ,6 , +5 ,5 ,4 ,4 ,3 +}; +static bool ar9003_hw_is_aic_enabled (struct ath_hw *ah) {struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
@@ -30,6 +46,56 @@ static bool ar9003_hw_is_aic_enabled(struct ath_hw *ah)return true; } +static int16_t ar9003_aic_find_valid (struct ath_aic_sram_info *cal_sram, +bool dir,u8 index) +{ +int16_t i; + +if (dir) { +for (i = index +1 ; i <ATH_AIC_MAX_BT_CHANNEL ; i++) { +if (cal_sram[i].valid) +break ; + } + }else { +for (i = index -1 ; i >=0 ; i--) { +if (cal_sram[i].valid) +break ; + } + } + +if ((i >=ATH_AIC_MAX_BT_CHANNEL ) || (i <0 )) + i =-1 ; + +return i; +} + +/* +* type 0: aic_lin_table, 1: com_att_db_table +*/ +static int16_t ar9003_aic_find_index (u8 type,int16_t value) +{ +int16_t i =-1 ; + +if (type ==0 ) { +for (i =ATH_AIC_MAX_AIC_LIN_TABLE -1 ; i >=0 ; i--) { +if (aic_lin_table[i] >= value) +break ; + } + }else if (type ==1 ) { +for (i =0 ; i <ATH_AIC_MAX_COM_ATT_DB_TABLE ; i++) { +if (com_att_db_table[i] > value) { + i--; +break ; + } + } + +if (i >=ATH_AIC_MAX_COM_ATT_DB_TABLE ) + i =-1 ; + } + +return i; +} +static void ar9003_aic_gain_table (struct ath_hw *ah) {u32 aic_atten_word[19 ], i;
@@ -186,12 +252,191 @@ static void ar9003_aic_cal_start(struct ath_hw *ah, u8 min_valid_count) aic->aic_cal_state =AIC_CAL_STATE_STARTED ; } +static bool ar9003_aic_cal_post_process (struct ath_hw *ah) +{ +struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; +struct ath_aic_sram_info cal_sram[ATH_AIC_MAX_BT_CHANNEL ]; +struct ath_aic_out_info aic_sram[ATH_AIC_MAX_BT_CHANNEL ]; +u32 dir_path_gain_idx, quad_path_gain_idx, value; +u32 fixed_com_att_db; +int8_t dir_path_sign, quad_path_sign; +int16_t i; +bool ret = true; + +memset (&cal_sram,0 ,sizeof (cal_sram)); +memset (&aic_sram,0 ,sizeof (aic_sram)); + +for (i =0 ; i <ATH_AIC_MAX_BT_CHANNEL ; i++) { + value = aic->aic_sram[i]; + + cal_sram[i].valid = +MS (value,AR_PHY_AIC_SRAM_VALID ); + cal_sram[i].rot_quad_att_db = +MS (value,AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB ); + cal_sram[i].vga_quad_sign = +MS (value,AR_PHY_AIC_SRAM_VGA_QUAD_SIGN ); + cal_sram[i].rot_dir_att_db = +MS (value,AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB ); + cal_sram[i].vga_dir_sign = +MS (value,AR_PHY_AIC_SRAM_VGA_DIR_SIGN ); + cal_sram[i].com_att_6db = +MS (value,AR_PHY_AIC_SRAM_COM_ATT_6DB ); + +if (cal_sram[i].valid) { + dir_path_gain_idx = cal_sram[i].rot_dir_att_db + + com_att_db_table[cal_sram[i].com_att_6db]; + quad_path_gain_idx = cal_sram[i].rot_quad_att_db + + com_att_db_table[cal_sram[i].com_att_6db]; + + dir_path_sign = (cal_sram[i].vga_dir_sign) ?1 :-1 ; + quad_path_sign = (cal_sram[i].vga_quad_sign) ?1 :-1 ; + + aic_sram[i].dir_path_gain_lin = dir_path_sign * + aic_lin_table[dir_path_gain_idx]; + aic_sram[i].quad_path_gain_lin = quad_path_sign * + aic_lin_table[quad_path_gain_idx]; + } + } + +for (i =0 ; i <ATH_AIC_MAX_BT_CHANNEL ; i++) { +int16_t start_idx, end_idx; + +if (cal_sram[i].valid) +continue ; + + start_idx =ar9003_aic_find_valid (cal_sram,0 , i); + end_idx =ar9003_aic_find_valid (cal_sram,1 , i); + +if (start_idx <0 ) { +/* extrapolation */ + start_idx = end_idx; + end_idx =ar9003_aic_find_valid (cal_sram,1 , start_idx); + +if (end_idx <0 ) { + ret = false; +break ; + } + + aic_sram[i].dir_path_gain_lin = + ((aic_sram[start_idx].dir_path_gain_lin - + aic_sram[end_idx].dir_path_gain_lin) * + (start_idx - i) + ((end_idx - i) >>1 )) / + (end_idx - i) + + aic_sram[start_idx].dir_path_gain_lin; + aic_sram[i].quad_path_gain_lin = + ((aic_sram[start_idx].quad_path_gain_lin - + aic_sram[end_idx].quad_path_gain_lin) * + (start_idx - i) + ((end_idx - i) >>1 )) / + (end_idx - i) + + aic_sram[start_idx].quad_path_gain_lin; + } + +if (end_idx <0 ) { +/* extrapolation */ + end_idx =ar9003_aic_find_valid (cal_sram,0 , start_idx); + +if (end_idx <0 ) { + ret = false; +break ; + } + + aic_sram[i].dir_path_gain_lin = + ((aic_sram[start_idx].dir_path_gain_lin - + aic_sram[end_idx].dir_path_gain_lin) * + (i - start_idx) + ((start_idx - end_idx) >>1 )) / + (start_idx - end_idx) + + aic_sram[start_idx].dir_path_gain_lin; + aic_sram[i].quad_path_gain_lin = + ((aic_sram[start_idx].quad_path_gain_lin - + aic_sram[end_idx].quad_path_gain_lin) * + (i - start_idx) + ((start_idx - end_idx) >>1 )) / + (start_idx - end_idx) + + aic_sram[start_idx].quad_path_gain_lin; + + }else if (start_idx >=0 ){ +/* interpolation */ + aic_sram[i].dir_path_gain_lin = + (((end_idx - i) * aic_sram[start_idx].dir_path_gain_lin) + + ((i - start_idx) * aic_sram[end_idx].dir_path_gain_lin) + + ((end_idx - start_idx) >>1 )) / + (end_idx - start_idx); + aic_sram[i].quad_path_gain_lin = + (((end_idx - i) * aic_sram[start_idx].quad_path_gain_lin) + + ((i - start_idx) * aic_sram[end_idx].quad_path_gain_lin) + + ((end_idx - start_idx) >>1 ))/ + (end_idx - start_idx); + } + } + +/* From dir/quad_path_gain_lin to sram. */ + i =ar9003_aic_find_valid (cal_sram,1 ,0 ); +if (i <0 ) { + i =0 ; + ret = false; + } + fixed_com_att_db = com_att_db_table[cal_sram[i].com_att_6db]; + +for (i =0 ; i <ATH_AIC_MAX_BT_CHANNEL ; i++) { +int16_t rot_dir_path_att_db, rot_quad_path_att_db; + + aic_sram[i].sram.vga_dir_sign = + (aic_sram[i].dir_path_gain_lin >=0 ) ?1 :0 ; + aic_sram[i].sram.vga_quad_sign= + (aic_sram[i].quad_path_gain_lin >=0 ) ?1 :0 ; + + rot_dir_path_att_db = +ar9003_aic_find_index (0 ,abs (aic_sram[i].dir_path_gain_lin)) - + fixed_com_att_db; + rot_quad_path_att_db = +ar9003_aic_find_index (0 ,abs (aic_sram[i].quad_path_gain_lin)) - + fixed_com_att_db; + + aic_sram[i].sram.com_att_6db = +ar9003_aic_find_index (1 , fixed_com_att_db); + + aic_sram[i].sram.valid =1 ; + + aic_sram[i].sram.rot_dir_att_db = +min (max (rot_dir_path_att_db, + (int16_t )ATH_AIC_MIN_ROT_DIR_ATT_DB ), +ATH_AIC_MAX_ROT_DIR_ATT_DB ); + aic_sram[i].sram.rot_quad_att_db = +min (max (rot_quad_path_att_db, + (int16_t )ATH_AIC_MIN_ROT_QUAD_ATT_DB ), +ATH_AIC_MAX_ROT_QUAD_ATT_DB ); + } + +for (i =0 ; i <ATH_AIC_MAX_BT_CHANNEL ; i++) { + aic->aic_sram[i] = (SM (aic_sram[i].sram.vga_dir_sign, +AR_PHY_AIC_SRAM_VGA_DIR_SIGN ) | +SM (aic_sram[i].sram.vga_quad_sign, +AR_PHY_AIC_SRAM_VGA_QUAD_SIGN ) | +SM (aic_sram[i].sram.com_att_6db, +AR_PHY_AIC_SRAM_COM_ATT_6DB ) | +SM (aic_sram[i].sram.valid, +AR_PHY_AIC_SRAM_VALID ) | +SM (aic_sram[i].sram.rot_dir_att_db, +AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB ) | +SM (aic_sram[i].sram.rot_quad_att_db, +AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB )); + } + +return ret; +} +static void ar9003_aic_cal_done (struct ath_hw *ah) { +struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; +/* Disable AIC reference signal in BT modem. */ REG_WRITE (ah,ATH_AIC_BT_JUPITER_CTRL , (REG_READ (ah,ATH_AIC_BT_JUPITER_CTRL ) & ~ATH_AIC_BT_AIC_ENABLE )); + +if (ar9003_aic_cal_post_process (ah)) + aic->aic_cal_state =AIC_CAL_STATE_DONE ; +else + aic->aic_cal_state =AIC_CAL_STATE_ERROR ; }static u8 ar9003_aic_cal_continue (struct ath_hw *ah,bool cal_once)
Signature · 1 line
2.3.1
PATCH v2 7/11 ath9k: Disable AIC by default
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
Since various MCI messages need to be
handled, along with driver-level support
in upper layers, disable AIC for now.
--- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 6 ++++++ drivers/net/wireless/ath/ath9k/ar9003_mci.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath9k/ar9003_aic.c +6 -0
@@ -40,6 +40,12 @@ static bool ar9003_hw_is_aic_enabled(struct ath_hw *ah) {struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; +/* +* Disable AIC for now, until we have all the +* HW code and the driver-layer support ready. +*/ +return false; +if (mci_hw->config &ATH_MCI_CONFIG_DISABLE_AIC )return false;
drivers/net/wireless/ath/ath9k/ar9003_mci.c +2 -1
@@ -1364,7 +1364,8 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) mci->need_flush_btinfo = false;break ;case MCI_STATE_AIC_CAL_SINGLE : - value =ar9003_aic_calibration_single (ah); +if (ath9k_hw_is_aic_enabled (ah)) + value =ar9003_aic_calibration_single (ah);break ;default :break ;
Signature · 1 line
2.3.1
PATCH v2 8/11 ath9k: Handle MCI_STATE_AIC_CAL_RESET
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
Add a routine to handle the MCI_STATE_AIC_CAL_RESET message.
--- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 8 ++++++++ drivers/net/wireless/ath/ath9k/ar9003_aic.h | 1 + drivers/net/wireless/ath/ath9k/ar9003_mci.c | 4 ++++ 3 files changed, 13 insertions(+)
drivers/net/wireless/ath/ath9k/ar9003_aic.c +8 -0
@@ -512,6 +512,14 @@ exit: } +u8 ar9003_aic_cal_reset (struct ath_hw *ah) +{ +struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; + + aic->aic_cal_state =AIC_CAL_STATE_IDLE ; +return aic->aic_cal_state; +} +u8 ar9003_aic_calibration_single (struct ath_hw *ah) {struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
drivers/net/wireless/ath/ath9k/ar9003_aic.h +1 -0
@@ -53,6 +53,7 @@ struct ath_aic_out_info { struct ath_aic_sram_info sram; }; +u8 ar9003_aic_cal_reset (struct ath_hw *ah);u8 ar9003_aic_calibration_single (struct ath_hw *ah);#endif /* AR9003_AIC_H */
drivers/net/wireless/ath/ath9k/ar9003_mci.c +4 -0
@@ -1363,6 +1363,10 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ?1 :0 ; mci->need_flush_btinfo = false;break ; +case MCI_STATE_AIC_CAL_RESET : +if (ath9k_hw_is_aic_enabled (ah)) + value =ar9003_aic_cal_reset (ah); +break ;case MCI_STATE_AIC_CAL_SINGLE :if (ath9k_hw_is_aic_enabled (ah)) value =ar9003_aic_calibration_single (ah);
Signature · 1 line
2.3.1
PATCH v2 9/11 ath9k: Handle MCI_STATE_AIC_START
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
This patch adds a function to handle the
MCI message MCI_STATE_AIC_START.
--- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 33 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_aic.h | 1 + drivers/net/wireless/ath/ath9k/ar9003_mci.c | 4 ++++ 3 files changed, 38 insertions(+)
drivers/net/wireless/ath/ath9k/ar9003_aic.c +33 -0
@@ -18,6 +18,7 @@#include "hw-ops.h" #include "ar9003_mci.h" #include "ar9003_aic.h" +#include "ar9003_phy.h" #include "reg_aic.h" static const u8 com_att_db_table[ATH_AIC_MAX_COM_ATT_DB_TABLE ] = {
@@ -512,6 +513,38 @@ exit: } +u8 ar9003_aic_start_normal (struct ath_hw *ah) +{ +struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; +int16_t i; + +if (aic->aic_cal_state !=AIC_CAL_STATE_DONE ) +return 1 ; + +ar9003_aic_gain_table (ah); + +REG_WRITE (ah,AR_PHY_AIC_SRAM_ADDR_B1 ,ATH_AIC_SRAM_AUTO_INCREMENT ); + +for (i =0 ; i <ATH_AIC_MAX_BT_CHANNEL ; i++) { +REG_WRITE (ah,AR_PHY_AIC_SRAM_DATA_B1 , aic->aic_sram[i]); + } + +/* FIXME: Replace these with proper register names */ +REG_WRITE (ah,0xa6b0 ,0x80 ); +REG_WRITE (ah,0xa6b4 ,0x5b2df0 ); +REG_WRITE (ah,0xa6b8 ,0x10762cc8 ); +REG_WRITE (ah,0xa6bc ,0x1219a4b ); +REG_WRITE (ah,0xa6c0 ,0x1e01 ); +REG_WRITE (ah,0xb6b4 ,0xf0 ); +REG_WRITE (ah,0xb6c0 ,0x1e01 ); +REG_WRITE (ah,0xb6b0 ,0x81 ); +REG_WRITE (ah,AR_PHY_65NM_CH1_RXTX4 ,0x40000000 ); + + aic->aic_enabled = true; + +return 0 ; +} +u8 ar9003_aic_cal_reset (struct ath_hw *ah) {struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
drivers/net/wireless/ath/ath9k/ar9003_aic.h +1 -0
@@ -53,6 +53,7 @@ struct ath_aic_out_info {struct ath_aic_sram_info sram; }; +u8 ar9003_aic_start_normal (struct ath_hw *ah);u8 ar9003_aic_cal_reset (struct ath_hw *ah);u8 ar9003_aic_calibration_single (struct ath_hw *ah);
drivers/net/wireless/ath/ath9k/ar9003_mci.c +4 -0
@@ -1363,6 +1363,10 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ?1 :0 ; mci->need_flush_btinfo = false;break ; +case MCI_STATE_AIC_START : +if (ath9k_hw_is_aic_enabled (ah)) +ar9003_aic_start_normal (ah); +break ;case MCI_STATE_AIC_CAL_RESET :if (ath9k_hw_is_aic_enabled (ah)) value =ar9003_aic_cal_reset (ah);
Signature · 1 line
2.3.1
PATCH v2 10/11 ath9k: Handle MCI_STATE_AIC_CAL
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
Add the main AIC calibration function to
handle MCI_STATE_AIC_CAL.
--- drivers/net/wireless/ath/ath9k/ar9003_aic.c | 28 ++++++++++++++++++++++++++-- drivers/net/wireless/ath/ath9k/ar9003_aic.h | 1 + drivers/net/wireless/ath/ath9k/ar9003_mci.c | 4 ++++ 3 files changed, 31 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/ar9003_aic.c +26 -2
@@ -162,7 +162,7 @@ static void ar9003_aic_gain_table(struct ath_hw *ah) } } -static void ar9003_aic_cal_start (struct ath_hw *ah,u8 min_valid_count) +static u8 ar9003_aic_cal_start (struct ath_hw *ah,u8 min_valid_count) {struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;int i;
@@ -257,6 +257,8 @@ static void ar9003_aic_cal_start(struct ath_hw *ah, u8 min_valid_count) aic->aic_caled_chan =0 ; aic->aic_cal_state =AIC_CAL_STATE_STARTED ; + +return aic->aic_cal_state; }static bool ar9003_aic_cal_post_process (struct ath_hw *ah)
@@ -513,6 +515,28 @@ exit: } +u8 ar9003_aic_calibration (struct ath_hw *ah) +{ +struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; +u8 cal_ret =AIC_CAL_STATE_ERROR ; + +switch (aic->aic_cal_state) { +case AIC_CAL_STATE_IDLE : + cal_ret =ar9003_aic_cal_start (ah,1 ); +break ; +case AIC_CAL_STATE_STARTED : + cal_ret =ar9003_aic_cal_continue (ah, false); +break ; +case AIC_CAL_STATE_DONE : + cal_ret =AIC_CAL_STATE_DONE ; +break ; +default : +break ; + } + +return cal_ret; +} +u8 ar9003_aic_start_normal (struct ath_hw *ah) {struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
@@ -561,7 +585,7 @@ u8 ar9003_aic_calibration_single(struct ath_hw *ah) num_chan =MS (mci_hw->config,ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN ); -ar9003_aic_cal_start (ah, num_chan); + (void )ar9003_aic_cal_start (ah, num_chan); cal_ret =ar9003_aic_cal_continue (ah, true);return cal_ret;
drivers/net/wireless/ath/ath9k/ar9003_aic.h +1 -0
@@ -53,6 +53,7 @@ struct ath_aic_out_info {struct ath_aic_sram_info sram; }; +u8 ar9003_aic_calibration (struct ath_hw *ah);u8 ar9003_aic_start_normal (struct ath_hw *ah);u8 ar9003_aic_cal_reset (struct ath_hw *ah);u8 ar9003_aic_calibration_single (struct ath_hw *ah);
drivers/net/wireless/ath/ath9k/ar9003_mci.c +4 -0
@@ -1363,6 +1363,10 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ?1 :0 ; mci->need_flush_btinfo = false;break ; +case MCI_STATE_AIC_CAL : +if (ath9k_hw_is_aic_enabled (ah)) + value =ar9003_aic_calibration (ah); +break ;case MCI_STATE_AIC_START :if (ath9k_hw_is_aic_enabled (ah))ar9003_aic_start_normal (ah);
Signature · 1 line
2.3.1
PATCH v2 11/11 ath9k: Start AIC calibration during MCI reset
In reply to Sujith ManoharanFrom: Sujith Manoharan <[email protected]>
When a MCI reset is done, make sure that AIC
is started.
--- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/ath/ath9k/ar9003_mci.c +3 -0
@@ -1017,6 +1017,9 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,if (en_int)ar9003_mci_enable_interrupt (ah); +if (ath9k_hw_is_aic_enabled (ah)) +ar9003_aic_start_normal (ah); +return 0 ; }
Signature · 1 line
2.3.1