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;