Some conexant devices has no mute capability on their Beep widgets. This patch makes sure we don't try setting mutes on those widgets.
Signed-off-by: David Henningsson david.henningsson@canonical.com ---
Another Beep fix. It's not that I'm suddenly obsessed with beeping; it's my automated test tool that finds them :-)
I admit "knew->info == snd_hda_mixer_amp_switch_info" and "kctl->private_value = 0x10000" looks a bit hacky, feel free to suggest something more elegant if you wish.
Example alsa info: codecs/canonical/cx20590-lenovo-thinkpad-t420-ccert-201102-7230
sound/pci/hda/hda_beep.c | 6 ++++-- sound/pci/hda/patch_conexant.c | 8 +++++++- 2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index d26ae65..3a72543 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -237,9 +237,9 @@ int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_beep *beep = codec->beep; - if (beep && !beep->enabled) { + if (beep && (!get_amp_nid(kcontrol) || !beep->enabled)) { ucontrol->value.integer.value[0] = - ucontrol->value.integer.value[1] = 0; + ucontrol->value.integer.value[1] = beep->enabled; return 0; } return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); @@ -263,6 +263,8 @@ int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, enable |= *valp; snd_hda_enable_beep_device(codec, enable); } + if (!get_amp_nid(kcontrol)) + return 0; return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); } EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5e22a8f..fa36c5e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -537,12 +537,18 @@ static int conexant_build_controls(struct hda_codec *codec) /* create beep controls if needed */ if (spec->beep_amp) { const struct snd_kcontrol_new *knew; + unsigned int caps; + caps = snd_hda_param_read(codec, spec->beep_amp, AC_PAR_AMP_OUT_CAP); + for (knew = cxt_beep_mixer; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); if (!kctl) return -ENOMEM; - kctl->private_value = spec->beep_amp; + if (knew->info == snd_hda_mixer_amp_switch_info && !(caps & AC_AMPCAP_MUTE)) + kctl->private_value = 0x10000; /* Mono channel, no nid */ + else + kctl->private_value = spec->beep_amp; err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err;