/* wlc_lcnphy_radio_2064_channel_tune_4313 */ static void b43_radio_2064_channel_setup(struct b43_wldev *dev) { u16 save[2]; b43_radio_set(dev, 0x09d, 0x4); b43_radio_write(dev, 0x09e, 0xf); /* Channel specific values in theory, in practice always the same */ b43_radio_write(dev, 0x02a, 0xb); b43_radio_maskset(dev, 0x030, ~0x3, 0xa); b43_radio_maskset(dev, 0x091, ~0x3, 0); b43_radio_maskset(dev, 0x038, ~0xf, 0x7); b43_radio_maskset(dev, 0x030, ~0xc, 0x8); b43_radio_maskset(dev, 0x05e, ~0xf, 0x8); b43_radio_maskset(dev, 0x05e, ~0xf0, 0x80); b43_radio_write(dev, 0x06c, 0x80); save[0] = b43_radio_read(dev, 0x044); save[1] = b43_radio_read(dev, 0x12b); b43_radio_set(dev, 0x044, 0x7); b43_radio_set(dev, 0x12b, 0xe); /* TODO */ b43_radio_write(dev, 0x040, 0xfb); b43_radio_write(dev, 0x041, 0x9a); b43_radio_write(dev, 0x042, 0xa3); b43_radio_write(dev, 0x043, 0x0c); /* TODO */ b43_radio_set(dev, 0x044, 0x0c); udelay(1); b43_radio_write(dev, 0x044, save[0]); b43_radio_write(dev, 0x12b, save[1]); if (dev->phy.rev == 1) { /* brcmsmac uses outdated 0x3 for 0x038 */ b43_radio_write(dev, 0x038, 0x0); b43_radio_write(dev, 0x091, 0x7); } }
/* wlc_radio_2064_init */ static void b43_radio_2064_init(struct b43_wldev *dev) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { b43_radio_write(dev, 0x09c, 0x0020); b43_radio_write(dev, 0x105, 0x0008); } else { /* TODO */ } b43_radio_write(dev, 0x032, 0x0062); b43_radio_write(dev, 0x033, 0x0019); b43_radio_write(dev, 0x090, 0x0010); b43_radio_write(dev, 0x010, 0x0000); if (dev->phy.rev == 1) { b43_radio_write(dev, 0x060, 0x007f); b43_radio_write(dev, 0x061, 0x0072); b43_radio_write(dev, 0x062, 0x007f); } b43_radio_write(dev, 0x01d, 0x0002); b43_radio_write(dev, 0x01e, 0x0006); b43_phy_write(dev, 0x4ea, 0x4688); b43_phy_maskset(dev, 0x4eb, ~0x7, 0x2); b43_phy_mask(dev, 0x4eb, ~0x01c0); b43_phy_maskset(dev, 0x46a, 0xff00, 0x19); b43_lcntab_write(dev, B43_LCNTAB16(0x00, 0x55), 0); b43_radio_mask(dev, 0x05b, (u16) ~0xff02); b43_radio_set(dev, 0x004, 0x40); b43_radio_set(dev, 0x120, 0x10); b43_radio_set(dev, 0x078, 0x80); b43_radio_set(dev, 0x129, 0x2); b43_radio_set(dev, 0x057, 0x1); b43_radio_set(dev, 0x05b, 0x2); /* TODO: wait for some bit to be set */ b43_radio_read(dev, 0x05c); b43_radio_mask(dev, 0x05b, (u16) ~0xff02); b43_radio_mask(dev, 0x057, (u16) ~0xff01); b43_phy_write(dev, 0x933, 0x2d6b); b43_phy_write(dev, 0x934, 0x2d6b); b43_phy_write(dev, 0x935, 0x2d6b); b43_phy_write(dev, 0x936, 0x2d6b); b43_phy_write(dev, 0x937, 0x016b); b43_radio_mask(dev, 0x057, (u16) ~0xff02); b43_radio_write(dev, 0x0c2, 0x006f); }
static void b43_radio_2059_init(struct b43_wldev *dev) { const u16 routing[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1 }; const u16 radio_values[3][2] = { { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, }; u16 i, j; b43_radio_write(dev, R2059_ALL | 0x51, 0x0070); b43_radio_write(dev, R2059_ALL | 0x5a, 0x0003); for (i = 0; i < ARRAY_SIZE(routing); i++) b43_radio_set(dev, routing[i] | 0x146, 0x3); b43_radio_set(dev, 0x2e, 0x0078); b43_radio_set(dev, 0xc0, 0x0080); msleep(2); b43_radio_mask(dev, 0x2e, ~0x0078); b43_radio_mask(dev, 0xc0, ~0x0080); if (1) { /* FIXME */ b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x1); udelay(10); b43_radio_set(dev, R2059_RXRX1 | 0x0BF, 0x1); b43_radio_maskset(dev, R2059_RXRX1 | 0x19B, 0x3, 0x2); b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x2); udelay(100); b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x2); for (i = 0; i < 10000; i++) { if (b43_radio_read(dev, R2059_RXRX1 | 0x145) & 1) { i = 0; break; } udelay(100); } if (i) b43err(dev->wl, "radio 0x945 timeout\n"); b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x1); b43_radio_set(dev, 0xa, 0x60); for (i = 0; i < 3; i++) { b43_radio_write(dev, 0x17F, radio_values[i][0]); b43_radio_write(dev, 0x13D, 0x6E); b43_radio_write(dev, 0x13E, radio_values[i][1]); b43_radio_write(dev, 0x13C, 0x55); for (j = 0; j < 10000; j++) { if (b43_radio_read(dev, 0x140) & 2) { j = 0; break; } udelay(500); } if (j) b43err(dev->wl, "radio 0x140 timeout\n"); b43_radio_write(dev, 0x13C, 0x15); } b43_radio_mask(dev, 0x17F, ~0x1); } b43_radio_mask(dev, 0x11, ~0x0008); }
/* wlc_lcnphy_vbat_temp_sense_setup */ static void b43_phy_lcn_sense_setup(struct b43_wldev *dev, enum lcn_sense_type sense_type) { u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain; u16 auxpga_vmid; u8 tx_pwr_idx; u8 i; u16 save_radio_regs[6][2] = { { 0x007, 0 }, { 0x0ff, 0 }, { 0x11f, 0 }, { 0x005, 0 }, { 0x025, 0 }, { 0x112, 0 }, }; u16 save_phy_regs[14][2] = { { 0x503, 0 }, { 0x4a4, 0 }, { 0x4d0, 0 }, { 0x4d9, 0 }, { 0x4da, 0 }, { 0x4a6, 0 }, { 0x938, 0 }, { 0x939, 0 }, { 0x4d8, 0 }, { 0x4d0, 0 }, { 0x4d7, 0 }, { 0x4a5, 0 }, { 0x40d, 0 }, { 0x4a2, 0 }, }; u16 save_radio_4a4; msleep(1); /* Save */ for (i = 0; i < 6; i++) save_radio_regs[i][1] = b43_radio_read(dev, save_radio_regs[i][0]); for (i = 0; i < 14; i++) save_phy_regs[i][1] = b43_phy_read(dev, save_phy_regs[i][0]); b43_mac_suspend(dev); save_radio_4a4 = b43_radio_read(dev, 0x4a4); /* wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); */ tx_pwr_idx = dev->phy.lcn->tx_pwr_curr_idx; /* Setup */ /* TODO: wlc_lcnphy_set_tx_pwr_by_index(pi, 127); */ b43_radio_set(dev, 0x007, 0x1); b43_radio_set(dev, 0x0ff, 0x10); b43_radio_set(dev, 0x11f, 0x4); b43_phy_mask(dev, 0x503, ~0x1); b43_phy_mask(dev, 0x503, ~0x4); b43_phy_mask(dev, 0x4a4, ~0x4000); b43_phy_mask(dev, 0x4a4, (u16) ~0x8000); b43_phy_mask(dev, 0x4d0, ~0x20); b43_phy_set(dev, 0x4a5, 0xff); b43_phy_maskset(dev, 0x4a5, ~0x7000, 0x5000); b43_phy_mask(dev, 0x4a5, ~0x700); b43_phy_maskset(dev, 0x40d, ~0xff, 64); b43_phy_maskset(dev, 0x40d, ~0x700, 0x600); b43_phy_maskset(dev, 0x4a2, ~0xff, 64); b43_phy_maskset(dev, 0x4a2, ~0x700, 0x600); b43_phy_maskset(dev, 0x4d9, ~0x70, 0x20); b43_phy_maskset(dev, 0x4d9, ~0x700, 0x300); b43_phy_maskset(dev, 0x4d9, ~0x7000, 0x1000); b43_phy_mask(dev, 0x4da, ~0x1000); b43_phy_set(dev, 0x4da, 0x2000); b43_phy_set(dev, 0x4a6, 0x8000); b43_radio_write(dev, 0x025, 0xc); b43_radio_set(dev, 0x005, 0x8); b43_phy_set(dev, 0x938, 0x4); b43_phy_set(dev, 0x939, 0x4); b43_phy_set(dev, 0x4a4, 0x1000); /* FIXME: don't hardcode */ b43_lcntab_write(dev, B43_LCNTAB16(0x8, 0x6), 0x640); switch (sense_type) { case B43_SENSE_TEMP: b43_phy_set(dev, 0x4d7, 0x8); b43_phy_maskset(dev, 0x4d7, ~0x7000, 0x1000); auxpga_vmidcourse = 8; auxpga_vmidfine = 0x4; auxpga_gain = 2; b43_radio_set(dev, 0x082, 0x20); break; case B43_SENSE_VBAT: b43_phy_set(dev, 0x4d7, 0x8); b43_phy_maskset(dev, 0x4d7, ~0x7000, 0x3000); auxpga_vmidcourse = 7; auxpga_vmidfine = 0xa; auxpga_gain = 2; break; } auxpga_vmid = (0x200 | (auxpga_vmidcourse << 4) | auxpga_vmidfine); b43_phy_set(dev, 0x4d8, 0x1); b43_phy_maskset(dev, 0x4d8, ~(0x3ff << 2), auxpga_vmid << 2); b43_phy_set(dev, 0x4d8, 0x2); b43_phy_maskset(dev, 0x4d8, ~(0x7 << 12), auxpga_gain << 12); b43_phy_set(dev, 0x4d0, 0x20); b43_radio_write(dev, 0x112, 0x6); /* TODO: dummy transmission? */ /* Wait if not done */ if (!(b43_phy_read(dev, 0x476) & 0x8000)) udelay(10); /* Restore */ for (i = 0; i < 6; i++) b43_radio_write(dev, save_radio_regs[i][0], save_radio_regs[i][1]); for (i = 0; i < 14; i++) b43_phy_write(dev, save_phy_regs[i][0], save_phy_regs[i][1]); /* TODO: wlc_lcnphy_set_tx_pwr_by_index(tx_pwr_idx) */ b43_radio_write(dev, 0x4a4, save_radio_4a4); b43_mac_enable(dev); msleep(1); }