On 05/05/11(Thu) 15:59, Martin Pieuchot wrote:
> The following diff adds the possibility to mute the master channel on
> any i2s based card. As a side effect the "mute key" on the keyboard now
> works as expected.
>
> Comments, Ok?
New diff, should fix mixerctl crash with chipsets that don't support
bass nor treble.
Index: dev/i2s.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/dev/i2s.c,v
retrieving revision 1.19
diff -u -p -r1.19 i2s.c
--- dev/i2s.c 4 May 2011 15:50:49 -0000 1.19
+++ dev/i2s.c 5 May 2011 14:00:23 -0000
@@ -155,6 +155,7 @@ i2s_attach(struct device *parent, struct
printf(": irq %d,%d,%d\n", cirq, oirq, iirq);
i2s_set_rate(sc, 44100);
+ sc->sc_mute = 0;
i2s_gpio_init(sc, ca->ca_node, parent);
}
@@ -512,15 +513,14 @@ enum {
I2S_VOL_OUTPUT,
I2S_INPUT_SELECT,
I2S_VOL_INPUT,
+ I2S_MUTE, /* should be before bass/treble */
I2S_BASS,
I2S_TREBLE,
I2S_ENUM_LAST
};
int
-i2s_set_port(h, mc)
- void *h;
- mixer_ctrl_t *mc;
+i2s_set_port(void *h, mixer_ctrl_t *mc)
{
struct i2s_softc *sc = h;
int l, r;
@@ -553,6 +553,30 @@ i2s_set_port(h, mc)
(*sc->sc_setvolume)(sc, l, r);
return 0;
+ case I2S_MUTE:
+ if (mc->type != AUDIO_MIXER_ENUM)
+ return (EINVAL);
+
+ sc->sc_mute = (mc->un.ord != 0);
+
+ if (sc->sc_mute) {
+ if (sc->sc_output_mask & 1 << 0)
+ i2s_mute_speaker(sc, 1);
+ if (sc->sc_output_mask & 1 << 1)
+ i2s_mute_headphone(sc, 1);
+ if (sc->sc_output_mask & 1 << 2)
+ i2s_mute_lineout(sc, 1);
+ } else {
+ if (sc->sc_output_mask & 1 << 0)
+ i2s_mute_speaker(sc, 0);
+ if (sc->sc_output_mask & 1 << 1)
+ i2s_mute_headphone(sc, 0);
+ if (sc->sc_output_mask & 1 << 2)
+ i2s_mute_lineout(sc, 0);
+ }
+
+ return (0);
+
case I2S_BASS:
if (sc->sc_setbass != NULL)
(*sc->sc_setbass)(sc, l);
@@ -589,9 +613,7 @@ i2s_set_port(h, mc)
}
int
-i2s_get_port(h, mc)
- void *h;
- mixer_ctrl_t *mc;
+i2s_get_port(void *h, mixer_ctrl_t *mc)
{
struct i2s_softc *sc = h;
@@ -607,6 +629,10 @@ i2s_get_port(h, mc)
mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = sc->sc_vol_r;
return 0;
+ case I2S_MUTE:
+ mc->un.ord = sc->sc_mute;
+ return (0);
+
case I2S_INPUT_SELECT:
mc->un.mask = sc->sc_record_source;
return 0;
@@ -670,13 +696,29 @@ i2s_query_devinfo(void *h, mixer_devinfo
dip->mixer_class = I2S_OUTPUT_CLASS;
strlcpy(dip->label.name, AudioNmaster, sizeof(dip->label.name));
dip->type = AUDIO_MIXER_VALUE;
- dip->prev = dip->next = AUDIO_MIXER_LAST;
+ dip->prev = AUDIO_MIXER_LAST;
+ dip->next = I2S_MUTE;
dip->un.v.num_channels = 2;
dip->un.v.delta = 8;
strlcpy(dip->un.v.units.name, AudioNvolume,
sizeof(dip->un.v.units.name));
return 0;
+ case I2S_MUTE:
+ dip->mixer_class = I2S_OUTPUT_CLASS;
+ dip->prev = I2S_VOL_OUTPUT;
+ dip->next = AUDIO_MIXER_LAST;
+ strlcpy(dip->label.name, AudioNmute, sizeof(dip->label.name));
+ dip->type = AUDIO_MIXER_ENUM;
+ dip->un.e.num_mem = 2;
+ strlcpy(dip->un.e.member[0].label.name, AudioNoff,
+ sizeof dip->un.e.member[0].label.name);
+ dip->un.e.member[0].ord = 0;
+ strlcpy(dip->un.e.member[1].label.name, AudioNon,
+ sizeof dip->un.e.member[1].label.name);
+ dip->un.e.member[1].ord = 1;
+ return (0);
+
case I2S_INPUT_SELECT:
dip->mixer_class = I2S_RECORD_CLASS;
strlcpy(dip->label.name, AudioNsource, sizeof(dip->label.name));
@@ -1086,7 +1128,8 @@ i2s_cint(v)
if (((sense & 0x02) >> 1) == headphone_detect_active) {
DPRINTF(("headphone is inserted\n"));
sc->sc_output_mask |= 1 << 1;
- i2s_mute_headphone(sc, 0);
+ if (!sc->sc_mute)
+ i2s_mute_headphone(sc, 0);
} else {
DPRINTF(("headphone is NOT inserted\n"));
}
@@ -1100,14 +1143,16 @@ i2s_cint(v)
if (((sense & 0x02) >> 1) == lineout_detect_active) {
DPRINTF(("lineout is inserted\n"));
sc->sc_output_mask |= 1 << 2;
- i2s_mute_lineout(sc, 0);
+ if (!sc->sc_mute)
+ i2s_mute_lineout(sc, 0);
} else {
DPRINTF(("lineout is NOT inserted\n"));
}
if (sc->sc_output_mask == 0) {
sc->sc_output_mask |= 1 << 0;
- i2s_mute_speaker(sc, 0);
+ if (!sc->sc_mute)
+ i2s_mute_speaker(sc, 0);
}
return 1;
Index: dev/i2svar.h
===================================================================
RCS file: /cvs/src/sys/arch/macppc/dev/i2svar.h,v
retrieving revision 1.6
diff -u -p -r1.6 i2svar.h
--- dev/i2svar.h 26 Feb 2010 21:53:43 -0000 1.6
+++ dev/i2svar.h 5 May 2011 14:00:23 -0000
@@ -70,6 +70,7 @@ struct i2s_softc {
u_int sc_vol_r;
u_int sc_bass;
u_int sc_treble;
+ u_int sc_mute;
bus_dma_tag_t sc_dmat;
dbdma_regmap_t *sc_odma;