From 4ad7935df6a566225c3d51900bde8f2f0f8b6de3 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 28 May 2021 21:51:23 +0300 Subject: [PATCH 1/7] ALSA: hda: Add AlderLake-M PCI ID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add HD Audio PCI ID for Intel AlderLake-M. Add rules to snd_intel_dsp_find_config() to choose SOF driver for ADL-M systems with PCH-DMIC or Soundwire codecs, and legacy driver for the rest. Signed-off-by: Kai Vehmanen Reviewed-by: Péter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210528185123.48332-1-kai.vehmanen@linux.intel.com Signed-off-by: Takashi Iwai --- sound/hda/intel-dsp-config.c | 4 ++++ sound/pci/hda/hda_intel.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c index ab5ff7867eb99..d8be146793eee 100644 --- a/sound/hda/intel-dsp-config.c +++ b/sound/hda/intel-dsp-config.c @@ -331,6 +331,10 @@ static const struct config_entry config_table[] = { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, .device = 0x51c8, }, + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = 0x51cc, + }, #endif }; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 79ade335c8a09..470753b36c8a1 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2485,6 +2485,9 @@ static const struct pci_device_id azx_ids[] = { /* Alderlake-P */ { PCI_DEVICE(0x8086, 0x51c8), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, + /* Alderlake-M */ + { PCI_DEVICE(0x8086, 0x51cc), + .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, /* Elkhart Lake */ { PCI_DEVICE(0x8086, 0x4b55), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, From 08a4b904a2a90246aadd6aa2e4f26abca9037385 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 31 May 2021 20:06:33 +0200 Subject: [PATCH 2/7] ALSA: hda: Fix a regression in Capture Switch mixer read The recent commit to drop the HDA-specific mute-LED control, e65bf99718b5 ("ALSA: HDA - remove the custom implementation for the audio LED trigger"), caused a regression on the mixer element read for "Capture Switch" when it's built from bind controls. The function create_bind_cap_vol_ctl() creates the snd_kcontrol_new object directly via snd_hda_gen_add_kctl() instead of add_control(). Although the commit above added a workaround for the SNDRV_CTL_ACCESS_READWRITE in add_control() as default, this code path fell out from the radar. As a result, now the driver gives -EPERM error because of the lack of the proper access bit at reading "Capture Switch" element value. Fix the regression by setting the access bit properly. Fixes: e65bf99718b5 ("ALSA: HDA - remove the custom implementation for the audio LED trigger") BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1186634 Link: https://lore.kernel.org/r/20210531180633.27831-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index b638fc2ef6f72..1f8018f9ce57a 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -3520,6 +3520,7 @@ static int cap_sw_put(struct snd_kcontrol *kcontrol, static const struct snd_kcontrol_new cap_sw_temp = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Switch", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .info = cap_sw_info, .get = cap_sw_get, .put = cap_sw_put, From 527ff9550682a3d08066a000435ffd8330bdd729 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Mon, 31 May 2021 17:37:54 +0100 Subject: [PATCH 3/7] ALSA: hda/cirrus: Set Initial DMIC volume to -26 dB Previously this fix was applied only to Bullseye variant laptops, and should be applied to Cyborg and Warlock variants. Fixes: 45b14fe200ba ("ALSA: hda/cirrus: Use CS8409 filter to fix abnormal sounds on Bullseye") Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20210531163754.136736-1-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_cirrus.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 726507d0b04ce..8629e84fef23d 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -2206,10 +2206,9 @@ static void cs8409_cs42l42_fixups(struct hda_codec *codec, break; case HDA_FIXUP_ACT_PROBE: - /* Set initial volume on Bullseye to -26 dB */ - if (codec->fixup_id == CS8409_BULLSEYE) - snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, - HDA_INPUT, 0, 0xff, 0x19); + /* Set initial DMIC volume to -26 dB */ + snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, + HDA_INPUT, 0, 0xff, 0x19); snd_hda_gen_add_kctl(&spec->gen, NULL, &cs8409_cs42l42_hp_volume_mixer); snd_hda_gen_add_kctl(&spec->gen, From 901be145a46eb79879367d853194346a549e623d Mon Sep 17 00:00:00 2001 From: Carlos M Date: Mon, 31 May 2021 22:20:26 +0200 Subject: [PATCH 4/7] ALSA: hda: Fix for mute key LED for HP Pavilion 15-CK0xx For the HP Pavilion 15-CK0xx, with audio subsystem ID 0x103c:0x841c, adding a line in patch_realtek.c to apply the ALC269_FIXUP_HP_MUTE_LED_MIC3 fix activates the mute key LED. Signed-off-by: Carlos M Cc: Link: https://lore.kernel.org/r/20210531202026.35427-1-carlos.marr.pz@gmail.com 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 61a60c420f6fd..43e37145eb5d9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8303,6 +8303,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x841c, "HP Pavilion 15-CK0xx", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN), SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), From 3ae72f6ab9c1f688bd578cdc252dabce65fdaf57 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Wed, 2 Jun 2021 11:41:36 +0800 Subject: [PATCH 5/7] ALSA: control led: fix memory leak in snd_ctl_led_register The snd_ctl_led_sysfs_add and snd_ctl_led_sysfs_remove should contain the refcount operations in pair. However, snd_ctl_led_sysfs_remove fails to decrease the refcount to zero, which causes device_release never to be invoked. This leads to memory leak to some resources, like struct device_private. In addition, we also free some other similar memory leaks in snd_ctl_led_init/snd_ctl_led_exit. Fix this by replacing device_del to device_unregister in snd_ctl_led_sysfs_remove/snd_ctl_led_init/snd_ctl_led_exit. Note that, when CONFIG_DEBUG_KOBJECT_RELEASE is enabled, put_device will call kobject_release and delay the release of kobject, which will cause use-after-free when the memory backing the kobject is freed at once. Reported-by: syzbot+08a7d8b51ea048a74ffb@syzkaller.appspotmail.com Fixes: a135dfb5de15 ("ALSA: led control - add sysfs kcontrol LED marking layer") Signed-off-by: Dongliang Mu Reviewed-by: Dan Carpenter Reviewed-by: Jaroslav Kysela Link: https://lore.kernel.org/r/20210602034136.2762497-1-mudongliangabcd@gmail.com Signed-off-by: Takashi Iwai --- sound/core/control_led.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/sound/core/control_led.c b/sound/core/control_led.c index 25f57c14f294f..a90e31dbde61f 100644 --- a/sound/core/control_led.c +++ b/sound/core/control_led.c @@ -17,6 +17,9 @@ MODULE_LICENSE("GPL"); #define MAX_LED (((SNDRV_CTL_ELEM_ACCESS_MIC_LED - SNDRV_CTL_ELEM_ACCESS_SPK_LED) \ >> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) + 1) +#define to_led_card_dev(_dev) \ + container_of(_dev, struct snd_ctl_led_card, dev) + enum snd_ctl_led_mode { MODE_FOLLOW_MUTE = 0, MODE_FOLLOW_ROUTE, @@ -371,6 +374,21 @@ static void snd_ctl_led_disconnect(struct snd_card *card) snd_ctl_led_refresh(); } +static void snd_ctl_led_card_release(struct device *dev) +{ + struct snd_ctl_led_card *led_card = to_led_card_dev(dev); + + kfree(led_card); +} + +static void snd_ctl_led_release(struct device *dev) +{ +} + +static void snd_ctl_led_dev_release(struct device *dev) +{ +} + /* * sysfs */ @@ -663,6 +681,7 @@ static void snd_ctl_led_sysfs_add(struct snd_card *card) led_card->number = card->number; led_card->led = led; device_initialize(&led_card->dev); + led_card->dev.release = snd_ctl_led_card_release; if (dev_set_name(&led_card->dev, "card%d", card->number) < 0) goto cerr; led_card->dev.parent = &led->dev; @@ -681,7 +700,6 @@ static void snd_ctl_led_sysfs_add(struct snd_card *card) put_device(&led_card->dev); cerr2: printk(KERN_ERR "snd_ctl_led: unable to add card%d", card->number); - kfree(led_card); } } @@ -700,8 +718,7 @@ static void snd_ctl_led_sysfs_remove(struct snd_card *card) snprintf(link_name, sizeof(link_name), "led-%s", led->name); sysfs_remove_link(&card->ctl_dev.kobj, link_name); sysfs_remove_link(&led_card->dev.kobj, "card"); - device_del(&led_card->dev); - kfree(led_card); + device_unregister(&led_card->dev); led->cards[card->number] = NULL; } } @@ -723,6 +740,7 @@ static int __init snd_ctl_led_init(void) device_initialize(&snd_ctl_led_dev); snd_ctl_led_dev.class = sound_class; + snd_ctl_led_dev.release = snd_ctl_led_dev_release; dev_set_name(&snd_ctl_led_dev, "ctl-led"); if (device_add(&snd_ctl_led_dev)) { put_device(&snd_ctl_led_dev); @@ -733,15 +751,16 @@ static int __init snd_ctl_led_init(void) INIT_LIST_HEAD(&led->controls); device_initialize(&led->dev); led->dev.parent = &snd_ctl_led_dev; + led->dev.release = snd_ctl_led_release; led->dev.groups = snd_ctl_led_dev_attr_groups; dev_set_name(&led->dev, led->name); if (device_add(&led->dev)) { put_device(&led->dev); for (; group > 0; group--) { led = &snd_ctl_leds[group - 1]; - device_del(&led->dev); + device_unregister(&led->dev); } - device_del(&snd_ctl_led_dev); + device_unregister(&snd_ctl_led_dev); return -ENOMEM; } } @@ -767,9 +786,9 @@ static void __exit snd_ctl_led_exit(void) } for (group = 0; group < MAX_LED; group++) { led = &snd_ctl_leds[group]; - device_del(&led->dev); + device_unregister(&led->dev); } - device_del(&snd_ctl_led_dev); + device_unregister(&snd_ctl_led_dev); snd_ctl_led_clean(NULL); } From 9c1fe96bded935369f8340c2ac2e9e189f697d5d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 2 Jun 2021 13:38:23 +0200 Subject: [PATCH 6/7] ALSA: timer: Fix master timer notification snd_timer_notify1() calls the notification to each slave for a master event, but it passes a wrong event number. It should be +10 offset, corresponding to SNDRV_TIMER_EVENT_MXXX, but it's incorrectly with +100 offset. Casually this was spotted by UBSAN check via syzkaller. Reported-by: syzbot+d102fa5b35335a7e544e@syzkaller.appspotmail.com Reviewed-by: Jaroslav Kysela Cc: Link: https://lore.kernel.org/r/000000000000e5560e05c3bd1d63@google.com Link: https://lore.kernel.org/r/20210602113823.23777-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 6898b1ac0d7f4..92b7008fcdb86 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -520,9 +520,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) return; if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) return; + event += 10; /* convert to SNDRV_TIMER_EVENT_MXXX */ list_for_each_entry(ts, &ti->slave_active_head, active_list) if (ts->ccallback) - ts->ccallback(ts, event + 100, &tstamp, resolution); + ts->ccallback(ts, event, &tstamp, resolution); } /* start/continue a master timer */ From b8b90c17602689eeaa5b219d104bbc215d1225cc Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Wed, 2 Jun 2021 22:54:24 +0800 Subject: [PATCH 7/7] ALSA: hda: update the power_state during the direct-complete The patch_realtek.c needs to check if the power_state.event equals PM_EVENT_SUSPEND, after using the direct-complete, the suspend() and resume() will be skipped if the codec is already rt_suspended, in this case, the patch_realtek.c will always get PM_EVENT_ON even the system is really resumed from S3. We could set power_state to PMSG_SUSPEND in the prepare(), if other PM functions are called before complete(), those functions will override power_state; if no other PM functions are called before complete(), we could know the suspend() and resume() are skipped since only S3 pm functions could be skipped by direct-complete, in this case set power_state to PMSG_RESUME in the complete(). This could guarantee the first time of calling hda_codec_runtime_resume() after complete() has the correct power_state. Fixes: 215a22ed31a1 ("ALSA: hda: Refactor codec PM to use direct-complete optimization") Cc: Signed-off-by: Hui Wang Link: https://lore.kernel.org/r/20210602145424.3132-1-hui.wang@canonical.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a31009afc025f..5462f771c2f90 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2917,6 +2917,7 @@ static int hda_codec_runtime_resume(struct device *dev) #ifdef CONFIG_PM_SLEEP static int hda_codec_pm_prepare(struct device *dev) { + dev->power.power_state = PMSG_SUSPEND; return pm_runtime_suspended(dev); } @@ -2924,6 +2925,10 @@ static void hda_codec_pm_complete(struct device *dev) { struct hda_codec *codec = dev_to_hda_codec(dev); + /* If no other pm-functions are called between prepare() and complete() */ + if (dev->power.power_state.event == PM_EVENT_SUSPEND) + dev->power.power_state = PMSG_RESUME; + if (pm_runtime_suspended(dev) && (codec->jackpoll_interval || hda_codec_need_resume(codec) || codec->forced_resume)) pm_request_resume(dev);