Get audio capture fully working with harmony(4) and fix PR/35239.
skrll@ reports that with this patch he can record and playback audio. Suprisingly the bug was actually with playback and not with capture. When not capturing or playing audio we write to or read from "empty buffers", the problem was that playback and capture were using the same buffer and the playback code managed to pick up a bit of data that was written from the capture code.
This commit is contained in:
parent
3d2a48dd46
commit
b6791e4a2a
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: harmony.c,v 1.13 2008/09/23 14:07:11 mjf Exp $ */
|
||||
/* $NetBSD: harmony.c,v 1.14 2009/04/15 20:07:58 mjf Exp $ */
|
||||
|
||||
/* $OpenBSD: harmony.c,v 1.23 2004/02/13 21:28:19 mickey Exp $ */
|
||||
|
||||
|
@ -133,6 +133,8 @@ void harmony_tick_pb(void *);
|
|||
void harmony_tick_cp(void *);
|
||||
void harmony_try_more(struct harmony_softc *, int, int,
|
||||
struct harmony_channel *);
|
||||
static void harmony_empty_input(struct harmony_softc *);
|
||||
static void harmony_empty_output(struct harmony_softc *);
|
||||
|
||||
#if NRND > 0
|
||||
void harmony_acc_tmo(void *);
|
||||
|
@ -243,7 +245,7 @@ harmony_attach(device_t parent, device_t self, void *aux)
|
|||
for (i = 0; i < CAPTURE_EMPTYS; i++)
|
||||
sc->sc_capture_paddrs[i] =
|
||||
sc->sc_empty_map->dm_segs[0].ds_addr +
|
||||
offsetof(struct harmony_empty, playback[i][0]);
|
||||
offsetof(struct harmony_empty, capture[i][0]);
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->sc_empty_map,
|
||||
offsetof(struct harmony_empty, playback[0][0]),
|
||||
|
@ -663,6 +665,18 @@ harmony_commit_settings(void *vsc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
harmony_empty_output(struct harmony_softc *sc)
|
||||
{
|
||||
|
||||
WRITE_REG(sc, HARMONY_PNXTADD,
|
||||
sc->sc_playback_paddrs[sc->sc_playback_empty]);
|
||||
SYNC_REG(sc, HARMONY_PNXTADD, BUS_SPACE_BARRIER_WRITE);
|
||||
|
||||
if (++sc->sc_playback_empty == PLAYBACK_EMPTYS)
|
||||
sc->sc_playback_empty = 0;
|
||||
}
|
||||
|
||||
int
|
||||
harmony_halt_output(void *vsc)
|
||||
{
|
||||
|
@ -670,9 +684,23 @@ harmony_halt_output(void *vsc)
|
|||
|
||||
sc = vsc;
|
||||
sc->sc_playing = 0;
|
||||
|
||||
harmony_empty_output(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
harmony_empty_input(struct harmony_softc *sc)
|
||||
{
|
||||
|
||||
WRITE_REG(sc, HARMONY_RNXTADD,
|
||||
sc->sc_capture_paddrs[sc->sc_capture_empty]);
|
||||
SYNC_REG(sc, HARMONY_RNXTADD, BUS_SPACE_BARRIER_WRITE);
|
||||
|
||||
if (++sc->sc_capture_empty == CAPTURE_EMPTYS)
|
||||
sc->sc_capture_empty = 0;
|
||||
}
|
||||
|
||||
int
|
||||
harmony_halt_input(void *vsc)
|
||||
{
|
||||
|
@ -680,6 +708,8 @@ harmony_halt_input(void *vsc)
|
|||
|
||||
sc = vsc;
|
||||
sc->sc_capturing = 0;
|
||||
|
||||
harmony_empty_input(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1097,12 +1127,9 @@ harmony_start_cp(struct harmony_softc *sc, int start)
|
|||
bus_size_t togo;
|
||||
|
||||
c = &sc->sc_capture;
|
||||
if (sc->sc_capturing == 0) {
|
||||
WRITE_REG(sc, HARMONY_RNXTADD,
|
||||
sc->sc_capture_paddrs[sc->sc_capture_empty]);
|
||||
if (++sc->sc_capture_empty == CAPTURE_EMPTYS)
|
||||
sc->sc_capture_empty = 0;
|
||||
} else {
|
||||
if (sc->sc_capturing == 0)
|
||||
harmony_empty_input(sc);
|
||||
else {
|
||||
d = c->c_current;
|
||||
togo = c->c_segsz - c->c_cnt;
|
||||
if (togo == 0) {
|
||||
|
@ -1143,12 +1170,9 @@ harmony_start_pp(struct harmony_softc *sc, int start)
|
|||
bus_size_t togo;
|
||||
|
||||
c = &sc->sc_playback;
|
||||
if (sc->sc_playing == 0) {
|
||||
WRITE_REG(sc, HARMONY_PNXTADD,
|
||||
sc->sc_playback_paddrs[sc->sc_playback_empty]);
|
||||
if (++sc->sc_playback_empty == PLAYBACK_EMPTYS)
|
||||
sc->sc_playback_empty = 0;
|
||||
} else {
|
||||
if (sc->sc_playing == 0)
|
||||
harmony_empty_output(sc);
|
||||
else {
|
||||
d = c->c_current;
|
||||
togo = c->c_segsz - c->c_cnt;
|
||||
if (togo == 0) {
|
||||
|
|
Loading…
Reference in New Issue