From: Joerg Albert <jal2@gmx.de>
To: Christian Lamparter <chunkeey@googlemail.com>,
"John W. Linville" <linville@tuxdriver.com>
Cc: Johannes Berg <johannes@sipsolutions.net>,
"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
Subject: [PATCH v2] ar9170: added phy register initialisation from eeprom values
Date: Thu, 03 Sep 2009 01:02:59 +0200 [thread overview]
Message-ID: <4A9EF9A3.1020904@gmx.de> (raw)
In-Reply-To: <22ee4e770908311437y4954a79eje48976a0203f1806@mail.gmail.com>
This patch adds the initialisation of some PHY registers
from the modal_header[] values in the EEPROM
(see otus/hal/hpmain.c, line 333 ff.)
Signed-off-by: Joerg Albert <jal2@gmx.de>
---
Compared to v1 I've included Christian's suggestions and removed
three unnecessary defval assignments for "ant * control".
This patch seems to depend on Christian's
"[RFT] ar9170: use eeprom's frequency calibration values"
(2009-08-21), I get a poor throughput here without it (1-stage fw,
802.11g AP).
drivers/net/wireless/ath/ar9170/phy.c | 136 ++++++++++++++++++++++++++++++++-
1 files changed, 135 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index df86f70..8fb1fa8 100644
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
@@ -396,6 +396,138 @@ static struct ar9170_phy_init ar5416_phy_init[] = {
{ 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
};
+/*
+ * look up a certain register in ar5416_phy_init[] and return the init. value
+ * for the band and bandwidth given. Return 0 if register address not found.
+ */
+static u32 ar9170_get_default_phy_reg_val(u32 reg, bool is_2ghz, bool is_40mhz)
+{
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
+ if (ar5416_phy_init[i].reg != reg)
+ continue;
+
+ if (is_2ghz) {
+ if (is_40mhz)
+ return ar5416_phy_init[i]._2ghz_40;
+ else
+ return ar5416_phy_init[i]._2ghz_20;
+ } else {
+ if (is_40mhz)
+ return ar5416_phy_init[i]._5ghz_40;
+ else
+ return ar5416_phy_init[i]._5ghz_20;
+ }
+ }
+ return 0;
+}
+
+/*
+ * initialize some phy regs from eeprom values in modal_header[]
+ * acc. to band and bandwith
+ */
+static int ar9170_init_phy_from_eeprom(struct ar9170 *ar,
+ bool is_2ghz, bool is_40mhz)
+{
+ static const u8 xpd2pd[16] = {
+ 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2,
+ 0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2
+ };
+ u32 defval, newval;
+ /* pointer to the modal_header acc. to band */
+ struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz];
+
+ ar9170_regwrite_begin(ar);
+
+ /* ant common control (index 0) */
+ newval = le32_to_cpu(m->antCtrlCommon);
+ ar9170_regwrite(0x1c5964, newval);
+
+ /* ant control chain 0 (index 1) */
+ newval = le32_to_cpu(m->antCtrlChain[0]);
+ ar9170_regwrite(0x1c5960, newval);
+
+ /* ant control chain 2 (index 2) */
+ newval = le32_to_cpu(m->antCtrlChain[1]);
+ ar9170_regwrite(0x1c7960, newval);
+
+ /* SwSettle (index 3) */
+ if (!is_40mhz) {
+ defval = ar9170_get_default_phy_reg_val(0x1c5844,
+ is_2ghz, is_40mhz);
+ newval = (defval & ~0x3f80) |
+ ((m->switchSettling & 0x7f) << 7);
+ ar9170_regwrite(0x1c5844, newval);
+ }
+
+ /* adcDesired, pdaDesired (index 4) */
+ defval = ar9170_get_default_phy_reg_val(0x1c5850, is_2ghz, is_40mhz);
+ newval = (defval & ~0xffff) | ((u8)m->pgaDesiredSize << 8) |
+ ((u8)m->adcDesiredSize);
+ ar9170_regwrite(0x1c5850, newval);
+
+ /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */
+ defval = ar9170_get_default_phy_reg_val(0x1c5834, is_2ghz, is_40mhz);
+ newval = (m->txEndToXpaOff << 24) | (m->txEndToXpaOff << 16) |
+ (m->txFrameToXpaOn << 8) | m->txFrameToXpaOn;
+ ar9170_regwrite(0x1c5834, newval);
+
+ /* TxEndToRxOn (index 6) */
+ defval = ar9170_get_default_phy_reg_val(0x1c5828, is_2ghz, is_40mhz);
+ newval = (defval & ~0xff0000) | (m->txEndToRxOn << 16);
+ ar9170_regwrite(0x1c5828, newval);
+
+ /* thresh62 (index 7) */
+ defval = ar9170_get_default_phy_reg_val(0x1c8864, is_2ghz, is_40mhz);
+ newval = (defval & ~0x7f000) | (m->thresh62 << 12);
+ ar9170_regwrite(0x1c8864, newval);
+
+ /* tx/rx attenuation chain 0 (index 8) */
+ defval = ar9170_get_default_phy_reg_val(0x1c5848, is_2ghz, is_40mhz);
+ newval = (defval & ~0x3f000) | ((m->txRxAttenCh[0] & 0x3f) << 12);
+ ar9170_regwrite(0x1c5848, newval);
+
+ /* tx/rx attenuation chain 2 (index 9) */
+ defval = ar9170_get_default_phy_reg_val(0x1c7848, is_2ghz, is_40mhz);
+ newval = (defval & ~0x3f000) | ((m->txRxAttenCh[1] & 0x3f) << 12);
+ ar9170_regwrite(0x1c7848, newval);
+
+ /* tx/rx margin chain 0 (index 10) */
+ defval = ar9170_get_default_phy_reg_val(0x1c620c, is_2ghz, is_40mhz);
+ newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[0] & 0x3f) << 18);
+ /* bsw margin chain 0 for 5GHz only */
+ if (!is_2ghz)
+ newval = (newval & ~0x3c00) | ((m->bswMargin[0] & 0xf) << 10);
+ ar9170_regwrite(0x1c620c, newval);
+
+ /* tx/rx margin chain 2 (index 11) */
+ defval = ar9170_get_default_phy_reg_val(0x1c820c, is_2ghz, is_40mhz);
+ newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[1] & 0x3f) << 18);
+ ar9170_regwrite(0x1c820c, newval);
+
+ /* iqCall, iqCallq chain 0 (index 12) */
+ defval = ar9170_get_default_phy_reg_val(0x1c5920, is_2ghz, is_40mhz);
+ newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[0] & 0x3f) << 5) |
+ ((u8)m->iqCalQCh[0] & 0x1f);
+ ar9170_regwrite(0x1c5920, newval);
+
+ /* iqCall, iqCallq chain 2 (index 13) */
+ defval = ar9170_get_default_phy_reg_val(0x1c7920, is_2ghz, is_40mhz);
+ newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[1] & 0x3f) << 5) |
+ ((u8)m->iqCalQCh[1] & 0x1f);
+ ar9170_regwrite(0x1c7920, newval);
+
+ /* xpd gain mask (index 14) */
+ defval = ar9170_get_default_phy_reg_val(0x1c6258, is_2ghz, is_40mhz);
+ newval = (defval & ~0xf0000) | (xpd2pd[m->xpdGain & 0xf] << 16);
+ ar9170_regwrite(0x1c6258, newval);
+
+
+ ar9170_regwrite_finish();
+
+ return ar9170_regwrite_result();
+}
+
int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
{
int i, err;
@@ -426,7 +558,9 @@ int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
if (err)
return err;
- /* XXX: use EEPROM data here! */
+ err = ar9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz);
+ if (err)
+ return err;
err = ar9170_init_power_cal(ar);
if (err)
--
1.6.0.4
next prev parent reply other threads:[~2009-09-02 23:03 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-31 9:53 [PATCH] ar9170: added phy register initialisation from eeprom values Chunkeey
2009-08-31 19:34 ` Joerg Albert
2009-08-31 21:37 ` Christian Lamparter
2009-09-02 23:02 ` Joerg Albert [this message]
2009-09-03 18:56 ` [PATCH v2] " Christian Lamparter
[not found] ` <4A9EF532.8070500@gmx.de>
2009-09-03 16:16 ` [PATCH] " Christian Lamparter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A9EF9A3.1020904@gmx.de \
--to=jal2@gmx.de \
--cc=chunkeey@googlemail.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).