diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2008-11-28 04:03:38 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2008-11-28 04:03:38 +0000 |
commit | 82cc23ac6fc632abcbbaca9ee7cc764b5bab0542 (patch) | |
tree | a955191584fd3c99de8f4eaa2f759e38f8022bf6 /sys/dev/pci/azalia_codec.c | |
parent | b409ba887aaa9a3fe1a8233e858854db76bf9b75 (diff) |
- use switch() instead of multiple if else
- put selectors that feed ADCs into the record class like we do for
mixers
- use azalia_nid_to_index more
- shrink mixer items list by condensing mutes for multiple input
sources into a single _source control of type AUDIO_MIXER_SET.
for example,
record.mix6_mic_mute=off
record.mix6_mic2_mute=off
record.mix6_line_mute=off
record.mix6_hp_mute=off
record.mix6_spkr_mute=off
record.mix6_mix_mute=off
is now represented as
record.mix6_source=mic,mic2,line,hp,spkr,mix
to mute all sources but the mic just do
record.mix6_source=mic
reduces mixer items by about 25% on my machine. also shortens the
longest names.
Diffstat (limited to 'sys/dev/pci/azalia_codec.c')
-rw-r--r-- | sys/dev/pci/azalia_codec.c | 217 |
1 files changed, 162 insertions, 55 deletions
diff --git a/sys/dev/pci/azalia_codec.c b/sys/dev/pci/azalia_codec.c index 8c0013b377f..7767111f4cc 100644 --- a/sys/dev/pci/azalia_codec.c +++ b/sys/dev/pci/azalia_codec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia_codec.c,v 1.71 2008/11/28 03:27:11 jakemsr Exp $ */ +/* $OpenBSD: azalia_codec.c,v 1.72 2008/11/28 04:03:37 jakemsr Exp $ */ /* $NetBSD: azalia_codec.c,v 1.8 2006/05/10 11:17:27 kent Exp $ */ /*- @@ -554,25 +554,32 @@ azalia_generic_mixer_init(codec_t *this) snprintf(d->label.name, sizeof(d->label.name), "%s_source", w->name); d->type = AUDIO_MIXER_ENUM; - if (w->type == COP_AWTYPE_AUDIO_MIXER) + switch (w->type) { + case COP_AWTYPE_AUDIO_INPUT: d->mixer_class = AZ_CLASS_RECORD; - else if (w->type == COP_AWTYPE_AUDIO_SELECTOR) + break; + case COP_AWTYPE_AUDIO_SELECTOR: d->mixer_class = AZ_CLASS_INPUT; - else + break; + default: d->mixer_class = AZ_CLASS_OUTPUT; + break; + } + for (j = 0; j < naconns; j++) { + if (aconns[j] == w->nid) { + d->mixer_class = AZ_CLASS_RECORD; + break; + } + } m->target = MI_TARGET_CONNLIST; for (j = 0, k = 0; j < w->nconnections && k < 32; j++) { - const widget_t *ww; - - if (!VALID_WIDGET_NID(w->connections[j], this)) - continue; - ww = &this->w[w->connections[j]]; - if (!ww->enable) + l = azalia_nid_to_index(this, + w->connections[j]); + if (l == -1) continue; d->un.e.member[k].ord = j; strlcpy(d->un.e.member[k].label.name, - this->w[w->connections[j]].name, - MAX_AUDIO_DEV_LEN); + this->w[l].name, MAX_AUDIO_DEV_LEN); k++; } d->un.e.num_mem = k; @@ -647,41 +654,35 @@ azalia_generic_mixer_init(codec_t *this) AudioNon, MAX_AUDIO_DEV_LEN); this->nmixers++; } else { - for (j = 0; j < w->nconnections; j++) { - const widget_t *ww; - - MIXER_REG_PROLOG; - if (!VALID_WIDGET_NID(w->connections[j], - this)) - continue; - ww = &this->w[w->connections[j]]; - if (!ww->enable) - continue; - snprintf(d->label.name, sizeof(d->label.name), - "%s_%s_mute", w->name, - this->w[w->connections[j]].name); - d->type = AUDIO_MIXER_ENUM; - if (w->type == COP_AWTYPE_AUDIO_INPUT) - d->mixer_class = AZ_CLASS_RECORD; - else - d->mixer_class = AZ_CLASS_INPUT; - for (k = 0; k < naconns; k++) { - if (aconns[k] == w->nid) { - d->mixer_class = - AZ_CLASS_RECORD; - break; - } + MIXER_REG_PROLOG; + snprintf(d->label.name, sizeof(d->label.name), + "%s_source", w->name); + m->target = MI_TARGET_MUTESET; + d->type = AUDIO_MIXER_SET; + if (w->type == COP_AWTYPE_AUDIO_INPUT) + d->mixer_class = AZ_CLASS_RECORD; + else + d->mixer_class = AZ_CLASS_INPUT; + for (j = 0; j < naconns; j++) { + if (aconns[j] == w->nid) { + d->mixer_class = + AZ_CLASS_RECORD; + break; } - m->target = j; - d->un.e.num_mem = 2; - d->un.e.member[0].ord = 0; - strlcpy(d->un.e.member[0].label.name, - AudioNoff, MAX_AUDIO_DEV_LEN); - d->un.e.member[1].ord = 1; - strlcpy(d->un.e.member[1].label.name, - AudioNon, MAX_AUDIO_DEV_LEN); - this->nmixers++; } + for (j = 0, l = 0; + j < w->nconnections && l < 32; j++) { + k = azalia_nid_to_index(this, + w->connections[j]); + if (k == -1) + continue; + d->un.s.member[l].mask = 1 << j; + strlcpy(d->un.s.member[l].label.name, + this->w[k].name, MAX_AUDIO_DEV_LEN); + l++; + } + d->un.s.num_mem = l; + this->nmixers++; } } @@ -934,28 +935,27 @@ azalia_generic_mixer_fix_indexes(codec_t *this) int azalia_generic_mixer_default(codec_t *this) { - int i; + widget_t *w; mixer_item_t *m; + mixer_ctrl_t mc; + int i, j, k; + /* unmute all */ for (i = 0; i < this->nmixers; i++) { - mixer_ctrl_t mc; - m = &this->mixers[i]; if (!IS_MI_TARGET_INAMP(m->target) && m->target != MI_TARGET_OUTAMP) continue; if (m->devinfo.type != AUDIO_MIXER_ENUM) continue; + bzero(&mc, sizeof(mc)); mc.dev = i; mc.type = AUDIO_MIXER_ENUM; - mc.un.ord = 0; azalia_generic_mixer_set(this, m->nid, m->target, &mc); } /* set unextreme volume */ for (i = 0; i < this->nmixers; i++) { - mixer_ctrl_t mc; - m = &this->mixers[i]; if (!IS_MI_TARGET_INAMP(m->target) && m->target != MI_TARGET_OUTAMP && @@ -963,6 +963,7 @@ azalia_generic_mixer_default(codec_t *this) continue; if (m->devinfo.type != AUDIO_MIXER_VALUE) continue; + bzero(&mc, sizeof(mc)); mc.dev = i; mc.type = AUDIO_MIXER_VALUE; mc.un.value.num_channels = 1; @@ -975,6 +976,31 @@ azalia_generic_mixer_default(codec_t *this) azalia_generic_mixer_set(this, m->nid, m->target, &mc); } + /* unmute all */ + for (i = 0; i < this->nmixers; i++) { + m = &this->mixers[i]; + if (m->target != MI_TARGET_MUTESET) + continue; + if (m->devinfo.type != AUDIO_MIXER_SET) + continue; + bzero(&mc, sizeof(mc)); + mc.dev = i; + mc.type = AUDIO_MIXER_SET; + j = azalia_nid_to_index(this, m->nid); + if (j == -1) { + DPRINTF(("%s: invalid muteset nid\n", __func__)); + return EINVAL; + } + w = &this->w[j]; + for (j = 0; j < w->nconnections; j++) { + k = azalia_nid_to_index(this, w->connections[j]); + if (k == -1) + continue; + mc.un.mask |= 1 << j; + } + azalia_generic_mixer_set(this, m->nid, m->target, &mc); + } + return 0; } @@ -1097,11 +1123,12 @@ azalia_generic_mixer_delete(codec_t *this) * @param mc mc->type must be set by the caller before the call */ int -azalia_generic_mixer_get(const codec_t *this, nid_t nid, int target, mixer_ctrl_t *mc) +azalia_generic_mixer_get(const codec_t *this, nid_t nid, int target, + mixer_ctrl_t *mc) { uint32_t result; nid_t n; - int err; + int i, j, err; /* inamp mute */ if (IS_MI_TARGET_INAMP(target) && mc->type == AUDIO_MIXER_ENUM) { @@ -1263,6 +1290,31 @@ azalia_generic_mixer_get(const codec_t *this, nid_t nid, int target, mixer_ctrl_ mc->un.ord = result & CORB_PS_PRESENCE ? 1 : 0; } + /* mute set */ + else if (target == MI_TARGET_MUTESET && mc->type == AUDIO_MIXER_SET) { + const widget_t *w; + + i = azalia_nid_to_index(this, nid); + if (i == -1) { + DPRINTF(("%s: invalid muteset nid\n")); + return EINVAL; + } + w = &this->w[i]; + mc->un.mask = 0; + for (i = 0; i < w->nconnections; i++) { + j = azalia_nid_to_index(this, w->connections[i]); + if (j == -1) + continue; + err = this->comresp(this, nid, + CORB_GET_AMPLIFIER_GAIN_MUTE, + CORB_GAGM_INPUT | CORB_GAGM_LEFT | + MI_TARGET_INAMP(i), &result); + if (err) + return err; + mc->un.mask |= (result & CORB_GAGM_MUTE) ? 0 : (1 << i); + } + } + else { printf("%s: internal error in %s: target=%x\n", XNAME(this), __func__, target); @@ -1272,10 +1324,11 @@ azalia_generic_mixer_get(const codec_t *this, nid_t nid, int target, mixer_ctrl_ } int -azalia_generic_mixer_set(codec_t *this, nid_t nid, int target, const mixer_ctrl_t *mc) +azalia_generic_mixer_set(codec_t *this, nid_t nid, int target, + const mixer_ctrl_t *mc) { uint32_t result, value; - int err; + int i, j, err; /* inamp mute */ if (IS_MI_TARGET_INAMP(target) && mc->type == AUDIO_MIXER_ENUM) { @@ -1548,6 +1601,60 @@ azalia_generic_mixer_set(codec_t *this, nid_t nid, int target, const mixer_ctrl_ /* do nothing, control is read only */ } + else if (target == MI_TARGET_MUTESET && mc->type == AUDIO_MIXER_SET) { + const widget_t *w; + + i = azalia_nid_to_index(this, nid); + if (i == -1) { + DPRINTF(("%s: invalid muteset nid\n")); + return EINVAL; + } + w = &this->w[i]; + for (i = 0; i < w->nconnections; i++) { + j = azalia_nid_to_index(this, w->connections[i]); + if (j == -1) + continue; + + /* We have to set stereo mute separately + * to keep each gain value. + */ + err = this->comresp(this, nid, + CORB_GET_AMPLIFIER_GAIN_MUTE, + CORB_GAGM_INPUT | CORB_GAGM_LEFT | + MI_TARGET_INAMP(i), &result); + if (err) + return err; + value = CORB_AGM_INPUT | CORB_AGM_LEFT | + (i << CORB_AGM_INDEX_SHIFT) | + CORB_GAGM_GAIN(result); + if ((mc->un.mask & (1 << i)) == 0) + value |= CORB_AGM_MUTE; + err = this->comresp(this, nid, + CORB_SET_AMPLIFIER_GAIN_MUTE, value, &result); + if (err) + return err; + + if (WIDGET_CHANNELS(w) == 2) { + err = this->comresp(this, nid, + CORB_GET_AMPLIFIER_GAIN_MUTE, + CORB_GAGM_INPUT | CORB_GAGM_RIGHT | + MI_TARGET_INAMP(i), &result); + if (err) + return err; + value = CORB_AGM_INPUT | CORB_AGM_RIGHT | + (i << CORB_AGM_INDEX_SHIFT) | + CORB_GAGM_GAIN(result); + if ((mc->un.mask & (1 << i)) == 0) + value |= CORB_AGM_MUTE; + err = this->comresp(this, nid, + CORB_SET_AMPLIFIER_GAIN_MUTE, + value, &result); + if (err) + return err; + } + } + } + else { printf("%s: internal error in %s: target=%x\n", XNAME(this), __func__, target); |