Commit 572d37a4 authored by Rafał Miłecki's avatar Rafał Miłecki Committed by John W. Linville

b43: N-PHY: init 0x2057 radio

Signed-off-by: default avatarRafał Miłecki <zajec5@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent d3d178f0
......@@ -4,6 +4,7 @@ b43-y += tables.o
b43-$(CONFIG_B43_PHY_N) += tables_nphy.o
b43-$(CONFIG_B43_PHY_N) += radio_2055.o
b43-$(CONFIG_B43_PHY_N) += radio_2056.o
b43-$(CONFIG_B43_PHY_N) += radio_2057.o
b43-y += phy_common.o
b43-y += phy_g.o
b43-y += phy_a.o
......
......@@ -32,6 +32,7 @@
#include "tables_nphy.h"
#include "radio_2055.h"
#include "radio_2056.h"
#include "radio_2057.h"
#include "main.h"
struct nphy_txgains {
......@@ -458,6 +459,136 @@ static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
b43_nphy_stay_in_carrier_search(dev, false);
}
/**************************************************
* Radio 0x2057
**************************************************/
/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */
static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
u16 tmp;
if (phy->radio_rev == 5) {
b43_phy_mask(dev, 0x342, ~0x2);
udelay(10);
b43_radio_set(dev, R2057_IQTEST_SEL_PU, 0x1);
b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
}
b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
udelay(10);
b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
return 0;
}
b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
if (phy->radio_rev == 5) {
b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
b43_radio_mask(dev, 0x1ca, ~0x2);
}
if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
b43_radio_maskset(dev, R2057_TEMPSENSE_CONFIG, ~0x3C, tmp);
b43_radio_maskset(dev, R2057_BANDGAP_RCAL_TRIM, ~0xF0,
tmp << 2);
}
return tmp & 0x3e;
}
/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
bool special = (phy->radio_rev == 3 || phy->radio_rev == 4 ||
phy->radio_rev == 6);
u16 tmp;
if (special) {
b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
} else {
b43_radio_write(dev, 0x1AE, 0x61);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
}
b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
5000000))
b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
if (special) {
b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
} else {
b43_radio_write(dev, 0x1AE, 0x69);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
}
b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
5000000))
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
if (special) {
b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
} else {
b43_radio_write(dev, 0x1AE, 0x73);
b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
}
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
5000000)) {
b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
return 0;
}
tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
return tmp;
}
static void b43_radio_2057_init_pre(struct b43_wldev *dev)
{
b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, ~B43_NPHY_RFCTL_CMD_CHIP0PU);
/* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */
b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_OEPORFORCE);
b43_phy_set(dev, B43_NPHY_RFCTL_CMD, ~B43_NPHY_RFCTL_CMD_OEPORFORCE);
b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_CHIP0PU);
}
static void b43_radio_2057_init_post(struct b43_wldev *dev)
{
b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x1);
b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78);
b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80);
mdelay(2);
b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);
b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);
if (dev->phy.n->init_por) {
b43_radio_2057_rcal(dev);
b43_radio_2057_rccal(dev);
}
b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
dev->phy.n->init_por = false;
}
/* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
static void b43_radio_2057_init(struct b43_wldev *dev)
{
b43_radio_2057_init_pre(dev);
r2057_upload_inittabs(dev);
b43_radio_2057_init_post(dev);
}
/**************************************************
* Radio 0x2056
**************************************************/
......@@ -5212,6 +5343,8 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;
nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;
}
nphy->init_por = true;
}
static void b43_nphy_op_free(struct b43_wldev *dev)
......@@ -5298,7 +5431,9 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
if (blocked) {
b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
~B43_NPHY_RFCTL_CMD_CHIP0PU);
if (dev->phy.rev >= 3) {
if (dev->phy.rev >= 7) {
/* TODO */
} else if (dev->phy.rev >= 3) {
b43_radio_mask(dev, 0x09, ~0x2);
b43_radio_write(dev, 0x204D, 0);
......@@ -5316,7 +5451,10 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
b43_radio_write(dev, 0x3064, 0);
}
} else {
if (dev->phy.rev >= 3) {
if (dev->phy.rev >= 7) {
b43_radio_2057_init(dev);
b43_switch_channel(dev, dev->phy.channel);
} else if (dev->phy.rev >= 3) {
b43_radio_init2056(dev);
b43_switch_channel(dev, dev->phy.channel);
} else {
......
/*
Broadcom B43 wireless driver
IEEE 802.11n 2057 radio device data tables
Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "b43.h"
#include "radio_2057.h"
#include "phy_common.h"
static u16 r2057_rev4_init[42][2] = {
{ 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
{ 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
{ 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
{ 0x8C, 0xf0 }, { 0x91, 0x3f }, { 0x92, 0x36 }, { 0xA4, 0x8c },
{ 0xA8, 0x55 }, { 0xAF, 0x01 }, { 0x10F, 0xf0 }, { 0x110, 0x10 },
{ 0x111, 0xf0 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x129, 0x8c },
{ 0x12D, 0x55 }, { 0x134, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 },
{ 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 },
{ 0x169, 0x02 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 },
{ 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 },
{ 0x1AB, 0x00 }, { 0x1AC, 0x00 },
};
static u16 r2057_rev5_init[44][2] = {
{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
{ 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
{ 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 },
{ 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f },
{ 0x117, 0x36 }, { 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 },
{ 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 },
{ 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 },
{ 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 },
{ 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
};
static u16 r2057_rev5a_init[45][2] = {
{ 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
{ 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
{ 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 },
{ 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f },
{ 0x117, 0x36 }, { 0x126, 0x20 }, { 0x14E, 0x01 }, { 0x15E, 0x00 },
{ 0x15F, 0x00 }, { 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 },
{ 0x163, 0x00 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 },
{ 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 },
{ 0x1AB, 0x00 }, { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 },
{ 0x1C2, 0x80 },
};
static u16 r2057_rev7_init[54][2] = {
{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
{ 0x66, 0xee }, { 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 },
{ 0x7C, 0x14 }, { 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f },
{ 0x92, 0x36 }, { 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 },
{ 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x13 }, { 0xEB, 0xee },
{ 0xF3, 0x58 }, { 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x14 },
{ 0x102, 0xee }, { 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 },
{ 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 },
{ 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 },
{ 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 },
{ 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
};
static u16 r2057_rev8_init[54][2] = {
{ 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
{ 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 }, { 0x7C, 0x0f },
{ 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
{ 0xA1, 0x20 }, { 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 },
{ 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0xF3, 0x58 },
{ 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x0f }, { 0x102, 0xee },
{ 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x126, 0x20 },
{ 0x14E, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 },
{ 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 },
{ 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 },
{ 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
};
void r2057_upload_inittabs(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
u16 *table = NULL;
u16 size, i;
if (phy->rev == 7) {
table = r2057_rev4_init[0];
size = ARRAY_SIZE(r2057_rev4_init);
} else if (phy->rev == 8 || phy->rev == 9) {
if (phy->radio_rev == 5) {
if (phy->radio_rev == 8) {
table = r2057_rev5_init[0];
size = ARRAY_SIZE(r2057_rev5_init);
} else {
table = r2057_rev5a_init[0];
size = ARRAY_SIZE(r2057_rev5a_init);
}
} else if (phy->radio_rev == 7) {
table = r2057_rev7_init[0];
size = ARRAY_SIZE(r2057_rev7_init);
} else if (phy->radio_rev == 9) {
table = r2057_rev8_init[0];
size = ARRAY_SIZE(r2057_rev8_init);
}
}
if (table) {
for (i = 0; i < 10; i++) {
pr_info("radio_write 0x%X ", *table);
table++;
pr_info("0x%X\n", *table);
table++;
}
}
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment