General mixer initialization improvements around the MONO_IN/MONO_OUT/
PreAmp register, including a new MONO_IN mixer stage bypass mixer control; inspired by (and fixing) PR kern/18342 from Stephen Ma.
This commit is contained in:
parent
b4f8e35755
commit
d42e56f0d5
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: eso.c,v 1.33 2004/02/17 17:39:55 kleink Exp $ */
|
||||
/* $NetBSD: eso.c,v 1.34 2004/05/25 21:38:11 kleink Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2000 Klaus J. Klein
|
||||
* Copyright (c) 1999, 2000, 2004 Klaus J. Klein
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: eso.c,v 1.33 2004/02/17 17:39:55 kleink Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: eso.c,v 1.34 2004/05/25 21:38:11 kleink Exp $");
|
||||
|
||||
#include "mpu.h"
|
||||
|
||||
|
@ -163,8 +163,10 @@ 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 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_recsrc __P((struct eso_softc *, unsigned int));
|
||||
static int eso_set_monooutsrc __P((struct eso_softc *, unsigned int));
|
||||
static int eso_set_monoinbypass __P((struct eso_softc *, unsigned int));
|
||||
static int eso_set_preamp __P((struct eso_softc *, unsigned int));
|
||||
static void eso_write_cmd __P((struct eso_softc *, uint8_t));
|
||||
static void eso_write_ctlreg __P((struct eso_softc *, uint8_t, uint8_t));
|
||||
static void eso_write_mixreg __P((struct eso_softc *, uint8_t, uint8_t));
|
||||
|
@ -284,9 +286,10 @@ eso_attach(parent, self, aux)
|
|||
eso_write_mixreg(sc, ESO_MIXREG_MVCTL, mvctl);
|
||||
|
||||
/* Set mixer regs to something reasonable, needs work. */
|
||||
sc->sc_recsrc = ESO_MIXREG_ERS_LINE;
|
||||
sc->sc_monooutsrc = ESO_MIXREG_MPM_MOMUTE;
|
||||
sc->sc_recmon = sc->sc_spatializer = sc->sc_mvmute = 0;
|
||||
eso_set_monooutsrc(sc, ESO_MIXREG_MPM_MOMUTE);
|
||||
eso_set_monoinbypass(sc, 0);
|
||||
eso_set_preamp(sc, 1);
|
||||
for (idx = 0; idx < ESO_NGAINDEVS; idx++) {
|
||||
int v;
|
||||
|
||||
|
@ -1070,7 +1073,13 @@ eso_set_port(hdl, cp)
|
|||
return (EINVAL);
|
||||
|
||||
return (eso_set_monooutsrc(sc, cp->un.ord));
|
||||
|
||||
|
||||
case ESO_MONOIN_BYPASS:
|
||||
if (cp->type != AUDIO_MIXER_ENUM)
|
||||
return (EINVAL);
|
||||
|
||||
return (eso_set_monoinbypass(sc, cp->un.ord));
|
||||
|
||||
case ESO_RECORD_MONITOR:
|
||||
if (cp->type != AUDIO_MIXER_ENUM)
|
||||
return (EINVAL);
|
||||
|
@ -1095,16 +1104,7 @@ eso_set_port(hdl, cp)
|
|||
if (cp->type != AUDIO_MIXER_ENUM)
|
||||
return (EINVAL);
|
||||
|
||||
sc->sc_preamp = (cp->un.ord != 0);
|
||||
|
||||
tmp = eso_read_mixreg(sc, ESO_MIXREG_MPM);
|
||||
tmp &= ~ESO_MIXREG_MPM_RESV0;
|
||||
if (sc->sc_preamp)
|
||||
tmp |= ESO_MIXREG_MPM_PREAMP;
|
||||
else
|
||||
tmp &= ~ESO_MIXREG_MPM_PREAMP;
|
||||
eso_write_mixreg(sc, ESO_MIXREG_MPM, tmp);
|
||||
break;
|
||||
return (eso_set_preamp(sc, cp->un.ord));
|
||||
|
||||
default:
|
||||
return (EINVAL);
|
||||
|
@ -1181,6 +1181,10 @@ eso_get_port(hdl, cp)
|
|||
case ESO_MONOOUT_SOURCE:
|
||||
cp->un.ord = sc->sc_monooutsrc;
|
||||
break;
|
||||
|
||||
case ESO_MONOIN_BYPASS:
|
||||
cp->un.ord = sc->sc_monoinbypass;
|
||||
break;
|
||||
|
||||
case ESO_SPATIALIZER_ENABLE:
|
||||
cp->un.ord = sc->sc_spatializer;
|
||||
|
@ -1338,6 +1342,25 @@ eso_query_devinfo(hdl, dip)
|
|||
strcpy(dip->un.e.member[2].label.name, AudioNmixerout);
|
||||
dip->un.e.member[2].ord = ESO_MIXREG_MPM_MOREC;
|
||||
break;
|
||||
|
||||
case ESO_MONOIN_BYPASS:
|
||||
dip->mixer_class = ESO_MONOIN_CLASS;
|
||||
dip->next = dip->prev = AUDIO_MIXER_LAST;
|
||||
strcpy(dip->label.name, "bypass");
|
||||
dip->type = AUDIO_MIXER_ENUM;
|
||||
dip->un.e.num_mem = 2;
|
||||
strcpy(dip->un.e.member[0].label.name, AudioNoff);
|
||||
dip->un.e.member[0].ord = 0;
|
||||
strcpy(dip->un.e.member[1].label.name, AudioNon);
|
||||
dip->un.e.member[1].ord = 1;
|
||||
break;
|
||||
case ESO_MONOIN_CLASS:
|
||||
dip->mixer_class = ESO_MONOIN_CLASS;
|
||||
dip->next = dip->prev = AUDIO_MIXER_LAST;
|
||||
strcpy(dip->label.name, "mono_in");
|
||||
dip->type = AUDIO_MIXER_CLASS;
|
||||
break;
|
||||
|
||||
case ESO_SPATIALIZER:
|
||||
dip->mixer_class = ESO_OUTPUT_CLASS;
|
||||
dip->prev = AUDIO_MIXER_LAST;
|
||||
|
@ -1846,6 +1869,32 @@ eso_trigger_input(hdl, start, end, blksize, intr, arg, param)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mixer utility functions.
|
||||
*/
|
||||
static int
|
||||
eso_set_recsrc(sc, recsrc)
|
||||
struct eso_softc *sc;
|
||||
unsigned int recsrc;
|
||||
{
|
||||
mixer_devinfo_t di;
|
||||
int i;
|
||||
|
||||
di.index = ESO_RECORD_SOURCE;
|
||||
if (eso_query_devinfo(sc, &di) != 0)
|
||||
panic("eso_set_recsrc: eso_query_devinfo failed");
|
||||
|
||||
for (i = 0; i < di.un.e.num_mem; i++) {
|
||||
if (recsrc == di.un.e.member[i].ord) {
|
||||
eso_write_mixreg(sc, ESO_MIXREG_ERS, recsrc);
|
||||
sc->sc_recsrc = recsrc;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
static int
|
||||
eso_set_monooutsrc(sc, monooutsrc)
|
||||
struct eso_softc *sc;
|
||||
|
@ -1874,25 +1923,56 @@ eso_set_monooutsrc(sc, monooutsrc)
|
|||
}
|
||||
|
||||
static int
|
||||
eso_set_recsrc(sc, recsrc)
|
||||
eso_set_monoinbypass(sc, monoinbypass)
|
||||
struct eso_softc *sc;
|
||||
unsigned int recsrc;
|
||||
unsigned int monoinbypass;
|
||||
{
|
||||
mixer_devinfo_t di;
|
||||
int i;
|
||||
uint8_t mpm;
|
||||
|
||||
di.index = ESO_RECORD_SOURCE;
|
||||
di.index = ESO_MONOIN_BYPASS;
|
||||
if (eso_query_devinfo(sc, &di) != 0)
|
||||
panic("eso_set_recsrc: eso_query_devinfo failed");
|
||||
panic("eso_set_monoinbypass: eso_query_devinfo failed");
|
||||
|
||||
for (i = 0; i < di.un.e.num_mem; i++) {
|
||||
if (recsrc == di.un.e.member[i].ord) {
|
||||
eso_write_mixreg(sc, ESO_MIXREG_ERS, recsrc);
|
||||
sc->sc_recsrc = recsrc;
|
||||
if (monoinbypass == di.un.e.member[i].ord) {
|
||||
mpm = eso_read_mixreg(sc, ESO_MIXREG_MPM);
|
||||
mpm &= ~(ESO_MIXREG_MPM_MOMASK | ESO_MIXREG_MPM_RESV0);
|
||||
mpm |= (monoinbypass ? ESO_MIXREG_MPM_MIBYPASS : 0);
|
||||
eso_write_mixreg(sc, ESO_MIXREG_MPM, mpm);
|
||||
sc->sc_monoinbypass = monoinbypass;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
static int
|
||||
eso_set_preamp(sc, preamp)
|
||||
struct eso_softc *sc;
|
||||
unsigned int preamp;
|
||||
{
|
||||
mixer_devinfo_t di;
|
||||
int i;
|
||||
uint8_t mpm;
|
||||
|
||||
di.index = ESO_MIC_PREAMP;
|
||||
if (eso_query_devinfo(sc, &di) != 0)
|
||||
panic("eso_set_preamp: eso_query_devinfo failed");
|
||||
|
||||
for (i = 0; i < di.un.e.num_mem; i++) {
|
||||
if (preamp == di.un.e.member[i].ord) {
|
||||
mpm = eso_read_mixreg(sc, ESO_MIXREG_MPM);
|
||||
mpm &= ~(ESO_MIXREG_MPM_PREAMP | ESO_MIXREG_MPM_RESV0);
|
||||
mpm |= (preamp ? ESO_MIXREG_MPM_PREAMP : 0);
|
||||
eso_write_mixreg(sc, ESO_MIXREG_MPM, mpm);
|
||||
sc->sc_preamp = preamp;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: esovar.h,v 1.4 2000/03/22 14:37:43 kleink Exp $ */
|
||||
/* $NetBSD: esovar.h,v 1.5 2004/05/25 21:38:11 kleink Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2000 Klaus J. Klein
|
||||
* Copyright (c) 1999, 2000, 2004 Klaus J. Klein
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -66,17 +66,19 @@
|
|||
/* Other, non-gain related mixer identifiers */
|
||||
#define ESO_RECORD_SOURCE 18
|
||||
#define ESO_MONOOUT_SOURCE 19
|
||||
#define ESO_RECORD_MONITOR 20
|
||||
#define ESO_MIC_PREAMP 21
|
||||
#define ESO_SPATIALIZER_ENABLE 22
|
||||
#define ESO_MASTER_MUTE 23
|
||||
#define ESO_MONOIN_BYPASS 20
|
||||
#define ESO_RECORD_MONITOR 21
|
||||
#define ESO_MIC_PREAMP 22
|
||||
#define ESO_SPATIALIZER_ENABLE 23
|
||||
#define ESO_MASTER_MUTE 24
|
||||
|
||||
/* Classes of the above */
|
||||
#define ESO_INPUT_CLASS 24
|
||||
#define ESO_OUTPUT_CLASS 25
|
||||
#define ESO_MICROPHONE_CLASS 26
|
||||
#define ESO_MONITOR_CLASS 27
|
||||
#define ESO_RECORD_CLASS 28
|
||||
#define ESO_INPUT_CLASS 25
|
||||
#define ESO_OUTPUT_CLASS 26
|
||||
#define ESO_MICROPHONE_CLASS 27
|
||||
#define ESO_MONITOR_CLASS 28
|
||||
#define ESO_RECORD_CLASS 29
|
||||
#define ESO_MONOIN_CLASS 30
|
||||
|
||||
|
||||
/*
|
||||
|
@ -136,6 +138,7 @@ struct eso_softc {
|
|||
#define ESO_RIGHT 1
|
||||
unsigned int sc_recsrc; /* record source selection */
|
||||
unsigned int sc_monooutsrc; /* MONO_OUT source selection */
|
||||
unsigned int sc_monoinbypass;/* MONO_IN bypass enable */
|
||||
unsigned int sc_recmon; /* record monitor setting */
|
||||
unsigned int sc_preamp; /* microphone preamp */
|
||||
unsigned int sc_spatializer; /* spatializer enable */
|
||||
|
|
Loading…
Reference in New Issue