26 #include <linux/slab.h>
38 return (2407 + 5 * channel);
39 else if (channel == 14)
41 else if (channel < 184)
42 return (5000 + 5 * channel);
44 return (4000 + 5 * channel);
47 static unsigned int b43_lpphy_op_get_default_chan(
struct b43_wldev *
dev)
54 static int b43_lpphy_op_allocate(
struct b43_wldev *dev)
66 static void b43_lpphy_op_prepare_structs(
struct b43_wldev *dev)
71 memset(lpphy, 0,
sizeof(*lpphy));
77 static void b43_lpphy_op_free(
struct b43_wldev *dev)
86 static void lpphy_read_band_sprom(
struct b43_wldev *dev)
115 for (i = 0; i < 4; i++) {
117 maxpwr - (ofdmpo & 0xF) * 2;
121 for (i = 4; i < 15; i++) {
123 maxpwr - (ofdmpo & 0xF) * 2;
128 for (i = 0; i < 4; i++)
130 for (i = 4; i < 15; i++)
154 for (i = 4; i < 12; i++) {
161 for (i = 4; i < 12; i++) {
168 for (i = 4; i < 12; i++) {
185 else if (freq <= 5320)
187 else if (freq <= 5700)
192 temp[0] = ((isolation - 26) / 12) << 12;
193 temp[1] = temp[0] + 0x1000;
194 temp[2] = temp[0] + 0x2000;
200 static void lpphy_table_init(
struct b43_wldev *dev)
202 u32 freq = channel2freq_lp(b43_lpphy_op_get_default_chan(dev));
204 if (dev->
phy.rev < 2)
211 if (dev->
phy.rev < 2)
212 lpphy_adjust_gain_table(dev, freq);
215 static void lpphy_baseband_rev0_1_init(
struct b43_wldev *dev)
251 if (dev->
phy.rev == 0) {
270 0xFFF9, (lpphy->
bx_arch << 1));
271 if (dev->
phy.rev == 1 &&
290 (dev->
dev->board_type == 0x048A) || ((dev->
phy.rev == 0) &&
300 }
else if (dev->
phy.rev == 1 ||
327 (dev->
dev->chip_id == 0x5354) &&
348 if (dev->
phy.rev == 1) {
350 tmp2 = (tmp & 0x03E0) >> 5;
354 tmp2 = (tmp & 0x1F00) >> 8;
364 static void lpphy_save_dig_flt_state(
struct b43_wldev *dev)
378 static const u16 coefs[] = {
379 0xDE5E, 0xE832, 0xE331, 0x4D26,
380 0x0026, 0x1420, 0x0020, 0xFE08,
393 static void lpphy_restore_dig_flt_state(
struct b43_wldev *dev)
395 static const u16 addr[] = {
414 static void lpphy_baseband_rev2plus_init(
struct b43_wldev *dev)
435 if (dev->
dev->board_rev >= 0x18) {
452 if ((dev->
dev->chip_id == 0x4325) && (dev->
dev->chip_rev == 0)) {
470 if ((dev->
dev->chip_id == 0x4325) && (dev->
dev->chip_rev == 0)) {
495 if ((dev->
dev->chip_id == 0x4325) && (dev->
dev->chip_rev == 0)) {
501 lpphy_save_dig_flt_state(dev);
504 static void lpphy_baseband_init(
struct b43_wldev *dev)
506 lpphy_table_init(dev);
507 if (dev->
phy.rev >= 2)
508 lpphy_baseband_rev2plus_init(dev);
510 lpphy_baseband_rev0_1_init(dev);
519 static void lpphy_2062_init(
struct b43_wldev *dev)
523 u32 crystalfreq,
tmp, ref;
528 { .
freq = 12000, .data[0] = 6, .data[1] = 6, .data[2] = 6,
529 .data[3] = 6, .data[4] = 10, .data[5] = 6, },
530 { .freq = 13000, .data[0] = 4, .data[1] = 4, .data[2] = 4,
531 .data[3] = 4, .data[4] = 11, .data[5] = 7, },
532 { .freq = 14400, .data[0] = 3, .data[1] = 3, .data[2] = 3,
533 .data[3] = 3, .data[4] = 12, .data[5] = 7, },
534 { .freq = 16200, .data[0] = 3, .data[1] = 3, .data[2] = 3,
535 .data[3] = 3, .data[4] = 13, .data[5] = 8, },
536 { .freq = 18000, .data[0] = 2, .data[1] = 2, .data[2] = 2,
537 .data[3] = 2, .data[4] = 14, .data[5] = 8, },
538 { .freq = 19200, .data[0] = 1, .data[1] = 1, .data[2] = 1,
539 .data[3] = 1, .data[4] = 14, .data[5] = 9, },
552 if (dev->
phy.rev > 0) {
562 crystalfreq = bus->
chipco.pmu.crystalfreq * 1000;
567 if (crystalfreq <= 30000000) {
575 tmp = (((800000000 * lpphy->
pdiv + crystalfreq) /
576 (2 * crystalfreq)) - 8) & 0xFF;
579 tmp = (((100 * crystalfreq + 16000000 * lpphy->
pdiv) /
580 (32000000 * lpphy->
pdiv)) - 1) & 0xFF;
583 tmp = (((2 * crystalfreq + 1000000 * lpphy->
pdiv) /
584 (2000000 * lpphy->
pdiv)) - 1) & 0xFF;
587 ref = (1000 * lpphy->
pdiv + 2 * crystalfreq) / (2000 * lpphy->
pdiv);
589 for (i = 0; i <
ARRAY_SIZE(freqdata_tab); i++) {
590 if (ref < freqdata_tab[i].freq) {
591 fd = &freqdata_tab[
i];
596 fd = &freqdata_tab[
ARRAY_SIZE(freqdata_tab) - 1];
597 b43dbg(dev->
wl,
"b2062: Using crystal tab entry %u kHz.\n",
609 static void lpphy_2063_init(
struct b43_wldev *dev)
619 if (dev->
phy.rev == 2) {
638 { .phy_offset = 2, .phy_shift = 6, .rf_addr = 0x3d, .rf_shift = 3, .mask = 0x01, },
639 { .phy_offset = 1, .phy_shift = 12, .rf_addr = 0x4c, .rf_shift = 1, .mask = 0x01, },
640 { .phy_offset = 1, .phy_shift = 8, .rf_addr = 0x50, .rf_shift = 0, .mask = 0x7f, },
641 { .phy_offset = 0, .phy_shift = 8, .rf_addr = 0x44, .rf_shift = 0, .mask = 0xff, },
642 { .phy_offset = 1, .phy_shift = 0, .rf_addr = 0x4a, .rf_shift = 0, .mask = 0xff, },
643 { .phy_offset = 0, .phy_shift = 4, .rf_addr = 0x4d, .rf_shift = 0, .mask = 0xff, },
644 { .phy_offset = 1, .phy_shift = 4, .rf_addr = 0x4e, .rf_shift = 0, .mask = 0xff, },
645 { .phy_offset = 0, .phy_shift = 12, .rf_addr = 0x4f, .rf_shift = 0, .mask = 0x0f, },
646 { .phy_offset = 1, .phy_shift = 0, .rf_addr = 0x4f, .rf_shift = 4, .mask = 0x0f, },
647 { .phy_offset = 3, .phy_shift = 0, .rf_addr = 0x49, .rf_shift = 0, .mask = 0x0f, },
648 { .phy_offset = 4, .phy_shift = 3, .rf_addr = 0x46, .rf_shift = 4, .mask = 0x07, },
649 { .phy_offset = 3, .phy_shift = 15, .rf_addr = 0x46, .rf_shift = 0, .mask = 0x01, },
650 { .phy_offset = 4, .phy_shift = 0, .rf_addr = 0x46, .rf_shift = 1, .mask = 0x07, },
651 { .phy_offset = 3, .phy_shift = 8, .rf_addr = 0x48, .rf_shift = 4, .mask = 0x07, },
652 { .phy_offset = 3, .phy_shift = 11, .rf_addr = 0x48, .rf_shift = 0, .mask = 0x0f, },
653 { .phy_offset = 3, .phy_shift = 4, .rf_addr = 0x49, .rf_shift = 4, .mask = 0x0f, },
654 { .phy_offset = 2, .phy_shift = 15, .rf_addr = 0x45, .rf_shift = 0, .mask = 0x01, },
655 { .phy_offset = 5, .phy_shift = 13, .rf_addr = 0x52, .rf_shift = 4, .mask = 0x07, },
656 { .phy_offset = 6, .phy_shift = 0, .rf_addr = 0x52, .rf_shift = 7, .mask = 0x01, },
657 { .phy_offset = 5, .phy_shift = 3, .rf_addr = 0x41, .rf_shift = 5, .mask = 0x07, },
658 { .phy_offset = 5, .phy_shift = 6, .rf_addr = 0x41, .rf_shift = 0, .mask = 0x0f, },
659 { .phy_offset = 5, .phy_shift = 10, .rf_addr = 0x42, .rf_shift = 5, .mask = 0x07, },
660 { .phy_offset = 4, .phy_shift = 15, .rf_addr = 0x42, .rf_shift = 0, .mask = 0x01, },
661 { .phy_offset = 5, .phy_shift = 0, .rf_addr = 0x42, .rf_shift = 1, .mask = 0x07, },
662 { .phy_offset = 4, .phy_shift = 11, .rf_addr = 0x43, .rf_shift = 4, .mask = 0x0f, },
663 { .phy_offset = 4, .phy_shift = 7, .rf_addr = 0x43, .rf_shift = 0, .mask = 0x0f, },
664 { .phy_offset = 4, .phy_shift = 6, .rf_addr = 0x45, .rf_shift = 1, .mask = 0x01, },
665 { .phy_offset = 2, .phy_shift = 7, .rf_addr = 0x40, .rf_shift = 4, .mask = 0x0f, },
666 { .phy_offset = 2, .phy_shift = 11, .rf_addr = 0x40, .rf_shift = 0, .mask = 0x0f, },
669 static void lpphy_sync_stx(
struct b43_wldev *dev)
675 for (i = 0; i <
ARRAY_SIZE(lpphy_stx_table); i++) {
676 e = &lpphy_stx_table[
i];
685 static void lpphy_radio_init(
struct b43_wldev *dev)
693 if (dev->
phy.radio_ver == 0x2062) {
694 lpphy_2062_init(dev);
696 lpphy_2063_init(dev);
700 if (dev->
dev->chip_id == 0x4325) {
708 static void lpphy_set_rc_cap(
struct b43_wldev *dev)
714 if (dev->
phy.rev == 1)
715 rc_cap =
min_t(
u8, rc_cap + 5, 15);
721 ((lpphy->
rc_cap & 0x1F) >> 2) | 0x80);
729 static void lpphy_set_bb_mult(
struct b43_wldev *dev,
u8 bb_mult)
745 static void lpphy_clear_deaf(
struct b43_wldev *dev,
bool user)
764 static void lpphy_set_trsw_over(
struct b43_wldev *dev,
bool tx,
bool rx)
766 u16 trsw = (tx << 1) | rx;
771 static void lpphy_disable_crs(
struct b43_wldev *dev,
bool user)
773 lpphy_set_deaf(dev, user);
774 lpphy_set_trsw_over(dev,
false,
true);
800 static void lpphy_restore_crs(
struct b43_wldev *dev,
bool user)
802 lpphy_clear_deaf(dev, user);
809 static void lpphy_disable_rx_gain_override(
struct b43_wldev *dev)
814 if (dev->
phy.rev >= 2) {
825 static void lpphy_enable_rx_gain_override(
struct b43_wldev *dev)
830 if (dev->
phy.rev >= 2) {
841 static void lpphy_disable_tx_gain_override(
struct b43_wldev *dev)
843 if (dev->
phy.rev < 2)
852 static void lpphy_enable_tx_gain_override(
struct b43_wldev *dev)
854 if (dev->
phy.rev < 2)
869 if (dev->
phy.rev < 2) {
872 gains.gm = tmp & 0x0007;
873 gains.pga = (tmp & 0x0078) >> 3;
874 gains.pad = (tmp & 0x780) >> 7;
878 gains.gm = tmp & 0xFF;
879 gains.pga = (tmp >> 8) & 0xFF;
903 static void lpphy_set_tx_gains(
struct b43_wldev *dev,
906 u16 rf_gain, pa_gain;
908 if (dev->
phy.rev < 2) {
909 rf_gain = (gains.
pad << 7) | (gains.
pga << 3) | gains.
gm;
913 pa_gain = lpphy_get_pa_gain(dev);
915 (gains.
pga << 8) | gains.
gm);
921 0x8000, gains.
pad | (pa_gain << 6));
923 (gains.
pga << 8) | gains.
gm);
925 0x8000, gains.
pad | (pa_gain << 8));
927 lpphy_set_dac_gain(dev, gains.
dac);
928 lpphy_enable_tx_gain_override(dev);
931 static void lpphy_rev0_1_set_rx_gain(
struct b43_wldev *dev,
u32 gain)
933 u16 trsw = gain & 0x1;
934 u16 lna = (gain & 0xFFFC) | ((gain & 0xC) >> 2);
935 u16 ext_lna = (gain & 2) >> 1;
939 0xFBFF, ext_lna << 10);
941 0xF7FF, ext_lna << 11);
945 static void lpphy_rev2plus_set_rx_gain(
struct b43_wldev *dev,
u32 gain)
947 u16 low_gain = gain & 0xFFFF;
948 u16 high_gain = (gain >> 16) & 0xF;
949 u16 ext_lna = (gain >> 21) & 0x1;
950 u16 trsw = ~(gain >> 20) & 0x1;
955 0xFDFF, ext_lna << 9);
957 0xFBFF, ext_lna << 10);
961 tmp = (gain >> 2) & 0x3;
968 static void lpphy_set_rx_gain(
struct b43_wldev *dev,
u32 gain)
970 if (dev->
phy.rev < 2)
971 lpphy_rev0_1_set_rx_gain(dev, gain);
973 lpphy_rev2plus_set_rx_gain(dev, gain);
974 lpphy_enable_rx_gain_override(dev);
980 lpphy_set_rx_gain(dev, gain);
983 static void lpphy_stop_ddfs(
struct b43_wldev *dev)
989 static void lpphy_run_ddfs(
struct b43_wldev *dev,
int i_on,
int q_on,
990 int incr1,
int incr2,
int scale_idx)
992 lpphy_stop_ddfs(dev);
1016 for (i = 0; i < 500; i++) {
1033 iq_est->
i_pwr <<= 16;
1037 iq_est->
q_pwr <<= 16;
1044 static int lpphy_loopback(
struct b43_wldev *dev)
1050 memset(&iq_est, 0,
sizeof(iq_est));
1052 lpphy_set_trsw_over(dev,
true,
true);
1062 for (i = 0; i < 32; i++) {
1063 lpphy_set_rx_gain_by_index(dev, i);
1064 lpphy_run_ddfs(dev, 1, 1, 5, 5, 0);
1065 if (!(lpphy_rx_iq_est(dev, 1000, 32, &iq_est)))
1068 if ((tmp > 4000) && (tmp < 10000)) {
1073 lpphy_stop_ddfs(dev);
1080 u32 quotient, remainder;
1085 quotient = dividend /
divisor;
1086 remainder = dividend %
divisor;
1088 while (precision > 0) {
1090 if (remainder << 1 >= divisor) {
1092 remainder = (remainder << 1) - divisor;
1097 if (remainder << 1 >= divisor)
1104 static void lpphy_read_tx_pctl_mode_from_hardware(
struct b43_wldev *dev)
1128 static void lpphy_write_tx_pctl_mode_to_hardware(
struct b43_wldev *dev)
1151 static void lpphy_set_tx_power_control(
struct b43_wldev *dev,
1157 lpphy_read_tx_pctl_mode_from_hardware(dev);
1159 if (oldmode == mode)
1174 lpphy_disable_tx_gain_override(dev);
1178 if (dev->
phy.rev >= 2) {
1184 lpphy_write_tx_pctl_mode_to_hardware(dev);
1187 static int b43_lpphy_op_switch_channel(
struct b43_wldev *dev,
1188 unsigned int new_channel);
1190 static void lpphy_rev0_1_rc_calib(
struct b43_wldev *dev)
1195 static const u32 ideal_pwr_table[21] = {
1196 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
1197 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
1198 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
1199 0x0004c, 0x0002c, 0x0001a,
1203 u16 old_rf_ovr, old_rf_ovrval, old_afe_ovr, old_afe_ovrval,
1204 old_rf2_ovr, old_rf2_ovrval, old_phy_ctl;
1206 u32 normal_pwr, ideal_pwr, mean_sq_pwr, tmp = 0, mean_sq_pwr_min = 0;
1209 memset(&iq_est, 0,
sizeof(iq_est));
1211 err = b43_lpphy_op_switch_channel(dev, 7);
1214 "RC calib: Failed to switch to channel 7, error = %d\n",
1218 old_bbmult = lpphy_get_bb_mult(dev);
1220 tx_gains = lpphy_get_tx_gains(dev);
1228 lpphy_read_tx_pctl_mode_from_hardware(dev);
1232 lpphy_disable_crs(dev,
true);
1233 loopback = lpphy_loopback(dev);
1236 lpphy_set_rx_gain_by_index(dev, loopback);
1241 for (i = 128; i <= 159; i++) {
1244 for (j = 5; j <= 25; j++) {
1245 lpphy_run_ddfs(dev, 1, 1, j, j, 0);
1246 if (!(lpphy_rx_iq_est(dev, 1000, 32, &iq_est)))
1251 ideal_pwr = ((ideal_pwr_table[j-5] >> 3) + 1) >> 1;
1252 normal_pwr = lpphy_qdiv_roundup(mean_sq_pwr, tmp, 12);
1253 mean_sq_pwr = ideal_pwr - normal_pwr;
1254 mean_sq_pwr *= mean_sq_pwr;
1255 inner_sum += mean_sq_pwr;
1256 if ((i == 128) || (inner_sum < mean_sq_pwr_min)) {
1258 mean_sq_pwr_min = inner_sum;
1262 lpphy_stop_ddfs(dev);
1265 lpphy_restore_crs(dev,
true);
1274 lpphy_set_bb_mult(dev, old_bbmult);
1283 lpphy_set_tx_gains(dev, tx_gains);
1285 lpphy_set_tx_power_control(dev, old_txpctl);
1287 lpphy_set_rc_cap(dev);
1290 static void lpphy_rev2plus_rc_calib(
struct b43_wldev *dev)
1293 u32 crystal_freq = bus->
chipco.pmu.crystalfreq * 1000;
1307 for (i = 0; i < 10000; i++) {
1324 if (crystal_freq == 24000000) {
1334 for (i = 0; i < 10000; i++) {
1346 static void lpphy_calibrate_rc(
struct b43_wldev *dev)
1350 if (dev->
phy.rev >= 2) {
1351 lpphy_rev2plus_rc_calib(dev);
1352 }
else if (!lpphy->
rc_cap) {
1354 lpphy_rev0_1_rc_calib(dev);
1356 lpphy_set_rc_cap(dev);
1360 static void b43_lpphy_op_set_rx_antenna(
struct b43_wldev *dev,
int antenna)
1362 if (dev->
phy.rev >= 2)
1387 static void lpphy_set_tx_power_by_index(
struct b43_wldev *dev,
u8 index)
1391 u32 iq_comp, tx_gain,
coeff, rf_power;
1394 lpphy_read_tx_pctl_mode_from_hardware(dev);
1397 if (dev->
phy.rev >= 2) {
1400 gains.
pad = (tx_gain >> 16) & 0xFF;
1401 gains.
gm = tx_gain & 0xFF;
1402 gains.
pga = (tx_gain >> 8) & 0xFF;
1403 gains.
dac = (iq_comp >> 28) & 0xFF;
1404 lpphy_set_tx_gains(dev, gains);
1409 0xF800, (tx_gain >> 4) & 0x7FFF);
1410 lpphy_set_dac_gain(dev, tx_gain & 0x7);
1411 lpphy_set_pa_gain(dev, (tx_gain >> 24) & 0x7F);
1413 lpphy_set_bb_mult(dev, (iq_comp >> 20) & 0xFF);
1414 lpphy_set_tx_iqcc(dev, (iq_comp >> 10) & 0x3FF, iq_comp & 0x3FF);
1415 if (dev->
phy.rev >= 2) {
1421 if (dev->
phy.rev >= 2) {
1426 lpphy_enable_tx_gain_override(dev);
1429 static void lpphy_btcoex_override(
struct b43_wldev *dev)
1435 static void b43_lpphy_op_software_rfkill(
struct b43_wldev *dev,
1440 if (dev->
phy.rev >= 2) {
1454 if (dev->
phy.rev >= 2)
1462 static void lpphy_set_analog_filter(
struct b43_wldev *dev,
int channel)
1465 u16 tmp = (channel == 14);
1467 if (dev->
phy.rev < 2) {
1469 if ((dev->
phy.rev == 1) && (lpphy->
rc_cap))
1470 lpphy_set_rc_cap(dev);
1495 static void lpphy_tx_pctl_init_hw(
struct b43_wldev *dev)
1501 for (i = 0; i < 64; i++) {
1502 if (dev->
phy.rev >= 2)
1511 if (dev->
phy.rev < 2) {
1532 if (dev->
phy.rev < 2) {
1536 lpphy_set_tx_power_by_index(dev, 0x7F);
1544 0xFFC0, (tmp & 0xFF) - 32);
1553 static void lpphy_tx_pctl_init_sw(
struct b43_wldev *dev)
1568 lpphy_set_tx_gains(dev, gains);
1569 lpphy_set_bb_mult(dev, 150);
1573 static void lpphy_tx_pctl_init(
struct b43_wldev *dev)
1576 lpphy_tx_pctl_init_hw(dev);
1578 lpphy_tx_pctl_init_sw(dev);
1582 static void lpphy_pr41573_workaround(
struct b43_wldev *dev)
1586 const unsigned int saved_tab_size = 256;
1591 saved_tab = kcalloc(saved_tab_size,
sizeof(saved_tab[0]),
GFP_KERNEL);
1593 b43err(dev->
wl,
"PR41573 failed. Out of memory!\n");
1597 lpphy_read_tx_pctl_mode_from_hardware(dev);
1603 if (dev->
phy.rev < 2) {
1605 saved_tab_size, saved_tab);
1608 saved_tab_size, saved_tab);
1611 lpphy_table_init(dev);
1612 lpphy_baseband_init(dev);
1613 lpphy_tx_pctl_init(dev);
1614 b43_lpphy_op_software_rfkill(dev,
false);
1616 if (dev->
phy.rev < 2) {
1618 saved_tab_size, saved_tab);
1621 saved_tab_size, saved_tab);
1626 lpphy_set_analog_filter(dev, lpphy->
channel);
1627 if (tx_pwr_idx_over != -1)
1628 lpphy_set_tx_power_by_index(dev, tx_pwr_idx_over);
1630 lpphy_set_rc_cap(dev);
1631 b43_lpphy_op_set_rx_antenna(dev, lpphy->
antenna);
1632 lpphy_set_tx_power_control(dev, txpctl_mode);
1639 { .chan = 1, .c1 = -66, .c0 = 15, },
1640 { .chan = 2, .c1 = -66, .c0 = 15, },
1641 { .chan = 3, .c1 = -66, .c0 = 15, },
1642 { .chan = 4, .c1 = -66, .c0 = 15, },
1643 { .chan = 5, .c1 = -66, .c0 = 15, },
1644 { .chan = 6, .c1 = -66, .c0 = 15, },
1645 { .chan = 7, .c1 = -66, .c0 = 14, },
1646 { .chan = 8, .c1 = -66, .c0 = 14, },
1647 { .chan = 9, .c1 = -66, .c0 = 14, },
1648 { .chan = 10, .c1 = -66, .c0 = 14, },
1649 { .chan = 11, .c1 = -66, .c0 = 14, },
1650 { .chan = 12, .c1 = -66, .c0 = 13, },
1651 { .chan = 13, .c1 = -66, .c0 = 13, },
1652 { .chan = 14, .c1 = -66, .c0 = 13, },
1656 { .chan = 1, .c1 = -64, .c0 = 13, },
1657 { .chan = 2, .c1 = -64, .c0 = 13, },
1658 { .chan = 3, .c1 = -64, .c0 = 13, },
1659 { .chan = 4, .c1 = -64, .c0 = 13, },
1660 { .chan = 5, .c1 = -64, .c0 = 12, },
1661 { .chan = 6, .c1 = -64, .c0 = 12, },
1662 { .chan = 7, .c1 = -64, .c0 = 12, },
1663 { .chan = 8, .c1 = -64, .c0 = 12, },
1664 { .chan = 9, .c1 = -64, .c0 = 12, },
1665 { .chan = 10, .c1 = -64, .c0 = 11, },
1666 { .chan = 11, .c1 = -64, .c0 = 11, },
1667 { .chan = 12, .c1 = -64, .c0 = 11, },
1668 { .chan = 13, .c1 = -64, .c0 = 11, },
1669 { .chan = 14, .c1 = -64, .c0 = 10, },
1670 { .chan = 34, .c1 = -62, .c0 = 24, },
1671 { .chan = 38, .c1 = -62, .c0 = 24, },
1672 { .chan = 42, .c1 = -62, .c0 = 24, },
1673 { .chan = 46, .c1 = -62, .c0 = 23, },
1674 { .chan = 36, .c1 = -62, .c0 = 24, },
1675 { .chan = 40, .c1 = -62, .c0 = 24, },
1676 { .chan = 44, .c1 = -62, .c0 = 23, },
1677 { .chan = 48, .c1 = -62, .c0 = 23, },
1678 { .chan = 52, .c1 = -62, .c0 = 23, },
1679 { .chan = 56, .c1 = -62, .c0 = 22, },
1680 { .chan = 60, .c1 = -62, .c0 = 22, },
1681 { .chan = 64, .c1 = -62, .c0 = 22, },
1682 { .chan = 100, .c1 = -62, .c0 = 16, },
1683 { .chan = 104, .c1 = -62, .c0 = 16, },
1684 { .chan = 108, .c1 = -62, .c0 = 15, },
1685 { .chan = 112, .c1 = -62, .c0 = 14, },
1686 { .chan = 116, .c1 = -62, .c0 = 14, },
1687 { .chan = 120, .c1 = -62, .c0 = 13, },
1688 { .chan = 124, .c1 = -62, .c0 = 12, },
1689 { .chan = 128, .c1 = -62, .c0 = 12, },
1690 { .chan = 132, .c1 = -62, .c0 = 12, },
1691 { .chan = 136, .c1 = -62, .c0 = 11, },
1692 { .chan = 140, .c1 = -62, .c0 = 10, },
1693 { .chan = 149, .c1 = -61, .c0 = 9, },
1694 { .chan = 153, .c1 = -61, .c0 = 9, },
1695 { .chan = 157, .c1 = -61, .c0 = 9, },
1696 { .chan = 161, .c1 = -61, .c0 = 8, },
1697 { .chan = 165, .c1 = -61, .c0 = 8, },
1698 { .chan = 184, .c1 = -62, .c0 = 25, },
1699 { .chan = 188, .c1 = -62, .c0 = 25, },
1700 { .chan = 192, .c1 = -62, .c0 = 25, },
1701 { .chan = 196, .c1 = -62, .c0 = 25, },
1702 { .chan = 200, .c1 = -62, .c0 = 25, },
1703 { .chan = 204, .c1 = -62, .c0 = 25, },
1704 { .chan = 208, .c1 = -62, .c0 = 25, },
1705 { .chan = 212, .c1 = -62, .c0 = 25, },
1706 { .chan = 216, .c1 = -62, .c0 = 26, },
1715 static int lpphy_calc_rx_iq_comp(
struct b43_wldev *dev,
u16 samples)
1719 int prod, ipwr, qpwr, prod_msb, q_msb,
tmp1, tmp2, tmp3, tmp4,
ret;
1728 ret = lpphy_rx_iq_est(dev, samples, 32, &iq_est);
1733 ipwr = iq_est.
i_pwr;
1734 qpwr = iq_est.
q_pwr;
1736 if (ipwr + qpwr < 2) {
1741 prod_msb = fls(
abs(prod));
1742 q_msb = fls(
abs(qpwr));
1743 tmp1 = prod_msb - 20;
1746 tmp3 = ((prod << (30 - prod_msb)) + (ipwr >> (1 +
tmp1))) /
1749 tmp3 = ((prod << (30 - prod_msb)) + (ipwr << (-1 -
tmp1))) /
1756 tmp4 = (qpwr << (31 - q_msb)) / (ipwr >> tmp2);
1758 tmp4 = (qpwr << (31 - q_msb)) / (ipwr << -tmp2);
1760 tmp4 -= tmp3 * tmp3;
1772 static void lpphy_run_samples(
struct b43_wldev *dev,
u16 samples,
u16 loops,
1776 0xFFC0, samples - 1);
1777 if (loops != 0xFFFF)
1789 int i, samples = 0,
angle = 0;
1790 int rotation = (((36 *
freq) / 20) << 16) / 100;
1797 for (i = 1; samples *
abs(freq) != 20000 *
i; i++) {
1798 samples = (20000 *
i) /
abs(freq);
1806 for (i = 0; i < samples; i++) {
1815 lpphy_run_samples(dev, samples, 0xFFFF, 0);
1818 static void lpphy_stop_tx_tone(
struct b43_wldev *dev)
1826 for (i = 0; i < 31; i++) {
1835 int mode,
bool useindex,
u8 index)
1840 static void lpphy_papd_cal_txpwr(
struct b43_wldev *dev)
1844 int old_txpctl, old_afe_ovr, old_rf, old_bbmult;
1846 lpphy_read_tx_pctl_mode_from_hardware(dev);
1850 oldgains = lpphy_get_tx_gains(dev);
1852 old_bbmult = lpphy_get_bb_mult(dev);
1856 if (dev->
dev->chip_id == 0x4325 && dev->
dev->chip_rev == 0)
1857 lpphy_papd_cal(dev, gains, 0, 1, 30);
1859 lpphy_papd_cal(dev, gains, 0, 1, 65);
1862 lpphy_set_tx_gains(dev, oldgains);
1863 lpphy_set_bb_mult(dev, old_bbmult);
1864 lpphy_set_tx_power_control(dev, old_txpctl);
1868 static int lpphy_rx_iq_cal(
struct b43_wldev *dev,
bool noise,
bool tx,
1877 memset(&nogains, 0,
sizeof(nogains));
1878 memset(&oldgains, 0,
sizeof(oldgains));
1880 if (dev->
dev->chip_id == 0x5354) {
1881 for (i = 0; i <
ARRAY_SIZE(lpphy_5354_iq_table); i++) {
1882 if (lpphy_5354_iq_table[i].
chan == lpphy->
channel) {
1883 iqcomp = &lpphy_5354_iq_table[
i];
1886 }
else if (dev->
phy.rev >= 2) {
1887 iqcomp = &lpphy_rev2plus_iq_comp;
1889 for (i = 0; i <
ARRAY_SIZE(lpphy_rev0_1_iq_table); i++) {
1890 if (lpphy_rev0_1_iq_table[i].
chan == lpphy->
channel) {
1891 iqcomp = &lpphy_rev0_1_iq_table[
i];
1901 0x00FF, iqcomp->
c0 << 8);
1909 lpphy_set_trsw_over(dev, tx, rx);
1924 lpphy_set_rx_gain(dev, 0x2D5D);
1927 oldgains = lpphy_get_tx_gains(dev);
1930 lpphy_set_tx_gains(dev, *gains);
1937 lpphy_set_deaf(dev,
false);
1939 ret = lpphy_calc_rx_iq_comp(dev, 0xFFF0);
1941 lpphy_start_tx_tone(dev, 4000, 100);
1942 ret = lpphy_calc_rx_iq_comp(dev, 0x4000);
1943 lpphy_stop_tx_tone(dev);
1945 lpphy_clear_deaf(dev,
false);
1951 lpphy_set_tx_gains(dev, oldgains);
1953 lpphy_disable_tx_gain_override(dev);
1955 lpphy_disable_rx_gain_override(dev);
1961 static void lpphy_calibration(
struct b43_wldev *dev)
1965 bool full_cal =
false;
1974 lpphy_btcoex_override(dev);
1975 if (dev->
phy.rev >= 2)
1976 lpphy_save_dig_flt_state(dev);
1977 lpphy_read_tx_pctl_mode_from_hardware(dev);
1982 lpphy_pr41573_workaround(dev);
1983 if ((dev->
phy.rev >= 2) && full_cal) {
1984 lpphy_papd_cal_txpwr(dev);
1986 lpphy_set_tx_power_control(dev, saved_pctl_mode);
1987 if (dev->
phy.rev >= 2)
1988 lpphy_restore_dig_flt_state(dev);
1989 lpphy_rx_iq_cal(dev,
true,
true,
false,
false,
NULL);
2019 if (dev->
phy.rev < 2) {
2045 { .channel = 1, .freq = 2412, .data[0] = 0xFF, .data[1] = 0xFF,
2046 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2047 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2048 { .channel = 2, .freq = 2417, .data[0] = 0xFF, .data[1] = 0xFF,
2049 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2050 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2051 { .channel = 3, .freq = 2422, .data[0] = 0xFF, .data[1] = 0xFF,
2052 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2053 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2054 { .channel = 4, .freq = 2427, .data[0] = 0xFF, .data[1] = 0xFF,
2055 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2056 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2057 { .channel = 5, .freq = 2432, .data[0] = 0xFF, .data[1] = 0xFF,
2058 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2059 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2060 { .channel = 6, .freq = 2437, .data[0] = 0xFF, .data[1] = 0xFF,
2061 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2062 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2063 { .channel = 7, .freq = 2442, .data[0] = 0xFF, .data[1] = 0xFF,
2064 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2065 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2066 { .channel = 8, .freq = 2447, .data[0] = 0xFF, .data[1] = 0xFF,
2067 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2068 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2069 { .channel = 9, .freq = 2452, .data[0] = 0xFF, .data[1] = 0xFF,
2070 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2071 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2072 { .channel = 10, .freq = 2457, .data[0] = 0xFF, .data[1] = 0xFF,
2073 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2074 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2075 { .channel = 11, .freq = 2462, .data[0] = 0xFF, .data[1] = 0xFF,
2076 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2077 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2078 { .channel = 12, .freq = 2467, .data[0] = 0xFF, .data[1] = 0xFF,
2079 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2080 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2081 { .channel = 13, .freq = 2472, .data[0] = 0xFF, .data[1] = 0xFF,
2082 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2083 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2084 { .channel = 14, .freq = 2484, .data[0] = 0xFF, .data[1] = 0xFF,
2085 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
2086 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
2087 { .channel = 34, .freq = 5170, .data[0] = 0x00, .data[1] = 0x22,
2088 .data[2] = 0x20, .data[3] = 0x84, .data[4] = 0x3C, .data[5] = 0x77,
2089 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2090 { .channel = 38, .freq = 5190, .data[0] = 0x00, .data[1] = 0x11,
2091 .data[2] = 0x10, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
2092 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2093 { .channel = 42, .freq = 5210, .data[0] = 0x00, .data[1] = 0x11,
2094 .data[2] = 0x10, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
2095 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2096 { .channel = 46, .freq = 5230, .data[0] = 0x00, .data[1] = 0x00,
2097 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
2098 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2099 { .channel = 36, .freq = 5180, .data[0] = 0x00, .data[1] = 0x11,
2100 .data[2] = 0x20, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
2101 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2102 { .channel = 40, .freq = 5200, .data[0] = 0x00, .data[1] = 0x11,
2103 .data[2] = 0x10, .data[3] = 0x84, .data[4] = 0x3C, .data[5] = 0x77,
2104 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2105 { .channel = 44, .freq = 5220, .data[0] = 0x00, .data[1] = 0x11,
2106 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
2107 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2108 { .channel = 48, .freq = 5240, .data[0] = 0x00, .data[1] = 0x00,
2109 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
2110 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2111 { .channel = 52, .freq = 5260, .data[0] = 0x00, .data[1] = 0x00,
2112 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
2113 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2114 { .channel = 56, .freq = 5280, .data[0] = 0x00, .data[1] = 0x00,
2115 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
2116 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2117 { .channel = 60, .freq = 5300, .data[0] = 0x00, .data[1] = 0x00,
2118 .data[2] = 0x00, .data[3] = 0x63, .data[4] = 0x3C, .data[5] = 0x77,
2119 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2120 { .channel = 64, .freq = 5320, .data[0] = 0x00, .data[1] = 0x00,
2121 .data[2] = 0x00, .data[3] = 0x62, .data[4] = 0x3C, .data[5] = 0x77,
2122 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2123 { .channel = 100, .freq = 5500, .data[0] = 0x00, .data[1] = 0x00,
2124 .data[2] = 0x00, .data[3] = 0x30, .data[4] = 0x3C, .data[5] = 0x77,
2125 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2126 { .channel = 104, .freq = 5520, .data[0] = 0x00, .data[1] = 0x00,
2127 .data[2] = 0x00, .data[3] = 0x20, .data[4] = 0x3C, .data[5] = 0x77,
2128 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2129 { .channel = 108, .freq = 5540, .data[0] = 0x00, .data[1] = 0x00,
2130 .data[2] = 0x00, .data[3] = 0x20, .data[4] = 0x3C, .data[5] = 0x77,
2131 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2132 { .channel = 112, .freq = 5560, .data[0] = 0x00, .data[1] = 0x00,
2133 .data[2] = 0x00, .data[3] = 0x20, .data[4] = 0x3C, .data[5] = 0x77,
2134 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2135 { .channel = 116, .freq = 5580, .data[0] = 0x00, .data[1] = 0x00,
2136 .data[2] = 0x00, .data[3] = 0x10, .data[4] = 0x3C, .data[5] = 0x77,
2137 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2138 { .channel = 120, .freq = 5600, .data[0] = 0x00, .data[1] = 0x00,
2139 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2140 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2141 { .channel = 124, .freq = 5620, .data[0] = 0x00, .data[1] = 0x00,
2142 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2143 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2144 { .channel = 128, .freq = 5640, .data[0] = 0x00, .data[1] = 0x00,
2145 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2146 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2147 { .channel = 132, .freq = 5660, .data[0] = 0x00, .data[1] = 0x00,
2148 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2149 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2150 { .channel = 136, .freq = 5680, .data[0] = 0x00, .data[1] = 0x00,
2151 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2152 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2153 { .channel = 140, .freq = 5700, .data[0] = 0x00, .data[1] = 0x00,
2154 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2155 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2156 { .channel = 149, .freq = 5745, .data[0] = 0x00, .data[1] = 0x00,
2157 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2158 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2159 { .channel = 153, .freq = 5765, .data[0] = 0x00, .data[1] = 0x00,
2160 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2161 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2162 { .channel = 157, .freq = 5785, .data[0] = 0x00, .data[1] = 0x00,
2163 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2164 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2165 { .channel = 161, .freq = 5805, .data[0] = 0x00, .data[1] = 0x00,
2166 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2167 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2168 { .channel = 165, .freq = 5825, .data[0] = 0x00, .data[1] = 0x00,
2169 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
2170 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
2171 { .channel = 184, .freq = 4920, .data[0] = 0x55, .data[1] = 0x77,
2172 .data[2] = 0x90, .data[3] = 0xF7, .data[4] = 0x3C, .data[5] = 0x77,
2173 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
2174 { .channel = 188, .freq = 4940, .data[0] = 0x44, .data[1] = 0x77,
2175 .data[2] = 0x80, .data[3] = 0xE7, .data[4] = 0x3C, .data[5] = 0x77,
2176 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
2177 { .channel = 192, .freq = 4960, .data[0] = 0x44, .data[1] = 0x66,
2178 .data[2] = 0x80, .data[3] = 0xE7, .data[4] = 0x3C, .data[5] = 0x77,
2179 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
2180 { .channel = 196, .freq = 4980, .data[0] = 0x33, .data[1] = 0x66,
2181 .data[2] = 0x70, .data[3] = 0xC7, .data[4] = 0x3C, .data[5] = 0x77,
2182 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
2183 { .channel = 200, .freq = 5000, .data[0] = 0x22, .data[1] = 0x55,
2184 .data[2] = 0x60, .data[3] = 0xD7, .data[4] = 0x3C, .data[5] = 0x77,
2185 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
2186 { .channel = 204, .freq = 5020, .data[0] = 0x22, .data[1] = 0x55,
2187 .data[2] = 0x60, .data[3] = 0xC7, .data[4] = 0x3C, .data[5] = 0x77,
2188 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
2189 { .channel = 208, .freq = 5040, .data[0] = 0x22, .data[1] = 0x44,
2190 .data[2] = 0x50, .data[3] = 0xC7, .data[4] = 0x3C, .data[5] = 0x77,
2191 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
2192 { .channel = 212, .freq = 5060, .data[0] = 0x11, .data[1] = 0x44,
2193 .data[2] = 0x50, .data[3] = 0xA5, .data[4] = 0x3C, .data[5] = 0x77,
2194 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2195 { .channel = 216, .freq = 5080, .data[0] = 0x00, .data[1] = 0x44,
2196 .data[2] = 0x40, .data[3] = 0xB6, .data[4] = 0x3C, .data[5] = 0x77,
2197 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
2201 { .channel = 1, .freq = 2412, .data[0] = 0x6F, .data[1] = 0x3C,
2202 .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2203 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2204 .data[10] = 0x80, .data[11] = 0x70, },
2205 { .channel = 2, .freq = 2417, .data[0] = 0x6F, .data[1] = 0x3C,
2206 .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2207 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2208 .data[10] = 0x80, .data[11] = 0x70, },
2209 { .channel = 3, .freq = 2422, .data[0] = 0x6F, .data[1] = 0x3C,
2210 .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2211 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2212 .data[10] = 0x80, .data[11] = 0x70, },
2213 { .channel = 4, .freq = 2427, .data[0] = 0x6F, .data[1] = 0x2C,
2214 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2215 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2216 .data[10] = 0x80, .data[11] = 0x70, },
2217 { .channel = 5, .freq = 2432, .data[0] = 0x6F, .data[1] = 0x2C,
2218 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2219 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2220 .data[10] = 0x80, .data[11] = 0x70, },
2221 { .channel = 6, .freq = 2437, .data[0] = 0x6F, .data[1] = 0x2C,
2222 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2223 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2224 .data[10] = 0x80, .data[11] = 0x70, },
2225 { .channel = 7, .freq = 2442, .data[0] = 0x6F, .data[1] = 0x2C,
2226 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2227 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2228 .data[10] = 0x80, .data[11] = 0x70, },
2229 { .channel = 8, .freq = 2447, .data[0] = 0x6F, .data[1] = 0x2C,
2230 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2231 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2232 .data[10] = 0x80, .data[11] = 0x70, },
2233 { .channel = 9, .freq = 2452, .data[0] = 0x6F, .data[1] = 0x1C,
2234 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2235 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2236 .data[10] = 0x80, .data[11] = 0x70, },
2237 { .channel = 10, .freq = 2457, .data[0] = 0x6F, .data[1] = 0x1C,
2238 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2239 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2240 .data[10] = 0x80, .data[11] = 0x70, },
2241 { .channel = 11, .freq = 2462, .data[0] = 0x6E, .data[1] = 0x1C,
2242 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2243 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2244 .data[10] = 0x80, .data[11] = 0x70, },
2245 { .channel = 12, .freq = 2467, .data[0] = 0x6E, .data[1] = 0x1C,
2246 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2247 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2248 .data[10] = 0x80, .data[11] = 0x70, },
2249 { .channel = 13, .freq = 2472, .data[0] = 0x6E, .data[1] = 0x1C,
2250 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2251 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2252 .data[10] = 0x80, .data[11] = 0x70, },
2253 { .channel = 14, .freq = 2484, .data[0] = 0x6E, .data[1] = 0x0C,
2254 .data[2] = 0x0C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
2255 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
2256 .data[10] = 0x80, .data[11] = 0x70, },
2257 { .channel = 34, .freq = 5170, .data[0] = 0x6A, .data[1] = 0x0C,
2258 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x02, .data[5] = 0x05,
2259 .data[6] = 0x0D, .data[7] = 0x0D, .data[8] = 0x77, .data[9] = 0x80,
2260 .data[10] = 0x20, .data[11] = 0x00, },
2261 { .channel = 36, .freq = 5180, .data[0] = 0x6A, .data[1] = 0x0C,
2262 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x05,
2263 .data[6] = 0x0D, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x80,
2264 .data[10] = 0x20, .data[11] = 0x00, },
2265 { .channel = 38, .freq = 5190, .data[0] = 0x6A, .data[1] = 0x0C,
2266 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04,
2267 .data[6] = 0x0C, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x80,
2268 .data[10] = 0x20, .data[11] = 0x00, },
2269 { .channel = 40, .freq = 5200, .data[0] = 0x69, .data[1] = 0x0C,
2270 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04,
2271 .data[6] = 0x0C, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x70,
2272 .data[10] = 0x20, .data[11] = 0x00, },
2273 { .channel = 42, .freq = 5210, .data[0] = 0x69, .data[1] = 0x0C,
2274 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04,
2275 .data[6] = 0x0B, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x70,
2276 .data[10] = 0x20, .data[11] = 0x00, },
2277 { .channel = 44, .freq = 5220, .data[0] = 0x69, .data[1] = 0x0C,
2278 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x04,
2279 .data[6] = 0x0B, .data[7] = 0x0B, .data[8] = 0x77, .data[9] = 0x60,
2280 .data[10] = 0x20, .data[11] = 0x00, },
2281 { .channel = 46, .freq = 5230, .data[0] = 0x69, .data[1] = 0x0C,
2282 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x03,
2283 .data[6] = 0x0A, .data[7] = 0x0B, .data[8] = 0x77, .data[9] = 0x60,
2284 .data[10] = 0x20, .data[11] = 0x00, },
2285 { .channel = 48, .freq = 5240, .data[0] = 0x69, .data[1] = 0x0C,
2286 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x03,
2287 .data[6] = 0x0A, .data[7] = 0x0A, .data[8] = 0x77, .data[9] = 0x60,
2288 .data[10] = 0x20, .data[11] = 0x00, },
2289 { .channel = 52, .freq = 5260, .data[0] = 0x68, .data[1] = 0x0C,
2290 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x02,
2291 .data[6] = 0x09, .data[7] = 0x09, .data[8] = 0x77, .data[9] = 0x60,
2292 .data[10] = 0x20, .data[11] = 0x00, },
2293 { .channel = 56, .freq = 5280, .data[0] = 0x68, .data[1] = 0x0C,
2294 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x01,
2295 .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50,
2296 .data[10] = 0x10, .data[11] = 0x00, },
2297 { .channel = 60, .freq = 5300, .data[0] = 0x68, .data[1] = 0x0C,
2298 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x01,
2299 .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50,
2300 .data[10] = 0x10, .data[11] = 0x00, },
2301 { .channel = 64, .freq = 5320, .data[0] = 0x67, .data[1] = 0x0C,
2302 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2303 .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50,
2304 .data[10] = 0x10, .data[11] = 0x00, },
2305 { .channel = 100, .freq = 5500, .data[0] = 0x64, .data[1] = 0x0C,
2306 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2307 .data[6] = 0x02, .data[7] = 0x01, .data[8] = 0x77, .data[9] = 0x20,
2308 .data[10] = 0x00, .data[11] = 0x00, },
2309 { .channel = 104, .freq = 5520, .data[0] = 0x64, .data[1] = 0x0C,
2310 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2311 .data[6] = 0x01, .data[7] = 0x01, .data[8] = 0x77, .data[9] = 0x20,
2312 .data[10] = 0x00, .data[11] = 0x00, },
2313 { .channel = 108, .freq = 5540, .data[0] = 0x63, .data[1] = 0x0C,
2314 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2315 .data[6] = 0x01, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10,
2316 .data[10] = 0x00, .data[11] = 0x00, },
2317 { .channel = 112, .freq = 5560, .data[0] = 0x63, .data[1] = 0x0C,
2318 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2319 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10,
2320 .data[10] = 0x00, .data[11] = 0x00, },
2321 { .channel = 116, .freq = 5580, .data[0] = 0x62, .data[1] = 0x0C,
2322 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2323 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10,
2324 .data[10] = 0x00, .data[11] = 0x00, },
2325 { .channel = 120, .freq = 5600, .data[0] = 0x62, .data[1] = 0x0C,
2326 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2327 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2328 .data[10] = 0x00, .data[11] = 0x00, },
2329 { .channel = 124, .freq = 5620, .data[0] = 0x62, .data[1] = 0x0C,
2330 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2331 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2332 .data[10] = 0x00, .data[11] = 0x00, },
2333 { .channel = 128, .freq = 5640, .data[0] = 0x61, .data[1] = 0x0C,
2334 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2335 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2336 .data[10] = 0x00, .data[11] = 0x00, },
2337 { .channel = 132, .freq = 5660, .data[0] = 0x61, .data[1] = 0x0C,
2338 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2339 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2340 .data[10] = 0x00, .data[11] = 0x00, },
2341 { .channel = 136, .freq = 5680, .data[0] = 0x61, .data[1] = 0x0C,
2342 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2343 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2344 .data[10] = 0x00, .data[11] = 0x00, },
2345 { .channel = 140, .freq = 5700, .data[0] = 0x60, .data[1] = 0x0C,
2346 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2347 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2348 .data[10] = 0x00, .data[11] = 0x00, },
2349 { .channel = 149, .freq = 5745, .data[0] = 0x60, .data[1] = 0x0C,
2350 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2351 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2352 .data[10] = 0x00, .data[11] = 0x00, },
2353 { .channel = 153, .freq = 5765, .data[0] = 0x60, .data[1] = 0x0C,
2354 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2355 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2356 .data[10] = 0x00, .data[11] = 0x00, },
2357 { .channel = 157, .freq = 5785, .data[0] = 0x60, .data[1] = 0x0C,
2358 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2359 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2360 .data[10] = 0x00, .data[11] = 0x00, },
2361 { .channel = 161, .freq = 5805, .data[0] = 0x60, .data[1] = 0x0C,
2362 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2363 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2364 .data[10] = 0x00, .data[11] = 0x00, },
2365 { .channel = 165, .freq = 5825, .data[0] = 0x60, .data[1] = 0x0C,
2366 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
2367 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
2368 .data[10] = 0x00, .data[11] = 0x00, },
2369 { .channel = 184, .freq = 4920, .data[0] = 0x6E, .data[1] = 0x0C,
2370 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x09, .data[5] = 0x0E,
2371 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xC0,
2372 .data[10] = 0x50, .data[11] = 0x00, },
2373 { .channel = 188, .freq = 4940, .data[0] = 0x6E, .data[1] = 0x0C,
2374 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x09, .data[5] = 0x0D,
2375 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xB0,
2376 .data[10] = 0x50, .data[11] = 0x00, },
2377 { .channel = 192, .freq = 4960, .data[0] = 0x6E, .data[1] = 0x0C,
2378 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0C,
2379 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xB0,
2380 .data[10] = 0x50, .data[11] = 0x00, },
2381 { .channel = 196, .freq = 4980, .data[0] = 0x6D, .data[1] = 0x0C,
2382 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0C,
2383 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0,
2384 .data[10] = 0x40, .data[11] = 0x00, },
2385 { .channel = 200, .freq = 5000, .data[0] = 0x6D, .data[1] = 0x0C,
2386 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0B,
2387 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0,
2388 .data[10] = 0x40, .data[11] = 0x00, },
2389 { .channel = 204, .freq = 5020, .data[0] = 0x6D, .data[1] = 0x0C,
2390 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0A,
2391 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0,
2392 .data[10] = 0x40, .data[11] = 0x00, },
2393 { .channel = 208, .freq = 5040, .data[0] = 0x6C, .data[1] = 0x0C,
2394 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x07, .data[5] = 0x09,
2395 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90,
2396 .data[10] = 0x40, .data[11] = 0x00, },
2397 { .channel = 212, .freq = 5060, .data[0] = 0x6C, .data[1] = 0x0C,
2398 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x06, .data[5] = 0x08,
2399 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90,
2400 .data[10] = 0x40, .data[11] = 0x00, },
2401 { .channel = 216, .freq = 5080, .data[0] = 0x6C, .data[1] = 0x0C,
2402 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x05, .data[5] = 0x08,
2403 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90,
2404 .data[10] = 0x40, .data[11] = 0x00, },
2407 static void lpphy_b2062_reset_pll_bias(
struct b43_wldev *dev)
2411 if (dev->
dev->chip_id == 0x5354) {
2420 static void lpphy_b2062_vco_calib(
struct b43_wldev *dev)
2427 static int lpphy_b2062_tune(
struct b43_wldev *dev,
2428 unsigned int channel)
2433 u32 crystal_freq = bus->
chipco.pmu.crystalfreq * 1000;
2434 u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
2437 for (i = 0; i <
ARRAY_SIZE(b2062_chantbl); i++) {
2438 if (b2062_chantbl[i].channel == channel) {
2439 chandata = &b2062_chantbl[
i];
2458 tmp1 = crystal_freq / 1000;
2459 tmp2 = lpphy->
pdiv * 1000;
2462 lpphy_b2062_reset_pll_bias(dev);
2463 tmp3 = tmp2 * channel2freq_lp(channel);
2464 if (channel2freq_lp(channel) < 4000)
2470 tmp5 = tmp7 * 0x100;
2474 tmp5 = tmp7 * 0x100;
2478 tmp5 = tmp7 * 0x100;
2483 tmp9 = ((2 * tmp3 * (tmp8 + 1)) + (3 *
tmp1)) / (6 *
tmp1);
2487 lpphy_b2062_vco_calib(dev);
2491 lpphy_b2062_reset_pll_bias(dev);
2492 lpphy_b2062_vco_calib(dev);
2501 static void lpphy_b2063_vco_calib(
struct b43_wldev *dev)
2518 static int lpphy_b2063_tune(
struct b43_wldev *dev,
2519 unsigned int channel)
2524 u32 crystal_freq = bus->
chipco.pmu.crystalfreq * 1000;
2526 u16 old_comm15, scale;
2527 u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
2528 int i,
div = (crystal_freq <= 26000000 ? 1 : 2);
2530 for (i = 0; i <
ARRAY_SIZE(b2063_chantbl); i++) {
2531 if (b2063_chantbl[i].channel == channel) {
2532 chandata = &b2063_chantbl[
i];
2556 if (chandata->
freq > 4000)
2557 vco_freq = chandata->
freq << 1;
2559 vco_freq = chandata->
freq << 2;
2561 freqref = crystal_freq * 3;
2562 val1 = lpphy_qdiv_roundup(crystal_freq, 1000000, 16);
2563 val2 = lpphy_qdiv_roundup(crystal_freq, 1000000 * div, 16);
2564 val3 = lpphy_qdiv_roundup(vco_freq, 3, 16);
2565 timeout = ((((8 * crystal_freq) / (div * 5000000)) + 1) >> 1) - 1;
2568 0xFFF8, timeout >> 2);
2570 0xFF9F,timeout << 5);
2572 timeoutref = ((((8 * crystal_freq) / (div * (timeout + 1))) +
2573 999999) / 1000000) + 1;
2576 count = lpphy_qdiv_roundup(val3, val2 + 16, 16);
2577 count *= (timeout + 1) * (timeoutref + 1);
2583 tmp1 = ((val3 * 62500) / freqref) << 4;
2584 tmp2 = ((val3 * 62500) % freqref) << 4;
2585 while (tmp2 >= freqref) {
2600 tmp3 = ((41 * (val3 - 3000)) /1200) + 27;
2601 tmp4 = lpphy_qdiv_roundup(132000 * tmp1, 8451, 16);
2603 if ((tmp4 + tmp3 - 1) / tmp3 > 60) {
2605 tmp5 = ((tmp4 + tmp3) / (tmp3 << 1)) - 8;
2608 tmp5 = ((tmp4 + (tmp3 >> 1)) / tmp3) - 8;
2613 tmp6 = lpphy_qdiv_roundup(100 * val1, val3, 16);
2614 tmp6 *= (tmp5 * 8) * (scale + 1);
2622 if (crystal_freq > 26000000)
2635 lpphy_b2063_vco_calib(dev);
2641 static int b43_lpphy_op_switch_channel(
struct b43_wldev *dev,
2642 unsigned int new_channel)
2647 if (dev->
phy.radio_ver == 0x2063) {
2648 err = lpphy_b2063_tune(dev, new_channel);
2652 err = lpphy_b2062_tune(dev, new_channel);
2655 lpphy_set_analog_filter(dev, new_channel);
2656 lpphy_adjust_gain_table(dev, channel2freq_lp(new_channel));
2665 static int b43_lpphy_op_init(
struct b43_wldev *dev)
2670 b43err(dev->
wl,
"LP-PHY is supported only on SSB!\n");
2674 lpphy_read_band_sprom(dev);
2675 lpphy_baseband_init(dev);
2676 lpphy_radio_init(dev);
2677 lpphy_calibrate_rc(dev);
2678 err = b43_lpphy_op_switch_channel(dev, 7);
2680 b43dbg(dev->
wl,
"Switch to channel 7 failed, error = %d.\n",
2683 lpphy_tx_pctl_init(dev);
2684 lpphy_calibration(dev);
2690 static void b43_lpphy_op_adjust_txpower(
struct b43_wldev *dev)
2702 static void b43_lpphy_op_switch_analog(
struct b43_wldev *dev,
bool on)
2712 static void b43_lpphy_op_pwork_15sec(
struct b43_wldev *dev)
2718 .allocate = b43_lpphy_op_allocate,
2719 .free = b43_lpphy_op_free,
2720 .prepare_structs = b43_lpphy_op_prepare_structs,
2721 .init = b43_lpphy_op_init,
2722 .phy_read = b43_lpphy_op_read,
2723 .phy_write = b43_lpphy_op_write,
2724 .phy_maskset = b43_lpphy_op_maskset,
2725 .radio_read = b43_lpphy_op_radio_read,
2726 .radio_write = b43_lpphy_op_radio_write,
2727 .software_rfkill = b43_lpphy_op_software_rfkill,
2728 .switch_analog = b43_lpphy_op_switch_analog,
2729 .switch_channel = b43_lpphy_op_switch_channel,
2730 .get_default_chan = b43_lpphy_op_get_default_chan,
2731 .set_rx_antenna = b43_lpphy_op_set_rx_antenna,
2732 .recalc_txpower = b43_lpphy_op_recalc_txpower,
2733 .adjust_txpower = b43_lpphy_op_adjust_txpower,
2734 .pwork_15sec = b43_lpphy_op_pwork_15sec,
2735 .pwork_60sec = lpphy_calibration,