summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ic/cs4231reg.h30
-rw-r--r--sys/dev/isa/ad1848.c378
-rw-r--r--sys/dev/isa/ad1848var.h36
-rw-r--r--sys/dev/isa/pss.c18
-rw-r--r--sys/dev/isa/wss.c18
-rw-r--r--sys/dev/isa/ym.c18
-rw-r--r--sys/dev/isa/ym_isapnp.c3
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;