diff options
-rw-r--r-- | sys/dev/ic/cs4231reg.h | 30 | ||||
-rw-r--r-- | sys/dev/isa/ad1848.c | 378 | ||||
-rw-r--r-- | sys/dev/isa/ad1848var.h | 36 | ||||
-rw-r--r-- | sys/dev/isa/pss.c | 18 | ||||
-rw-r--r-- | sys/dev/isa/wss.c | 18 | ||||
-rw-r--r-- | sys/dev/isa/ym.c | 18 | ||||
-rw-r--r-- | sys/dev/isa/ym_isapnp.c | 3 |
7 files changed, 219 insertions, 282 deletions
diff --git a/sys/dev/ic/cs4231reg.h b/sys/dev/ic/cs4231reg.h index dfb3e848a08..e66c79bcb39 100644 --- a/sys/dev/ic/cs4231reg.h +++ b/sys/dev/ic/cs4231reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cs4231reg.h,v 1.6 2008/06/26 05:42:15 ray Exp $ */ +/* $OpenBSD: cs4231reg.h,v 1.7 2010/06/30 11:21:35 jakemsr Exp $ */ /* $NetBSD: cs4231reg.h,v 1.4 1996/02/16 08:12:33 mycroft Exp $ */ /*- @@ -77,26 +77,32 @@ #define CS_ALT_FEATURE2 0x11 #define CS_LEFT_LINE_CONTROL 0x12 #define CS_RIGHT_LINE_CONTROL 0x13 +#define LINE_INPUT_ATTEN_BITS 0x1f +#define LINE_INPUT_ATTEN_MASK 0xe0 +#define LINE_INPUT_MUTE 0x80 +#define LINE_INPUT_MUTE_MASK 0x7f #define CS_TIMER_LOW 0x14 #define CS_TIMER_HIGH 0x15 #define CS_UPPER_FREQUENCY_SEL 0x16 #define CS_LOWER_FREQUENCY_SEL 0x17 #define CS_IRQ_STATUS 0x18 +#define CS_IRQ_PU 0x01 /* Playback Underrun */ +#define CS_IRQ_PO 0x02 /* Playback Overrun */ +#define CS_IRQ_CO 0x04 /* Capture Overrrun */ +#define CS_IRQ_CU 0x08 /* Capture Underrun */ +#define CS_IRQ_PI 0x10 /* Playback Interrupt */ +#define CS_IRQ_CI 0x20 /* Capture Interrupt */ +#define CS_IRQ_TI 0x40 /* Timer Interrupt */ +#define CS_IRQ_RES 0x80 /* reserved */ #define CS_VERSION_ID 0x19 #define CS_MONO_IO_CONTROL 0x1A +#define MONO_INPUT_ATTEN_BITS 0x0f +#define MONO_INPUT_ATTEN_MASK 0xf0 +#define MONO_OUTPUT_MUTE 0x40 +#define MONO_INPUT_MUTE 0x80 +#define MONO_INPUT_MUTE_MASK 0x7f #define CS_POWERDOWN_CONTROL 0x1B #define CS_REC_FORMAT 0x1C #define CS_XTAL_SELECT 0x1D #define CS_UPPER_REC_CNT 0x1E #define CS_LOWER_REC_CNT 0x1F - -#define MONO_INPUT_ATTEN_BITS 0x0f -#define MONO_INPUT_ATTEN_MASK 0xf0 -#define MONO_OUTPUT_MUTE 0x40 -#define MONO_INPUT_MUTE 0x80 -#define MONO_INPUT_MUTE_MASK 0x7f - -#define LINE_INPUT_ATTEN_BITS 0x1f -#define LINE_INPUT_ATTEN_MASK 0xe0 -#define LINE_INPUT_MUTE 0x80 -#define LINE_INPUT_MUTE_MASK 0x7f diff --git a/sys/dev/isa/ad1848.c b/sys/dev/isa/ad1848.c index caf499d2e54..815928a44f6 100644 --- a/sys/dev/isa/ad1848.c +++ b/sys/dev/isa/ad1848.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ad1848.c,v 1.33 2007/11/05 00:17:28 jakemsr Exp $ */ +/* $OpenBSD: ad1848.c,v 1.34 2010/06/30 11:21:35 jakemsr Exp $ */ /* $NetBSD: ad1848.c,v 1.45 1998/01/30 02:02:38 augustss Exp $ */ /* @@ -93,7 +93,7 @@ #include <dev/isa/cs4231var.h> #ifdef AUDIO_DEBUG -#define DPRINTF(x) if (ad1848debug) printf x +#define DPRINTF(x) do { if (ad1848debug) printf x; } while (0); int ad1848debug = 0; #else #define DPRINTF(x) @@ -149,11 +149,13 @@ void ad1848_reset(struct ad1848_softc *); int ad1848_set_speed(struct ad1848_softc *, u_long *); void ad1848_mute_monitor(void *, int); +/* indirect register access */ static int ad_read(struct ad1848_softc *, int); static void ad_write(struct ad1848_softc *, int, int); static void ad_set_MCE(struct ad1848_softc *, int); static void wait_for_calibration(struct ad1848_softc *); +/* direct register (AD1848_{IADDR,IDATA,STATUS} only) access */ #define ADREAD(sc, addr) bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_iooffs+(addr)) #define ADWRITE(sc, addr, data) bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_iooffs+(addr), (data)) @@ -209,34 +211,32 @@ wait_for_calibration(sc) /* * 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. + * 1) Wait until the chip becomes ready (reads don't return SP_IN_INIT). + * 2) Wait until the ACI bit of I11 goes hi and then lo. + * a) With AD1848 alike, ACI goes hi within 5 sample cycles + * and remains hi for ~384 sample periods. + * b) With CS4231 alike, ACI goes hi immediately and remains + * hi for at least 168 sample periods. */ - timeout = 100000; + timeout = AD1848_TIMO; while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) timeout--; if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) DPRINTF(("ad1848: Auto calibration timed out(1).\n")); - ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT); - timeout = 100000; - while (timeout > 0 && ADREAD(sc, AD1848_IADDR) != SP_TEST_AND_INIT) - timeout--; - - if (ADREAD(sc, AD1848_IADDR) == SP_TEST_AND_INIT) - DPRINTF(("ad1848: Auto calibration timed out(1.5).\n")); - - if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) { - timeout = 100000; - while (timeout > 0 && !(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) + if (!(sc->sc_flags & AD1848_FLAG_32REGS)) { + timeout = AD1848_TIMO; + while (timeout > 0 && + !(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) timeout--; - if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) + if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) { DPRINTF(("ad1848: Auto calibration timed out(2).\n")); + } } - timeout = 100000; + timeout = AD1848_TIMO; while (timeout > 0 && ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG) timeout--; if (ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG) @@ -311,6 +311,7 @@ ad1848_probe(sc) /* 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. @@ -460,15 +461,18 @@ ad1848_probe(sc) sc->chip_name = "CS4231 or AD1845"; break; case 0x82: - case 0xa2: 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; } } @@ -508,9 +512,8 @@ ad1848_attach(sc) struct audio_params pparams, rparams; int timeout; - sc->sc_locked = 0; - sc->sc_playrun = NOTRUNNING; - sc->sc_recrun = NOTRUNNING; + sc->sc_playrun = 0; + sc->sc_recrun = 0; if (sc->sc_drq != -1) { if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, MAX_ISADMA, @@ -523,7 +526,7 @@ ad1848_attach(sc) if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) { if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { - printf("ad1848_attach: can't creape map for drq %d\n", + printf("ad1848_attach: can't create map for second drq %d\n", sc->sc_recdrq); return; } @@ -532,19 +535,26 @@ ad1848_attach(sc) /* Initialize the ad1848... */ for (i = 0; i < 0x10; i++) { ad_write(sc, i, ad1848_init_values[i]); - timeout = 100000; - while (timeout > 0 && ad_read(sc, AD1848_IADDR) & SP_IN_INIT) + timeout = AD1848_TIMO; + while (timeout > 0 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT) timeout--; } + /* need 2 separate drqs for mode 2 */ + if ((sc->mode == 2) && + ((sc->sc_recdrq == -1) || (sc->sc_recdrq == sc->sc_drq))) { + ad_write(sc, SP_MISC_INFO, ad_read(sc, SP_MISC_INFO) & ~MODE2); + if (!(ad_read(sc, SP_MISC_INFO) & MODE2)) + sc->mode = 1; + } /* ...and additional CS4231 stuff too */ if (sc->mode == 2) { ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */ for (i = 0x10; i < 0x20; i++) if (ad1848_init_values[i] != 0) { ad_write(sc, i, ad1848_init_values[i]); - timeout = 100000; + timeout = AD1848_TIMO; while (timeout > 0 && - ad_read(sc, AD1848_IADDR) & SP_IN_INIT) + ADREAD(sc, AD1848_IADDR) & SP_IN_INIT) timeout--; } } @@ -572,7 +582,6 @@ ad1848_attach(sc) if (sc->chip_name) printf(": %s", sc->chip_name); -#undef WAITREADY } /* @@ -1053,29 +1062,29 @@ ad1848_set_params(addr, setmode, usemode, p, r) } switch (enc) { case AUDIO_ENCODING_ULAW: - bits = FMT_ULAW >> 5; + bits = FMT_ULAW; break; case AUDIO_ENCODING_ALAW: - bits = FMT_ALAW >> 5; + bits = FMT_ALAW; break; case AUDIO_ENCODING_ADPCM: - bits = FMT_ADPCM >> 5; + bits = FMT_ADPCM; break; case AUDIO_ENCODING_SLINEAR_LE: if (p->precision == 16) - bits = FMT_TWOS_COMP >> 5; + bits = FMT_TWOS_COMP; else return EINVAL; break; case AUDIO_ENCODING_SLINEAR_BE: if (p->precision == 16) - bits = FMT_TWOS_COMP_BE >> 5; + bits = FMT_TWOS_COMP_BE; else return EINVAL; break; case AUDIO_ENCODING_ULINEAR_LE: if (p->precision == 8) - bits = FMT_PCM8 >> 5; + bits = FMT_PCM8; else return EINVAL; break; @@ -1151,10 +1160,6 @@ ad1848_round_blocksize(addr, blk) void *addr; int blk; { - struct ad1848_softc *sc = addr; - - sc->sc_lastcc = -1; - /* Round to a multiple of the biggest sample size. */ blk = (blk + 3) & -4; @@ -1170,16 +1175,15 @@ ad1848_open(addr, flags) DPRINTF(("ad1848_open: sc=%p\n", sc)); - sc->sc_intr = 0; - sc->sc_lastcc = -1; - sc->sc_locked = 0; + sc->sc_pintr = sc->sc_parg = NULL; + sc->sc_rintr = sc->sc_rarg = NULL; /* Enable interrupts */ DPRINTF(("ad1848_open: enable intrs\n")); ad_write(sc, SP_PIN_CONTROL, INTERRUPT_ENABLE|ad_read(sc, SP_PIN_CONTROL)); #ifdef AUDIO_DEBUG - if (ad1848debug) + if (ad1848debug > 2) ad1848_dump_regs(sc); #endif @@ -1195,18 +1199,15 @@ ad1848_close(addr) { struct ad1848_softc *sc = addr; u_char r; - - sc->sc_intr = 0; + + ad1848_halt_output(sc); + ad1848_halt_input(sc); + + sc->sc_pintr = NULL; + sc->sc_rintr = NULL; DPRINTF(("ad1848_close: stop DMA\n")); - if (sc->sc_playrun != NOTRUNNING) { - isa_dmaabort(sc->sc_isa, sc->sc_drq); - sc->sc_playrun = NOTRUNNING; - } - if (sc->sc_recrun != NOTRUNNING) { - isa_dmaabort(sc->sc_isa, sc->sc_recdrq); - sc->sc_recrun = NOTRUNNING; - } + ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)0); ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)0); @@ -1221,7 +1222,7 @@ ad1848_close(addr) ad_write(sc, SP_INTERFACE_CONFIG, r); #ifdef AUDIO_DEBUG - if (ad1848debug) + if (ad1848debug > 2) ad1848_dump_regs(sc); #endif } @@ -1247,7 +1248,7 @@ ad1848_commit_settings(addr) ad_set_MCE(sc, 1); /* Enables changes to the format select reg */ - fs = sc->speed_bits | (sc->format_bits << 5); + fs = sc->speed_bits | sc->format_bits; if (sc->channels == 2) fs |= FMT_STEREO; @@ -1266,7 +1267,7 @@ ad1848_commit_settings(addr) /* * Write to I8 starts resynchronization. Wait until it completes. */ - timeout = 100000; + timeout = AD1848_TIMO; while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) timeout--; @@ -1281,7 +1282,7 @@ ad1848_commit_settings(addr) /* * Write to I8 starts resynchronization. Wait until it completes. */ - timeout = 100000; + timeout = AD1848_TIMO; while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) timeout--; @@ -1297,8 +1298,6 @@ ad1848_commit_settings(addr) ad1848_mute_monitor(sc, 0); - sc->sc_lastcc = -1; - splx(s); sc->need_commit = 0; @@ -1318,14 +1317,13 @@ ad1848_reset(sc) r &= ~(CAPTURE_ENABLE|PLAYBACK_ENABLE); ad_write(sc, SP_INTERFACE_CONFIG, r); - if (sc->mode == 2) { - ADWRITE(sc, AD1848_IADDR, CS_IRQ_STATUS); - ADWRITE(sc, AD1848_IDATA, 0); - } /* Clear interrupt status */ + if (sc->mode == 2) + ad_write(sc, CS_IRQ_STATUS, 0); ADWRITE(sc, AD1848_STATUS, 0); + #ifdef AUDIO_DEBUG - if (ad1848debug) + if (ad1848debug > 2) ad1848_dump_regs(sc); #endif } @@ -1407,198 +1405,121 @@ ad1848_set_speed(sc, argp) * Halt a DMA in progress. */ int -ad1848_halt_out_dma(addr) +ad1848_halt_output(addr) void *addr; { struct ad1848_softc *sc = addr; u_char reg; - - DPRINTF(("ad1848: ad1848_halt_out_dma\n")); + + DPRINTF(("ad1848: ad1848_halt_output\n")); reg = ad_read(sc, SP_INTERFACE_CONFIG); ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~PLAYBACK_ENABLE)); - sc->sc_locked = 0; + + if (sc->sc_playrun == 1) { + isa_dmaabort(sc->sc_isa, sc->sc_drq); + sc->sc_playrun = 0; + } return(0); } int -ad1848_halt_in_dma(addr) +ad1848_halt_input(addr) void *addr; { struct ad1848_softc *sc = addr; u_char reg; - DPRINTF(("ad1848: ad1848_halt_in_dma\n")); + DPRINTF(("ad1848: ad1848_halt_input\n")); reg = ad_read(sc, SP_INTERFACE_CONFIG); ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~CAPTURE_ENABLE)); - sc->sc_locked = 0; - - return(0); -} -int -ad1848_dma_init_input(addr, buf, cc) - void *addr; - void *buf; - int cc; -{ - struct ad1848_softc *sc = addr; + if (sc->sc_recrun == 1) { + isa_dmaabort(sc->sc_isa, sc->sc_recdrq); + sc->sc_recrun = 0; + } - sc->sc_recrun = DMARUNNING; - sc->sc_dma_flags = DMAMODE_READ | DMAMODE_LOOP; - sc->sc_dma_bp = buf; - sc->sc_dma_cnt = cc; - isa_dmastart(sc->sc_isa, sc->sc_recdrq, buf, cc, NULL, - sc->sc_dma_flags, BUS_DMA_NOWAIT); - DPRINTF(("ad1848_dma_init_input: %p %d\n", buf, cc)); - return 0; + return(0); } -/* - * DMA input/output are called at splaudio(). - */ int -ad1848_dma_input(addr, p, cc, intr, arg) +ad1848_trigger_input(addr, start, end, blksize, intr, arg, param) void *addr; - void *p; - int cc; + void *start, *end; + int blksize; void (*intr)(void *); void *arg; + struct audio_params *param; { struct ad1848_softc *sc = addr; u_char reg; - - if (sc->sc_locked) { - DPRINTF(("ad1848_dma_input: locked\n")); - return 0; + + if (sc->sc_recdrq == -1) { + DPRINTF(("ad1848_trigger_input: invalid recording drq\n")); + return ENXIO; } -#ifdef AUDIO_DEBUG - if (ad1848debug > 1) - printf("ad1848_dma_input: cc=%d %p (%p)\n", cc, intr, arg); -#endif - sc->sc_locked = 1; - sc->sc_intr = intr; - sc->sc_arg = arg; - - switch (sc->sc_recrun) { - case NOTRUNNING: - sc->sc_dma_flags = DMAMODE_READ; - sc->sc_dma_bp = p; - sc->sc_dma_cnt = cc; - isa_dmastart(sc->sc_isa, sc->sc_recdrq, p, cc, NULL, - DMAMODE_READ, BUS_DMA_NOWAIT); - goto startpcm; - case DMARUNNING: - sc->sc_recrun = PCMRUNNING; - startpcm: - if (sc->precision == 16) - cc >>= 1; - if (sc->channels == 2) - cc >>= 1; - cc--; - - if (sc->sc_lastcc != cc || sc->sc_mode != AUMODE_RECORD) { - ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)(cc & 0xff)); - ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)((cc >> 8) & 0xff)); + isa_dmastart(sc->sc_isa, sc->sc_recdrq, start, (char *)end - (char *)start, + NULL, DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT); - if (sc->mode == 2) { - ad_write(sc, CS_LOWER_REC_CNT, (u_char)(cc & 0xff)); - ad_write(sc, CS_UPPER_REC_CNT, (u_char)((cc >> 8) & 0xff)); - } + sc->sc_recrun = 1; + sc->sc_rintr = intr; + sc->sc_rarg = arg; - reg = ad_read(sc, SP_INTERFACE_CONFIG); - ad_write(sc, SP_INTERFACE_CONFIG, (CAPTURE_ENABLE|reg)); + blksize = (blksize * NBBY) / (param->precision * param->channels) - 1; - sc->sc_lastcc = cc; - sc->sc_mode = AUMODE_RECORD; -#ifdef AUDIO_DEBUG - if (ad1848debug > 1) - printf("ad1848_dma_input: started capture\n"); -#endif - } - case PCMRUNNING: - break; + if (sc->mode == 2) { + ad_write(sc, CS_LOWER_REC_CNT, (blksize & 0xff)); + ad_write(sc, CS_UPPER_REC_CNT, ((blksize >> 8) & 0xff)); + } else { + ad_write(sc, SP_LOWER_BASE_COUNT, blksize & 0xff); + ad_write(sc, SP_UPPER_BASE_COUNT, (blksize >> 8) & 0xff); } - - return 0; -} -int -ad1848_dma_init_output(addr, buf, cc) - void *addr; - void *buf; - int cc; -{ - struct ad1848_softc *sc = addr; + reg = ad_read(sc, SP_INTERFACE_CONFIG); + ad_write(sc, SP_INTERFACE_CONFIG, (CAPTURE_ENABLE|reg)); - sc->sc_playrun = DMARUNNING; - sc->sc_dma_flags = DMAMODE_WRITE | DMAMODE_LOOP; - sc->sc_dma_bp = buf; - sc->sc_dma_cnt = cc; - isa_dmastart(sc->sc_isa, sc->sc_drq, buf, cc, NULL, - sc->sc_dma_flags, BUS_DMA_NOWAIT); - DPRINTF(("ad1848_dma_init_output: %p %d\n", buf, cc)); +#ifdef AUDIO_DEBUG + if (ad1848debug > 1) + printf("ad1848_trigger_input: started capture\n"); +#endif + return 0; } int -ad1848_dma_output(addr, p, cc, intr, arg) +ad1848_trigger_output(addr, start, end, blksize, intr, arg, param) void *addr; - void *p; - int cc; + void *start, *end; + int blksize; void (*intr)(void *); void *arg; + struct audio_params *param; { struct ad1848_softc *sc = addr; u_char reg; - if (sc->sc_locked) { - DPRINTF(("ad1848_dma_output: locked\n")); - return 0; - } - + isa_dmastart(sc->sc_isa, sc->sc_drq, start, (char *)end - (char *)start, + NULL, DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT); + + sc->sc_playrun = 1; + sc->sc_pintr = intr; + sc->sc_parg = arg; + + blksize = (blksize * NBBY) / (param->precision * param->channels) - 1; + + ad_write(sc, SP_LOWER_BASE_COUNT, blksize & 0xff); + ad_write(sc, SP_UPPER_BASE_COUNT, (blksize >> 8) & 0xff); + + reg = ad_read(sc, SP_INTERFACE_CONFIG); + ad_write(sc, SP_INTERFACE_CONFIG, (PLAYBACK_ENABLE|reg)); + #ifdef AUDIO_DEBUG - if (ad1848debug > 0) - printf("ad1848_dma_output: cc=%d at %p %p (%p)\n", cc, p, intr, arg); + if (ad1848debug > 1) + printf("ad1848_trigger_output: started playback\n"); #endif - sc->sc_locked = 1; - sc->sc_intr = intr; - sc->sc_arg = arg; - - switch (sc->sc_playrun) { - case NOTRUNNING: - sc->sc_dma_flags = DMAMODE_WRITE; - sc->sc_dma_bp = p; - sc->sc_dma_cnt = cc; - isa_dmastart(sc->sc_isa, sc->sc_drq, p, cc, NULL, - DMAMODE_WRITE, BUS_DMA_NOWAIT); - goto startpcm; - case DMARUNNING: - sc->sc_playrun = PCMRUNNING; - startpcm: - if (sc->precision == 16) - cc >>= 1; - if (sc->channels == 2) - cc >>= 1; - cc--; - - if (sc->sc_lastcc != cc || sc->sc_mode != AUMODE_PLAY) { - ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)(cc & 0xff)); - ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)((cc >> 8) & 0xff)); - - reg = ad_read(sc, SP_INTERFACE_CONFIG); - ad_write(sc, SP_INTERFACE_CONFIG, (PLAYBACK_ENABLE|reg)); - - sc->sc_lastcc = cc; - sc->sc_mode = AUMODE_PLAY; - } - break; - case PCMRUNNING: - break; - } return 0; } @@ -1616,24 +1537,39 @@ ad1848_intr(arg) #ifdef AUDIO_DEBUG if (ad1848debug > 1) - printf("ad1848_intr: intr=%p status=%x\n", sc->sc_intr, status); + printf("ad1848_intr: mode=%d pintr=%p prun=%d rintr=%p rrun=%d status=0x%x\n", + sc->mode, sc->sc_pintr, sc->sc_playrun, sc->sc_rintr, sc->sc_recrun, status); #endif - sc->sc_locked = 0; - sc->sc_interrupts++; /* Handle interrupt */ - if (sc->sc_intr && (status & INTERRUPT_STATUS)) { - /* ACK DMA read because it may be in a bounce buffer */ - /* XXX Do write to mask DMA ? */ - if ((sc->sc_dma_flags & DMAMODE_READ) && sc->sc_recrun == NOTRUNNING) - isa_dmadone(sc->sc_isa, sc->sc_recdrq); - (*sc->sc_intr)(sc->sc_arg); - retval = 1; - } - - /* clear interrupt */ - if (status & INTERRUPT_STATUS) + if ((status & INTERRUPT_STATUS) != 0) { + if (sc->mode == 2) { + status = ad_read(sc, CS_IRQ_STATUS); +#ifdef AUDIO_DEBUG + if (ad1848debug > 2) + printf("ad1848_intr: cs_irq_status=0x%x (play=0x%x rec0x%x)\n", + status, CS_IRQ_PI, CS_IRQ_CI); +#endif + if ((status & CS_IRQ_PI) && sc->sc_playrun) { + (*sc->sc_pintr)(sc->sc_parg); + retval = 1; + } + if ((status & CS_IRQ_CI) && sc->sc_recrun) { + (*sc->sc_rintr)(sc->sc_rarg); + retval = 1; + } + } else { + if (sc->sc_playrun) { + (*sc->sc_pintr)(sc->sc_parg); + retval = 1; + } else if (sc->sc_recrun) { + (*sc->sc_rintr)(sc->sc_rarg); + retval = 1; + } + } + /* clear interrupt */ ADWRITE(sc, AD1848_STATUS, 0); + } return(retval); } @@ -1649,10 +1585,10 @@ ad1848_malloc(addr, direction, size, pool, flags) struct ad1848_softc *sc = addr; int drq; - if (sc->sc_mode == AUMODE_RECORD) - drq = sc->sc_recdrq == -1 ? sc->sc_drq : sc->sc_recdrq; - else + if (direction == AUMODE_PLAY) drq = sc->sc_drq; + else + drq = sc->sc_recdrq; return isa_malloc(sc->sc_isa, drq, size, pool, flags); } @@ -1694,5 +1630,5 @@ ad1848_get_props(addr) struct ad1848_softc *sc = addr; return AUDIO_PROP_MMAP | - (sc->sc_drq != sc->sc_recdrq ? AUDIO_PROP_FULLDUPLEX : 0); + (sc->mode == 2 ? AUDIO_PROP_FULLDUPLEX : 0); } diff --git a/sys/dev/isa/ad1848var.h b/sys/dev/isa/ad1848var.h index e96fada888a..b5d1e73bed9 100644 --- a/sys/dev/isa/ad1848var.h +++ b/sys/dev/isa/ad1848var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ad1848var.h,v 1.12 2002/03/14 03:16:05 millert Exp $ */ +/* $OpenBSD: ad1848var.h,v 1.13 2010/06/30 11:21:35 jakemsr Exp $ */ /* $NetBSD: ad1848var.h,v 1.22 1998/01/19 22:18:26 augustss Exp $ */ /* @@ -37,6 +37,7 @@ */ #define AD1848_NPORT 4 +#define AD1848_TIMO 1000000 struct ad1848_volume { u_char left; @@ -54,24 +55,16 @@ struct ad1848_softc { void *parent; struct device *sc_isa; /* ISA bus's device */ - u_short sc_locked; /* true when doing HS DMA */ - u_int sc_lastcc; /* size of last DMA xfer */ - int sc_mode; /* half-duplex record/play */ - - int sc_dma_flags; - void *sc_dma_bp; - u_int sc_dma_cnt; - char sc_playrun; /* running in continuous mode */ char sc_recrun; /* running in continuous mode */ -#define NOTRUNNING 0 -#define DMARUNNING 1 -#define PCMRUNNING 2 int sc_irq; /* interrupt */ int sc_drq; /* DMA */ int sc_recdrq; /* record/capture DMA */ + int sc_flags; +#define AD1848_FLAG_32REGS 0x01 /* newer chip (cs4231 compatible) */ + /* We keep track of these */ struct ad1848_volume gains[6]; @@ -94,9 +87,10 @@ struct ad1848_softc { u_char format_bits; u_char need_commit; - u_long sc_interrupts; /* number of interrupts taken */ - void (*sc_intr)(void *); /* dma completion intr handler */ - void *sc_arg; /* arg for sc_intr() */ + void (*sc_pintr)(void *); /* play dma completion intr handler */ + void (*sc_rintr)(void *); /* rec dma completion intr handler */ + void *sc_parg; /* play arg for sc_intr() */ + void *sc_rarg; /* rec arg for sc_intr() */ /* Only used by pss XXX */ int sc_iobase; @@ -194,15 +188,15 @@ int ad1848_set_params(void *, int, int, struct audio_params *, struct audio_para int ad1848_round_blocksize(void *, int); -int ad1848_dma_init_output(void *, void *, int); -int ad1848_dma_init_input(void *, void *, int); -int ad1848_dma_output(void *, void *, int, void (*)(void *), void *); -int ad1848_dma_input(void *, void *, int, void (*)(void *), void *); +int ad1848_trigger_input(void *, void *, void *, int, void (*)(void *), + void *, struct audio_params *); +int ad1848_trigger_output(void *, void *, void *, int, void (*)(void *), + void *, struct audio_params *); int ad1848_commit_settings(void *); -int ad1848_halt_in_dma(void *); -int ad1848_halt_out_dma(void *); +int ad1848_halt_input(void *); +int ad1848_halt_output(void *); int ad1848_intr(void *); diff --git a/sys/dev/isa/pss.c b/sys/dev/isa/pss.c index a8d7cf3b071..71ed5310d4d 100644 --- a/sys/dev/isa/pss.c +++ b/sys/dev/isa/pss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pss.c,v 1.23 2008/04/21 00:32:42 jakemsr Exp $ */ +/* $OpenBSD: pss.c,v 1.24 2010/06/30 11:21:35 jakemsr Exp $ */ /* $NetBSD: pss.c,v 1.38 1998/01/12 09:43:44 thorpej Exp $ */ /* @@ -219,12 +219,12 @@ struct audio_hw_if pss_audio_if = { ad1848_set_params, ad1848_round_blocksize, ad1848_commit_settings, - ad1848_dma_init_output, - ad1848_dma_init_input, - ad1848_dma_output, - ad1848_dma_input, - ad1848_halt_out_dma, - ad1848_halt_in_dma, + NULL, + NULL, + NULL, + NULL, + ad1848_halt_output, + ad1848_halt_input, pss_speaker_ctl, pss_getdev, NULL, @@ -236,8 +236,8 @@ struct audio_hw_if pss_audio_if = { ad1848_round, ad1848_mappage, ad1848_get_props, - NULL, - NULL, + ad1848_trigger_output, + ad1848_trigger_input, NULL }; diff --git a/sys/dev/isa/wss.c b/sys/dev/isa/wss.c index 6f244ba514b..7eeef51c921 100644 --- a/sys/dev/isa/wss.c +++ b/sys/dev/isa/wss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wss.c,v 1.23 2008/04/21 00:32:42 jakemsr Exp $ */ +/* $OpenBSD: wss.c,v 1.24 2010/06/30 11:21:35 jakemsr Exp $ */ /* $NetBSD: wss.c,v 1.42 1998/01/19 22:18:23 augustss Exp $ */ /* @@ -92,12 +92,12 @@ struct audio_hw_if wss_hw_if = { ad1848_set_params, ad1848_round_blocksize, ad1848_commit_settings, - ad1848_dma_init_output, - ad1848_dma_init_input, - ad1848_dma_output, - ad1848_dma_input, - ad1848_halt_out_dma, - ad1848_halt_in_dma, + NULL, + NULL, + NULL, + NULL, + ad1848_halt_output, + ad1848_halt_input, NULL, wss_getdev, NULL, @@ -109,8 +109,8 @@ struct audio_hw_if wss_hw_if = { ad1848_round, ad1848_mappage, ad1848_get_props, - NULL, - NULL, + ad1848_trigger_output, + ad1848_trigger_input, NULL }; diff --git a/sys/dev/isa/ym.c b/sys/dev/isa/ym.c index a0313ef5833..ded7fbd8978 100644 --- a/sys/dev/isa/ym.c +++ b/sys/dev/isa/ym.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ym.c,v 1.14 2008/04/21 00:32:42 jakemsr Exp $ */ +/* $OpenBSD: ym.c,v 1.15 2010/06/30 11:21:35 jakemsr Exp $ */ /* @@ -75,12 +75,12 @@ struct audio_hw_if ym_hw_if = { ad1848_set_params, ad1848_round_blocksize, ad1848_commit_settings, - ad1848_dma_init_output, - ad1848_dma_init_input, - ad1848_dma_output, - ad1848_dma_input, - ad1848_halt_out_dma, - ad1848_halt_in_dma, + NULL, + NULL, + NULL, + NULL, + ad1848_halt_output, + ad1848_halt_input, NULL, ym_getdev, NULL, @@ -92,8 +92,8 @@ struct audio_hw_if ym_hw_if = { ad1848_round, ad1848_mappage, ad1848_get_props, - NULL, - NULL, + ad1848_trigger_output, + ad1848_trigger_input, NULL }; diff --git a/sys/dev/isa/ym_isapnp.c b/sys/dev/isa/ym_isapnp.c index 79ec91cd594..606b8ec2687 100644 --- a/sys/dev/isa/ym_isapnp.c +++ b/sys/dev/isa/ym_isapnp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ym_isapnp.c,v 1.8 2002/03/14 01:26:57 millert Exp $ */ +/* $OpenBSD: ym_isapnp.c,v 1.9 2010/06/30 11:21:35 jakemsr Exp $ */ /* @@ -113,6 +113,7 @@ ym_isapnp_attach(parent, self, aux) sc->sc_ad1848.sc_iooffs = WSS_CODEC; sc->sc_ad1848.mode = 2; sc->sc_ad1848.MCE_bit = MODE_CHANGE_ENABLE; + sc->sc_ad1848.sc_flags = AD1848_FLAG_32REGS; #if NMIDI > 0 sc->sc_mpu_sc.iobase = ia->ipa_io[3].base; |