[alsa-devel] [PATCH v2 1/2] ALSA: hda - Add mic mute hotkey quirk for Lenovo ThinkCentre AIO
Takashi Iwai
tiwai at suse.de
Tue Dec 29 10:05:24 CET 2015
On Mon, 28 Dec 2015 04:35:24 +0100,
Hui Wang wrote:
>
> From: Kailang <kailang at realtek.com>
>
> The Lenovo ThinkCenter AIO uses Line2 (NID 0x1b) to implement the
> micmute hotkey, here we register an input device and use Line2 unsol
> event to collect the hotkey pressing or releasing.
>
> In the meanwhile, the micmute led is controlled by GPIO2, so we
> use an existing function alc_fixup_gpio_mic_mute_hook() to control
> the led.
>
> [Hui: And there are two places to register the input device, to make
> the code simple and clean, move the two same code sections into a
> function.]
>
> Cc: <stable at vger.kernel.org>
> Signed-off-by: Kailang <kailang at realtek.com>
> Signed-off-by: Hui Wang <hui.wang at canonical.com>
Applied both patch. Thanks.
Takashi
> ---
> sound/pci/hda/patch_realtek.c | 84 ++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 71 insertions(+), 13 deletions(-)
>
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index fe96428..257b839 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -3468,6 +3468,29 @@ static void gpio2_mic_hotkey_event(struct hda_codec *codec,
> input_sync(spec->kb_dev);
> }
>
> +static int alc_register_micmute_input_device(struct hda_codec *codec)
> +{
> + struct alc_spec *spec = codec->spec;
> +
> + spec->kb_dev = input_allocate_device();
> + if (!spec->kb_dev) {
> + codec_err(codec, "Out of memory (input_allocate_device)\n");
> + return -ENOMEM;
> + }
> + spec->kb_dev->name = "Microphone Mute Button";
> + spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
> + spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
> +
> + if (input_register_device(spec->kb_dev)) {
> + codec_err(codec, "input_register_device failed\n");
> + input_free_device(spec->kb_dev);
> + spec->kb_dev = NULL;
> + return -ENOMEM;
> + }
> +
> + return 0;
> +}
> +
> static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
> const struct hda_fixup *fix, int action)
> {
> @@ -3485,20 +3508,8 @@ static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
> struct alc_spec *spec = codec->spec;
>
> if (action == HDA_FIXUP_ACT_PRE_PROBE) {
> - spec->kb_dev = input_allocate_device();
> - if (!spec->kb_dev) {
> - codec_err(codec, "Out of memory (input_allocate_device)\n");
> + if (alc_register_micmute_input_device(codec) != 0)
> return;
> - }
> - spec->kb_dev->name = "Microphone Mute Button";
> - spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
> - spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
> - if (input_register_device(spec->kb_dev)) {
> - codec_err(codec, "input_register_device failed\n");
> - input_free_device(spec->kb_dev);
> - spec->kb_dev = NULL;
> - return;
> - }
>
> snd_hda_add_verbs(codec, gpio_init);
> snd_hda_codec_write_cache(codec, codec->core.afg, 0,
> @@ -3528,6 +3539,47 @@ static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
> }
> }
>
> +static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
> + const struct hda_fixup *fix, int action)
> +{
> + /* Line2 = mic mute hotkey
> + GPIO2 = mic mute LED */
> + static const struct hda_verb gpio_init[] = {
> + { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
> + { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
> + {}
> + };
> +
> + struct alc_spec *spec = codec->spec;
> +
> + if (action == HDA_FIXUP_ACT_PRE_PROBE) {
> + if (alc_register_micmute_input_device(codec) != 0)
> + return;
> +
> + snd_hda_add_verbs(codec, gpio_init);
> + snd_hda_jack_detect_enable_callback(codec, 0x1b,
> + gpio2_mic_hotkey_event);
> +
> + spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
> + spec->gpio_led = 0;
> + spec->mute_led_polarity = 0;
> + spec->gpio_mic_led_mask = 0x04;
> + return;
> + }
> +
> + if (!spec->kb_dev)
> + return;
> +
> + switch (action) {
> + case HDA_FIXUP_ACT_PROBE:
> + spec->init_amp = ALC_INIT_DEFAULT;
> + break;
> + case HDA_FIXUP_ACT_FREE:
> + input_unregister_device(spec->kb_dev);
> + spec->kb_dev = NULL;
> + }
> +}
> +
> static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
> const struct hda_fixup *fix, int action)
> {
> @@ -4628,6 +4680,7 @@ enum {
> ALC275_FIXUP_DELL_XPS,
> ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
> ALC293_FIXUP_LENOVO_SPK_NOISE,
> + ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
> };
>
> static const struct hda_fixup alc269_fixups[] = {
> @@ -5237,6 +5290,10 @@ static const struct hda_fixup alc269_fixups[] = {
> .chained = true,
> .chain_id = ALC269_FIXUP_THINKPAD_ACPI
> },
> + [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
> + .type = HDA_FIXUP_FUNC,
> + .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
> + },
> };
>
> static const struct snd_pci_quirk alc269_fixup_tbl[] = {
> @@ -5386,6 +5443,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
> SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
> SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
> SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
> + SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
> SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
> SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
> SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
> --
> 1.9.1
>
More information about the Alsa-devel
mailing list