summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2011-01-01 13:44:43 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2011-01-01 13:44:43 +0000
commit986975698d5df2adf73f5ae068d98c756a426c49 (patch)
treed27e37cbe14cccc39c312824978ce53c82165113
parent6f75bc374e5c3fe755b9cd7b959fc2835e2b112b (diff)
more AR9380/AR9485 bits.
add Tx gain initvals for high-power AR9380 solutions.
-rw-r--r--sys/dev/ic/ar9003.c11
-rw-r--r--sys/dev/ic/ar9003reg.h69
-rw-r--r--sys/dev/ic/ar9380.c184
-rw-r--r--sys/dev/ic/ar9380reg.h67
4 files changed, 295 insertions, 36 deletions
diff --git a/sys/dev/ic/ar9003.c b/sys/dev/ic/ar9003.c
index 4c3da50dbb3..9d94b427d16 100644
--- a/sys/dev/ic/ar9003.c
+++ b/sys/dev/ic/ar9003.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar9003.c,v 1.21 2011/01/01 10:48:31 damien Exp $ */
+/* $OpenBSD: ar9003.c,v 1.22 2011/01/01 13:44:42 damien Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -231,7 +231,7 @@ ar9003_attach(struct athn_softc *sc)
}
/*
- * Read 16-bit word from ROM.
+ * Read 16-bit word from EEPROM.
*/
int
ar9003_read_eep_word(struct athn_softc *sc, uint32_t addr, uint16_t *val)
@@ -254,7 +254,7 @@ ar9003_read_eep_word(struct athn_softc *sc, uint32_t addr, uint16_t *val)
}
/*
- * Read an arbitrary number of bytes at a specified address in ROM.
+ * Read an arbitrary number of bytes at a specified address in EEPROM.
* NB: The address may not be 16-bit aligned.
*/
int
@@ -2461,7 +2461,10 @@ ar9003_paprd_calib(struct athn_softc *sc, struct ieee80211_channel *c)
reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_COARSE_CORR_LEN, 4);
reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_NUM_CORR_STAGES, 7);
reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_MIN_LOOPBACK_DEL, 1);
- reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_QUICK_DROP, -6);
+ if (AR_SREV_9485(sc))
+ reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_QUICK_DROP, -3);
+ else
+ reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_QUICK_DROP, -6);
reg = RW(reg, AR_PHY_PAPRD_TRAINER_CNTL3_ADC_DESIRED_SIZE, -15);
reg |= AR_PHY_PAPRD_TRAINER_CNTL3_BBTXMIX_DISABLE;
AR_WRITE(sc, AR_PHY_PAPRD_TRAINER_CNTL3, reg);
diff --git a/sys/dev/ic/ar9003reg.h b/sys/dev/ic/ar9003reg.h
index bbd31dcb823..fbf170f8f19 100644
--- a/sys/dev/ic/ar9003reg.h
+++ b/sys/dev/ic/ar9003reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar9003reg.h,v 1.6 2011/01/01 10:48:31 damien Exp $ */
+/* $OpenBSD: ar9003reg.h,v 1.7 2011/01/01 13:44:42 damien Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -228,12 +228,16 @@
#define AR_PHY_65NM_CH0_RXTX1 0x16100
#define AR_PHY_65NM_CH0_RXTX2 0x16104
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
+#define AR9485_PHY_65NM_CH0_TOP2 0x16284
#define AR_PHY_65NM_CH0_TOP 0x16288
#define AR_PHY_65NM_CH0_THERM 0x16290
+#define AR9485_PHY_CH0_XTAL 0x16290
#define AR_PHY_65NM_CH1_RXTX1 0x16500
#define AR_PHY_65NM_CH1_RXTX2 0x16504
#define AR_PHY_65NM_CH2_RXTX1 0x16900
#define AR_PHY_65NM_CH2_RXTX2 0x16904
+#define AR_PHY_PMU1 0x16c40
+#define AR_PHY_PMU2 0x16c44
/* Bits for AR_PHY_TIMING2. */
@@ -498,6 +502,11 @@
#define AR_PHY_RESTART_DIV_GC_M 0x001c0000
#define AR_PHY_RESTART_DIV_GC_S 18
+/* Bits for AR_PHY_MC_GAIN_CTRL. */
+#define AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV 0x01000000
+#define AR_PHY_MC_GAIN_CTRL_ANT_DIV_CTRL_ALL_M 0x7e000000
+#define AR_PHY_MC_GAIN_CTRL_ANT_DIV_CTRL_ALL_S 25
+
/* Bits for AR_PHY_CCK_DETECT. */
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_M 0x0000003f
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
@@ -831,9 +840,55 @@
#define AR9380_FRACMODE 0x40000000
#define AR9380_LOAD_SYNTH 0x80000000
+/* Bits for AR_PHY_65NM_CH0_BIAS1. */
+#define AR_PHY_65NM_CH0_BIAS1_0_M 0x000001c0
+#define AR_PHY_65NM_CH0_BIAS1_0_S 6
+#define AR_PHY_65NM_CH0_BIAS1_1_M 0x00000e00
+#define AR_PHY_65NM_CH0_BIAS1_1_S 9
+#define AR_PHY_65NM_CH0_BIAS1_2_M 0x00007000
+#define AR_PHY_65NM_CH0_BIAS1_2_S 12
+#define AR_PHY_65NM_CH0_BIAS1_3_M 0x00038000
+#define AR_PHY_65NM_CH0_BIAS1_3_S 15
+#define AR_PHY_65NM_CH0_BIAS1_4_M 0x001c0000
+#define AR_PHY_65NM_CH0_BIAS1_4_S 18
+#define AR_PHY_65NM_CH0_BIAS1_5_M 0x00e00000
+#define AR_PHY_65NM_CH0_BIAS1_5_S 21
+
+/* Bits for AR_PHY_65NM_CH0_BIAS2. */
+#define AR_PHY_65NM_CH0_BIAS2_0_M 0x000000e0
+#define AR_PHY_65NM_CH0_BIAS2_0_S 5
+#define AR_PHY_65NM_CH0_BIAS2_1_M 0x00000700
+#define AR_PHY_65NM_CH0_BIAS2_1_S 8
+#define AR_PHY_65NM_CH0_BIAS2_2_M 0x00003800
+#define AR_PHY_65NM_CH0_BIAS2_2_S 11
+#define AR_PHY_65NM_CH0_BIAS2_3_M 0x0001c000
+#define AR_PHY_65NM_CH0_BIAS2_3_S 14
+#define AR_PHY_65NM_CH0_BIAS2_4_M 0x000e0000
+#define AR_PHY_65NM_CH0_BIAS2_4_S 17
+#define AR_PHY_65NM_CH0_BIAS2_5_M 0x00700000
+#define AR_PHY_65NM_CH0_BIAS2_5_S 20
+#define AR_PHY_65NM_CH0_BIAS2_6_M 0x03800000
+#define AR_PHY_65NM_CH0_BIAS2_6_S 23
+#define AR_PHY_65NM_CH0_BIAS2_7_M 0x1c000000
+#define AR_PHY_65NM_CH0_BIAS2_7_S 26
+#define AR_PHY_65NM_CH0_BIAS2_8_M 0xe0000000
+#define AR_PHY_65NM_CH0_BIAS2_8_S 29
+
+/* Bits for AR_PHY_65NM_CH0_BIAS4. */
+#define AR_PHY_65NM_CH0_BIAS4_0_M 0x03800000
+#define AR_PHY_65NM_CH0_BIAS4_0_S 23
+#define AR_PHY_65NM_CH0_BIAS4_1_M 0x1c000000
+#define AR_PHY_65NM_CH0_BIAS4_1_S 26
+#define AR_PHY_65NM_CH0_BIAS4_2_M 0xe0000000
+#define AR_PHY_65NM_CH0_BIAS4_2_S 29
+
/* Bits for AR_PHY_65NM_CH0_RXTX4. */
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000
+/* Bits for AR9485_PHY_65NM_CH0_TOP2. */
+#define AR9485_PHY_65NM_CH0_TOP2_XPABIASLVL_M 0x0000f000
+#define AR9485_PHY_65NM_CH0_TOP2_XPABIASLVL_S 12
+
/* Bits for AR_PHY_65NM_CH0_TOP. */
#define AR_PHY_65NM_CH0_TOP_XPABIASLVL_M 0x00000300
#define AR_PHY_65NM_CH0_TOP_XPABIASLVL_S 8
@@ -847,6 +902,18 @@
#define AR_PHY_65NM_CH0_THERM_START 0x20000000
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
+/* Bits for AR9485_PHY_CH0_XTAL. */
+#define AR9485_PHY_CH0_XTAL_CAPINDAC_M 0x7f000000
+#define AR9485_PHY_CH0_XTAL_CAPINDAC_S 24
+#define AR9485_PHY_CH0_XTAL_CAPOUTDAC_M 0x00fe0000
+#define AR9485_PHY_CH0_XTAL_CAPOUTDAC_S 17
+
+/* Bits for AR_PHY_PMU1. */
+#define AR_PHY_PMU1_PWD 0x00000001
+
+/* Bits for AR_PHY_PMU2. */
+#define AR_PHY_PMU2_PGM 0x00200000
+
/*
* OTP registers.
*/
diff --git a/sys/dev/ic/ar9380.c b/sys/dev/ic/ar9380.c
index 0bac740a7bd..8490e7e7604 100644
--- a/sys/dev/ic/ar9380.c
+++ b/sys/dev/ic/ar9380.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: ar9380.c,v 1.10 2011/01/01 10:48:31 damien Exp $ */
+/* $OpenBSD: ar9380.c,v 1.11 2011/01/01 13:44:42 damien Exp $ */
/*-
- * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2010 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -72,6 +72,9 @@ void ar9380_get_paprd_masks(struct athn_softc *, struct ieee80211_channel *,
uint32_t *, uint32_t *);
void ar9380_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
struct ieee80211_channel *);
+void ar9380_init_swreg(struct athn_softc *);
+int ar9485_pmu_write(struct athn_softc *, uint32_t, uint32_t);
+void ar9485_init_swreg(struct athn_softc *);
void ar9380_spur_mitigate_cck(struct athn_softc *,
struct ieee80211_channel *, struct ieee80211_channel *);
void ar9380_spur_mitigate_ofdm(struct athn_softc *,
@@ -114,7 +117,10 @@ ar9380_attach(struct athn_softc *sc)
sc->cca_max_2g = AR9380_PHY_CCA_MAX_GOOD_VAL_2GHZ;
sc->cca_min_5g = AR9380_PHY_CCA_MIN_GOOD_VAL_5GHZ;
sc->cca_max_5g = AR9380_PHY_CCA_MAX_GOOD_VAL_5GHZ;
- sc->ini = &ar9380_2_2_ini;
+ if (AR_SREV_9485(sc))
+ sc->ini = &ar9485_1_0_ini;
+ else
+ sc->ini = &ar9380_2_2_ini;
return (ar9003_attach(sc));
}
@@ -166,19 +172,27 @@ ar9380_setup(struct athn_softc *sc)
/* Select initialization values based on ROM. */
type = MS(eep->baseEepHeader.txrxgain, AR_EEP_RX_GAIN);
- if (type == AR_EEP_RX_GAIN_WO_XLNA)
- sc->rx_gain = &ar9380_2_2_rx_gain_wo_xlna;
- else
- sc->rx_gain = &ar9380_2_2_rx_gain;
+ if (!AR_SREV_9485(sc)) {
+ if (type == AR_EEP_RX_GAIN_WO_XLNA)
+ sc->rx_gain = &ar9380_2_2_rx_gain_wo_xlna;
+ else
+ sc->rx_gain = &ar9380_2_2_rx_gain;
+ } else
+ sc->rx_gain = &ar9485_1_0_rx_gain;
/* Select initialization values based on ROM. */
type = MS(eep->baseEepHeader.txrxgain, AR_EEP_TX_GAIN);
- if (type == AR_EEP_TX_GAIN_HIGH_OB_DB)
- sc->tx_gain = &ar9380_2_2_tx_gain_high_ob_db;
- else if (type == AR_EEP_TX_GAIN_LOW_OB_DB)
- sc->tx_gain = &ar9380_2_2_tx_gain_low_ob_db;
- else
- sc->tx_gain = &ar9380_2_2_tx_gain;
+ if (!AR_SREV_9485(sc)) {
+ if (type == AR_EEP_TX_GAIN_HIGH_OB_DB)
+ sc->tx_gain = &ar9380_2_2_tx_gain_high_ob_db;
+ else if (type == AR_EEP_TX_GAIN_LOW_OB_DB)
+ sc->tx_gain = &ar9380_2_2_tx_gain_low_ob_db;
+ else if (type == AR_EEP_TX_GAIN_HIGH_POWER)
+ sc->tx_gain = &ar9380_2_2_tx_gain_high_power;
+ else
+ sc->tx_gain = &ar9380_2_2_tx_gain;
+ } else
+ sc->tx_gain = &ar9485_1_0_tx_gain;
}
const uint8_t *
@@ -247,7 +261,10 @@ ar9380_set_synth(struct athn_softc *sc, struct ieee80211_channel *c,
uint32_t chansel, phy;
if (IEEE80211_IS_CHAN_2GHZ(c)) {
- chansel = (freq << 16) / 15;
+ if (AR_SREV_9485(sc))
+ chansel = ((freq << 16) - 215) / 15;
+ else
+ chansel = (freq << 16) / 15;
AR_WRITE(sc, AR_PHY_SYNTH_CONTROL, AR9380_BMODE);
} else {
chansel = (freq << 15) / 15;
@@ -277,9 +294,9 @@ ar9380_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
{
const struct ar9380_eeprom *eep = sc->eep;
const struct ar9380_modal_eep_header *modal;
- uint8_t db, margin;
+ uint8_t db, margin, ant_div_ctrl;
uint32_t reg;
- int i;
+ int i, maxchains;
if (IEEE80211_IS_CHAN_2GHZ(c))
modal = &eep->modalHeader2G;
@@ -287,15 +304,22 @@ ar9380_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
modal = &eep->modalHeader5G;
/* Apply XPA bias level. */
- reg = AR_READ(sc, AR_PHY_65NM_CH0_TOP);
- reg = RW(reg, AR_PHY_65NM_CH0_TOP_XPABIASLVL,
- modal->xpaBiasLvl & 0x3);
- AR_WRITE(sc, AR_PHY_65NM_CH0_TOP, reg);
- reg = AR_READ(sc, AR_PHY_65NM_CH0_THERM);
- reg = RW(reg, AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB,
- modal->xpaBiasLvl >> 2);
- reg |= AR_PHY_65NM_CH0_THERM_XPASHORT2GND;
- AR_WRITE(sc, AR_PHY_65NM_CH0_THERM, reg);
+ if (AR_SREV_9485(sc)) {
+ reg = AR_READ(sc, AR9485_PHY_65NM_CH0_TOP2);
+ reg = RW(reg, AR9485_PHY_65NM_CH0_TOP2_XPABIASLVL,
+ modal->xpaBiasLvl);
+ AR_WRITE(sc, AR9485_PHY_65NM_CH0_TOP2, reg);
+ } else {
+ reg = AR_READ(sc, AR_PHY_65NM_CH0_TOP);
+ reg = RW(reg, AR_PHY_65NM_CH0_TOP_XPABIASLVL,
+ modal->xpaBiasLvl & 0x3);
+ AR_WRITE(sc, AR_PHY_65NM_CH0_TOP, reg);
+ reg = AR_READ(sc, AR_PHY_65NM_CH0_THERM);
+ reg = RW(reg, AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB,
+ modal->xpaBiasLvl >> 2);
+ reg |= AR_PHY_65NM_CH0_THERM_XPASHORT2GND;
+ AR_WRITE(sc, AR_PHY_65NM_CH0_THERM, reg);
+ }
/* Apply antenna control. */
reg = AR_READ(sc, AR_PHY_SWITCH_COM);
@@ -305,29 +329,64 @@ ar9380_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
reg = RW(reg, AR_SWITCH_TABLE_COM_2_ALL, modal->antCtrlCommon2);
AR_WRITE(sc, AR_PHY_SWITCH_COM_2, reg);
- for (i = 0; i < AR9380_MAX_CHAINS; i++) {
+ maxchains = AR_SREV_9485(sc) ? 1 : AR9380_MAX_CHAINS;
+ for (i = 0; i < maxchains; i++) {
reg = AR_READ(sc, AR_PHY_SWITCH_CHAIN(i));
reg = RW(reg, AR_SWITCH_TABLE_ALL, modal->antCtrlChain[i]);
AR_WRITE(sc, AR_PHY_SWITCH_CHAIN(i), reg);
}
+ if (AR_SREV_9485(sc)) {
+ ant_div_ctrl = eep->base_ext1.ant_div_control;
+ reg = AR_READ(sc, AR_PHY_MC_GAIN_CTRL);
+ reg = RW(reg, AR_PHY_MC_GAIN_CTRL_ANT_DIV_CTRL_ALL,
+ MS(ant_div_ctrl, AR_EEP_ANT_DIV_CTRL_ALL));
+ if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_ANT_DIV)
+ reg |= AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV;
+ else
+ reg &= ~AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV;
+ AR_WRITE(sc, AR_PHY_MC_GAIN_CTRL, reg);
+ reg = AR_READ(sc, AR_PHY_CCK_DETECT);
+ if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_FAST_DIV)
+ reg |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+ else
+ reg &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+ AR_WRITE(sc, AR_PHY_CCK_DETECT, reg);
+ }
+
if (eep->baseEepHeader.miscConfiguration & AR_EEP_DRIVE_STRENGTH) {
/* Apply drive strength. */
reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS1);
- reg = (reg & ~0x00ffffc0) | 0x00b6db40;
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_0, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_1, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_2, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_3, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_4, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_5, 5);
AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS1, reg);
reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS2);
- reg = (reg & ~0xffffffe0) | 0xb6db6da0;
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_0, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_1, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_2, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_3, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_4, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_5, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_6, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_7, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_8, 5);
AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS2, reg);
reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS4);
- reg = (reg & ~0xff800000) | 0xb6800000;
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_0, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_1, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_2, 5);
AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS4, reg);
}
/* Apply attenuation settings. */
- for (i = 0; i < AR9380_MAX_CHAINS; i++) {
+ maxchains = AR_SREV_9485(sc) ? 1 : AR9380_MAX_CHAINS;
+ for (i = 0; i < maxchains; i++) {
if (IEEE80211_IS_CHAN_5GHZ(c) &&
eep->base_ext2.xatten1DBLow[i] != 0) {
if (c->ic_freq <= 5500) {
@@ -360,6 +419,30 @@ ar9380_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
AR_WRITE(sc, AR_PHY_EXT_ATTEN_CTL(i), reg);
}
+ /* Initialize switching regulator. */
+ if (AR_SREV_9485(sc))
+ ar9485_init_swreg(sc);
+ else
+ ar9485_init_swreg(sc);
+
+ /* Apply tuning capabilities. */
+ if (AR_SREV_9485(sc) &&
+ (eep->baseEepHeader.featureEnable & AR_EEP_TUNING_CAPS)) {
+ reg = AR_READ(sc, AR9485_PHY_CH0_XTAL);
+ reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPINDAC,
+ eep->baseEepHeader.params_for_tuning_caps[0]);
+ reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPOUTDAC,
+ eep->baseEepHeader.params_for_tuning_caps[0]);
+ AR_WRITE(sc, AR9485_PHY_CH0_XTAL, reg);
+ }
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar9380_init_swreg(struct athn_softc *sc)
+{
+ const struct ar9380_eeprom *eep = sc->eep;
+
if (eep->baseEepHeader.featureEnable & AR_EEP_INTERNAL_REGULATOR) {
/* Internal regulator is ON. */
AR_CLRBITS(sc, AR_RTC_REG_CONTROL1,
@@ -372,6 +455,47 @@ ar9380_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
AR_WRITE_BARRIER(sc);
}
+int
+ar9485_pmu_write(struct athn_softc *sc, uint32_t addr, uint32_t val)
+{
+ int ntries;
+
+ AR_WRITE(sc, addr, val);
+ /* Wait for write to complete. */
+ for (ntries = 0; ntries < 100; ntries++) {
+ if (AR_READ(sc, addr) == val)
+ return (0);
+ AR_WRITE(sc, addr, val); /* Insist. */
+ AR_WRITE_BARRIER(sc);
+ DELAY(10);
+ }
+ return (ETIMEDOUT);
+}
+
+void
+ar9485_init_swreg(struct athn_softc *sc)
+{
+ const struct ar9380_eeprom *eep = sc->eep;
+ uint32_t reg;
+
+ ar9485_pmu_write(sc, AR_PHY_PMU2,
+ AR_READ(sc, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM);
+
+ if (eep->baseEepHeader.featureEnable & AR_EEP_INTERNAL_REGULATOR) {
+ ar9485_pmu_write(sc, AR_PHY_PMU1, 0x131dc17a);
+
+ reg = AR_READ(sc, AR_PHY_PMU2);
+ reg = (reg & ~0xffc00000) | 0x10000000;
+ ar9485_pmu_write(sc, AR_PHY_PMU2, reg);
+ } else {
+ ar9485_pmu_write(sc, AR_PHY_PMU1,
+ AR_READ(sc, AR_PHY_PMU1) | AR_PHY_PMU1_PWD);
+ }
+
+ ar9485_pmu_write(sc, AR_PHY_PMU2,
+ AR_READ(sc, AR_PHY_PMU2) | AR_PHY_PMU2_PGM);
+}
+
void
ar9380_spur_mitigate_cck(struct athn_softc *sc, struct ieee80211_channel *c,
struct ieee80211_channel *extc)
diff --git a/sys/dev/ic/ar9380reg.h b/sys/dev/ic/ar9380reg.h
index e7b99064335..5a60ce2e54d 100644
--- a/sys/dev/ic/ar9380reg.h
+++ b/sys/dev/ic/ar9380reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar9380reg.h,v 1.15 2011/01/01 10:48:31 damien Exp $ */
+/* $OpenBSD: ar9380reg.h,v 1.16 2011/01/01 13:44:42 damien Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -89,6 +89,7 @@ struct ar9380_base_eep_hdr {
#define AR_EEP_DOUBLING_EN 0x08
#define AR_EEP_INTERNAL_REGULATOR 0x10
#define AR_EEP_PAPRD 0x20
+#define AR_EEP_TUNING_CAPS 0x40
uint8_t miscConfiguration;
#define AR_EEP_DRIVE_STRENGTH 0x01
@@ -103,6 +104,7 @@ struct ar9380_base_eep_hdr {
#define AR_EEP_TX_GAIN_S 4
#define AR_EEP_TX_GAIN_HIGH_OB_DB 1
#define AR_EEP_TX_GAIN_LOW_OB_DB 2
+#define AR_EEP_TX_GAIN_HIGH_POWER 3
#define AR_EEP_RX_GAIN_M 0x0f
#define AR_EEP_RX_GAIN_S 0
#define AR_EEP_RX_GAIN_WO_XLNA 1
@@ -151,6 +153,11 @@ struct ar9380_cal_data_per_freq_op_loop {
struct ar9380_base_extension_1 {
uint8_t ant_div_control;
+#define AR_EEP_ANT_DIV_CTRL_ALL_M 0x3f
+#define AR_EEP_ANT_DIV_CTRL_ALL_S 0
+#define AR_EEP_ANT_DIV_CTRL_ANT_DIV 0x40
+#define AR_EEP_ANT_DIV_CTRL_FAST_DIV 0x80
+
uint8_t future[13];
} __packed;
@@ -1509,6 +1516,64 @@ static const struct athn_gain ar9380_2_2_tx_gain_low_ob_db = {
};
/*
+ * AR9380 2.2 high power Tx gains.
+ */
+static const uint32_t ar9380_2_2_tx_gain_high_power_vals_5g[] = {
+ 0x0380c7fc, 0x0000f800, 0x03ff0000, 0x00000000, 0x000050d8,
+ 0x00002220, 0x04002222, 0x09002421, 0x0d002621, 0x13004620,
+ 0x19004a20, 0x1d004e20, 0x21005420, 0x26005e20, 0x2b005e40,
+ 0x2f005e42, 0x33005e44, 0x38005e65, 0x3c005e69, 0x40005e6b,
+ 0x44005e6d, 0x49005e72, 0x4e005eb2, 0x53005f12, 0x59025eb2,
+ 0x5e025f12, 0x61027f12, 0x6702bf12, 0x6b02bf14, 0x6f02bf16,
+ 0x6f02bf16, 0x6f02bf16, 0x6f02bf16, 0x6f02bf16, 0x6f02bf16,
+ 0x6f02bf16, 0x6f02bf16, 0x00802220, 0x04802222, 0x09802421,
+ 0x0d802621, 0x13804620, 0x19804a20, 0x1d804e20, 0x21805420,
+ 0x26805e20, 0x2b805e40, 0x2f805e42, 0x33805e44, 0x38805e65,
+ 0x3c805e69, 0x40805e6b, 0x44805e6d, 0x49805e72, 0x4e805eb2,
+ 0x53805f12, 0x59825eb2, 0x5e825f12, 0x61827f12, 0x6782bf12,
+ 0x6b82bf14, 0x6f82bf16, 0x6f82bf16, 0x6f82bf16, 0x6f82bf16,
+ 0x6f82bf16, 0x6f82bf16, 0x6f82bf16, 0x6f82bf16, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00804000, 0x00804201,
+ 0x0280c802, 0x0280ca03, 0x04c15104, 0x04c15305, 0x04c15305,
+ 0x04c15305, 0x04c15305, 0x04c15305, 0x04c15305, 0x04c15305,
+ 0x0380c7fc, 0x0000f800, 0x03ff0000, 0x00000000, 0x0380c7fc,
+ 0x0000f800, 0x03ff0000, 0x00000000, 0x056db2e6, 0xae480001,
+ 0x6eb6db6c, 0x056db2e6, 0xae480001, 0x6eb6db6c, 0x056db2e6,
+ 0xae480001, 0x6eb6db6c
+};
+
+static const uint32_t ar9380_2_2_tx_gain_high_power_vals_2g[] = {
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x000050d9,
+ 0x00000000, 0x04000002, 0x08000004, 0x0b000200, 0x0f000202,
+ 0x11000400, 0x15000402, 0x19000404, 0x1b000603, 0x1f000a02,
+ 0x23000a04, 0x26000a20, 0x2a000e20, 0x2e000e22, 0x31000e24,
+ 0x34001640, 0x38001660, 0x3b001861, 0x3e001a81, 0x42001a83,
+ 0x44001c84, 0x48001ce3, 0x4c001ce5, 0x50001ce9, 0x54001ceb,
+ 0x56001eec, 0x56001eec, 0x56001eec, 0x56001eec, 0x56001eec,
+ 0x56001eec, 0x56001eec, 0x00800000, 0x04800002, 0x08800004,
+ 0x0b800200, 0x0f800202, 0x11800400, 0x15800402, 0x19800404,
+ 0x1b800603, 0x1f800a02, 0x23800a04, 0x26800a20, 0x2a800e20,
+ 0x2e800e22, 0x31800e24, 0x34801640, 0x38801660, 0x3b801861,
+ 0x3e801a81, 0x42801a83, 0x44801c84, 0x48801ce3, 0x4c801ce5,
+ 0x50801ce9, 0x54801ceb, 0x56801eec, 0x56801eec, 0x56801eec,
+ 0x56801eec, 0x56801eec, 0x56801eec, 0x56801eec, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01404000,
+ 0x01404501, 0x02008501, 0x0280ca03, 0x03010c04, 0x04014c04,
+ 0x04015005, 0x04015005, 0x04015005, 0x04015005, 0x04015005,
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x00637800,
+ 0x03838000, 0x03fc0000, 0x00000000, 0x056db2e6, 0xae480001,
+ 0x6eb6db6c, 0x056db2e6, 0xae480001, 0x6eb6db6c, 0x056db2e6,
+ 0xae480001, 0x6eb6db6c
+};
+
+static const struct athn_gain ar9380_2_2_tx_gain_high_power = {
+ nitems(ar9380_2_2_tx_gain_regs),
+ ar9380_2_2_tx_gain_regs,
+ ar9380_2_2_tx_gain_high_power_vals_5g,
+ ar9380_2_2_tx_gain_high_power_vals_2g
+};
+
+/*
* AR9485 1.0 Tx gains.
*/
static const uint16_t ar9485_1_0_tx_gain_regs[] = {