static void ad_write(struct ad1848_softc *sc, int reg, int data) { ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit); ADWRITE(sc, AD1848_IDATA, data & 0xff); /* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */ }
void ad_xwrite(struct ad1848_softc *sc, int reg, int val) { ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit); ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff); ADWRITE(sc, AD1848_IDATA, val & 0xff); }
int ad_xread(struct ad1848_softc *sc, int reg) { int x; ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit); ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff); x = ADREAD(sc, AD1848_IDATA); return x; }
static void ad_set_MCE(struct ad1848_softc *sc, int state) { if (state) sc->MCE_bit = MODE_CHANGE_ENABLE; else sc->MCE_bit = 0; ADWRITE(sc, AD1848_IADDR, sc->MCE_bit); }
int ad_read(struct ad1848_softc *sc, int reg) { int x; ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit); x = ADREAD(sc, AD1848_IDATA); /* printf("(%02x<-%02x) ", reg|sc->MCE_bit, x); */ return x; }
void ad1848_reset(struct ad1848_softc *sc) { u_char r; DPRINTF(("ad1848_reset\n")); /* Clear the PEN and CEN bits */ r = ad_read(sc, SP_INTERFACE_CONFIG); r &= ~(CAPTURE_ENABLE | PLAYBACK_ENABLE); ad_write(sc, SP_INTERFACE_CONFIG, r); /* Clear interrupt status */ if (sc->mode == 2) ad_write(sc, CS_IRQ_STATUS, 0); ADWRITE(sc, AD1848_STATUS, 0); #ifdef AUDIO_DEBUG if (ad1848debug > 2) ad1848_dump_regs(sc); #endif }
/* * Probe for the ad1848 chip */ int ad1848_isa_probe(struct ad1848_isa_softc *isc) { struct ad1848_softc *sc; u_char tmp, tmp1 = 0xff, tmp2 = 0xff; int i, t; sc = &isc->sc_ad1848; sc->sc_readreg = ad1848_isa_read; sc->sc_writereg = ad1848_isa_write; /* Is there an ad1848 chip ? */ sc->MCE_bit = MODE_CHANGE_ENABLE; sc->mode = 1; /* MODE 1 = original ad1848/ad1846/cs4248 */ /* * Check that the I/O address is in use. * * The SP_IN_INIT bit of the base I/O port is known to be 0 after the * chip has performed its power-on initialization. Just assume * this has happened before the OS is starting. * * If the I/O address is unused, inb() typically returns 0xff. */ tmp = ADREAD(sc, AD1848_IADDR); if (tmp & SP_IN_INIT) { /* Not a AD1848 */ DPRINTF(("ad_detect_A %x\n", tmp)); goto bad; } /* * Test if it's possible to change contents of the indirect registers. * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read * only so try to avoid using it. The bit 0x20 is the mic preamp * enable; on some chips it is always the same in both registers, so * we avoid tests where they are different. */ ad_write(sc, 0, 0x8a); ad_write(sc, 1, 0x45); /* 0x55 with bit 0x10 clear */ tmp1 = ad_read(sc, 0); tmp2 = ad_read(sc, 1); if (tmp1 != 0x8a || tmp2 != 0x45) { DPRINTF(("ad_detect_B (%x/%x)\n", tmp1, tmp2)); goto bad; } ad_write(sc, 0, 0x65); ad_write(sc, 1, 0xaa); tmp1 = ad_read(sc, 0); tmp2 = ad_read(sc, 1); if (tmp1 != 0x65 || tmp2 != 0xaa) { DPRINTF(("ad_detect_C (%x/%x)\n", tmp1, tmp2)); goto bad; } /* * The indirect register I12 has some read only bits. Lets * try to change them. */ tmp = ad_read(sc, SP_MISC_INFO); ad_write(sc, SP_MISC_INFO, (~tmp) & 0x0f); /* Here, AD1845 may sometimes be busy. Wait til it becomes ready. */ for (t = 0; t < 100000 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT; t++) ; #ifdef AUDIO_DEBUG if (t) DPRINTF(("ad1848_isa_probe: t %d\n", t)); #endif if ((tmp & 0x0f) != ((tmp1 = ad_read(sc, SP_MISC_INFO)) & 0x0f)) { DPRINTF(("ad_detect_D (%x)\n", tmp1)); goto bad; } /* * MSB and 4 LSBs of the reg I12 tell the chip revision. * * A preliminary version of the AD1846 data sheet stated that it * used an ID field of 0x0B. The current version, however, * states that the AD1846 uses ID 0x0A, just like the AD1848K. * * this switch statement will need updating as newer clones arrive.... */ switch (tmp1 & 0x8f) { case 0x09: sc->chip_name = "AD1848J"; break; case 0x0A: sc->chip_name = "AD1848K"; break; #if 0 /* See above */ case 0x0B: sc->chip_name = "AD1846"; break; #endif case 0x81: sc->chip_name = "CS4248revB"; /* or CS4231 rev B; see below */ break; case 0x89: sc->chip_name = "CS4248"; break; case 0x8A: sc->chip_name = "broken"; /* CS4231/AD1845; see below */ break; default: sc->chip_name = "unknown"; DPRINTF(("ad1848: unknown codec version 0x%02x\n", tmp1 & 0x8f)); break; } /* * The original AD1848/CS4248 has just 16 indirect registers. This * means that I0 and I16 should return the same value (etc.). * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test * fails with CS4231, AD1845, etc. */ ad_write(sc, SP_MISC_INFO, 0); /* Mode2 = disabled */ for (i = 0; i < 16; i++) if ((tmp1 = ad_read(sc, i)) != (tmp2 = ad_read(sc, i + 16))) { if (i != SP_TEST_AND_INIT) { DPRINTF(("ad_detect_F(%d/%x/%x)\n", i, tmp1, tmp2)); goto bad; } } /* * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit * The bit 0x80 is always 1 in CS4248, CS4231, and AD1845. */ ad_write(sc, SP_MISC_INFO, MODE2); /* Set mode2, clear 0x80 */ tmp1 = ad_read(sc, SP_MISC_INFO); if ((tmp1 & 0xc0) == (0x80 | MODE2)) { /* * CS4231 or AD1845 detected - is it? * * Verify that setting I2 doesn't change I18. */ ad_write(sc, 18, 0x88); /* Set I18 to known value */ ad_write(sc, 2, 0x45); if ((tmp2 = ad_read(sc, 18)) != 0x45) { /* No change -> CS4231? */ ad_write(sc, 2, 0xaa); if ((tmp2 = ad_read(sc, 18)) == 0xaa) { /* Rotten bits? */ DPRINTF(("ad_detect_H(%x)\n", tmp2)); goto bad; } sc->mode = 2; /* * It's a CS4231, or another clone with 32 registers. * Let's find out which by checking I25. */ if ((tmp1 & 0x8f) == 0x8a) { tmp1 = ad_read(sc, CS_VERSION_ID); switch (tmp1 & 0xe7) { case 0xA0: sc->chip_name = "CS4231A"; break; case 0x80: /* XXX I25 no good, AD1845 same as CS4231 */ /* * XXX * This test is correct only after reset */ if (ad_read(sc, 17) & 0xf0) { sc->chip_name = "AD1845"; sc->is_ad1845 = 1; } else sc->chip_name = "CS4231"; break; case 0x82: sc->chip_name = "CS4232"; break; case 0xa2: sc->chip_name = "CS4232C"; break; case 0x03: case 0x83: sc->chip_name = "CS4236"; /* * Try to switch to mode3 (CS4236B or * CS4237B) by setting CMS to 3. A * plain CS4236 will not react to * LLBM settings. */ ad_write(sc, SP_MISC_INFO, MODE3); tmp1 = ad_read(sc, CS_LEFT_LINE_CONTROL); ad_write(sc, CS_LEFT_LINE_CONTROL, 0xe0); tmp2 = ad_read(sc, CS_LEFT_LINE_CONTROL); if (tmp2 == 0xe0) { /* * it's a CS4237B or another * clone supporting mode 3. * Let's determine which by * enabling extended registers * and checking X25. */ tmp2 = ad_xread(sc, CS_X_CHIP_VERSION); switch (tmp2 & X_CHIP_VERSIONF_CID) { case X_CHIP_CID_CS4236BB: sc->chip_name = "CS4236BrevB"; break; case X_CHIP_CID_CS4236B: sc->chip_name = "CS4236B"; break; case X_CHIP_CID_CS4237B: sc->chip_name = "CS4237B"; break; default: sc->chip_name = "CS4236B compatible"; DPRINTF(("cs4236: unknown mode 3 compatible codec, version 0x%02x\n", tmp2)); break; } sc->mode = 3; } /* restore volume control information */ ad_write(sc, CS_LEFT_LINE_CONTROL, tmp1); break; } } } } /* Wait for 1848 to init */ while (ADREAD(sc, AD1848_IADDR) & SP_IN_INIT) ; /* Wait for 1848 to autocal */ ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT); while (ADREAD(sc, AD1848_IDATA) & AUTO_CAL_IN_PROG) ; return 1; bad: return 0; }
/* * Probe for the ad1848 chip */ int ad1848_probe(struct ad1848_softc *sc) { u_char tmp, tmp1 = 0xff, tmp2 = 0xff; #if 0 int i; #endif /* Is there an ad1848 chip ? */ sc->MCE_bit = MODE_CHANGE_ENABLE; sc->mode = 1; /* MODE 1 = original ad1848/ad1846/cs4248 */ sc->sc_flags = 0; /* * Check that the I/O address is in use. * * The SP_IN_INIT bit of the base I/O port is known to be 0 after the * chip has performed its power-on initialization. Just assume * this has happened before the OS is starting. * * If the I/O address is unused, inb() typically returns 0xff. */ tmp = ADREAD(sc, AD1848_IADDR); if (tmp & SP_IN_INIT) { /* Not a AD1848 */ #if 0 DPRINTF(("ad_detect_A %x\n", tmp)); #endif goto bad; } /* * Test if it's possible to change contents of the indirect registers. * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read * only so try to avoid using it. */ ad_write(sc, 0, 0xaa); ad_write(sc, 1, 0x45); /* 0x55 with bit 0x10 clear */ if ((tmp1 = ad_read(sc, 0)) != 0xaa || (tmp2 = ad_read(sc, 1)) != 0x45) { DPRINTF(("ad_detect_B (%x/%x)\n", tmp1, tmp2)); goto bad; } ad_write(sc, 0, 0x45); ad_write(sc, 1, 0xaa); if ((tmp1 = ad_read(sc, 0)) != 0x45 || (tmp2 = ad_read(sc, 1)) != 0xaa) { DPRINTF(("ad_detect_C (%x/%x)\n", tmp1, tmp2)); goto bad; } /* * The indirect register I12 has some read only bits. Lets * try to change them. */ tmp = ad_read(sc, SP_MISC_INFO); ad_write(sc, SP_MISC_INFO, (~tmp) & 0x0f); if ((tmp & 0x0f) != ((tmp1 = ad_read(sc, SP_MISC_INFO)) & 0x0f)) { DPRINTF(("ad_detect_D (%x)\n", tmp1)); goto bad; } /* * MSB and 4 LSBs of the reg I12 tell the chip revision. * * A preliminary version of the AD1846 data sheet stated that it * used an ID field of 0x0B. The current version, however, * states that the AD1846 uses ID 0x0A, just like the AD1848K. * * this switch statement will need updating as newer clones arrive.... */ switch (tmp1 & 0x8f) { case 0x09: sc->chip_name = "AD1848J"; break; case 0x0A: sc->chip_name = "AD1848K"; break; #if 0 /* See above */ case 0x0B: sc->chip_name = "AD1846"; break; #endif case 0x81: sc->chip_name = "CS4248revB"; /* or CS4231 rev B; see below */ break; case 0x89: sc->chip_name = "CS4248"; break; case 0x8A: sc->chip_name = "broken"; /* CS4231/AD1845; see below */ break; default: sc->chip_name = "unknown"; DPRINTF(("ad1848: unknown codec version %#02X\n", (tmp1 & 0x8f))); } #if 0 /* * XXX I don't know why, but this probe fails on an otherwise * well-working AW35/pro card, so I'll just take it out for now. * [[email protected]] */ /* * The original AD1848/CS4248 has just 16 indirect registers. This * means that I0 and I16 should return the same value (etc.). * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test * fails with CS4231, AD1845, etc. */ ad_write(sc, SP_MISC_INFO, 0); /* Mode2 = disabled */ for (i = 0; i < 16; i++) { if ((tmp1 = ad_read(sc, i)) != (tmp2 = ad_read(sc, i + 16))) { if (i != SP_TEST_AND_INIT) { DPRINTF(("ad_detect_F(%d/%x/%x)\n", i, tmp1, tmp2)); goto bad; } } } #endif /* * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit * The bit 0x80 is always 1 in CS4248, CS4231, and AD1845. */ ad_write(sc, SP_MISC_INFO, MODE2); /* Set mode2, clear 0x80 */ tmp1 = ad_read(sc, SP_MISC_INFO); if ((tmp1 & 0xc0) == (0x80 | MODE2)) { /* * CS4231 or AD1845 detected - is it? * * Verify that setting I2 doesn't change I18. */ ad_write(sc, 18, 0x88); /* Set I18 to known value */ ad_write(sc, 2, 0x45); if ((tmp2 = ad_read(sc, 18)) != 0x45) { /* No change -> CS4231? */ ad_write(sc, 2, 0xaa); if ((tmp2 = ad_read(sc, 18)) == 0xaa) { /* Rotten bits? */ DPRINTF(("ad_detect_H(%x)\n", tmp2)); goto bad; } /* * It's a CS4231, or another clone with 32 registers. * Let's find out which by checking I25. */ if ((tmp1 & 0x8f) == 0x8a) { tmp1 = ad_read(sc, CS_VERSION_ID); switch (tmp1 & 0xe7) { case 0xA0: sc->chip_name = "CS4231A"; break; case 0x80: /* I25 no good, AD1845 same as CS4231 */ sc->chip_name = "CS4231 or AD1845"; break; case 0x82: sc->chip_name = "CS4232"; break; case 0xa2: sc->chip_name = "CS4232C"; break; case 0x03: sc->chip_name = "CS4236/CS4236B"; break; } } sc->mode = 2; sc->sc_flags |= AD1848_FLAG_32REGS; } } /* Wait for 1848 to init */ while(ADREAD(sc, AD1848_IADDR) & SP_IN_INIT) ; /* Wait for 1848 to autocal */ ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT); while(ADREAD(sc, AD1848_IDATA) & AUTO_CAL_IN_PROG) ; return 1; bad: return 0; }
static void wait_for_calibration(struct ad1848_softc *sc) { int timeout; DPRINTF(("ad1848: Auto calibration started.\n")); /* * Wait until the auto calibration process has finished. * * 1) Wait until the chip becomes ready (reads don't return 0x80). * 2) Wait until the ACI bit of I11 gets on and then off. * Because newer chips are fast we may never see the ACI * bit go on. Just delay a little instead. */ timeout = 10000; while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) { delay(10); timeout--; } if (timeout <= 0) { DPRINTF(("ad1848: Auto calibration timed out(1).\n")); } /* Set register addr */ ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT); /* Wait for address to appear when read back. */ timeout = 100000; while (timeout > 0 && (ADREAD(sc, AD1848_IADDR)&SP_IADDR_MASK) != SP_TEST_AND_INIT) { delay(10); timeout--; } if (timeout <= 0) { DPRINTF(("ad1848: Auto calibration timed out(1.5).\n")); } if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) { if (sc->mode > 1) { /* A new chip, just delay a little. */ delay(100); /* XXX what should it be? */ } else { timeout = 10000; while (timeout > 0 && !(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) { delay(10); timeout--; } if (timeout <= 0) { DPRINTF(("ad1848: Auto calibration timed out(2).\n")); } } } timeout = 10000; while (timeout > 0 && ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG) { delay(10); timeout--; } if (timeout <= 0) { DPRINTF(("ad1848: Auto calibration timed out(3).\n")); } }