From 0edeb3dc90c1121dea6dcf7d1563e0256e9fb487 Mon Sep 17 00:00:00 2001 From: Nick Sayer Date: Wed, 9 Aug 2000 07:14:56 +0000 Subject: [PATCH] A couple of cosmetic fixes, plus a biggie: When checking the DMA position, channel 1's dma position register must be quiescent. So the driver will spl, pause the DMA, delay a bit and hold as still as possible while snapping the picture. I'm sure there HAS to be a better way to do this, but if there is, it's not documented. So far as I can tell, this fixes recording, which means the Solo is open for business. --- sys/dev/sound/pci/solo.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c index 1414fae01901..2f6a159b197c 100644 --- a/sys/dev/sound/pci/solo.c +++ b/sys/dev/sound/pci/solo.c @@ -267,7 +267,7 @@ ess_get_byte(struct ess_info *sc) int i; for (i = 1000; i > 0; i--) { - if (ess_rd(sc, DSP_DATA_AVAIL) & 0x80) + if (ess_rd(sc, 0xc) & 0x40) return ess_rd(sc, DSP_READ); else DELAY(20); @@ -494,7 +494,9 @@ ess_start(struct ess_chinfo *ch) if (ch->hwch == 1) { ess_write(sc, 0xb8, ess_read(sc, 0xb8) | 0x01); if (ch->dir == PCMDIR_PLAY) { +#if 0 DELAY(100000); /* 100 ms */ +#endif ess_cmd(sc, 0xd1); } } else @@ -741,7 +743,7 @@ ess_dmasetup(struct ess_info *sc, int ch, u_int32_t base, u_int16_t cnt, int dir port_wr(sc->vc, 0xf, 0x01, 1); /* mask */ port_wr(sc->vc, 0xb, dir == PCMDIR_PLAY? 0x58 : 0x54, 1); /* mode */ port_wr(sc->vc, 0x0, base, 4); - port_wr(sc->vc, 0x4, cnt-1, 2); + port_wr(sc->vc, 0x4, cnt - 1, 2); } else if (ch == 2) { port_wr(sc->io, 0x6, 0x08, 1); /* autoinit */ @@ -755,12 +757,25 @@ static int ess_dmapos(struct ess_info *sc, int ch) { int p = 0; + u_long flags; KASSERT(ch == 1 || ch == 2, ("bad ch")); - if (ch == 1) + flags = spltty(); + if (ch == 1) { + +/* + * During recording, this register is known to give back + * garbage if it's not quiescent while being read. That's + * why we spl, stop the DMA, wait, and be vewy, vewy quiet + */ + ess_dmatrigger(sc, ch, 0); + DELAY(20); p = port_rd(sc->vc, 0x4, 2) + 1; + ess_dmatrigger(sc, ch, 1); + } else if (ch == 2) p = port_rd(sc->io, 0x4, 2); + splx(flags); return sc->dmasz[ch - 1] - p; }