diff options
author | Gábor Stefanik <netrolller.3d@gmail.com> | 2009-08-13 16:46:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-20 11:35:50 -0400 |
commit | 588f8377c5470fab611c14ead768f7f9af87da94 (patch) | |
tree | 5bf7814511759cae41f4984409d8e743dc949678 /drivers/net/wireless/b43/phy_lp.c | |
parent | 6f632d57f35303118685b88c139f3da73df077e2 (diff) |
b43: LP-PHY: Implement channel switching for rev2+/B2063 radio
Rev.2+/B2063 will now hopefully show some signs of life, though
it won't work at full performance, as calibration is still missing.
Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/phy_lp.c')
-rw-r--r-- | drivers/net/wireless/b43/phy_lp.c | 424 |
1 files changed, 402 insertions, 22 deletions
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 996b7eccfaf8..86da8281d929 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c | |||
@@ -29,6 +29,25 @@ | |||
29 | #include "tables_lpphy.h" | 29 | #include "tables_lpphy.h" |
30 | 30 | ||
31 | 31 | ||
32 | static inline u16 channel2freq_lp(u8 channel) | ||
33 | { | ||
34 | if (channel < 14) | ||
35 | return (2407 + 5 * channel); | ||
36 | else if (channel == 14) | ||
37 | return 2484; | ||
38 | else if (channel < 184) | ||
39 | return (5000 + 5 * channel); | ||
40 | else | ||
41 | return (4000 + 5 * channel); | ||
42 | } | ||
43 | |||
44 | static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev) | ||
45 | { | ||
46 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
47 | return 1; | ||
48 | return 36; | ||
49 | } | ||
50 | |||
32 | static int b43_lpphy_op_allocate(struct b43_wldev *dev) | 51 | static int b43_lpphy_op_allocate(struct b43_wldev *dev) |
33 | { | 52 | { |
34 | struct b43_phy_lp *lpphy; | 53 | struct b43_phy_lp *lpphy; |
@@ -142,10 +161,9 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev) | |||
142 | } | 161 | } |
143 | } | 162 | } |
144 | 163 | ||
145 | static void lpphy_adjust_gain_table(struct b43_wldev *dev) | 164 | static void lpphy_adjust_gain_table(struct b43_wldev *dev, u32 freq) |
146 | { | 165 | { |
147 | struct b43_phy_lp *lpphy = dev->phy.lp; | 166 | struct b43_phy_lp *lpphy = dev->phy.lp; |
148 | u32 freq = dev->wl->hw->conf.channel->center_freq; | ||
149 | u16 temp[3]; | 167 | u16 temp[3]; |
150 | u16 isolation; | 168 | u16 isolation; |
151 | 169 | ||
@@ -170,6 +188,8 @@ static void lpphy_adjust_gain_table(struct b43_wldev *dev) | |||
170 | 188 | ||
171 | static void lpphy_table_init(struct b43_wldev *dev) | 189 | static void lpphy_table_init(struct b43_wldev *dev) |
172 | { | 190 | { |
191 | u32 freq = channel2freq_lp(b43_lpphy_op_get_default_chan(dev)); | ||
192 | |||
173 | if (dev->phy.rev < 2) | 193 | if (dev->phy.rev < 2) |
174 | lpphy_rev0_1_table_init(dev); | 194 | lpphy_rev0_1_table_init(dev); |
175 | else | 195 | else |
@@ -178,7 +198,7 @@ static void lpphy_table_init(struct b43_wldev *dev) | |||
178 | lpphy_init_tx_gain_table(dev); | 198 | lpphy_init_tx_gain_table(dev); |
179 | 199 | ||
180 | if (dev->phy.rev < 2) | 200 | if (dev->phy.rev < 2) |
181 | lpphy_adjust_gain_table(dev); | 201 | lpphy_adjust_gain_table(dev, freq); |
182 | } | 202 | } |
183 | 203 | ||
184 | static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | 204 | static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) |
@@ -1363,20 +1383,6 @@ static void lpphy_tx_pctl_init(struct b43_wldev *dev) | |||
1363 | } | 1383 | } |
1364 | } | 1384 | } |
1365 | 1385 | ||
1366 | static int b43_lpphy_op_init(struct b43_wldev *dev) | ||
1367 | { | ||
1368 | lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs? | ||
1369 | lpphy_baseband_init(dev); | ||
1370 | lpphy_radio_init(dev); | ||
1371 | lpphy_calibrate_rc(dev); | ||
1372 | //TODO set channel | ||
1373 | lpphy_tx_pctl_init(dev); | ||
1374 | lpphy_calibration(dev); | ||
1375 | //TODO ACI init | ||
1376 | |||
1377 | return 0; | ||
1378 | } | ||
1379 | |||
1380 | static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg) | 1386 | static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg) |
1381 | { | 1387 | { |
1382 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 1388 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); |
@@ -1419,18 +1425,392 @@ static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, | |||
1419 | //TODO | 1425 | //TODO |
1420 | } | 1426 | } |
1421 | 1427 | ||
1428 | struct b206x_channel { | ||
1429 | u8 channel; | ||
1430 | u16 freq; | ||
1431 | u8 data[12]; | ||
1432 | }; | ||
1433 | |||
1434 | static const struct b206x_channel b2063_chantbl[] = { | ||
1435 | { .channel = 1, .freq = 2412, .data[0] = 0x6F, .data[1] = 0x3C, | ||
1436 | .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1437 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1438 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1439 | { .channel = 2, .freq = 2417, .data[0] = 0x6F, .data[1] = 0x3C, | ||
1440 | .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1441 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1442 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1443 | { .channel = 3, .freq = 2422, .data[0] = 0x6F, .data[1] = 0x3C, | ||
1444 | .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1445 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1446 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1447 | { .channel = 4, .freq = 2427, .data[0] = 0x6F, .data[1] = 0x2C, | ||
1448 | .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1449 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1450 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1451 | { .channel = 5, .freq = 2432, .data[0] = 0x6F, .data[1] = 0x2C, | ||
1452 | .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1453 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1454 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1455 | { .channel = 6, .freq = 2437, .data[0] = 0x6F, .data[1] = 0x2C, | ||
1456 | .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1457 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1458 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1459 | { .channel = 7, .freq = 2442, .data[0] = 0x6F, .data[1] = 0x2C, | ||
1460 | .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1461 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1462 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1463 | { .channel = 8, .freq = 2447, .data[0] = 0x6F, .data[1] = 0x2C, | ||
1464 | .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1465 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1466 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1467 | { .channel = 9, .freq = 2452, .data[0] = 0x6F, .data[1] = 0x1C, | ||
1468 | .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1469 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1470 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1471 | { .channel = 10, .freq = 2457, .data[0] = 0x6F, .data[1] = 0x1C, | ||
1472 | .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1473 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1474 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1475 | { .channel = 11, .freq = 2462, .data[0] = 0x6E, .data[1] = 0x1C, | ||
1476 | .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1477 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1478 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1479 | { .channel = 12, .freq = 2467, .data[0] = 0x6E, .data[1] = 0x1C, | ||
1480 | .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1481 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1482 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1483 | { .channel = 13, .freq = 2472, .data[0] = 0x6E, .data[1] = 0x1C, | ||
1484 | .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1485 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1486 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1487 | { .channel = 14, .freq = 2484, .data[0] = 0x6E, .data[1] = 0x0C, | ||
1488 | .data[2] = 0x0C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05, | ||
1489 | .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80, | ||
1490 | .data[10] = 0x80, .data[11] = 0x70, }, | ||
1491 | { .channel = 34, .freq = 5170, .data[0] = 0x6A, .data[1] = 0x0C, | ||
1492 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x02, .data[5] = 0x05, | ||
1493 | .data[6] = 0x0D, .data[7] = 0x0D, .data[8] = 0x77, .data[9] = 0x80, | ||
1494 | .data[10] = 0x20, .data[11] = 0x00, }, | ||
1495 | { .channel = 36, .freq = 5180, .data[0] = 0x6A, .data[1] = 0x0C, | ||
1496 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x05, | ||
1497 | .data[6] = 0x0D, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x80, | ||
1498 | .data[10] = 0x20, .data[11] = 0x00, }, | ||
1499 | { .channel = 38, .freq = 5190, .data[0] = 0x6A, .data[1] = 0x0C, | ||
1500 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04, | ||
1501 | .data[6] = 0x0C, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x80, | ||
1502 | .data[10] = 0x20, .data[11] = 0x00, }, | ||
1503 | { .channel = 40, .freq = 5200, .data[0] = 0x69, .data[1] = 0x0C, | ||
1504 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04, | ||
1505 | .data[6] = 0x0C, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x70, | ||
1506 | .data[10] = 0x20, .data[11] = 0x00, }, | ||
1507 | { .channel = 42, .freq = 5210, .data[0] = 0x69, .data[1] = 0x0C, | ||
1508 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04, | ||
1509 | .data[6] = 0x0B, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x70, | ||
1510 | .data[10] = 0x20, .data[11] = 0x00, }, | ||
1511 | { .channel = 44, .freq = 5220, .data[0] = 0x69, .data[1] = 0x0C, | ||
1512 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x04, | ||
1513 | .data[6] = 0x0B, .data[7] = 0x0B, .data[8] = 0x77, .data[9] = 0x60, | ||
1514 | .data[10] = 0x20, .data[11] = 0x00, }, | ||
1515 | { .channel = 46, .freq = 5230, .data[0] = 0x69, .data[1] = 0x0C, | ||
1516 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x03, | ||
1517 | .data[6] = 0x0A, .data[7] = 0x0B, .data[8] = 0x77, .data[9] = 0x60, | ||
1518 | .data[10] = 0x20, .data[11] = 0x00, }, | ||
1519 | { .channel = 48, .freq = 5240, .data[0] = 0x69, .data[1] = 0x0C, | ||
1520 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x03, | ||
1521 | .data[6] = 0x0A, .data[7] = 0x0A, .data[8] = 0x77, .data[9] = 0x60, | ||
1522 | .data[10] = 0x20, .data[11] = 0x00, }, | ||
1523 | { .channel = 52, .freq = 5260, .data[0] = 0x68, .data[1] = 0x0C, | ||
1524 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x02, | ||
1525 | .data[6] = 0x09, .data[7] = 0x09, .data[8] = 0x77, .data[9] = 0x60, | ||
1526 | .data[10] = 0x20, .data[11] = 0x00, }, | ||
1527 | { .channel = 56, .freq = 5280, .data[0] = 0x68, .data[1] = 0x0C, | ||
1528 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x01, | ||
1529 | .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50, | ||
1530 | .data[10] = 0x10, .data[11] = 0x00, }, | ||
1531 | { .channel = 60, .freq = 5300, .data[0] = 0x68, .data[1] = 0x0C, | ||
1532 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x01, | ||
1533 | .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50, | ||
1534 | .data[10] = 0x10, .data[11] = 0x00, }, | ||
1535 | { .channel = 64, .freq = 5320, .data[0] = 0x67, .data[1] = 0x0C, | ||
1536 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1537 | .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50, | ||
1538 | .data[10] = 0x10, .data[11] = 0x00, }, | ||
1539 | { .channel = 100, .freq = 5500, .data[0] = 0x64, .data[1] = 0x0C, | ||
1540 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1541 | .data[6] = 0x02, .data[7] = 0x01, .data[8] = 0x77, .data[9] = 0x20, | ||
1542 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1543 | { .channel = 104, .freq = 5520, .data[0] = 0x64, .data[1] = 0x0C, | ||
1544 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1545 | .data[6] = 0x01, .data[7] = 0x01, .data[8] = 0x77, .data[9] = 0x20, | ||
1546 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1547 | { .channel = 108, .freq = 5540, .data[0] = 0x63, .data[1] = 0x0C, | ||
1548 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1549 | .data[6] = 0x01, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10, | ||
1550 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1551 | { .channel = 112, .freq = 5560, .data[0] = 0x63, .data[1] = 0x0C, | ||
1552 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1553 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10, | ||
1554 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1555 | { .channel = 116, .freq = 5580, .data[0] = 0x62, .data[1] = 0x0C, | ||
1556 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1557 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10, | ||
1558 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1559 | { .channel = 120, .freq = 5600, .data[0] = 0x62, .data[1] = 0x0C, | ||
1560 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1561 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1562 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1563 | { .channel = 124, .freq = 5620, .data[0] = 0x62, .data[1] = 0x0C, | ||
1564 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1565 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1566 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1567 | { .channel = 128, .freq = 5640, .data[0] = 0x61, .data[1] = 0x0C, | ||
1568 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1569 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1570 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1571 | { .channel = 132, .freq = 5660, .data[0] = 0x61, .data[1] = 0x0C, | ||
1572 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1573 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1574 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1575 | { .channel = 136, .freq = 5680, .data[0] = 0x61, .data[1] = 0x0C, | ||
1576 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1577 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1578 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1579 | { .channel = 140, .freq = 5700, .data[0] = 0x60, .data[1] = 0x0C, | ||
1580 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1581 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1582 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1583 | { .channel = 149, .freq = 5745, .data[0] = 0x60, .data[1] = 0x0C, | ||
1584 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1585 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1586 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1587 | { .channel = 153, .freq = 5765, .data[0] = 0x60, .data[1] = 0x0C, | ||
1588 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1589 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1590 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1591 | { .channel = 157, .freq = 5785, .data[0] = 0x60, .data[1] = 0x0C, | ||
1592 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1593 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1594 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1595 | { .channel = 161, .freq = 5805, .data[0] = 0x60, .data[1] = 0x0C, | ||
1596 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1597 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1598 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1599 | { .channel = 165, .freq = 5825, .data[0] = 0x60, .data[1] = 0x0C, | ||
1600 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00, | ||
1601 | .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00, | ||
1602 | .data[10] = 0x00, .data[11] = 0x00, }, | ||
1603 | { .channel = 184, .freq = 4920, .data[0] = 0x6E, .data[1] = 0x0C, | ||
1604 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x09, .data[5] = 0x0E, | ||
1605 | .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xC0, | ||
1606 | .data[10] = 0x50, .data[11] = 0x00, }, | ||
1607 | { .channel = 188, .freq = 4940, .data[0] = 0x6E, .data[1] = 0x0C, | ||
1608 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x09, .data[5] = 0x0D, | ||
1609 | .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xB0, | ||
1610 | .data[10] = 0x50, .data[11] = 0x00, }, | ||
1611 | { .channel = 192, .freq = 4960, .data[0] = 0x6E, .data[1] = 0x0C, | ||
1612 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0C, | ||
1613 | .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xB0, | ||
1614 | .data[10] = 0x50, .data[11] = 0x00, }, | ||
1615 | { .channel = 196, .freq = 4980, .data[0] = 0x6D, .data[1] = 0x0C, | ||
1616 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0C, | ||
1617 | .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0, | ||
1618 | .data[10] = 0x40, .data[11] = 0x00, }, | ||
1619 | { .channel = 200, .freq = 5000, .data[0] = 0x6D, .data[1] = 0x0C, | ||
1620 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0B, | ||
1621 | .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0, | ||
1622 | .data[10] = 0x40, .data[11] = 0x00, }, | ||
1623 | { .channel = 204, .freq = 5020, .data[0] = 0x6D, .data[1] = 0x0C, | ||
1624 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0A, | ||
1625 | .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0, | ||
1626 | .data[10] = 0x40, .data[11] = 0x00, }, | ||
1627 | { .channel = 208, .freq = 5040, .data[0] = 0x6C, .data[1] = 0x0C, | ||
1628 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x07, .data[5] = 0x09, | ||
1629 | .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90, | ||
1630 | .data[10] = 0x40, .data[11] = 0x00, }, | ||
1631 | { .channel = 212, .freq = 5060, .data[0] = 0x6C, .data[1] = 0x0C, | ||
1632 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x06, .data[5] = 0x08, | ||
1633 | .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90, | ||
1634 | .data[10] = 0x40, .data[11] = 0x00, }, | ||
1635 | { .channel = 216, .freq = 5080, .data[0] = 0x6C, .data[1] = 0x0C, | ||
1636 | .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x05, .data[5] = 0x08, | ||
1637 | .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90, | ||
1638 | .data[10] = 0x40, .data[11] = 0x00, }, | ||
1639 | }; | ||
1640 | |||
1641 | static void lpphy_b2062_tune(struct b43_wldev *dev, | ||
1642 | unsigned int channel) | ||
1643 | { | ||
1644 | //TODO | ||
1645 | } | ||
1646 | |||
1647 | static void lpphy_b2063_vco_calib(struct b43_wldev *dev) | ||
1648 | { | ||
1649 | u16 tmp; | ||
1650 | |||
1651 | b43_phy_mask(dev, B2063_PLL_SP1, ~0x40); | ||
1652 | tmp = b43_phy_read(dev, B2063_PLL_JTAG_CALNRST) & 0xF8; | ||
1653 | b43_phy_write(dev, B2063_PLL_JTAG_CALNRST, tmp); | ||
1654 | udelay(1); | ||
1655 | b43_phy_write(dev, B2063_PLL_JTAG_CALNRST, tmp | 0x4); | ||
1656 | udelay(1); | ||
1657 | b43_phy_write(dev, B2063_PLL_JTAG_CALNRST, tmp | 0x6); | ||
1658 | udelay(1); | ||
1659 | b43_phy_write(dev, B2063_PLL_JTAG_CALNRST, tmp | 0x7); | ||
1660 | udelay(300); | ||
1661 | b43_phy_set(dev, B2063_PLL_SP1, 0x40); | ||
1662 | } | ||
1663 | |||
1664 | static void lpphy_b2063_tune(struct b43_wldev *dev, | ||
1665 | unsigned int channel) | ||
1666 | { | ||
1667 | struct ssb_bus *bus = dev->dev->bus; | ||
1668 | |||
1669 | static const struct b206x_channel *chandata = NULL; | ||
1670 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; | ||
1671 | u32 freqref, vco_freq, val1, val2, val3, timeout, timeoutref, count; | ||
1672 | u16 old_comm15, scale; | ||
1673 | u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6; | ||
1674 | int i, div = (crystal_freq <= 26000000 ? 1 : 2); | ||
1675 | |||
1676 | for (i = 0; i < ARRAY_SIZE(b2063_chantbl); i++) { | ||
1677 | if (b2063_chantbl[i].channel == channel) { | ||
1678 | chandata = &b2063_chantbl[i]; | ||
1679 | break; | ||
1680 | } | ||
1681 | } | ||
1682 | |||
1683 | if (B43_WARN_ON(!chandata)) | ||
1684 | return; | ||
1685 | |||
1686 | b43_radio_write(dev, B2063_LOGEN_VCOBUF1, chandata->data[0]); | ||
1687 | b43_radio_write(dev, B2063_LOGEN_MIXER2, chandata->data[1]); | ||
1688 | b43_radio_write(dev, B2063_LOGEN_BUF2, chandata->data[2]); | ||
1689 | b43_radio_write(dev, B2063_LOGEN_RCCR1, chandata->data[3]); | ||
1690 | b43_radio_write(dev, B2063_A_RX_1ST3, chandata->data[4]); | ||
1691 | b43_radio_write(dev, B2063_A_RX_2ND1, chandata->data[5]); | ||
1692 | b43_radio_write(dev, B2063_A_RX_2ND4, chandata->data[6]); | ||
1693 | b43_radio_write(dev, B2063_A_RX_2ND7, chandata->data[7]); | ||
1694 | b43_radio_write(dev, B2063_A_RX_PS6, chandata->data[8]); | ||
1695 | b43_radio_write(dev, B2063_TX_RF_CTL2, chandata->data[9]); | ||
1696 | b43_radio_write(dev, B2063_TX_RF_CTL5, chandata->data[10]); | ||
1697 | b43_radio_write(dev, B2063_PA_CTL11, chandata->data[11]); | ||
1698 | |||
1699 | old_comm15 = b43_radio_read(dev, B2063_COMM15); | ||
1700 | b43_radio_set(dev, B2063_COMM15, 0x1E); | ||
1701 | |||
1702 | if (chandata->freq > 4000) /* spec says 2484, but 4000 is safer */ | ||
1703 | vco_freq = chandata->freq << 1; | ||
1704 | else | ||
1705 | vco_freq = chandata->freq << 2; | ||
1706 | |||
1707 | freqref = crystal_freq * 3; | ||
1708 | val1 = lpphy_qdiv_roundup(crystal_freq, 1000000, 16); | ||
1709 | val2 = lpphy_qdiv_roundup(crystal_freq, 1000000 * div, 16); | ||
1710 | val3 = lpphy_qdiv_roundup(vco_freq, 3, 16); | ||
1711 | timeout = ((((8 * crystal_freq) / (div * 5000000)) + 1) >> 1) - 1; | ||
1712 | b43_radio_write(dev, B2063_PLL_JTAG_PLL_VCO_CALIB3, 0x2); | ||
1713 | b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_VCO_CALIB6, | ||
1714 | 0xFFF8, timeout >> 2); | ||
1715 | b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_VCO_CALIB7, | ||
1716 | 0xFF9F,timeout << 5); | ||
1717 | |||
1718 | timeoutref = ((((8 * crystal_freq) / (div * (timeout + 1))) + | ||
1719 | 999999) / 1000000) + 1; | ||
1720 | b43_radio_write(dev, B2063_PLL_JTAG_PLL_VCO_CALIB5, timeoutref); | ||
1721 | |||
1722 | count = lpphy_qdiv_roundup(val3, val2 + 16, 16); | ||
1723 | count *= (timeout + 1) * (timeoutref + 1); | ||
1724 | count--; | ||
1725 | b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_VCO_CALIB7, | ||
1726 | 0xF0, count >> 8); | ||
1727 | b43_radio_write(dev, B2063_PLL_JTAG_PLL_VCO_CALIB8, count & 0xFF); | ||
1728 | |||
1729 | tmp1 = ((val3 * 62500) / freqref) << 4; | ||
1730 | tmp2 = ((val3 * 62500) % freqref) << 4; | ||
1731 | while (tmp2 >= freqref) { | ||
1732 | tmp1++; | ||
1733 | tmp2 -= freqref; | ||
1734 | } | ||
1735 | b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_SG1, 0xFFE0, tmp1 >> 4); | ||
1736 | b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_SG2, 0xFE0F, tmp1 << 4); | ||
1737 | b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_SG2, 0xFFF0, tmp1 >> 16); | ||
1738 | b43_radio_write(dev, B2063_PLL_JTAG_PLL_SG3, (tmp2 >> 8) & 0xFF); | ||
1739 | b43_radio_write(dev, B2063_PLL_JTAG_PLL_SG4, tmp2 & 0xFF); | ||
1740 | |||
1741 | b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF1, 0xB9); | ||
1742 | b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF2, 0x88); | ||
1743 | b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF3, 0x28); | ||
1744 | b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF4, 0x63); | ||
1745 | |||
1746 | tmp3 = ((41 * (val3 - 3000)) /1200) + 27; | ||
1747 | tmp4 = lpphy_qdiv_roundup(132000 * tmp1, 8451, 16); | ||
1748 | |||
1749 | if ((tmp4 + tmp3 - 1) / tmp3 > 60) { | ||
1750 | scale = 1; | ||
1751 | tmp5 = ((tmp4 + tmp3) / (tmp3 << 1)) - 8; | ||
1752 | } else { | ||
1753 | scale = 0; | ||
1754 | tmp5 = ((tmp4 + (tmp3 >> 1)) / tmp3) - 8; | ||
1755 | } | ||
1756 | b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_CP2, 0xFFC0, tmp5); | ||
1757 | b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_CP2, 0xFFBF, scale << 6); | ||
1758 | |||
1759 | tmp6 = lpphy_qdiv_roundup(100 * val1, val3, 16); | ||
1760 | tmp6 *= (tmp5 * 8) * (scale + 1); | ||
1761 | if (tmp6 > 150) | ||
1762 | tmp6 = 0; | ||
1763 | |||
1764 | b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_CP3, 0xFFE0, tmp6); | ||
1765 | b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_CP3, 0xFFDF, scale << 5); | ||
1766 | |||
1767 | b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_XTAL_12, 0xFFFB, 0x4); | ||
1768 | if (crystal_freq > 26000000) | ||
1769 | b43_phy_set(dev, B2063_PLL_JTAG_PLL_XTAL_12, 0x2); | ||
1770 | else | ||
1771 | b43_phy_mask(dev, B2063_PLL_JTAG_PLL_XTAL_12, 0xFD); | ||
1772 | |||
1773 | if (val1 == 45) | ||
1774 | b43_phy_set(dev, B2063_PLL_JTAG_PLL_VCO1, 0x2); | ||
1775 | else | ||
1776 | b43_phy_mask(dev, B2063_PLL_JTAG_PLL_VCO1, 0xFD); | ||
1777 | |||
1778 | b43_phy_set(dev, B2063_PLL_SP2, 0x3); | ||
1779 | udelay(1); | ||
1780 | b43_phy_mask(dev, B2063_PLL_SP2, 0xFFFC); | ||
1781 | lpphy_b2063_vco_calib(dev); | ||
1782 | b43_radio_write(dev, B2063_COMM15, old_comm15); | ||
1783 | } | ||
1784 | |||
1422 | static int b43_lpphy_op_switch_channel(struct b43_wldev *dev, | 1785 | static int b43_lpphy_op_switch_channel(struct b43_wldev *dev, |
1423 | unsigned int new_channel) | 1786 | unsigned int new_channel) |
1424 | { | 1787 | { |
1425 | //TODO | 1788 | b43_write16(dev, B43_MMIO_CHANNEL, new_channel); |
1789 | |||
1790 | if (dev->phy.radio_ver == 0x2063) { | ||
1791 | lpphy_b2063_tune(dev, new_channel); | ||
1792 | } else { | ||
1793 | lpphy_b2062_tune(dev, new_channel); | ||
1794 | //TODO Japan filter | ||
1795 | } | ||
1796 | |||
1797 | lpphy_adjust_gain_table(dev, channel2freq_lp(new_channel)); | ||
1798 | |||
1426 | return 0; | 1799 | return 0; |
1427 | } | 1800 | } |
1428 | 1801 | ||
1429 | static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev) | 1802 | static int b43_lpphy_op_init(struct b43_wldev *dev) |
1430 | { | 1803 | { |
1431 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | 1804 | lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs? |
1432 | return 1; | 1805 | lpphy_baseband_init(dev); |
1433 | return 36; | 1806 | lpphy_radio_init(dev); |
1807 | lpphy_calibrate_rc(dev); | ||
1808 | b43_lpphy_op_switch_channel(dev, b43_lpphy_op_get_default_chan(dev)); | ||
1809 | lpphy_tx_pctl_init(dev); | ||
1810 | lpphy_calibration(dev); | ||
1811 | //TODO ACI init | ||
1812 | |||
1813 | return 0; | ||
1434 | } | 1814 | } |
1435 | 1815 | ||
1436 | static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) | 1816 | static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) |