summaryrefslogtreecommitdiff
path: root/sys/dev/ic/bcw.c
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2007-02-23 12:24:56 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2007-02-23 12:24:56 +0000
commitbfb964c097d234cf8981d03ee638233146a49bfa (patch)
tree41b9bcfb473bb7cfa5cf4f31639a707d4d60f585 /sys/dev/ic/bcw.c
parente85e14eac3ade0dcbb7d8cd8d20af3a3d63f3ed1 (diff)
Add and activate bcw_radio_init2050 (radio type B).
Diffstat (limited to 'sys/dev/ic/bcw.c')
-rw-r--r--sys/dev/ic/bcw.c176
1 files changed, 173 insertions, 3 deletions
diff --git a/sys/dev/ic/bcw.c b/sys/dev/ic/bcw.c
index bbdc52db1c0..66f5a279358 100644
--- a/sys/dev/ic/bcw.c
+++ b/sys/dev/ic/bcw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bcw.c,v 1.48 2007/02/23 10:52:24 mglocker Exp $ */
+/* $OpenBSD: bcw.c,v 1.49 2007/02/23 12:24:55 mglocker Exp $ */
/*
* Copyright (c) 2006 Jon Simola <jsimola@gmail.com>
@@ -160,6 +160,7 @@ uint16_t bcw_radio_calibrationvalue(struct bcw_softc *);
void bcw_radio_set_txpower_a(struct bcw_softc *, uint16_t);
void bcw_radio_set_txpower_bg(struct bcw_softc *, uint16_t, uint16_t,
uint16_t);
+uint16_t bcw_radio_init2050(struct bcw_softc *);
void bcw_radio_init2060(struct bcw_softc *);
void bcw_radio_spw(struct bcw_softc *, uint8_t);
int bcw_radio_channel(struct bcw_softc *, uint8_t, int );
@@ -3326,7 +3327,7 @@ bcw_phy_initb2(struct bcw_softc *sc)
bcw_radio_write16(sc, 0x005c, 0x00b0);
bcw_radio_write16(sc, 0x007a, 0x000f);
bcw_phy_write16(sc, 0x0038, 0x0677);
- /* TODO bcw_radio_init2050() */
+ bcw_radio_init2050(sc);
}
bcw_phy_write16(sc, 0x0014, 0x0080);
bcw_phy_write16(sc, 0x0032, 0x00ca);
@@ -3369,7 +3370,7 @@ bcw_phy_initb4(struct bcw_softc *sc)
bcw_radio_write16(sc, 0x005c, 0x00b0);
bcw_radio_write16(sc, 0x007a, 0x000f);
bcw_phy_write16(sc, 0x0038, 0x0677);
- /* TODO bcw_radio_init2050() */
+ bcw_radio_init2050(sc);
}
bcw_phy_write16(sc, 0x0014, 0x0080);
bcw_phy_write16(sc, 0x0032, 0x00ca);
@@ -5191,6 +5192,175 @@ bcw_radio_set_txpower_bg(struct bcw_softc *sc, uint16_t baseband_atten,
bcw_phy_lo_adjust(sc, 0);
}
+uint16_t
+bcw_radio_init2050(struct bcw_softc *sc)
+{
+ uint16_t backup[19] = { 0 };
+ uint16_t r;
+ uint16_t i, j;
+ uint32_t tmp1 = 0, tmp2 = 0;
+
+ backup[0] = bcw_radio_read16(sc, 0x0043);
+ backup[14] = bcw_radio_read16(sc, 0x0051);
+ backup[15] = bcw_radio_read16(sc, 0x0052);
+ backup[1] = bcw_phy_read16(sc, 0x0015);
+ backup[16] = bcw_phy_read16(sc, 0x005a);
+ backup[17] = bcw_phy_read16(sc, 0x0059);
+ backup[18] = bcw_phy_read16(sc, 0x0058);
+ if (sc->sc_phy_type == BCW_PHY_TYPEB) {
+ backup[2] = bcw_phy_read16(sc, 0x0030);
+ backup[3] = BCW_READ16(sc, 0x03ec);
+ bcw_phy_write16(sc, 0x0030, 0x00ff);
+ BCW_WRITE16(sc, 0x03ec, 0x3f3f);
+ } else {
+ if (sc->sc_phy_connected) {
+ backup[4] = bcw_phy_read16(sc, 0x0811);
+ backup[5] = bcw_phy_read16(sc, 0x0812);
+ backup[6] = bcw_phy_read16(sc, 0x0814);
+ backup[7] = bcw_phy_read16(sc, 0x0815);
+ backup[8] = bcw_phy_read16(sc, BCW_PHY_G_CRS);
+ backup[9] = bcw_phy_read16(sc, 0x0802);
+ bcw_phy_write16(sc, 0x0814,
+ (bcw_phy_read16(sc, 0x0814) | 0x0003));
+ bcw_phy_write16(sc, 0x0815,
+ (bcw_phy_read16(sc, 0x0815) & 0xfffc));
+ bcw_phy_write16(sc, BCW_PHY_G_CRS,
+ (bcw_phy_read16(sc, BCW_PHY_G_CRS) & 0x7fff));
+ bcw_phy_write16(sc, 0x0802,
+ (bcw_phy_read16(sc, 0x0802) & 0xfffc));
+ bcw_phy_write16(sc, 0x0811, 0x01b3);
+ bcw_phy_write16(sc, 0x0812, 0x0fb2);
+ }
+ BCW_WRITE16(sc, BCW_MMIO_PHY_RADIO,
+ (BCW_READ16(sc, BCW_MMIO_PHY_RADIO) | 0x8000));
+ }
+ backup[10] = bcw_phy_read16(sc, 0x0035);
+ bcw_phy_write16(sc, 0x0035, (bcw_phy_read16(sc, 0x0035) & 0xff7f));
+ backup[11] = BCW_READ16(sc, 0x03e6);
+ backup[12] = BCW_READ16(sc, BCW_MMIO_CHANNEL_EXT);
+
+ /* initialization */
+ if (sc->sc_phy_version == 0)
+ BCW_WRITE16(sc, 0x03e6, 0x0122);
+ else {
+ if (sc->sc_phy_version >= 2)
+ BCW_WRITE16(sc, 0x03e6, 0x0040);
+ BCW_WRITE16(sc, BCW_MMIO_CHANNEL_EXT,
+ (BCW_READ16(sc, BCW_MMIO_CHANNEL_EXT) | 0x2000));
+ }
+
+ r = bcw_radio_calibrationvalue(sc);
+
+ if (sc->sc_phy_type == BCW_PHY_TYPEB)
+ bcw_radio_write16(sc, 0x0078, 0x0003);
+
+ bcw_phy_write16(sc, 0x0015, 0xbfaf);
+ bcw_phy_write16(sc, 0x002b, 0x1403);
+ if (sc->sc_phy_connected)
+ bcw_phy_write16(sc, 0x0812, 0x00b2);
+ bcw_phy_write16(sc, 0x0015, 0xbfa0);
+ bcw_radio_write16(sc, 0x0051, (bcw_radio_read16(sc, 0x0051) |
+ 0x0004));
+ bcw_radio_write16(sc, 0x0052, 0);
+ bcw_radio_write16(sc, 0x0043, bcw_radio_read16(sc, 0x0043) | 0x0009);
+ bcw_phy_write16(sc, 0x0058, 0);
+
+ for (i = 0; i < 16; i++) {
+ bcw_phy_write16(sc, 0x005a, 0x0480);
+ bcw_phy_write16(sc, 0x0059, 0xc810);
+ bcw_phy_write16(sc, 0x0058, 0x000d);
+ if (sc->sc_phy_connected)
+ bcw_phy_write16(sc, 0x0812, 0x30b2);
+ bcw_phy_write16(sc, 0x0015, 0xafb0);
+ delay(10);
+ if (sc->sc_phy_connected)
+ bcw_phy_write16(sc, 0x0812, 0x30b2);
+ bcw_phy_write16(sc, 0x0015, 0xfff0);
+ delay(10);
+ if (sc->sc_phy_connected)
+ bcw_phy_write16(sc, 0x0812, 0x30b2);
+ bcw_phy_write16(sc, 0x0015, 0xfff0);
+ delay(10);
+ tmp1 += bcw_phy_read16(sc, 0x002d);
+ bcw_phy_write16(sc, 0x0058, 0);
+ if (sc->sc_phy_connected)
+ bcw_phy_write16(sc, 0x0812, 0x30b2);
+ bcw_phy_write16(sc, 0x0015, 0xafb0);
+ }
+
+ tmp1++;
+ tmp1 >>= 9;
+ delay(10);
+ bcw_phy_write16(sc, 0x0058, 0);
+
+ for (i = 0; i < 16; i++) {
+ /* XXX flip_4bit(i) */
+ bcw_radio_write16(sc, 0x0078, i << 1 | 0x0020);
+
+ backup[13] = bcw_radio_read16(sc, 0x0078);
+ delay(10);
+ for (j = 0; j < 16; j++) {
+ bcw_phy_write16(sc, 0x005a, 0x0d80);
+ bcw_phy_write16(sc, 0x0059, 0xc810);
+ bcw_phy_write16(sc, 0x0058, 0x000d);
+ if (sc->sc_phy_connected)
+ bcw_phy_write16(sc, 0x0812, 0x30b2);
+ bcw_phy_write16(sc, 0x0015, 0xafb0);
+ delay(10);
+ if (sc->sc_phy_connected)
+ bcw_phy_write16(sc, 0x0812, 0x30b2);
+ bcw_phy_write16(sc, 0x0015, 0xefb0);
+ delay(10);
+ if (sc->sc_phy_connected)
+ bcw_phy_write16(sc, 0x812, 0x30b3);
+ bcw_phy_write16(sc, 0x0015, 0xfff0);
+ delay(10);
+ tmp2 += bcw_phy_read16(sc, 0x002d);
+ bcw_phy_write16(sc, 0x0058, 0);
+ if (sc->sc_phy_connected)
+ bcw_phy_write16(sc, 0x0812, 0x30b2);
+ bcw_phy_write16(sc, 0x0015, 0xafb0);
+ }
+ tmp2++;
+ tmp2 >>= 8;
+ if (tmp1 < tmp2)
+ break;
+ }
+
+ /* restore the registers */
+ bcw_phy_write16(sc, 0x0015, backup[1]);
+ bcw_radio_write16(sc, 0x0051, backup[14]);
+ bcw_radio_write16(sc, 0x0052, backup[15]);
+ bcw_radio_write16(sc, 0x0043, backup[0]);
+ bcw_phy_write16(sc, 0x005a, backup[16]);
+ bcw_phy_write16(sc, 0x0059, backup[17]);
+ bcw_phy_write16(sc, 0x0058, backup[18]);
+ BCW_WRITE16(sc, 0x03e6, backup[11]);
+ if (sc->sc_phy_version != 0)
+ BCW_WRITE16(sc, BCW_MMIO_CHANNEL_EXT, backup[12]);
+ bcw_phy_write16(sc, 0x0035, backup[10]);
+ bcw_radio_channel(sc, sc->sc_radio_channel, 1);
+ if (sc->sc_phy_type == BCW_PHY_TYPEB) {
+ bcw_phy_write16(sc, 0x0030, backup[2]);
+ BCW_WRITE16(sc, 0x03ec, backup[3]);
+ } else {
+ BCW_WRITE16(sc, BCW_MMIO_PHY_RADIO,
+ (BCW_READ16(sc, BCW_MMIO_PHY_RADIO) & 0x7fff));
+ if (sc->sc_phy_connected) {
+ bcw_phy_write16(sc, 0x0811, backup[4]);
+ bcw_phy_write16(sc, 0x0812, backup[5]);
+ bcw_phy_write16(sc, 0x0814, backup[6]);
+ bcw_phy_write16(sc, 0x0815, backup[7]);
+ bcw_phy_write16(sc, BCW_PHY_G_CRS, backup[8]);
+ bcw_phy_write16(sc, 0x0802, backup[9]);
+ }
+ }
+ if (i >= 15)
+ r = backup[13];
+
+ return (r);
+}
+
void
bcw_radio_init2060(struct bcw_softc *sc)
{