Add support code to have the Hardware Volume Control interact with the
software mixer Master Volume state in a defined way by lazily updating the latter if input from the former was processed.
This commit is contained in:
parent
486d64de0f
commit
c88b5146dc
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: eso.c,v 1.13 1999/12/03 22:34:28 kleink Exp $ */
|
/* $NetBSD: eso.c,v 1.14 1999/12/10 19:13:00 kleink Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999 Klaus J. Klein
|
* Copyright (c) 1999 Klaus J. Klein
|
||||||
@ -156,6 +156,7 @@ static const char * const eso_rev2model[] = {
|
|||||||
static uint8_t eso_read_ctlreg __P((struct eso_softc *, uint8_t));
|
static uint8_t eso_read_ctlreg __P((struct eso_softc *, uint8_t));
|
||||||
static uint8_t eso_read_mixreg __P((struct eso_softc *, uint8_t));
|
static uint8_t eso_read_mixreg __P((struct eso_softc *, uint8_t));
|
||||||
static uint8_t eso_read_rdr __P((struct eso_softc *));
|
static uint8_t eso_read_rdr __P((struct eso_softc *));
|
||||||
|
static void eso_reload_master_vol __P((struct eso_softc *));
|
||||||
static int eso_reset __P((struct eso_softc *));
|
static int eso_reset __P((struct eso_softc *));
|
||||||
static void eso_set_gain __P((struct eso_softc *, unsigned int));
|
static void eso_set_gain __P((struct eso_softc *, unsigned int));
|
||||||
static int eso_set_monooutsrc __P((struct eso_softc *, unsigned int));
|
static int eso_set_monooutsrc __P((struct eso_softc *, unsigned int));
|
||||||
@ -258,13 +259,20 @@ eso_attach(parent, self, aux)
|
|||||||
|
|
||||||
/* Enable the relevant (DMA) interrupts. */
|
/* Enable the relevant (DMA) interrupts. */
|
||||||
bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL,
|
bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL,
|
||||||
ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ | ESO_IO_IRQCTL_MPUIRQ);
|
ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ | ESO_IO_IRQCTL_HVIRQ |
|
||||||
|
ESO_IO_IRQCTL_MPUIRQ);
|
||||||
|
|
||||||
/* Set up A1's sample rate generator for new-style parameters. */
|
/* Set up A1's sample rate generator for new-style parameters. */
|
||||||
a2mode = eso_read_mixreg(sc, ESO_MIXREG_A2MODE);
|
a2mode = eso_read_mixreg(sc, ESO_MIXREG_A2MODE);
|
||||||
a2mode |= ESO_MIXREG_A2MODE_NEWA1 | ESO_MIXREG_A2MODE_ASYNC;
|
a2mode |= ESO_MIXREG_A2MODE_NEWA1 | ESO_MIXREG_A2MODE_ASYNC;
|
||||||
eso_write_mixreg(sc, ESO_MIXREG_A2MODE, a2mode);
|
eso_write_mixreg(sc, ESO_MIXREG_A2MODE, a2mode);
|
||||||
|
|
||||||
|
/* Slave Master Volume to Hardware Volume Control Counter, unask IRQ. */
|
||||||
|
mvctl = eso_read_mixreg(sc, ESO_MIXREG_MVCTL);
|
||||||
|
mvctl &= ~ESO_MIXREG_MVCTL_SPLIT;
|
||||||
|
mvctl |= ESO_MIXREG_MVCTL_HVIRQM;
|
||||||
|
eso_write_mixreg(sc, ESO_MIXREG_MVCTL, mvctl);
|
||||||
|
|
||||||
/* Set mixer regs to something reasonable, needs work. */
|
/* Set mixer regs to something reasonable, needs work. */
|
||||||
sc->sc_recsrc = ESO_MIXREG_ERS_LINE;
|
sc->sc_recsrc = ESO_MIXREG_ERS_LINE;
|
||||||
sc->sc_monooutsrc = ESO_MIXREG_MPM_MOMUTE;
|
sc->sc_monooutsrc = ESO_MIXREG_MPM_MOMUTE;
|
||||||
@ -513,7 +521,7 @@ eso_intr(hdl)
|
|||||||
|
|
||||||
/* If it wasn't ours, that's all she wrote. */
|
/* If it wasn't ours, that's all she wrote. */
|
||||||
if ((irqctl & (ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ |
|
if ((irqctl & (ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ |
|
||||||
ESO_IO_IRQCTL_MPUIRQ)) == 0)
|
ESO_IO_IRQCTL_HVIRQ | ESO_IO_IRQCTL_MPUIRQ)) == 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (irqctl & ESO_IO_IRQCTL_A1IRQ) {
|
if (irqctl & ESO_IO_IRQCTL_A1IRQ) {
|
||||||
@ -540,6 +548,19 @@ eso_intr(hdl)
|
|||||||
wakeup(&sc->sc_pintr);
|
wakeup(&sc->sc_pintr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (irqctl & ESO_IO_IRQCTL_HVIRQ) {
|
||||||
|
/* Clear interrupt. */
|
||||||
|
eso_write_mixreg(sc, ESO_MIXREG_CHVIR, ESO_MIXREG_CHVIR_CHVIR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Raise a flag to cause a lazy update of the in-softc gain
|
||||||
|
* values the next time the software mixer is read to keep
|
||||||
|
* interrupt service cost low. ~0 cannot occur otherwise
|
||||||
|
* as the master volume has a precision of 6 bits only.
|
||||||
|
*/
|
||||||
|
sc->sc_gain[ESO_MASTER_VOL][ESO_LEFT] = (uint8_t)~0;
|
||||||
|
}
|
||||||
|
|
||||||
#if NMPU > 0
|
#if NMPU > 0
|
||||||
if ((irqctl & ESO_IO_IRQCTL_MPUIRQ) && sc->sc_mpudev != NULL)
|
if ((irqctl & ESO_IO_IRQCTL_MPUIRQ) && sc->sc_mpudev != NULL)
|
||||||
mpu_intr(sc->sc_mpudev);
|
mpu_intr(sc->sc_mpudev);
|
||||||
@ -1069,13 +1090,17 @@ eso_get_port(hdl, cp)
|
|||||||
struct eso_softc *sc = hdl;
|
struct eso_softc *sc = hdl;
|
||||||
|
|
||||||
switch (cp->dev) {
|
switch (cp->dev) {
|
||||||
|
case ESO_MASTER_VOL:
|
||||||
|
/* Reload from mixer after hardware volume control use. */
|
||||||
|
if (sc->sc_gain[cp->dev][ESO_LEFT] == (uint8_t)~0)
|
||||||
|
eso_reload_master_vol(sc);
|
||||||
|
/* FALLTHROUGH */
|
||||||
case ESO_DAC_PLAY_VOL:
|
case ESO_DAC_PLAY_VOL:
|
||||||
case ESO_MIC_PLAY_VOL:
|
case ESO_MIC_PLAY_VOL:
|
||||||
case ESO_LINE_PLAY_VOL:
|
case ESO_LINE_PLAY_VOL:
|
||||||
case ESO_SYNTH_PLAY_VOL:
|
case ESO_SYNTH_PLAY_VOL:
|
||||||
case ESO_CD_PLAY_VOL:
|
case ESO_CD_PLAY_VOL:
|
||||||
case ESO_AUXB_PLAY_VOL:
|
case ESO_AUXB_PLAY_VOL:
|
||||||
case ESO_MASTER_VOL:
|
|
||||||
case ESO_RECORD_VOL:
|
case ESO_RECORD_VOL:
|
||||||
case ESO_DAC_REC_VOL:
|
case ESO_DAC_REC_VOL:
|
||||||
case ESO_MIC_REC_VOL:
|
case ESO_MIC_REC_VOL:
|
||||||
@ -1135,6 +1160,9 @@ eso_get_port(hdl, cp)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ESO_MASTER_MUTE:
|
case ESO_MASTER_MUTE:
|
||||||
|
/* Reload from mixer after hardware volume control use. */
|
||||||
|
if (sc->sc_gain[cp->dev][ESO_LEFT] == (uint8_t)~0)
|
||||||
|
eso_reload_master_vol(sc);
|
||||||
cp->un.ord = sc->sc_mvmute;
|
cp->un.ord = sc->sc_mvmute;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1812,6 +1840,26 @@ eso_set_recsrc(sc, recsrc)
|
|||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reload Master Volume and Mute values in softc from mixer; used when
|
||||||
|
* those have previously been invalidated by use of hardware volume controls.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
eso_reload_master_vol(sc)
|
||||||
|
struct eso_softc *sc;
|
||||||
|
{
|
||||||
|
uint8_t mv;
|
||||||
|
|
||||||
|
mv = eso_read_mixreg(sc, ESO_MIXREG_LMVM);
|
||||||
|
sc->sc_gain[ESO_MASTER_VOL][ESO_LEFT] =
|
||||||
|
(mv & ~ESO_MIXREG_LMVM_MUTE) << 2;
|
||||||
|
mv = eso_read_mixreg(sc, ESO_MIXREG_LMVM);
|
||||||
|
sc->sc_gain[ESO_MASTER_VOL][ESO_RIGHT] =
|
||||||
|
(mv & ~ESO_MIXREG_RMVM_MUTE) << 2;
|
||||||
|
/* Currently both channels are muted simultaneously; either is OK. */
|
||||||
|
sc->sc_mvmute = (mv & ESO_MIXREG_RMVM_MUTE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eso_set_gain(sc, port)
|
eso_set_gain(sc, port)
|
||||||
struct eso_softc *sc;
|
struct eso_softc *sc;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: esoreg.h,v 1.4 1999/12/10 16:50:52 kleink Exp $ */
|
/* $NetBSD: esoreg.h,v 1.5 1999/12/10 19:13:00 kleink Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999 Klaus J. Klein
|
* Copyright (c) 1999 Klaus J. Klein
|
||||||
@ -142,10 +142,16 @@
|
|||||||
#define ESO_MIXREG_SPATLVL 0x52 /* Spatializer Level */
|
#define ESO_MIXREG_SPATLVL 0x52 /* Spatializer Level */
|
||||||
#define ESO_MIXREG_LMVM 0x60 /* Left Master Volume and Mute */
|
#define ESO_MIXREG_LMVM 0x60 /* Left Master Volume and Mute */
|
||||||
#define ESO_MIXREG_LMVM_MUTE 0x40 /* Mute enable */
|
#define ESO_MIXREG_LMVM_MUTE 0x40 /* Mute enable */
|
||||||
|
#define ESO_MIXREG_LHVCC 0x61 /* Left Hardware Volume Control Ctr */
|
||||||
#define ESO_MIXREG_RMVM 0x62 /* Right Master Volume and Mute */
|
#define ESO_MIXREG_RMVM 0x62 /* Right Master Volume and Mute */
|
||||||
#define ESO_MIXREG_RMVM_MUTE 0x40 /* Mute enable */
|
#define ESO_MIXREG_RMVM_MUTE 0x40 /* Mute enable */
|
||||||
|
#define ESO_MIXREG_RHVCC 0x63 /* Left Hardware Volume Control Ctr */
|
||||||
#define ESO_MIXREG_MVCTL 0x64 /* Master Volume Control */
|
#define ESO_MIXREG_MVCTL 0x64 /* Master Volume Control */
|
||||||
|
#define ESO_MIXREG_MVCTL_HVIRQM 0x02 /* Hardware Volume Control intr mask */
|
||||||
#define ESO_MIXREG_MVCTL_MPUIRQM 0x40 /* MPU-401 interrupt unmask */
|
#define ESO_MIXREG_MVCTL_MPUIRQM 0x40 /* MPU-401 interrupt unmask */
|
||||||
|
#define ESO_MIXREG_MVCTL_SPLIT 0x80 /* Split xHVCC/xMVM registers */
|
||||||
|
#define ESO_MIXREG_CHVIR 0x66 /* Clear Hardware Volume IRQ */
|
||||||
|
#define ESO_MIXREG_CHVIR_CHVIR 0x00 /* Any value will do */
|
||||||
#define ESO_MIXREG_RVR_MIC 0x68 /* Record mixer: Microphone */
|
#define ESO_MIXREG_RVR_MIC 0x68 /* Record mixer: Microphone */
|
||||||
#define ESO_MIXREG_RVR_A2 0x69 /* Record mixer: Audio 2 */
|
#define ESO_MIXREG_RVR_A2 0x69 /* Record mixer: Audio 2 */
|
||||||
#define ESO_MIXREG_RVR_CD 0x6a /* Record mixer: AuxA/CD */
|
#define ESO_MIXREG_RVR_CD 0x6a /* Record mixer: AuxA/CD */
|
||||||
|
Loading…
Reference in New Issue
Block a user