diff options
author | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2011-05-05 18:54:24 +0000 |
---|---|---|
committer | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2011-05-05 18:54:24 +0000 |
commit | 32503b13d206ec26e16ef34fc47207f337d5a6db (patch) | |
tree | d199ed4d9407ebb12878169f89c25e2c0698f33f /sys/arch | |
parent | bdf87b739d23476f67a5c97ad91de8a96a704f60 (diff) |
add support for muting the master channel on i2s based cards, this allows the
"mute" key on keyboards to function too.
tested by kettenis on aoa(4) and snapper(4) by me.
from Martin Pieuchot
ok kettenis@ ratchov@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/macppc/dev/i2s.c | 67 | ||||
-rw-r--r-- | sys/arch/macppc/dev/i2svar.h | 3 |
2 files changed, 58 insertions, 12 deletions
diff --git a/sys/arch/macppc/dev/i2s.c b/sys/arch/macppc/dev/i2s.c index 6797d702743..3d0727fee02 100644 --- a/sys/arch/macppc/dev/i2s.c +++ b/sys/arch/macppc/dev/i2s.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i2s.c,v 1.19 2011/05/04 15:50:49 jasper Exp $ */ +/* $OpenBSD: i2s.c,v 1.20 2011/05/05 18:54:23 jasper Exp $ */ /* $NetBSD: i2s.c,v 1.1 2003/12/27 02:19:34 grant Exp $ */ /*- @@ -155,6 +155,7 @@ i2s_attach(struct device *parent, struct i2s_softc *sc, struct confargs *ca) 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_t *dip) 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; diff --git a/sys/arch/macppc/dev/i2svar.h b/sys/arch/macppc/dev/i2svar.h index a27e6a34fda..ff4dc25b909 100644 --- a/sys/arch/macppc/dev/i2svar.h +++ b/sys/arch/macppc/dev/i2svar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i2svar.h,v 1.6 2010/02/26 21:53:43 jasper Exp $ */ +/* $OpenBSD: i2svar.h,v 1.7 2011/05/05 18:54:23 jasper Exp $ */ /*- * Copyright (c) 2001,2003 Tsubai Masanari. All rights reserved. @@ -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; |