From 2f2020327cc8561d7c520d2f2d9acea84fa7b3a3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Tue, 26 Nov 2024 15:09:43 -0500 Subject: [PATCH 01/16] ASoC: mediatek: Check num_codecs is not zero to avoid panic during probe MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Following commit 13f58267cda3 ("ASoC: soc.h: don't create dummy Component via COMP_DUMMY()"), COMP_DUMMY() became an array with zero length, and only gets populated with the dummy struct after the card is registered. Since the sound card driver's probe happens before the card registration, accessing any of the members of a dummy component during probe will result in undefined behavior. This can be observed in the mt8188 and mt8195 machine sound drivers. By omitting a dai link subnode in the sound card's node in the Devicetree, the default uninitialized dummy codec is used, and when its dai_name pointer gets passed to strcmp() it results in a null pointer dereference and a kernel panic. In addition to that, set_card_codec_info() in the generic helpers file, mtk-soundcard-driver.c, will populate a dai link with a dummy codec when a dai link node is present in DT but with no codec property. The result is that at probe time, a dummy codec can either be uninitialized with num_codecs = 0, or be an initialized dummy codec, with num_codecs = 1 and dai_name = "snd-soc-dummy-dai". In order to accommodate for both situations, check that num_codecs is not zero before accessing the codecs' fields but still check for the codec's dai name against "snd-soc-dummy-dai" as needed. While at it, also drop the check that dai_name is not null in the mt8192 driver, introduced in commit 4d4e1b6319e5 ("ASoC: mediatek: mt8192: Check existence of dai_name before dereferencing"), as it is actually redundant given the preceding num_codecs != 0 check. Fixes: 13f58267cda3 ("ASoC: soc.h: don't create dummy Component via COMP_DUMMY()") Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: AngeloGioacchino Del Regno Acked-by: Kuninori Morimoto Reviewed-by: Fei Shao Acked-by: Trevor Wu Link: https://patch.msgid.link/20241126-asoc-mtk-dummy-panic-v1-1-42d53e168d2e@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8188/mt8188-mt6359.c | 9 +++++++-- sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 4 ++-- sound/soc/mediatek/mt8195/mt8195-mt6359.c | 9 +++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index 84abdba9ddb6..e04b88a57535 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -1277,10 +1277,12 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, for_each_card_prelinks(card, i, dai_link) { if (strcmp(dai_link->name, "DPTX_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8188_dptx_codec_init; } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8188_hdmi_codec_init; } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || strcmp(dai_link->name, "UL_SRC_BE") == 0) { @@ -1292,6 +1294,9 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 || strcmp(dai_link->name, "ETDM1_IN_BE") == 0 || strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { + if (!dai_link->num_codecs) + continue; + if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) { /* * The TDM protocol settings with fixed 4 slots are defined in diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index 1aba9c75594e..b1598cc5587e 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -1091,7 +1091,7 @@ static int mt8192_mt6359_legacy_probe(struct mtk_soc_card_data *soc_card_data) dai_link->ignore = 0; } - if (dai_link->num_codecs && dai_link->codecs[0].dai_name && + if (dai_link->num_codecs && strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) dai_link->ops = &mt8192_rt1015_i2s_ops; } @@ -1119,7 +1119,7 @@ static int mt8192_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, int i; for_each_card_prelinks(card, i, dai_link) - if (dai_link->num_codecs && dai_link->codecs[0].dai_name && + if (dai_link->num_codecs && strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) dai_link->ops = &mt8192_rt1015_i2s_ops; } diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c index 56b9d2433a1e..2b9cb3248795 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c @@ -1378,10 +1378,12 @@ static int mt8195_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, for_each_card_prelinks(card, i, dai_link) { if (strcmp(dai_link->name, "DPTX_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8195_dptx_codec_init; } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8195_hdmi_codec_init; } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || strcmp(dai_link->name, "UL_SRC1_BE") == 0 || @@ -1394,6 +1396,9 @@ static int mt8195_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 || strcmp(dai_link->name, "ETDM1_IN_BE") == 0 || strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { + if (!dai_link->num_codecs) + continue; + if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) { if (!(codec_init & MAX98390_CODEC_INIT)) { dai_link->init = mt8195_max98390_init; -- 2.51.0 From e9db1b551774037ebe39dde4a658d89ba95e260b Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 27 Nov 2024 17:29:54 +0800 Subject: [PATCH 02/16] ASoC: SOF: ipc3-topology: Convert the topology pin index to ALH dai index MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Intel SoundWire machine driver always uses Pin number 2 and above. Currently, the pin number is used as the FW DAI index directly. As a result, FW DAI 0 and 1 are never used. That worked fine because we use up to 2 DAIs in a SDW link. Convert the topology pin index to ALH dai index, the mapping is using 2-off indexing, iow, pin #2 is ALH dai #0. The issue exists since beginning. And the Fixes tag is the first commit that this commit can be applied. Fixes: b66bfc3a9810 ("ASoC: SOF: sof-audio: Fix broken early bclk feature for SSP") Signed-off-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Liam Girdwood Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20241127092955.20026-1-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-topology.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index be61e377e59e..c2fce554a674 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -20,6 +20,9 @@ /* size of tplg ABI in bytes */ #define SOF_IPC3_TPLG_ABI_SIZE 3 +/* Base of SOF_DAI_INTEL_ALH, this should be aligned with SOC_SDW_INTEL_BIDIR_PDI_BASE */ +#define INTEL_ALH_DAI_INDEX_BASE 2 + struct sof_widget_data { int ctrl_type; int ipc_cmd; @@ -1594,6 +1597,17 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget) if (ret < 0) goto free; + /* Subtract the base to match the FW dai index. */ + if (comp_dai->type == SOF_DAI_INTEL_ALH) { + if (comp_dai->dai_index < INTEL_ALH_DAI_INDEX_BASE) { + dev_err(sdev->dev, + "Invalid ALH dai index %d, only Pin numbers >= %d can be used\n", + comp_dai->dai_index, INTEL_ALH_DAI_INDEX_BASE); + return -EINVAL; + } + comp_dai->dai_index -= INTEL_ALH_DAI_INDEX_BASE; + } + dev_dbg(scomp->dev, "dai %s: type %d index %d\n", swidget->widget->name, comp_dai->type, comp_dai->dai_index); sof_dbg_comp_config(scomp, &comp_dai->config); @@ -2167,8 +2181,16 @@ static int sof_ipc3_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget * case SOF_DAI_INTEL_ALH: if (data) { /* save the dai_index during hw_params and reuse it for hw_free */ - if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) - config->dai_index = data->dai_index; + if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) { + /* Subtract the base to match the FW dai index. */ + if (data->dai_index < INTEL_ALH_DAI_INDEX_BASE) { + dev_err(sdev->dev, + "Invalid ALH dai index %d, only Pin numbers >= %d can be used\n", + config->dai_index, INTEL_ALH_DAI_INDEX_BASE); + return -EINVAL; + } + config->dai_index = data->dai_index - INTEL_ALH_DAI_INDEX_BASE; + } config->alh.stream_id = data->dai_data; } break; -- 2.51.0 From b682aa788e5f9f1ddacdfbb453e49fd3f4e83721 Mon Sep 17 00:00:00 2001 From: Ilya Zverev Date: Wed, 27 Nov 2024 15:44:20 +0200 Subject: [PATCH 03/16] ASoC: amd: yc: Add a quirk for microfone on Lenovo ThinkPad P14s Gen 5 21MES00B00 New ThinkPads need new quirk entries. Ilya has tested this one. Laptop product id is 21MES00B00, though the shorthand 21ME works. Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219533 Cc: stable@vger.kernel.org Signed-off-by: Ilya Zverev Link: https://patch.msgid.link/20241127134420.14471-1-ilya@zverev.info Signed-off-by: Mark Brown --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index facd82f0f251..e38c5885dadf 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -248,6 +248,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "21M5"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21ME"), + } + }, { .driver_data = &acp6x_card, .matches = { -- 2.51.0 From ca0f79f0286046f6a91c099dc941cf7afae198d6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 28 Nov 2024 08:26:45 +0100 Subject: [PATCH 04/16] ALSA: hda/realtek: Apply quirk for Medion E15433 Medion E15433 laptop wich ALC269VC (SSID 2782:1705) needs the same workaround for the missing speaker as another model. Link: https://bugzilla.suse.com/show_bug.cgi?id=1233298 Cc: Link: https://patch.msgid.link/20241128072646.15659-1-tiwai@suse.de 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 d950666f9c74..4355282f5b2d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10952,6 +10952,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13), SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO), SND_PCI_QUIRK(0x2782, 0x1701, "Infinix Y4 Max", ALC269VC_FIXUP_INFINIX_Y4_MAX), + SND_PCI_QUIRK(0x2782, 0x1705, "MEDION E15433", ALC269VC_FIXUP_INFINIX_Y4_MAX), SND_PCI_QUIRK(0x2782, 0x1707, "Vaio VJFE-ADL", ALC298_FIXUP_SPK_VOLUME), SND_PCI_QUIRK(0x2782, 0x4900, "MEDION E15443", ALC233_FIXUP_MEDION_MTL_SPK), SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), -- 2.51.0 From a7df7f909cec96e2fb7813a9b0b7e06a976983ab Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 28 Nov 2024 12:21:45 +0100 Subject: [PATCH 05/16] ALSA: hda: improve bass speaker support for ASUS Zenbook UM5606WA This hardware has ALC294 codec with speaker NID 0x17 and bass speaker NID 0x15. This patch removes DAC NID 0x06 (without volume control) from the connection list for bass speaker NID 0x15. Both speaker PINs are routed to DAC NID 0x03 with this change. Link: https://github.com/alsa-project/alsa-ucm-conf/issues/467 Signed-off-by: Jaroslav Kysela Link: https://patch.msgid.link/20241128112145.3409492-1-perex@perex.cz Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4355282f5b2d..2bf5c512ebaf 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6491,6 +6491,16 @@ static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec, } } +/* disable DAC3 (0x06) selection on NID 0x15 - share Speaker/Bass Speaker DAC 0x03 */ +static void alc294_fixup_bass_speaker_15(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + static const hda_nid_t conn[] = { 0x02, 0x03 }; + snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn), conn); + } +} + /* Hook to update amp GPIO4 for automute */ static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec, struct hda_jack_callback *jack) @@ -7773,6 +7783,7 @@ enum { ALC245_FIXUP_CLEVO_NOISY_MIC, ALC269_FIXUP_VAIO_VJFH52_MIC_NO_PRESENCE, ALC233_FIXUP_MEDION_MTL_SPK, + ALC294_FIXUP_BASS_SPEAKER_15, }; /* A special fixup for Lenovo C940 and Yoga Duet 7; @@ -10081,6 +10092,10 @@ static const struct hda_fixup alc269_fixups[] = { { } }, }, + [ALC294_FIXUP_BASS_SPEAKER_15] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc294_fixup_bass_speaker_15, + }, }; static const struct hda_quirk alc269_fixup_tbl[] = { @@ -10590,6 +10605,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1df3, "ASUS UM5606WA", ALC294_FIXUP_BASS_SPEAKER_15), SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), -- 2.51.0 From aaa55faa2495320e44bc643a917c701f2cc89ee7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 28 Nov 2024 18:04:22 +0100 Subject: [PATCH 06/16] ALSA: seq: ump: Fix seq port updates per FB info notify update_port_infos() is called when a UMP FB Info update notification is received, and this function is supposed to update the attributes of the corresponding sequencer port. However, the function had a few issues and it brought to the incorrect states. Namely: - It tried to get a wrong sequencer info for the update without correcting the port number with the group-offset 1 - The loop exited immediately when a sequencer port isn't present; this ended up with the truncation if a sequencer port in the middle goes away This patch addresses those bugs. Fixes: 4a16a3af0571 ("ALSA: seq: ump: Handle FB info update") Link: https://patch.msgid.link/20241128170423.23351-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/seq/seq_ump_client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/core/seq/seq_ump_client.c b/sound/core/seq/seq_ump_client.c index e5d3f4d206bf..e956f17f3792 100644 --- a/sound/core/seq/seq_ump_client.c +++ b/sound/core/seq/seq_ump_client.c @@ -257,12 +257,12 @@ static void update_port_infos(struct seq_ump_client *client) continue; old->addr.client = client->seq_client; - old->addr.port = i; + old->addr.port = ump_group_to_seq_port(i); err = snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, old); if (err < 0) - return; + continue; fill_port_info(new, client, &client->ump->groups[i]); if (old->capability == new->capability && !strcmp(old->name, new->name)) @@ -271,7 +271,7 @@ static void update_port_infos(struct seq_ump_client *client) SNDRV_SEQ_IOCTL_SET_PORT_INFO, new); if (err < 0) - return; + continue; /* notify to system port */ snd_seq_system_client_ev_port_change(client->seq_client, i); } -- 2.51.0 From 3978d53df7236f0a517c2abeb43ddf6ac162cdd8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 29 Nov 2024 10:45:42 +0100 Subject: [PATCH 07/16] ALSA: ump: Don't open legacy substream for an inactive group When a UMP Group is inactive, we shouldn't allow users to access it via the legacy MIDI access. Add the group active flag check and return -ENODEV if it's inactive. Link: https://patch.msgid.link/20241129094546.32119-2-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/ump.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/core/ump.c b/sound/core/ump.c index 6d0aac6c763f..9f9ad106107f 100644 --- a/sound/core/ump.c +++ b/sound/core/ump.c @@ -1087,6 +1087,8 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream) guard(mutex)(&ump->open_mutex); if (ump->legacy_substreams[dir][group]) return -EBUSY; + if (!ump->groups[group].active) + return -ENODEV; if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) { if (!ump->legacy_out_opens) { err = snd_rawmidi_kernel_open(&ump->core, 0, -- 2.51.0 From e29e504e7890b9ee438ca6370d0180d607c473f9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 29 Nov 2024 10:45:43 +0100 Subject: [PATCH 08/16] ALSA: ump: Indicate the inactive group in legacy substream names Since the legacy rawmidi has no proper way to know the inactive group, indicate it in the rawmidi substream names with "[Inactive]" suffix when the corresponding UMP group is inactive. Link: https://patch.msgid.link/20241129094546.32119-3-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/ump.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/core/ump.c b/sound/core/ump.c index 9f9ad106107f..7b00a957e548 100644 --- a/sound/core/ump.c +++ b/sound/core/ump.c @@ -1256,8 +1256,9 @@ static void fill_substream_names(struct snd_ump_endpoint *ump, name = ump->groups[idx].name; if (!*name) name = ump->info.name; - snprintf(s->name, sizeof(s->name), "Group %d (%.16s)", - idx + 1, name); + snprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s", + idx + 1, name, + ump->groups[idx].active ? "" : " [Inactive]"); } } -- 2.51.0 From edad3f9519fcacb926d0e3f3217aecaf628a593f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 29 Nov 2024 10:45:44 +0100 Subject: [PATCH 09/16] ALSA: ump: Update legacy substream names upon FB info update The legacy rawmidi substreams should be updated when UMP FB Info or UMP FB Name are received, too. Link: https://patch.msgid.link/20241129094546.32119-4-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/ump.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/sound/core/ump.c b/sound/core/ump.c index 7b00a957e548..d2b810eb84bc 100644 --- a/sound/core/ump.c +++ b/sound/core/ump.c @@ -37,6 +37,7 @@ static int process_legacy_output(struct snd_ump_endpoint *ump, u32 *buffer, int count); static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src, int words); +static void update_legacy_names(struct snd_ump_endpoint *ump); #else static inline int process_legacy_output(struct snd_ump_endpoint *ump, u32 *buffer, int count) @@ -47,6 +48,9 @@ static inline void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src, int words) { } +static inline void update_legacy_names(struct snd_ump_endpoint *ump) +{ +} #endif static const struct snd_rawmidi_global_ops snd_ump_rawmidi_ops = { @@ -861,6 +865,7 @@ static int ump_handle_fb_info_msg(struct snd_ump_endpoint *ump, fill_fb_info(ump, &fb->info, buf); if (ump->parsed) { snd_ump_update_group_attrs(ump); + update_legacy_names(ump); seq_notify_fb_change(ump, fb); } } @@ -893,6 +898,7 @@ static int ump_handle_fb_name_msg(struct snd_ump_endpoint *ump, /* notify the FB name update to sequencer, too */ if (ret > 0 && ump->parsed) { snd_ump_update_group_attrs(ump); + update_legacy_names(ump); seq_notify_fb_change(ump, fb); } return ret; @@ -1262,6 +1268,14 @@ static void fill_substream_names(struct snd_ump_endpoint *ump, } } +static void update_legacy_names(struct snd_ump_endpoint *ump) +{ + struct snd_rawmidi *rmidi = ump->legacy_rmidi; + + fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT); + fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT); +} + int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, char *id, int device) { @@ -1298,10 +1312,7 @@ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, rmidi->ops = &snd_ump_legacy_ops; rmidi->private_data = ump; ump->legacy_rmidi = rmidi; - if (input) - fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT); - if (output) - fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT); + update_legacy_names(ump); ump_dbg(ump, "Created a legacy rawmidi #%d (%s)\n", device, id); return 0; -- 2.51.0 From 947c4012f8f03a8bb946beb6e5294d5e32817d67 Mon Sep 17 00:00:00 2001 From: bo liu Date: Fri, 29 Nov 2024 09:44:41 +0800 Subject: [PATCH 10/16] ALSA: hda/conexant: fix Z60MR100 startup pop issue When Z60MR100 startup, speaker will output a pop. To fix this issue, we mute codec by init verbs in bios when system startup, and set GPIO to low to unmute codec in codec driver when it loaded . [ white space fixes and compile warning fix by tiwai ] Signed-off-by: bo liu Link: https://patch.msgid.link/20241129014441.437205-1-bo.liu@senarytech.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2e9f817b948e..538c37a78a56 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -307,6 +307,7 @@ enum { CXT_FIXUP_HP_MIC_NO_PRESENCE, CXT_PINCFG_SWS_JS201D, CXT_PINCFG_TOP_SPEAKER, + CXT_FIXUP_HP_A_U, }; /* for hda_fixup_thinkpad_acpi() */ @@ -774,6 +775,18 @@ static void cxt_setup_mute_led(struct hda_codec *codec, } } +static void cxt_setup_gpio_unmute(struct hda_codec *codec, + unsigned int gpio_mute_mask) +{ + if (gpio_mute_mask) { + // set gpio data to 0. + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, gpio_mute_mask); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, gpio_mute_mask); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_STICKY_MASK, 0); + } +} + static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -788,6 +801,15 @@ static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec, cxt_setup_mute_led(codec, 0x10, 0x20); } +static void cxt_fixup_hp_a_u(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + // Init vers in BIOS mute the spk/hp by set gpio high to avoid pop noise, + // so need to unmute once by clearing the gpio data when runs into the system. + if (action == HDA_FIXUP_ACT_INIT) + cxt_setup_gpio_unmute(codec, 0x2); +} + /* ThinkPad X200 & co with cxt5051 */ static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { { 0x16, 0x042140ff }, /* HP (seq# overridden) */ @@ -998,6 +1020,10 @@ static const struct hda_fixup cxt_fixups[] = { { } }, }, + [CXT_FIXUP_HP_A_U] = { + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_hp_a_u, + }, }; static const struct hda_quirk cxt5045_fixups[] = { @@ -1072,6 +1098,7 @@ static const struct hda_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x8458, "HP Z2 G4 mini premium", CXT_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), + SND_PCI_QUIRK(0x14f1, 0x0252, "MBX-Z60MR100", CXT_FIXUP_HP_A_U), SND_PCI_QUIRK(0x14f1, 0x0265, "SWS JS201D", CXT_PINCFG_SWS_JS201D), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), @@ -1117,6 +1144,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, { .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" }, { .id = CXT_PINCFG_TOP_SPEAKER, .name = "sirius-top-speaker" }, + { .id = CXT_FIXUP_HP_A_U, .name = "HP-U-support" }, {} }; -- 2.51.0 From 4f9d674377d090e38d93360bd4df21b67534d622 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 28 Nov 2024 09:04:16 +0100 Subject: [PATCH 11/16] ALSA: usb-audio: Notify xrun for low-latency mode The low-latency mode of USB-audio driver uses a similar approach like the implicit feedback mode but it has an explicit queuing at the trigger start time. The difference is, however, that no packet will be handled any longer after all queued packets are handled but no enough data is fed. In the case of implicit feedback mode, the capture-side packet handling triggers the re-queuing, and this checks the XRUN. OTOH, in the low-latency mode, it just stops without XRUN notification unless any new action is taken from user-space via ack callback. For example, when you stop the stream in aplay, no XRUN is reported. This patch adds the XRUN check at the packet complete callback in the case all pending URBs are exhausted. Strictly speaking, this state doesn't match really with XRUN; in theory the application may queue immediately after this happens. But such behavior is only for 1-period configuration, which the USB-audio driver doesn't support. So we may conclude that this situation leads certainly to XRUN. A caveat is that the XRUN should be triggered only for the PCM RUNNING state, and not during DRAINING. This additional state check is put in notify_xrun(), too. Fixes: d5f871f89e21 ("ALSA: usb-audio: Improved lowlatency playback support") Reported-by: Leonard Crestez Link: https://lore.kernel.org/25d5b0d8-4efd-4630-9d33-7a9e3fa9dc2b@gmail.com Link: https://patch.msgid.link/20241128080446.1181-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/usb/endpoint.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 568099467dbb..a29f28eb7d0c 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -403,10 +403,15 @@ static int prepare_inbound_urb(struct snd_usb_endpoint *ep, static void notify_xrun(struct snd_usb_endpoint *ep) { struct snd_usb_substream *data_subs; + struct snd_pcm_substream *psubs; data_subs = READ_ONCE(ep->data_subs); - if (data_subs && data_subs->pcm_substream) - snd_pcm_stop_xrun(data_subs->pcm_substream); + if (!data_subs) + return; + psubs = data_subs->pcm_substream; + if (psubs && psubs->runtime && + psubs->runtime->state == SNDRV_PCM_STATE_RUNNING) + snd_pcm_stop_xrun(psubs); } static struct snd_usb_packet_info * @@ -562,7 +567,10 @@ static void snd_complete_urb(struct urb *urb) push_back_to_ready_list(ep, ctx); clear_bit(ctx->index, &ep->active_mask); snd_usb_queue_pending_output_urbs(ep, false); - atomic_dec(&ep->submitted_urbs); /* decrement at last */ + /* decrement at last, and check xrun */ + if (atomic_dec_and_test(&ep->submitted_urbs) && + !snd_usb_endpoint_implicit_feedback_sink(ep)) + notify_xrun(ep); return; } -- 2.51.0 From 9b5f8ee43e48c25fbe1a10163ec04343d750acd0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 28 Nov 2024 11:49:38 +0100 Subject: [PATCH 12/16] ALSA: sh: Use standard helper for buffer accesses The SH DAC audio driver uses the kmalloc'ed buffer as the main PCM buffer, and the data is transferred via hrtimer callbacks manually from there to the hardware. Meanwhile, some of its code are written as if the buffer is on iomem and use the special helpers for the iomem (e.g. copy_from_iter_toio() or memset_io()). Those are rather useless and the standard helpers should be used. Similarly, the PCM mmap callback is set to a special one with snd_pcm_lib_mmap_iomem, but this is also nonsense, because SH architecture doesn't support this function, hence it leads just to NULL -- the fallback to the standard helper. This patch replaces those special setups with the standard ones. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202411281337.I4M07b7i-lkp@intel.com/ Link: https://patch.msgid.link/20241128104939.13755-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/sh/sh_dac_audio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c index e7b80328f0ef..a4d07438ad64 100644 --- a/sound/sh/sh_dac_audio.c +++ b/sound/sh/sh_dac_audio.c @@ -163,7 +163,7 @@ static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, /* channel is not used (interleaved data) */ struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - if (copy_from_iter_toio(chip->data_buffer + pos, src, count)) + if (copy_from_iter(chip->data_buffer + pos, src, count) != count) return -EFAULT; chip->buffer_end = chip->data_buffer + pos + count; @@ -182,7 +182,7 @@ static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream, /* channel is not used (interleaved data) */ struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - memset_io(chip->data_buffer + pos, 0, count); + memset(chip->data_buffer + pos, 0, count); chip->buffer_end = chip->data_buffer + pos + count; if (chip->empty) { @@ -211,7 +211,6 @@ static const struct snd_pcm_ops snd_sh_dac_pcm_ops = { .pointer = snd_sh_dac_pcm_pointer, .copy = snd_sh_dac_pcm_copy, .fill_silence = snd_sh_dac_pcm_silence, - .mmap = snd_pcm_lib_mmap_iomem, }; static int snd_sh_dac_pcm(struct snd_sh_dac *chip, int device) -- 2.51.0 From ed990c07af70d286f5736021c6e25d8df6f2f7b0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 30 Nov 2024 10:00:08 +0100 Subject: [PATCH 13/16] ALSA: ump: Shut up truncated string warning The recent change for the legacy substream name update brought a compile warning for some compilers due to the nature of snprintf(). Use scnprintf() to shut up the warning since the truncation is intentional. Fixes: e29e504e7890 ("ALSA: ump: Indicate the inactive group in legacy substream names") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202411300103.FrGuTAYp-lkp@intel.com/ Link: https://patch.msgid.link/20241130090009.19849-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/ump.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/core/ump.c b/sound/core/ump.c index d2b810eb84bc..fe4d39ae1159 100644 --- a/sound/core/ump.c +++ b/sound/core/ump.c @@ -1262,9 +1262,9 @@ static void fill_substream_names(struct snd_ump_endpoint *ump, name = ump->groups[idx].name; if (!*name) name = ump->info.name; - snprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s", - idx + 1, name, - ump->groups[idx].active ? "" : " [Inactive]"); + scnprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s", + idx + 1, name, + ump->groups[idx].active ? "" : " [Inactive]"); } } -- 2.51.0 From a7de2b873f3dbcda02d504536f1ec6dc50e3f6c4 Mon Sep 17 00:00:00 2001 From: Marie Ramlow Date: Sat, 30 Nov 2024 17:52:40 +0100 Subject: [PATCH 14/16] ALSA: usb-audio: add mixer mapping for Corsair HS80 The Corsair HS80 RGB Wireless is a USB headset with a mic and a sidetone feature. It has the same quirk as the Virtuoso series. This labels the mixers appropriately, so applications don't move the sidetone volume when they actually intend to move the main headset volume. Signed-off-by: Marie Ramlow cc: Link: https://patch.msgid.link/20241130165240.17838-1-me@nycode.dev Signed-off-by: Takashi Iwai --- sound/usb/mixer_maps.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 23260aa1919d..0e9b5431a47f 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -621,6 +621,16 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x1b1c, 0x0a42), .map = corsair_virtuoso_map, }, + { + /* Corsair HS80 RGB Wireless (wired mode) */ + .id = USB_ID(0x1b1c, 0x0a6a), + .map = corsair_virtuoso_map, + }, + { + /* Corsair HS80 RGB Wireless (wireless mode) */ + .id = USB_ID(0x1b1c, 0x0a6b), + .map = corsair_virtuoso_map, + }, { /* Gigabyte TRX40 Aorus Master (rear panel + front mic) */ .id = USB_ID(0x0414, 0xa001), .map = aorus_master_alc1220vb_map, -- 2.51.0 From 3a83f7baf1346aca885cb83cb888e835fef7c472 Mon Sep 17 00:00:00 2001 From: Nazar Bilinskyi Date: Sun, 1 Dec 2024 01:16:31 +0200 Subject: [PATCH 15/16] ALSA: hda/realtek: Enable mute and micmute LED on HP ProBook 430 G8 HP ProBook 430 G8 has a mute and micmute LEDs that can be made to work using quirk ALC236_FIXUP_HP_GPIO_LED. Enable already existing quirk. Signed-off-by: Nazar Bilinskyi Cc: Link: https://patch.msgid.link/20241130231631.8929-1-nbilinskyi@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 2bf5c512ebaf..877c5d20ac77 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10340,6 +10340,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x87b7, "HP Laptop 14-fq0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87d3, "HP Laptop 15-gw0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x87df, "HP ProBook 430 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87e7, "HP ProBook 450 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87f1, "HP ProBook 630 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), -- 2.51.0 From a0cd2b265fe3f675c121df848aec2e79ff7c100f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 30 Nov 2024 13:08:18 +0300 Subject: [PATCH 16/16] ALSA: hda/tas2781: Fix error code tas2781_read_acpi() Return an error code if acpi_get_subsystem_id() fails. Don't return success. Fixes: 4e7035a75da9 ("ALSA: hda/tas2781: Add speaker id check for ASUS projects") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/ef773f8a-a61d-478b-9e81-41a38a75c77b@stanley.mountain Signed-off-by: Takashi Iwai --- sound/pci/hda/tas2781_hda_i2c.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index 45cfb5a6f309..8ec03bda85f3 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -143,6 +143,7 @@ static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid) sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev)); if (IS_ERR(sub)) { dev_err(p->dev, "Failed to get SUBSYS ID.\n"); + ret = PTR_ERR(sub); goto err; } /* Speaker id was needed for ASUS projects. */ -- 2.51.0