From f8f1becfa4ac3231da55de68698cf7facf089646 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 6 Feb 2014 18:14:03 +0100 Subject: [PATCH 1/6] ALSA: hda - Fix leftover ifdef checks after modularization Since the commit [595fe1b702c3: ALSA: hda - Make CONFIG_SND_HDA_CODEC_* tristate], the kconfig variables for the generic parser and codec drivers can be "m" instead of boolean, but some codes are left unchanged to check only #ifdef CONFIG_SND_HDA_CODEC_XXX, which is no longer true for modules. This patch fixes them by replacing with IS_ENABLED() macros. Fixes: 595fe1b702c3 ('ALSA: hda - Make CONFIG_SND_HDA_CODEC_* tristate') Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=70161 Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 6 +++--- sound/pci/hda/hda_intel.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ec4536c8d8d4..69acbf758bbb 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -932,7 +932,7 @@ int snd_hda_bus_new(struct snd_card *card, } EXPORT_SYMBOL_GPL(snd_hda_bus_new); -#ifdef CONFIG_SND_HDA_GENERIC +#if IS_ENABLED(CONFIG_SND_HDA_GENERIC) #define is_generic_config(codec) \ (codec->modelname && !strcmp(codec->modelname, "generic")) #else @@ -1570,7 +1570,7 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec) EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets); -#ifdef CONFIG_SND_HDA_CODEC_HDMI +#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) /* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */ static bool is_likely_hdmi_codec(struct hda_codec *codec) { @@ -1622,7 +1622,7 @@ int snd_hda_codec_configure(struct hda_codec *codec) unload_parser(codec); /* to be sure */ if (is_likely_hdmi_codec(codec)) patch = load_parser(codec, snd_hda_parse_hdmi_codec); -#ifdef CONFIG_SND_HDA_GENERIC +#if IS_ENABLED(CONFIG_SND_HDA_GENERIC) if (!patch) patch = load_parser(codec, snd_hda_parse_generic_codec); #endif diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fa2879a21a50..e354ab1ec20f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -198,7 +198,7 @@ MODULE_DESCRIPTION("Intel HDA driver"); #endif #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO) -#ifdef CONFIG_SND_HDA_CODEC_HDMI +#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) #define SUPPORT_VGA_SWITCHEROO #endif #endif From 7fe307117db5bd7ec6efb93c563dcf44577b6d2b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Jan 2014 17:59:02 +0100 Subject: [PATCH 2/6] ALSA: hda - Fix inconsistent Mic mute LED The current code for controlling mic mute LED in patch_sigmatel.c blindly assumes that there is a single capture switch. But, there can be multiple multiple ones, and each of them flips the state, ended up in an inconsistent state. For fixing this problem, this patch adds kcontrol to be passed to the hook function so that the callee can check which switch is being accessed. In stac_capture_led_hook(), the state is checked as a bitmask, and turns on the LED when all capture switches are off. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 8 ++++---- sound/pci/hda/hda_generic.h | 1 + sound/pci/hda/patch_conexant.c | 3 ++- sound/pci/hda/patch_realtek.c | 9 ++++++--- sound/pci/hda/patch_sigmatel.c | 27 +++++++++++++++++---------- sound/pci/hda/thinkpad_helper.c | 1 + 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 8321a97d5c05..d9a09bdd09db 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -3269,7 +3269,7 @@ static int cap_put_caller(struct snd_kcontrol *kcontrol, mutex_unlock(&codec->control_mutex); snd_hda_codec_flush_cache(codec); /* flush the updates */ if (err >= 0 && spec->cap_sync_hook) - spec->cap_sync_hook(codec, ucontrol); + spec->cap_sync_hook(codec, kcontrol, ucontrol); return err; } @@ -3390,7 +3390,7 @@ static int cap_single_sw_put(struct snd_kcontrol *kcontrol, return ret; if (spec->cap_sync_hook) - spec->cap_sync_hook(codec, ucontrol); + spec->cap_sync_hook(codec, kcontrol, ucontrol); return ret; } @@ -3795,7 +3795,7 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx, return 0; snd_hda_activate_path(codec, path, true, false); if (spec->cap_sync_hook) - spec->cap_sync_hook(codec, NULL); + spec->cap_sync_hook(codec, NULL, NULL); path_power_down_sync(codec, old_path); return 1; } @@ -5270,7 +5270,7 @@ static void init_input_src(struct hda_codec *codec) } if (spec->cap_sync_hook) - spec->cap_sync_hook(codec, NULL); + spec->cap_sync_hook(codec, NULL, NULL); } /* set right pin controls for digital I/O */ diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 07f767231c9f..c908afbe4d94 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -274,6 +274,7 @@ struct hda_gen_spec { void (*init_hook)(struct hda_codec *codec); void (*automute_hook)(struct hda_codec *codec); void (*cap_sync_hook)(struct hda_codec *codec, + struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); /* PCM hooks */ diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 4e0ec146553d..bcf91bea3317 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3291,7 +3291,8 @@ static void cxt_update_headset_mode(struct hda_codec *codec) } static void cxt_update_headset_mode_hook(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { cxt_update_headset_mode(codec); } diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d9693ca9546f..f363238668b7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -708,7 +708,8 @@ static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) } static void alc_inv_dmic_hook(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { alc_inv_dmic_sync(codec, false); } @@ -3218,7 +3219,8 @@ static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) /* turn on/off mic-mute LED per capture hook */ static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct alc_spec *spec = codec->spec; unsigned int oldval = spec->gpio_led; @@ -3528,7 +3530,8 @@ static void alc_update_headset_mode(struct hda_codec *codec) } static void alc_update_headset_mode_hook(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { alc_update_headset_mode(codec); } diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6998cf29b9bc..7311badf6a94 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -194,7 +194,7 @@ struct sigmatel_spec { int default_polarity; unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */ - bool mic_mute_led_on; /* current mic mute state */ + unsigned int mic_enabled; /* current mic mute state (bitmask) */ /* stream */ unsigned int stream_delay; @@ -324,19 +324,26 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, /* hook for controlling mic-mute LED GPIO */ static void stac_capture_led_hook(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct sigmatel_spec *spec = codec->spec; - bool mute; + unsigned int mask; + bool cur_mute, prev_mute; - if (!ucontrol) + if (!kcontrol || !ucontrol) return; - mute = !(ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]); - if (spec->mic_mute_led_on != mute) { - spec->mic_mute_led_on = mute; - if (mute) + mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + prev_mute = !spec->mic_enabled; + if (ucontrol->value.integer.value[0] || + ucontrol->value.integer.value[1]) + spec->mic_enabled |= mask; + else + spec->mic_enabled &= ~mask; + cur_mute = !spec->mic_enabled; + if (cur_mute != prev_mute) { + if (cur_mute) spec->gpio_data |= spec->mic_mute_led_gpio; else spec->gpio_data &= ~spec->mic_mute_led_gpio; @@ -4462,7 +4469,7 @@ static void stac_setup_gpio(struct hda_codec *codec) if (spec->mic_mute_led_gpio) { spec->gpio_mask |= spec->mic_mute_led_gpio; spec->gpio_dir |= spec->mic_mute_led_gpio; - spec->mic_mute_led_on = true; + spec->mic_enabled = 0; spec->gpio_data |= spec->mic_mute_led_gpio; spec->gen.cap_sync_hook = stac_capture_led_hook; diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c index 5799fbc24c28..8fe3b8c18ed4 100644 --- a/sound/pci/hda/thinkpad_helper.c +++ b/sound/pci/hda/thinkpad_helper.c @@ -39,6 +39,7 @@ static void update_tpacpi_mute_led(void *private_data, int enabled) } static void update_tpacpi_micmute_led(struct hda_codec *codec, + struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { if (!ucontrol || !led_set_func) From f47e5dc464251f661da9495fcbf003a0d22c1360 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Fri, 7 Feb 2014 11:00:16 +0100 Subject: [PATCH 3/6] ALSA: hda - Add a headset quirk for Dell XPS 13 This quirk is needed for the headset microphone to work. Alsa-info at http://www.alsa-project.org/db/?f=8c7dfe857ceff462ca2de133e67023c0f68de9cb Cc: stable@vger.kernel.org (3.10+) Reported-by: Po-Hsu Lin Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f363238668b7..1266f18ce352 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5109,6 +5109,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), From f88abaa0d0dc0d1f1a9ae21f8e822918e5aadfdf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 7 Feb 2014 12:07:59 +0100 Subject: [PATCH 4/6] ALSA: hda - Fix mic capture on Sony VAIO Pro 11 The very same fixup is needed to make the mic on Sony VAIO Pro 11 working as well as VAIO Pro 13 model. Reported-and-tested-by: Hendrik-Jan Heins Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1266f18ce352..0ab0b9e05967 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4332,6 +4332,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), + SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), From ef8e39b51f24c8ac907e1f1995910ee3083375e0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 10 Feb 2014 11:43:41 +0100 Subject: [PATCH 5/6] ALSA: hda - Fix undefined symbol due to builtin/module mixup Even after the fix for leftover kconfig handling (commit f8f1becf), the current code still doesn't handle properly the builtin/module mixup case between the core snd-hda-codec and other codec drivers. For example, when CONFIG_SND_HDA_INTEL=y and CONFIG_SND_HDA_CODEC_HDMI=m, it'll end up with an unresolved symbol snd_hda_parse_hdmi_codec. This patch fixes the issue. Now codec->parser points to the parser object *only* when a module (either generic or HDMI parser) is loaded and bound. When a builtin symbol is used, codec->parser still points to NULL. This is the difference from the previous versions. Fixes: f8f1becfa4ac ('ALSA: hda - Fix leftover ifdef checks after modularization') Reported-by: Fengguang Wu Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 69acbf758bbb..dafcf82139e2 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1339,23 +1339,15 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid) /* * Dynamic symbol binding for the codec parsers */ -#ifdef MODULE -#define load_parser_sym(sym) ((int (*)(struct hda_codec *))symbol_request(sym)) -#define unload_parser_addr(addr) symbol_put_addr(addr) -#else -#define load_parser_sym(sym) (sym) -#define unload_parser_addr(addr) do {} while (0) -#endif #define load_parser(codec, sym) \ - ((codec)->parser = load_parser_sym(sym)) + ((codec)->parser = (int (*)(struct hda_codec *))symbol_request(sym)) static void unload_parser(struct hda_codec *codec) { - if (codec->parser) { - unload_parser_addr(codec->parser); - codec->parser = NULL; - } + if (codec->parser) + symbol_put_addr(codec->parser); + codec->parser = NULL; } /* @@ -1620,12 +1612,20 @@ int snd_hda_codec_configure(struct hda_codec *codec) patch = codec->preset->patch; if (!patch) { unload_parser(codec); /* to be sure */ - if (is_likely_hdmi_codec(codec)) + if (is_likely_hdmi_codec(codec)) { +#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI) patch = load_parser(codec, snd_hda_parse_hdmi_codec); -#if IS_ENABLED(CONFIG_SND_HDA_GENERIC) - if (!patch) - patch = load_parser(codec, snd_hda_parse_generic_codec); +#elif IS_BUILTIN(CONFIG_SND_HDA_CODEC_HDMI) + patch = snd_hda_parse_hdmi_codec; #endif + } + if (!patch) { +#if IS_MODULE(CONFIG_SND_HDA_GENERIC) + patch = load_parser(codec, snd_hda_parse_generic_codec); +#elif IS_BUILTIN(CONFIG_SND_HDA_GENERIC) + patch = snd_hda_parse_generic_codec; +#endif + } if (!patch) { printk(KERN_ERR "hda-codec: No codec parser is available\n"); return -ENODEV; From 2078600b1f8fc68b02f6ebdda1759fb0c9f51afb Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Wed, 12 Feb 2014 17:09:23 +0100 Subject: [PATCH 6/6] ALSA: Revert "ALSA: hda/realtek - Avoid invalid COEFs for ALC271X" This reverts commit d3c56568f43807135f2c2a09582a69f809f0d8b7. The reverted commit breaks audio through headphone line out on the Acer TravelMate B113 (Type1Sku0) Notebook, my main work machine. I don't know much about it but this fixes my problem. Bisected and tested. Fixes: d3c56568f438 ('ALSA: hda/realtek - Avoid invalid COEFs for ALC271X') Cc: Tested-by: Martin Kepplinger Signed-off-by: Martin Kepplinger Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0ab0b9e05967..a9a83b85517a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4438,9 +4438,6 @@ static void alc269_fill_coef(struct hda_codec *codec) if (spec->codec_variant != ALC269_TYPE_ALC269VB) return; - /* ALC271X doesn't seem to support these COEFs (bko#52181) */ - if (!strcmp(codec->chip_name, "ALC271X")) - return; if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { alc_write_coef_idx(codec, 0xf, 0x960b);