From 13a5b21197587a3d9cac9e1a00de9b91526a55e4 Mon Sep 17 00:00:00 2001 From: Aabish Malik Date: Fri, 29 Dec 2023 22:33:54 +0530 Subject: [PATCH 01/32] ALSA: hda/realtek: enable SND_PCI_QUIRK for hp pavilion 14-ec1xxx series The HP Pavilion 14 ec1xxx series uses the HP mainboard 8A0F with the ALC287 codec. The mute led can be enabled using the already existing ALC287_FIXUP_HP_GPIO_LED quirk. Tested on an HP Pavilion ec1003AU Signed-off-by: Aabish Malik Cc: Link: https://lore.kernel.org/r/20231229170352.742261-3-aabishmalik3337@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 c3a75652888677..e2f68e502dafed 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9881,6 +9881,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), From 18a434f32fa61b3fda8ddcd9a63d5274569c6a41 Mon Sep 17 00:00:00 2001 From: Andy Chi Date: Tue, 2 Jan 2024 10:49:15 +0800 Subject: [PATCH 02/32] ALSA: hda/realtek: fix mute/micmute LEDs for a HP ZBook There is a HP ZBook which using ALC236 codec and need the ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF quirk to make mute LED and micmute LED work. [ confirmed that the new entries are for new models that have no proper name, so the strings are left as "HP" which will be updated eventually later -- tiwai ] Signed-off-by: Andy Chi Cc: Link: https://lore.kernel.org/r/20240102024916.19093-1-andy.chi@canonical.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 e2f68e502dafed..a4e2bc4f010729 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9926,6 +9926,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8c70, "HP EliteBook 835 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8c71, "HP EliteBook 845 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8c72, "HP EliteBook 865 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), From 8c14dbf36424eb751d70c15f9a671549390057b2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 3 Jan 2024 11:25:59 +0100 Subject: [PATCH 03/32] ALSA: hda: cs35l41: fix building without CONFIG_SPI When CONFIG_SPI is disabled, the driver produces unused-variable warning: sound/pci/hda/cs35l41_hda_property.c: In function 'generic_dsd_config': sound/pci/hda/cs35l41_hda_property.c:181:28: error: unused variable 'spi' [-Werror=unused-variable] 181 | struct spi_device *spi; | ^~~ sound/pci/hda/cs35l41_hda_property.c:180:27: error: unused variable 'cs_gpiod' [-Werror=unused-variable] 180 | struct gpio_desc *cs_gpiod; | ^~~~~~~~ Avoid these by turning the preprocessor contionals into equivalent C code, which also helps readability. Fixes: 916d051730ae ("ALSA: hda: cs35l41: Only add SPI CS GPIO if SPI is enabled in kernel") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20240103102606.3742476-1-arnd@kernel.org Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda_property.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c index 194e1179a253e2..c1afb721b4c677 100644 --- a/sound/pci/hda/cs35l41_hda_property.c +++ b/sound/pci/hda/cs35l41_hda_property.c @@ -211,7 +211,6 @@ static int generic_dsd_config(struct cs35l41_hda *cs35l41, struct device *physde if (cfg->bus == SPI) { cs35l41->index = id; -#if IS_ENABLED(CONFIG_SPI) /* * Manually set the Chip Select for the second amp in the node. * This is only supported for systems with 2 amps, since we cannot expand the @@ -220,7 +219,7 @@ static int generic_dsd_config(struct cs35l41_hda *cs35l41, struct device *physde * uses a native chip select), to ensure the second amp does not clash with the * first. */ - if (cfg->cs_gpio_index >= 0) { + if (IS_ENABLED(CONFIG_SPI) && cfg->cs_gpio_index >= 0) { spi = to_spi_device(cs35l41->dev); if (cfg->num_amps != 2) { @@ -251,7 +250,6 @@ static int generic_dsd_config(struct cs35l41_hda *cs35l41, struct device *physde spi_setup(spi); } } -#endif } else { if (cfg->num_amps > 2) /* From c344ef36dbc2fe920ec7291b68b11fe867a2c8f6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 7 Dec 2023 11:54:25 +0200 Subject: [PATCH 04/32] ASoC: SOF: Intel: hda-codec: Delay the codec device registration The current code flow is: 1. snd_hdac_device_register() 2. set parameters needed by the hdac driver 3. request_codec_module() the hdac driver is probed at this point During boot the codec drivers are not loaded when the hdac device is registered, it is going to be probed later when loading the codec module, which point the parameters are set. On module remove/insert rmmod snd_sof_pci_intel_tgl modprobe snd_sof_pci_intel_tgl The codec module remains loaded and the driver will be probed when the hdac device is created right away, before the parameters for the driver has been configured: 1. snd_hdac_device_register() the hdac driver is probed at this point 2. set parameters needed by the hdac driver 3. request_codec_module() will be a NOP as the module is already loaded Move the snd_hdac_device_register() later, to be done right before requesting the codec module to make sure that the parameters are all set before the device is created: 1. set parameters needed by the hdac driver 2. snd_hdac_device_register() 3. request_codec_module() This way at the hdac driver probe all parameters will be set in all cases. Link: https://github.com/thesofproject/linux/issues/4731 Fixes: a0575b4add21 ("ASoC: hdac_hda: Conditionally register dais for HDMI and Analog") Signed-off-by: Peter Ujfalusi Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231207095425.19597-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/ZYvUIxtrqBQZbNlC@shine.dominikbrodowski.net Link: https://bugzilla.kernel.org/show_bug.cgi?id=218304 Signed-off-by: Takashi Iwai --- sound/soc/sof/intel/hda-codec.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c index 28ecbebb4b848f..9f84b0d287a5f5 100644 --- a/sound/soc/sof/intel/hda-codec.c +++ b/sound/soc/sof/intel/hda-codec.c @@ -54,8 +54,16 @@ static int request_codec_module(struct hda_codec *codec) static int hda_codec_load_module(struct hda_codec *codec) { - int ret = request_codec_module(codec); + int ret; + + ret = snd_hdac_device_register(&codec->core); + if (ret) { + dev_err(&codec->core.dev, "failed to register hdac device\n"); + put_device(&codec->core.dev); + return ret; + } + ret = request_codec_module(codec); if (ret <= 0) { codec->probe_id = HDA_CODEC_ID_GENERIC; ret = request_codec_module(codec); @@ -116,7 +124,6 @@ EXPORT_SYMBOL_NS_GPL(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC); static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, int type) { struct hda_codec *codec; - int ret; codec = snd_hda_codec_device_init(to_hda_bus(bus), addr, "ehdaudio%dD%d", bus->idx, addr); if (IS_ERR(codec)) { @@ -126,13 +133,6 @@ static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, i codec->core.type = type; - ret = snd_hdac_device_register(&codec->core); - if (ret) { - dev_err(bus->dev, "failed to register hdac device\n"); - put_device(&codec->core.dev); - return ERR_PTR(ret); - } - return codec; } From 3150b70e944ead909260285dfb5707d0bedcf87b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Jan 2024 18:34:01 +0000 Subject: [PATCH 05/32] ASoC: meson: g12a-toacodec: Validate written enum values When writing to an enum we need to verify that the value written is valid for the enumeration, the helper function snd_soc_item_enum_to_val() doesn't do it since it needs to return an unsigned (and in any case we'd need to check the return value). Fixes: af2618a2eee8 ("ASoC: meson: g12a: add internal DAC glue driver") Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20240103-meson-enum-val-v1-1-424af7a8fb91@kernel.org Signed-off-by: Mark Brown --- sound/soc/meson/g12a-toacodec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/meson/g12a-toacodec.c b/sound/soc/meson/g12a-toacodec.c index 6c4503766fdcae..dd7f07de2685af 100644 --- a/sound/soc/meson/g12a-toacodec.c +++ b/sound/soc/meson/g12a-toacodec.c @@ -71,6 +71,9 @@ static int g12a_toacodec_mux_put_enum(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int mux, reg; + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); regmap_field_read(priv->field_dat_sel, ®); From 1e001206804be3f3d21f4a1cf16e5d059d75643f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Jan 2024 18:34:02 +0000 Subject: [PATCH 06/32] ASoC: meson: g12a-tohdmitx: Validate written enum values When writing to an enum we need to verify that the value written is valid for the enumeration, the helper function snd_soc_item_enum_to_val() doesn't do it since it needs to return an unsigned (and in any case we'd need to check the return value). Fixes: c8609f3870f7 ("ASoC: meson: add g12a tohdmitx control") Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20240103-meson-enum-val-v1-2-424af7a8fb91@kernel.org Signed-off-by: Mark Brown --- sound/soc/meson/g12a-tohdmitx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c index f7ef9aa1eed8db..51b7703e1834f3 100644 --- a/sound/soc/meson/g12a-tohdmitx.c +++ b/sound/soc/meson/g12a-tohdmitx.c @@ -45,6 +45,9 @@ static int g12a_tohdmitx_i2s_mux_put_enum(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int mux, changed; + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); changed = snd_soc_component_test_bits(component, e->reg, CTRL0_I2S_DAT_SEL, @@ -93,6 +96,9 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int mux, changed; + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); changed = snd_soc_component_test_bits(component, TOHDMITX_CTRL0, CTRL0_SPDIF_SEL, From 172c88244b5f2d3375403ebb504d407be0fded59 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Jan 2024 18:34:03 +0000 Subject: [PATCH 07/32] ASoC: meson: g12a-toacodec: Fix event generation When a control changes value the return value from _put() should be 1 so we get events generated to userspace notifying applications of the change. We are checking if there has been a change and exiting early if not but we are not providing the correct return value in the latter case, fix this. Fixes: af2618a2eee8 ("ASoC: meson: g12a: add internal DAC glue driver") Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20240103-meson-enum-val-v1-3-424af7a8fb91@kernel.org Signed-off-by: Mark Brown --- sound/soc/meson/g12a-toacodec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/meson/g12a-toacodec.c b/sound/soc/meson/g12a-toacodec.c index dd7f07de2685af..531bb8707a3ec4 100644 --- a/sound/soc/meson/g12a-toacodec.c +++ b/sound/soc/meson/g12a-toacodec.c @@ -104,7 +104,7 @@ static int g12a_toacodec_mux_put_enum(struct snd_kcontrol *kcontrol, snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); - return 0; + return 1; } static SOC_ENUM_SINGLE_DECL(g12a_toacodec_mux_enum, TOACODEC_CTRL0, From b036d8ef3120b996751495ce25994eea58032a98 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Jan 2024 18:34:04 +0000 Subject: [PATCH 08/32] ASoC: meson: g12a-tohdmitx: Fix event generation for S/PDIF mux When a control changes value the return value from _put() should be 1 so we get events generated to userspace notifying applications of the change. While the I2S mux gets this right the S/PDIF mux does not, fix the return value. Fixes: c8609f3870f7 ("ASoC: meson: add g12a tohdmitx control") Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20240103-meson-enum-val-v1-4-424af7a8fb91@kernel.org Signed-off-by: Mark Brown --- sound/soc/meson/g12a-tohdmitx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c index 51b7703e1834f3..b92434125face1 100644 --- a/sound/soc/meson/g12a-tohdmitx.c +++ b/sound/soc/meson/g12a-tohdmitx.c @@ -118,7 +118,7 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol, snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); - return 0; + return 1; } static SOC_ENUM_SINGLE_DECL(g12a_tohdmitx_spdif_mux_enum, TOHDMITX_CTRL0, From b6ce6e6c79e4ec650887f1fe391a70e54972001a Mon Sep 17 00:00:00 2001 From: Siddhesh Dharme Date: Thu, 4 Jan 2024 11:37:36 +0530 Subject: [PATCH 09/32] ALSA: hda/realtek: Fix mute and mic-mute LEDs for HP ProBook 440 G6 LEDs in 'HP ProBook 440 G6' laptop are controlled by ALC236 codec. Enable already existing quirk 'ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF' to fix mute and mic-mute LEDs. Signed-off-by: Siddhesh Dharme Cc: Link: https://lore.kernel.org/r/20240104060736.5149-1-siddheshdharme18@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 a4e2bc4f010729..70b17b08d4ffa0 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9799,6 +9799,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { 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), SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360), + SND_PCI_QUIRK(0x103c, 0x8537, "HP ProBook 440 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x861f, "HP Elite Dragonfly G1", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), From 3dbb4e3602d217d7139b95a36077a6b7252dc290 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 4 Jan 2024 22:57:16 +0800 Subject: [PATCH 10/32] ASoC: dt-bindings: move tas2563 from tas2562.yaml to tas2781.yaml Move tas2563 from tas2562.yaml to tas2781.yaml to unbind tas2563 from tas2562 driver code and bind it to tas2781 driver code, because tas2563 only work in bypass-DSP mode with tas2562 driver. In order to enable DSP mode for tas2563, it has been moved to tas2781 driver. As to the hardware part, such as register setting and DSP firmware, all these are stored in the binary firmware. What tas2781 drivder does is to parse the firmware and download it to the chip, then power on the chip. So, tas2781 driver can be resued as tas2563 driver. Only attention will be paid to downloading corresponding firmware. Signed-off-by: Shenghao Ding Reviewed-by: Krzysztof Kozlowski Link: https://msgid.link/r/20240104145721.1398-1-shenghao-ding@ti.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/tas2562.yaml | 2 - .../devicetree/bindings/sound/ti,tas2781.yaml | 78 +++++++++++++++---- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/tas2562.yaml b/Documentation/devicetree/bindings/sound/tas2562.yaml index f01c0dde0cf740..d28c102c0ce7f0 100644 --- a/Documentation/devicetree/bindings/sound/tas2562.yaml +++ b/Documentation/devicetree/bindings/sound/tas2562.yaml @@ -18,7 +18,6 @@ description: | Specifications about the audio amplifier can be found at: https://www.ti.com/lit/gpn/tas2562 - https://www.ti.com/lit/gpn/tas2563 https://www.ti.com/lit/gpn/tas2564 https://www.ti.com/lit/gpn/tas2110 @@ -29,7 +28,6 @@ properties: compatible: enum: - ti,tas2562 - - ti,tas2563 - ti,tas2564 - ti,tas2110 diff --git a/Documentation/devicetree/bindings/sound/ti,tas2781.yaml b/Documentation/devicetree/bindings/sound/ti,tas2781.yaml index a69e6c223308e6..97623868924951 100644 --- a/Documentation/devicetree/bindings/sound/ti,tas2781.yaml +++ b/Documentation/devicetree/bindings/sound/ti,tas2781.yaml @@ -5,36 +5,46 @@ $id: http://devicetree.org/schemas/sound/ti,tas2781.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Texas Instruments TAS2781 SmartAMP +title: Texas Instruments TAS2563/TAS2781 SmartAMP maintainers: - Shenghao Ding -description: - The TAS2781 is a mono, digital input Class-D audio amplifier - optimized for efficiently driving high peak power into small - loudspeakers. An integrated on-chip DSP supports Texas Instruments - Smart Amp speaker protection algorithm. The integrated speaker - voltage and current sense provides for real time +description: | + The TAS2563/TAS2781 is a mono, digital input Class-D audio + amplifier optimized for efficiently driving high peak power into + small loudspeakers. An integrated on-chip DSP supports Texas + Instruments Smart Amp speaker protection algorithm. The + integrated speaker voltage and current sense provides for real time monitoring of loudspeaker behavior. -allOf: - - $ref: dai-common.yaml# + Specifications about the audio amplifier can be found at: + https://www.ti.com/lit/gpn/tas2563 + https://www.ti.com/lit/gpn/tas2781 properties: compatible: - enum: - - ti,tas2781 + description: | + ti,tas2563: 6.1-W Boosted Class-D Audio Amplifier With Integrated + DSP and IV Sense, 16/20/24/32bit stereo I2S or multichannel TDM. + + ti,tas2781: 24-V Class-D Amplifier with Real Time Integrated Speaker + Protection and Audio Processing, 16/20/24/32bit stereo I2S or + multichannel TDM. + oneOf: + - items: + - enum: + - ti,tas2563 + - const: ti,tas2781 + - enum: + - ti,tas2781 reg: description: - I2C address, in multiple tas2781s case, all the i2c address + I2C address, in multiple-AMP case, all the i2c address aggregate as one Audio Device to support multiple audio slots. maxItems: 8 minItems: 1 - items: - minimum: 0x38 - maximum: 0x3f reset-gpios: maxItems: 1 @@ -49,6 +59,44 @@ required: - compatible - reg +allOf: + - $ref: dai-common.yaml# + - if: + properties: + compatible: + contains: + enum: + - ti,tas2563 + then: + properties: + reg: + description: + I2C address, in multiple-AMP case, all the i2c address + aggregate as one Audio Device to support multiple audio slots. + maxItems: 4 + minItems: 1 + items: + minimum: 0x4c + maximum: 0x4f + + - if: + properties: + compatible: + contains: + enum: + - ti,tas2781 + then: + properties: + reg: + description: + I2C address, in multiple-AMP case, all the i2c address + aggregate as one Audio Device to support multiple audio slots. + maxItems: 8 + minItems: 1 + items: + minimum: 0x38 + maximum: 0x3f + additionalProperties: false examples: From 645994d21287a1ad2f637818d737f7a3d84e97d7 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 4 Jan 2024 22:57:17 +0800 Subject: [PATCH 11/32] ASoC: tas2562: move tas2563 from tas2562 driver to tas2781 driver Move tas2563 from tas2562 driver to tas2781 driver to unbind tas2563 from tas2562 driver code and bind it to tas2781 driver code, because tas2563 only work in bypass-DSP mode with tas2562 driver. In order to enable DSP mode for tas2563, it has been moved to tas2781 driver. As to the hardware part, such as register setting and DSP firmware, all these are stored in the binary firmware. What tas2781 drivder does is to parse the firmware and download it to the chip, then power on the chip. So, tas2781 driver can be resued as tas2563 driver. Only attention will be paid to downloading corresponding firmware. Signed-off-by: Shenghao Ding Link: https://msgid.link/r/20240104145721.1398-2-shenghao-ding@ti.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2562.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c index 962c2cdfa01744..54561ae598b87a 100644 --- a/sound/soc/codecs/tas2562.c +++ b/sound/soc/codecs/tas2562.c @@ -59,7 +59,6 @@ struct tas2562_data { enum tas256x_model { TAS2562, - TAS2563, TAS2564, TAS2110, }; @@ -721,7 +720,6 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562) static const struct i2c_device_id tas2562_id[] = { { "tas2562", TAS2562 }, - { "tas2563", TAS2563 }, { "tas2564", TAS2564 }, { "tas2110", TAS2110 }, { } @@ -770,7 +768,6 @@ static int tas2562_probe(struct i2c_client *client) #ifdef CONFIG_OF static const struct of_device_id tas2562_of_match[] = { { .compatible = "ti,tas2562", }, - { .compatible = "ti,tas2563", }, { .compatible = "ti,tas2564", }, { .compatible = "ti,tas2110", }, { }, From e9aa44736cb75e901d76ee59d80db1ae79d516f1 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 4 Jan 2024 22:57:18 +0800 Subject: [PATCH 12/32] ASoC: tas2781: Add tas2563 into header file for DSP mode Move tas2563 from tas2562 header file to tas2781 header file to unbind tas2563 from tas2562 driver code and bind it to tas2781 driver code, because tas2563 only work in bypass-DSP mode with tas2562 driver. In order to enable DSP mode for tas2563, it has been moved to tas2781 driver. As to the hardware part, such as register setting and DSP firmware, all these are stored in the binary firmware. What tas2781 drivder does is to parse the firmware and download it to the chip, then power on the chip. So, tas2781 driver can be resued as tas2563 driver. Only attention will be paid to downloading corresponding firmware. Signed-off-by: Shenghao Ding Link: https://msgid.link/r/20240104145721.1398-3-shenghao-ding@ti.com Signed-off-by: Mark Brown --- include/sound/tas2781.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index a6c808b223183a..813cf9446a58c6 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -1,13 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0 */ // -// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier +// ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier // // Copyright (C) 2022 - 2023 Texas Instruments Incorporated // https://www.ti.com // -// The TAS2781 driver implements a flexible and configurable +// The TAS2563/TAS2781 driver implements a flexible and configurable // algo coefficient setting for one, two, or even multiple -// TAS2781 chips. +// TAS2563/TAS2781 chips. // // Author: Shenghao Ding // Author: Kevin Lu @@ -59,7 +59,8 @@ #define TASDEVICE_CMD_FIELD_W 0x4 enum audio_device { - TAS2781 = 0, + TAS2563, + TAS2781, }; enum device_catlog_id { From 9f1bcd16e2bd41d758438f1d74e5f2d35f1e8c8e Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 4 Jan 2024 22:57:19 +0800 Subject: [PATCH 13/32] ASoC: tas2781: Add tas2563 into driver Move tas2563 from tas2562 driver to tas2781 driver to unbind tas2563 from tas2562 driver code and bind it to tas2781 driver code, because tas2563 only work in bypass-DSP mode with tas2562 driver. In order to enable DSP mode for tas2563, it has been moved to tas2781 driver. As to the hardware part, such as register setting and DSP firmware, all these are stored in the binary firmware. What tas2781 drivder does is to parse the firmware and download it to the chip, then power on the chip. So, tas2781 driver can be resued as tas2563 driver. Only attention will be paid to downloading corresponding firmware. Signed-off-by: Shenghao Ding Link: https://msgid.link/r/20240104145721.1398-4-shenghao-ding@ti.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2781-i2c.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 55cd5e3c23a5d9..bd5ef4ff96feb5 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -1,13 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 // -// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier +// ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier // // Copyright (C) 2022 - 2023 Texas Instruments Incorporated // https://www.ti.com // -// The TAS2781 driver implements a flexible and configurable +// The TAS2563/TAS2781 driver implements a flexible and configurable // algo coefficient setting for one, two, or even multiple -// TAS2781 chips. +// TAS2563/TAS2781 chips. // // Author: Shenghao Ding // Author: Kevin Lu @@ -32,6 +32,7 @@ #include static const struct i2c_device_id tasdevice_id[] = { + { "tas2563", TAS2563 }, { "tas2781", TAS2781 }, {} }; @@ -39,6 +40,7 @@ MODULE_DEVICE_TABLE(i2c, tasdevice_id); #ifdef CONFIG_OF static const struct of_device_id tasdevice_of_match[] = { + { .compatible = "ti,tas2563" }, { .compatible = "ti,tas2781" }, {}, }; From 35040410372ca27a33cec8382d42c90b6b6c99f6 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Fri, 29 Dec 2023 09:46:01 +0800 Subject: [PATCH 14/32] ASoC: codecs: rtq9128: Fix PM_RUNTIME usage If 'pm_runtime_resume_and_get' is used, must check the return value to prevent the active count not matched problem. Signed-off-by: ChiYuan Huang Link: https://msgid.link/r/bebd9e2bed9e0528a7fd9c528d785da02caf4f1a.1703813842.git.cy_huang@richtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rtq9128.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rtq9128.c b/sound/soc/codecs/rtq9128.c index c22b047115cc47..bda64f9eeb624c 100644 --- a/sound/soc/codecs/rtq9128.c +++ b/sound/soc/codecs/rtq9128.c @@ -391,7 +391,11 @@ static int rtq9128_component_probe(struct snd_soc_component *comp) unsigned int val; int i, ret; - pm_runtime_resume_and_get(comp->dev); + ret = pm_runtime_resume_and_get(comp->dev); + if (ret < 0) { + dev_err(comp->dev, "Failed to resume device (%d)\n", ret); + return ret; + } val = snd_soc_component_read(comp, RTQ9128_REG_EFUSE_DATA); From 415d10ccef712f3ec73cd880c1fef3eb48601c3a Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Fri, 29 Dec 2023 09:46:02 +0800 Subject: [PATCH 15/32] ASoC: codecs: rtq9128: Fix TDM enable and DAI format control flow To enable TDM mode, the current control flow limits the function calling order should be 'set_tdm_slot->set_dai_fmt'. But not all platform sound card like as simeple card to follow this design. To bypass this limit, adjust the DAI format setting in runtime 'hw_param' callback. Signed-off-by: ChiYuan Huang Link: https://msgid.link/r/c4c8df00d8d179b8b5b39a8521de3a85325c57e8.1703813842.git.cy_huang@richtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rtq9128.c | 67 ++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/sound/soc/codecs/rtq9128.c b/sound/soc/codecs/rtq9128.c index bda64f9eeb624c..aa3eadecd9746c 100644 --- a/sound/soc/codecs/rtq9128.c +++ b/sound/soc/codecs/rtq9128.c @@ -59,6 +59,7 @@ struct rtq9128_data { struct gpio_desc *enable; + unsigned int daifmt; int tdm_slots; int tdm_slot_width; bool tdm_input_data2_select; @@ -441,10 +442,7 @@ static const struct snd_soc_component_driver rtq9128_comp_driver = { static int rtq9128_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct rtq9128_data *data = snd_soc_dai_get_drvdata(dai); - struct snd_soc_component *comp = dai->component; struct device *dev = dai->dev; - unsigned int audfmt, fmtval; - int ret; dev_dbg(dev, "%s: fmt 0x%8x\n", __func__, fmt); @@ -454,35 +452,10 @@ static int rtq9128_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - fmtval = fmt & SND_SOC_DAIFMT_FORMAT_MASK; - if (data->tdm_slots && fmtval != SND_SOC_DAIFMT_DSP_A && fmtval != SND_SOC_DAIFMT_DSP_B) { - dev_err(dev, "TDM is used, format only support DSP_A or DSP_B\n"); - return -EINVAL; - } + /* Store here and will be used in runtime hw_params for DAI format setting */ + data->daifmt = fmt; - switch (fmtval) { - case SND_SOC_DAIFMT_I2S: - audfmt = 8; - break; - case SND_SOC_DAIFMT_LEFT_J: - audfmt = 9; - break; - case SND_SOC_DAIFMT_RIGHT_J: - audfmt = 10; - break; - case SND_SOC_DAIFMT_DSP_A: - audfmt = data->tdm_slots ? 12 : 11; - break; - case SND_SOC_DAIFMT_DSP_B: - audfmt = data->tdm_slots ? 4 : 3; - break; - default: - dev_err(dev, "Unsupported format 0x%8x\n", fmt); - return -EINVAL; - } - - ret = snd_soc_component_write_field(comp, RTQ9128_REG_I2S_OPT, RTQ9128_AUDFMT_MASK, audfmt); - return ret < 0 ? ret : 0; + return 0; } static int rtq9128_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, @@ -558,10 +531,38 @@ static int rtq9128_dai_hw_params(struct snd_pcm_substream *stream, struct snd_pc unsigned int width, slot_width, bitrate, audbit, dolen; struct snd_soc_component *comp = dai->component; struct device *dev = dai->dev; + unsigned int fmtval, audfmt; int ret; dev_dbg(dev, "%s: width %d\n", __func__, params_width(param)); + fmtval = FIELD_GET(SND_SOC_DAIFMT_FORMAT_MASK, data->daifmt); + if (data->tdm_slots && fmtval != SND_SOC_DAIFMT_DSP_A && fmtval != SND_SOC_DAIFMT_DSP_B) { + dev_err(dev, "TDM is used, format only support DSP_A or DSP_B\n"); + return -EINVAL; + } + + switch (fmtval) { + case SND_SOC_DAIFMT_I2S: + audfmt = 8; + break; + case SND_SOC_DAIFMT_LEFT_J: + audfmt = 9; + break; + case SND_SOC_DAIFMT_RIGHT_J: + audfmt = 10; + break; + case SND_SOC_DAIFMT_DSP_A: + audfmt = data->tdm_slots ? 12 : 11; + break; + case SND_SOC_DAIFMT_DSP_B: + audfmt = data->tdm_slots ? 4 : 3; + break; + default: + dev_err(dev, "Unsupported format 0x%8x\n", fmtval); + return -EINVAL; + } + switch (width = params_width(param)) { case 16: audbit = 0; @@ -615,6 +616,10 @@ static int rtq9128_dai_hw_params(struct snd_pcm_substream *stream, struct snd_pc return -EINVAL; } + ret = snd_soc_component_write_field(comp, RTQ9128_REG_I2S_OPT, RTQ9128_AUDFMT_MASK, audfmt); + if (ret < 0) + return ret; + ret = snd_soc_component_write_field(comp, RTQ9128_REG_I2S_OPT, RTQ9128_AUDBIT_MASK, audbit); if (ret < 0) return ret; From 59b946ea30806064c4ac78f0ac93642655dd4f2e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 8 Jan 2024 11:48:41 +0200 Subject: [PATCH 16/32] ASoC: Intel: bxt_da7219_max98357a: Fix kernel ops due to COMP_DUMMY change The change to avoid dummy components will leave the component name and dai_name NULL which will cause NULL dereference when trying to access to it in the machine driver when applying fixups. Link: https://github.com/thesofproject/linux/pull/4759#issuecomment-1878641868 Fixes: 13f58267cda3 ("ASoC: soc.h: don't create dummy Component via COMP_DUMMY()") Signed-off-by: Peter Ujfalusi Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://msgid.link/r/20240108094842.28782-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bxt_da7219_max98357a.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index 816fad8c1ff0ef..540f7a29310a9f 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -797,6 +797,9 @@ static int broxton_audio_probe(struct platform_device *pdev) broxton_audio_card.name = "glkda7219max"; /* Fixup the SSP entries for geminilake */ for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) { + if (!broxton_dais[i].codecs->dai_name) + continue; + /* MAXIM_CODEC is connected to SSP1. */ if (!strcmp(broxton_dais[i].codecs->dai_name, BXT_MAXIM_CODEC_DAI)) { @@ -822,6 +825,9 @@ static int broxton_audio_probe(struct platform_device *pdev) broxton_audio_card.name = "cmlda7219max"; for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) { + if (!broxton_dais[i].codecs->dai_name) + continue; + /* MAXIM_CODEC is connected to SSP1. */ if (!strcmp(broxton_dais[i].codecs->dai_name, BXT_MAXIM_CODEC_DAI)) { From 3ec71290db4de298b67659ef2bc2a8f84cf9537b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 8 Jan 2024 11:48:42 +0200 Subject: [PATCH 17/32] ASoC: Intel: bxt_rt298: Fix kernel ops due to COMP_DUMMY change The change to avoid dummy components will leave the component name and dai_name NULL which will cause NULL dereference when trying to access to it in the machine driver when applying fixups. Link: https://github.com/thesofproject/linux/pull/4759#issuecomment-1878641868 Fixes: 13f58267cda3 ("ASoC: soc.h: don't create dummy Component via COMP_DUMMY()") Signed-off-by: Peter Ujfalusi Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://msgid.link/r/20240108094842.28782-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bxt_rt298.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 4631106f2a2823..c0eb65c14aa97b 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -604,7 +604,8 @@ static int broxton_audio_probe(struct platform_device *pdev) int i; for (i = 0; i < ARRAY_SIZE(broxton_rt298_dais); i++) { - if (!strncmp(card->dai_link[i].codecs->name, "i2c-INT343A:00", + if (card->dai_link[i].codecs->name && + !strncmp(card->dai_link[i].codecs->name, "i2c-INT343A:00", I2C_NAME_SIZE)) { if (!strncmp(card->name, "broxton-rt298", PLATFORM_NAME_SIZE)) { From 7aeb259086487417f0fecf66e325bee133e8813a Mon Sep 17 00:00:00 2001 From: bo liu Date: Mon, 8 Jan 2024 19:02:35 +0800 Subject: [PATCH 18/32] ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140 When OMTP headset plugin the headset jack of CX8070 and SN6160 sound cards, the headset type detection circuit will recognize the headset type as CTIA. At this point, plugout and plugin the headset will get the correct headset type as OMTP. The reason for the failure of headset type recognition is that the sound card creation will enable the VREF voltage of the headset mic, which interferes with the headset type automatic detection circuit. Plugout and plugin the headset will restart the headset detection and get the correct headset type. The patch is disable the VREF voltage when the headset is not present, and will enable the VREF voltage when the headset is present. Signed-off-by: bo liu Link: https://lore.kernel.org/r/20240108110235.3867-1-bo.liu@senarytech.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 115 ++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a889cccdd607cf..e8819e8a98763c 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -21,6 +21,12 @@ #include "hda_jack.h" #include "hda_generic.h" +enum { + CX_HEADSET_NOPRESENT = 0, + CX_HEADSET_PARTPRESENT, + CX_HEADSET_ALLPRESENT, +}; + struct conexant_spec { struct hda_gen_spec gen; @@ -42,7 +48,8 @@ struct conexant_spec { unsigned int gpio_led; unsigned int gpio_mute_led_mask; unsigned int gpio_mic_led_mask; - + unsigned int headset_present_flag; + bool is_cx8070_sn6140; }; @@ -164,6 +171,27 @@ static void cxt_init_gpio_led(struct hda_codec *codec) } } +static void cx_fixup_headset_recog(struct hda_codec *codec) +{ + unsigned int mic_persent; + + /* fix some headset type recognize fail issue, such as EDIFIER headset */ + /* set micbiasd output current comparator threshold from 66% to 55%. */ + snd_hda_codec_write(codec, 0x1c, 0, 0x320, 0x010); + /* set OFF voltage for DFET from -1.2V to -0.8V, set headset micbias registor + * value adjustment trim from 2.2K ohms to 2.0K ohms. + */ + snd_hda_codec_write(codec, 0x1c, 0, 0x3b0, 0xe10); + /* fix reboot headset type recognize fail issue */ + mic_persent = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0); + if (mic_persent & AC_PINSENSE_PRESENCE) + /* enable headset mic VREF */ + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); + else + /* disable headset mic VREF */ + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20); +} + static int cx_auto_init(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; @@ -174,6 +202,9 @@ static int cx_auto_init(struct hda_codec *codec) cxt_init_gpio_led(codec); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); + if (spec->is_cx8070_sn6140) + cx_fixup_headset_recog(codec); + return 0; } @@ -192,6 +223,77 @@ static void cx_auto_free(struct hda_codec *codec) snd_hda_gen_free(codec); } +static void cx_process_headset_plugin(struct hda_codec *codec) +{ + unsigned int val; + unsigned int count = 0; + + /* Wait headset detect done. */ + do { + val = snd_hda_codec_read(codec, 0x1c, 0, 0xca0, 0x0); + if (val & 0x080) { + codec_dbg(codec, "headset type detect done!\n"); + break; + } + msleep(20); + count++; + } while (count < 3); + val = snd_hda_codec_read(codec, 0x1c, 0, 0xcb0, 0x0); + if (val & 0x800) { + codec_dbg(codec, "headset plugin, type is CTIA\n"); + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); + } else if (val & 0x400) { + codec_dbg(codec, "headset plugin, type is OMTP\n"); + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); + } else { + codec_dbg(codec, "headphone plugin\n"); + } +} + +static void cx_update_headset_mic_vref(struct hda_codec *codec, unsigned int res) +{ + unsigned int phone_present, mic_persent, phone_tag, mic_tag; + struct conexant_spec *spec = codec->spec; + + /* In cx8070 and sn6140, the node 16 can only be config to headphone or disabled, + * the node 19 can only be config to microphone or disabled. + * Check hp&mic tag to process headset pulgin&plugout. + */ + phone_tag = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); + mic_tag = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); + if ((phone_tag & (res >> AC_UNSOL_RES_TAG_SHIFT)) || + (mic_tag & (res >> AC_UNSOL_RES_TAG_SHIFT))) { + phone_present = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_PIN_SENSE, 0x0); + if (!(phone_present & AC_PINSENSE_PRESENCE)) {/* headphone plugout */ + spec->headset_present_flag = CX_HEADSET_NOPRESENT; + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20); + return; + } + if (spec->headset_present_flag == CX_HEADSET_NOPRESENT) { + spec->headset_present_flag = CX_HEADSET_PARTPRESENT; + } else if (spec->headset_present_flag == CX_HEADSET_PARTPRESENT) { + mic_persent = snd_hda_codec_read(codec, 0x19, 0, + AC_VERB_GET_PIN_SENSE, 0x0); + /* headset is present */ + if ((phone_present & AC_PINSENSE_PRESENCE) && + (mic_persent & AC_PINSENSE_PRESENCE)) { + cx_process_headset_plugin(codec); + spec->headset_present_flag = CX_HEADSET_ALLPRESENT; + } + } + } +} + +static void cx_jack_unsol_event(struct hda_codec *codec, unsigned int res) +{ + struct conexant_spec *spec = codec->spec; + + if (spec->is_cx8070_sn6140) + cx_update_headset_mic_vref(codec, res); + + snd_hda_jack_unsol_event(codec, res); +} + #ifdef CONFIG_PM static int cx_auto_suspend(struct hda_codec *codec) { @@ -205,7 +307,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = { .build_pcms = snd_hda_gen_build_pcms, .init = cx_auto_init, .free = cx_auto_free, - .unsol_event = snd_hda_jack_unsol_event, + .unsol_event = cx_jack_unsol_event, #ifdef CONFIG_PM .suspend = cx_auto_suspend, .check_power_status = snd_hda_gen_check_power_status, @@ -1042,6 +1144,15 @@ static int patch_conexant_auto(struct hda_codec *codec) codec->spec = spec; codec->patch_ops = cx_auto_patch_ops; + /* init cx8070/sn6140 flag and reset headset_present_flag */ + switch (codec->core.vendor_id) { + case 0x14f11f86: + case 0x14f11f87: + spec->is_cx8070_sn6140 = true; + spec->headset_present_flag = CX_HEADSET_NOPRESENT; + break; + } + cx_auto_parse_eapd(codec); spec->gen.own_eapd_ctl = 1; From 6b3d14b7f9b1acaf7303d8499836bf78ee9c470c Mon Sep 17 00:00:00 2001 From: Tom Jason Schwanke Date: Mon, 8 Jan 2024 16:15:21 +0100 Subject: [PATCH 19/32] ALSA: hda/realtek: Fix mute and mic-mute LEDs for HP Envy X360 13-ay0xxx This enables the mute and mic-mute LEDs on the HP Envy X360 13-ay0xxx convertibles. The quirk 'ALC245_FIXUP_HP_X360_MUTE_LEDS' already exists and is now enabled for this device. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216197 Signed-off-by: Tom Jason Schwanke Cc: Link: https://lore.kernel.org/r/651b26e9-e86b-45dd-aa90-3e43d6b99823@catboys.cloud 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 1dcfba27e075ec..b68c9475705105 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9842,6 +9842,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8735, "HP ProBook 435 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x876e, "HP ENVY x360 Convertible 13-ay0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8780, "HP ZBook Fury 17 G7 Mobile Workstation", From 4d4e1b6319e5c4425ea3faeaf9a10b8b4c16c1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Mon, 8 Jan 2024 17:44:58 -0300 Subject: [PATCH 20/32] ASoC: mediatek: mt8192: Check existence of dai_name before dereferencing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following commit 13f58267cda3 ("ASoC: soc.h: don't create dummy Component via COMP_DUMMY()"), the dai_name field is only populated for dummy components after the card is registered. This causes a null pointer dereference in the mt8192-mt6359 sound card driver's probe function when searching for a dai_name among all the card's dai links. Verify that the dai_name is non-null before passing it to strcmp. While at it, also check that there's at least one codec. Reported-by: kernelci.org bot Closes: https://linux.kernelci.org/test/case/id/6582cd6d992645c680e13478/ Fixes: 13f58267cda3 ("ASoC: soc.h: don't create dummy Component via COMP_DUMMY()") Signed-off-by: Nícolas F. R. A. Prado Link: https://msgid.link/r/20240108204508.691739-1-nfraprado@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index 5bd6addd145051..bfcb2c486c39df 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -1208,7 +1208,8 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) dai_link->ignore = 0; } - if (strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) + if (dai_link->num_codecs && dai_link->codecs[0].dai_name && + strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) dai_link->ops = &mt8192_rt1015_i2s_ops; if (!dai_link->platforms->name) From dcaca1b5f0d47f4ed59f606795df531cc8a2d7d2 Mon Sep 17 00:00:00 2001 From: Gergo Koteles Date: Mon, 8 Jan 2024 22:16:46 +0100 Subject: [PATCH 21/32] ALSA: hda/tas2781: annotate calibration data endianness Sparse reports an endian mismatch. The amplifier expects the calibration data as big-endian. Use the __be32 type to express endianness better. Fixes: c3ca4458cc2f ("ALSA: hda/tas2781: add TAS2563 support for 14ARB7") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202401072137.Oc7pQgRW-lkp@intel.com/ Signed-off-by: Gergo Koteles Link: https://lore.kernel.org/r/3852ff28ea7d5d8f2086d8dd78aeff8d1d984991.1704748435.git.soyer@irl.hu Signed-off-by: Takashi Iwai --- sound/pci/hda/tas2781_hda_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index 4805cf0b648082..2dd809de62e5a4 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -424,8 +424,8 @@ static const struct snd_kcontrol_new tas2781_dsp_conf_ctrl = { static void tas2563_apply_calib(struct tasdevice_priv *tas_priv) { - unsigned int data; int offset = 0; + __be32 data; int ret; for (int i = 0; i < tas_priv->ndev; i++) { From 8c51c13dc63d46e754c44215eabc0890a8bd9bfb Mon Sep 17 00:00:00 2001 From: Mirsad Todorovac Date: Sun, 7 Jan 2024 18:37:02 +0100 Subject: [PATCH 22/32] kselftest/alsa - mixer-test: fix the number of parameters to ksft_exit_fail_msg() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minor fix in the number of arguments to error reporting function in the test program as reported by GCC 13.2.0 warning. mixer-test.c: In function ‘find_controls’: mixer-test.c:169:44: warning: too many arguments for format [-Wformat-extra-args] 169 | ksft_exit_fail_msg("snd_ctl_poll_descriptors() failed for %d\n", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The number of arguments in call to ksft_exit_fail_msg() doesn't correspond to the format specifiers, so this is adjusted resembling the sibling calls to the error function. Fixes: b1446bda56456 ("kselftest: alsa: Check for event generation when we write to controls") Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Shuah Khan Cc: linux-sound@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mirsad Todorovac Acked-by: Mark Brown Link: https://lore.kernel.org/r/20240107173704.937824-2-mirsad.todorovac@alu.unizg.hr Signed-off-by: Takashi Iwai --- tools/testing/selftests/alsa/mixer-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c index 23df154fcdd77b..208c2170c0749a 100644 --- a/tools/testing/selftests/alsa/mixer-test.c +++ b/tools/testing/selftests/alsa/mixer-test.c @@ -166,7 +166,7 @@ static void find_controls(void) err = snd_ctl_poll_descriptors(card_data->handle, &card_data->pollfd, 1); if (err != 1) { - ksft_exit_fail_msg("snd_ctl_poll_descriptors() failed for %d\n", + ksft_exit_fail_msg("snd_ctl_poll_descriptors() failed for card %d: %d\n", card, err); } From 3f47c1ebe5ca9c5883e596c7888dec4bec0176d8 Mon Sep 17 00:00:00 2001 From: Mirsad Todorovac Date: Sun, 7 Jan 2024 18:37:04 +0100 Subject: [PATCH 23/32] kselftest/alsa - mixer-test: Fix the print format specifier warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GCC 13.2.0 compiler issued the following warning: mixer-test.c: In function ‘ctl_value_index_valid’: mixer-test.c:322:79: warning: format ‘%lld’ expects argument of type ‘long long int’, \ but argument 5 has type ‘long int’ [-Wformat=] 322 | ksft_print_msg("%s.%d value %lld more than maximum %lld\n", | ~~~^ | | | long long int | %ld 323 | ctl->name, index, int64_val, 324 | snd_ctl_elem_info_get_max(ctl->info)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | long int Fixing the format specifier as advised by the compiler suggestion removes the warning. Fixes: 3f48b137d88e7 ("kselftest: alsa: Factor out check that values meet constraints") Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Shuah Khan Cc: linux-sound@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mirsad Todorovac Acked-by: Mark Brown Link: https://lore.kernel.org/r/20240107173704.937824-3-mirsad.todorovac@alu.unizg.hr Signed-off-by: Takashi Iwai --- tools/testing/selftests/alsa/mixer-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c index 208c2170c0749a..df942149c6f6c5 100644 --- a/tools/testing/selftests/alsa/mixer-test.c +++ b/tools/testing/selftests/alsa/mixer-test.c @@ -319,7 +319,7 @@ static bool ctl_value_index_valid(struct ctl_data *ctl, } if (int64_val > snd_ctl_elem_info_get_max64(ctl->info)) { - ksft_print_msg("%s.%d value %lld more than maximum %lld\n", + ksft_print_msg("%s.%d value %lld more than maximum %ld\n", ctl->name, index, int64_val, snd_ctl_elem_info_get_max(ctl->info)); return false; From f77a255e74c348a158d21a471e993e70ff710737 Mon Sep 17 00:00:00 2001 From: Mirsad Todorovac Date: Sun, 7 Jan 2024 18:37:06 +0100 Subject: [PATCH 24/32] kselftest/alsa - mixer-test: Fix the print format specifier warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC 13.2.0 compiler issued the following warning: mixer-test.c:350:80: warning: format ‘%ld’ expects argument of type ‘long int’, \ but argument 5 has type ‘unsigned int’ [-Wformat=] 350 | ksft_print_msg("%s.%d value %ld more than item count %ld\n", | ~~^ | | | long int | %d 351 | ctl->name, index, int_val, 352 | snd_ctl_elem_info_get_items(ctl->info)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | unsigned int Fixing the format specifier in call to ksft_print_msg() according to the compiler suggestion silences the warning. Fixes: 10f2f194663af ("kselftest: alsa: Validate values read from enumerations") Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Shuah Khan Cc: linux-sound@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mirsad Todorovac Acked-by: Mark Brown Link: https://lore.kernel.org/r/20240107173704.937824-4-mirsad.todorovac@alu.unizg.hr Signed-off-by: Takashi Iwai --- tools/testing/selftests/alsa/mixer-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c index df942149c6f6c5..1c04e5f638a0b0 100644 --- a/tools/testing/selftests/alsa/mixer-test.c +++ b/tools/testing/selftests/alsa/mixer-test.c @@ -347,7 +347,7 @@ static bool ctl_value_index_valid(struct ctl_data *ctl, } if (int_val >= snd_ctl_elem_info_get_items(ctl->info)) { - ksft_print_msg("%s.%d value %ld more than item count %ld\n", + ksft_print_msg("%s.%d value %ld more than item count %u\n", ctl->name, index, int_val, snd_ctl_elem_info_get_items(ctl->info)); return false; From fd38dd6abda589a8771e7872e4dea28c99c6a6ef Mon Sep 17 00:00:00 2001 From: Mirsad Todorovac Date: Sun, 7 Jan 2024 18:37:08 +0100 Subject: [PATCH 25/32] kselftest/alsa - conf: Stringify the printed errno in sysfs_get() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC 13.2.0 reported the warning of the print format specifier: conf.c: In function ‘sysfs_get’: conf.c:181:72: warning: format ‘%s’ expects argument of type ‘char *’, \ but argument 3 has type ‘int’ [-Wformat=] 181 | ksft_exit_fail_msg("sysfs: unable to read value '%s': %s\n", | ~^ | | | char * | %d The fix passes strerror(errno) as it was intended, like in the sibling error exit message. Fixes: aba51cd0949ae ("selftests: alsa - add PCM test") Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Shuah Khan Cc: linux-sound@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mirsad Todorovac Acked-by: Mark Brown Link: https://lore.kernel.org/r/20240107173704.937824-5-mirsad.todorovac@alu.unizg.hr Signed-off-by: Takashi Iwai --- tools/testing/selftests/alsa/conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/alsa/conf.c b/tools/testing/selftests/alsa/conf.c index 00925eb8d9f477..89e3656a042d76 100644 --- a/tools/testing/selftests/alsa/conf.c +++ b/tools/testing/selftests/alsa/conf.c @@ -179,7 +179,7 @@ static char *sysfs_get(const char *sysfs_root, const char *id) close(fd); if (len < 0) ksft_exit_fail_msg("sysfs: unable to read value '%s': %s\n", - path, errno); + path, strerror(errno)); while (len > 0 && path[len-1] == '\n') len--; path[len] = '\0'; From e70b8dd26711704b1ff1f1b4eb3d048ba69e29da Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 10 Jan 2024 11:57:57 +0100 Subject: [PATCH 26/32] ASoC: mediatek: mt8195: Remove afe-dai component and rework codec link Remove the extra 'mt8195-afe-pcm-dai' component, register the DAI drivers to the main AFE component, and rework the DAI linking between the headset codec (RT5682/RT5682S) and the TDM interface in the probe function to stop assigning name, relying on the of_node of the codec. Also replace the COMP_DUMMY codec entry with a COMP_EMPTY for the ETDM2_IN and remove it entirely from ETDM1_OUT to fix the registration flow for this sound card. While at it, since we also need to swap the codec init function from ETDM2_IN to ETDM1_OUT, remove the static assignment of both `ops` and `init` for both, as we now assign these dynamically during probe. Fixes: 13f58267cda3 ("ASoC: soc.h: don't create dummy Component via COMP_DUMMY()") Signed-off-by: AngeloGioacchino Del Regno Link: https://msgid.link/r/20240110105757.539089-1-angelogioacchino.delregno@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 33 +---------------- sound/soc/mediatek/mt8195/mt8195-mt6359.c | 41 +++++++++++++++------- 2 files changed, 29 insertions(+), 45 deletions(-) diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c index 1e33863c85ca06..620d7ade1992e3 100644 --- a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c +++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c @@ -1795,10 +1795,6 @@ static const struct snd_kcontrol_new mt8195_memif_controls[] = { MT8195_AFE_IRQ_28), }; -static const struct snd_soc_component_driver mt8195_afe_pcm_dai_component = { - .name = "mt8195-afe-pcm-dai", -}; - static const struct mtk_base_memif_data memif_data[MT8195_AFE_MEMIF_NUM] = { [MT8195_AFE_MEMIF_DL2] = { .name = "DL2", @@ -3037,7 +3033,6 @@ static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct reset_control *rstc; int i, irq_id, ret; - struct snd_soc_component *component; ret = of_reserved_mem_device_init(dev); if (ret) @@ -3170,36 +3165,12 @@ static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev) /* register component */ ret = devm_snd_soc_register_component(dev, &mt8195_afe_component, - NULL, 0); + afe->dai_drivers, afe->num_dai_drivers); if (ret) { dev_warn(dev, "err_platform\n"); goto err_pm_put; } - component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL); - if (!component) { - ret = -ENOMEM; - goto err_pm_put; - } - - ret = snd_soc_component_initialize(component, - &mt8195_afe_pcm_dai_component, - dev); - if (ret) - goto err_pm_put; - -#ifdef CONFIG_DEBUG_FS - component->debugfs_prefix = "pcm"; -#endif - - ret = snd_soc_add_component(component, - afe->dai_drivers, - afe->num_dai_drivers); - if (ret) { - dev_warn(dev, "err_dai_component\n"); - goto err_pm_put; - } - ret = regmap_multi_reg_write(afe->regmap, mt8195_afe_reg_defaults, ARRAY_SIZE(mt8195_afe_reg_defaults)); if (ret) @@ -3224,8 +3195,6 @@ static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev) static void mt8195_afe_pcm_dev_remove(struct platform_device *pdev) { - snd_soc_unregister_component(&pdev->dev); - pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) mt8195_afe_runtime_suspend(&pdev->dev); diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c index 4feb9fb7696792..53fd8a897b9d27 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c @@ -934,12 +934,11 @@ SND_SOC_DAILINK_DEFS(ETDM1_IN_BE, SND_SOC_DAILINK_DEFS(ETDM2_IN_BE, DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")), - DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY()), DAILINK_COMP_ARRAY(COMP_EMPTY())); SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE, DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")), - DAILINK_COMP_ARRAY(COMP_DUMMY()), DAILINK_COMP_ARRAY(COMP_EMPTY())); SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE, @@ -1237,8 +1236,6 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .dpcm_capture = 1, - .init = mt8195_rt5682_init, - .ops = &mt8195_rt5682_etdm_ops, .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, SND_SOC_DAILINK_REG(ETDM2_IN_BE), }, @@ -1249,7 +1246,6 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .dpcm_playback = 1, - .ops = &mt8195_rt5682_etdm_ops, .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, SND_SOC_DAILINK_REG(ETDM1_OUT_BE), }, @@ -1381,7 +1377,7 @@ static int mt8195_mt6359_dev_probe(struct platform_device *pdev) struct snd_soc_dai_link *dai_link; struct mtk_soc_card_data *soc_card_data; struct mt8195_mt6359_priv *mach_priv; - struct device_node *platform_node, *adsp_node, *dp_node, *hdmi_node; + struct device_node *platform_node, *adsp_node, *codec_node, *dp_node, *hdmi_node; struct mt8195_card_data *card_data; int is5682s = 0; int init6359 = 0; @@ -1401,8 +1397,12 @@ static int mt8195_mt6359_dev_probe(struct platform_device *pdev) if (!card->name) card->name = card_data->name; - if (strstr(card->name, "_5682s")) + if (strstr(card->name, "_5682s")) { + codec_node = of_find_compatible_node(NULL, NULL, "realtek,rt5682s"); is5682s = 1; + } else + codec_node = of_find_compatible_node(NULL, NULL, "realtek,rt5682i"); + soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*card_data), GFP_KERNEL); if (!soc_card_data) return -ENOMEM; @@ -1488,12 +1488,27 @@ static int mt8195_mt6359_dev_probe(struct platform_device *pdev) dai_link->codecs->dai_name = "i2s-hifi"; dai_link->init = mt8195_hdmi_codec_init; } - } else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0 || - strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { - dai_link->codecs->name = - is5682s ? RT5682S_DEV0_NAME : RT5682_DEV0_NAME; - dai_link->codecs->dai_name = - is5682s ? RT5682S_CODEC_DAI : RT5682_CODEC_DAI; + } else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0) { + if (!codec_node) { + dev_err(&pdev->dev, "Codec not found!\n"); + } else { + dai_link->codecs->of_node = codec_node; + dai_link->codecs->name = NULL; + dai_link->codecs->dai_name = + is5682s ? RT5682S_CODEC_DAI : RT5682_CODEC_DAI; + dai_link->init = mt8195_rt5682_init; + dai_link->ops = &mt8195_rt5682_etdm_ops; + } + } else if (strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { + if (!codec_node) { + dev_err(&pdev->dev, "Codec not found!\n"); + } else { + dai_link->codecs->of_node = codec_node; + dai_link->codecs->name = NULL; + dai_link->codecs->dai_name = + is5682s ? RT5682S_CODEC_DAI : RT5682_CODEC_DAI; + dai_link->ops = &mt8195_rt5682_etdm_ops; + } } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || strcmp(dai_link->name, "UL_SRC1_BE") == 0 || strcmp(dai_link->name, "UL_SRC2_BE") == 0) { From e3b3ec967a7d93b9010a5af9a2394c8b5c8f31ed Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Thu, 11 Jan 2024 11:52:26 +0100 Subject: [PATCH 27/32] ASoC: mediatek: sof-common: Add NULL check for normal_link string It's not granted that all entries of struct sof_conn_stream declare a `normal_link` (a non-SOF, direct link) string, and this is the case for SoCs that support only SOF paths (hence do not support both direct and SOF usecases). For example, in the case of MT8188 there is no normal_link string in any of the sof_conn_stream entries and there will be more drivers doing that in the future. To avoid possible NULL pointer KPs, add a NULL check for `normal_link`. Fixes: 0caf1120c583 ("ASoC: mediatek: mt8195: extract SOF common code") Signed-off-by: AngeloGioacchino Del Regno Link: https://msgid.link/r/20240111105226.117603-1-angelogioacchino.delregno@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/common/mtk-dsp-sof-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/common/mtk-dsp-sof-common.c b/sound/soc/mediatek/common/mtk-dsp-sof-common.c index f3894010f6563a..7ec8965a70c06b 100644 --- a/sound/soc/mediatek/common/mtk-dsp-sof-common.c +++ b/sound/soc/mediatek/common/mtk-dsp-sof-common.c @@ -24,7 +24,7 @@ int mtk_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai_link *sof_dai_link = NULL; const struct sof_conn_stream *conn = &sof_priv->conn_streams[i]; - if (strcmp(rtd->dai_link->name, conn->normal_link)) + if (conn->normal_link && strcmp(rtd->dai_link->name, conn->normal_link)) continue; for_each_card_rtds(card, runtime) { From cdac6e1f716419ce307ad3e44a718557a5469c17 Mon Sep 17 00:00:00 2001 From: Chancel Liu Date: Thu, 11 Jan 2024 11:52:19 +0900 Subject: [PATCH 28/32] ALSA: aloop: Introduce a function to get if access is interleaved mode There's a use case that playback stream of a loopback cable works on RW_INTERLEAVED mode while capture stream works on MMAP_INTERLEAVED mode: aplay -Dhw:Loopback,0,0 S32_48K_2ch.wav; arecord -Dplughw:Loopback,1,0 -fS32_LE -r16000 -c2 cap.wav; The plug plugin handles only slave PCM support MMAP mode. Not only plug plugin but also other plugins like direct plugins(dmix/dsnoop/dshare) work on MMAP access mode. In this case capture stream is the slave PCM works on MMAP_INTERLEAVED mode. However loopback_check_format() rejects this access setting and return: arecord: pcm_read:2240: read error: Input/output error To fix it a function called is_access_interleaved() is introduced to get if access is interleaved mode. If both access of capture stream and playback stream is interleaved mode loopback_check_format() will allow this kind of access setting. Fixes: 462494565c27 ("ALSA: aloop: Add support for the non-interleaved access mode") Signed-off-by: Chancel Liu Link: https://lore.kernel.org/r/20240111025219.2678764-1-chancel.liu@nxp.com Signed-off-by: Takashi Iwai --- sound/drivers/aloop.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index e87dc67f33c692..1c65e0a3b13ce8 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -322,6 +322,17 @@ static int loopback_snd_timer_close_cable(struct loopback_pcm *dpcm) return 0; } +static bool is_access_interleaved(snd_pcm_access_t access) +{ + switch (access) { + case SNDRV_PCM_ACCESS_MMAP_INTERLEAVED: + case SNDRV_PCM_ACCESS_RW_INTERLEAVED: + return true; + default: + return false; + } +}; + static int loopback_check_format(struct loopback_cable *cable, int stream) { struct snd_pcm_runtime *runtime, *cruntime; @@ -341,7 +352,8 @@ static int loopback_check_format(struct loopback_cable *cable, int stream) check = runtime->format != cruntime->format || runtime->rate != cruntime->rate || runtime->channels != cruntime->channels || - runtime->access != cruntime->access; + is_access_interleaved(runtime->access) != + is_access_interleaved(cruntime->access); if (!check) return 0; if (stream == SNDRV_PCM_STREAM_CAPTURE) { @@ -369,7 +381,8 @@ static int loopback_check_format(struct loopback_cable *cable, int stream) &setup->channels_id); setup->channels = runtime->channels; } - if (setup->access != runtime->access) { + if (is_access_interleaved(setup->access) != + is_access_interleaved(runtime->access)) { snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &setup->access_id); setup->access = runtime->access; @@ -584,8 +597,7 @@ static void copy_play_buf(struct loopback_pcm *play, size = play->pcm_buffer_size - src_off; if (dst_off + size > capt->pcm_buffer_size) size = capt->pcm_buffer_size - dst_off; - if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED || - runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) + if (!is_access_interleaved(runtime->access)) copy_play_buf_part_n(play, capt, size, src_off, dst_off); else memcpy(dst + dst_off, src + src_off, size); @@ -1544,8 +1556,7 @@ static int loopback_access_get(struct snd_kcontrol *kcontrol, mutex_lock(&loopback->cable_lock); access = loopback->setup[kcontrol->id.subdevice][kcontrol->id.device].access; - ucontrol->value.enumerated.item[0] = access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED || - access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED; + ucontrol->value.enumerated.item[0] = !is_access_interleaved(access); mutex_unlock(&loopback->cable_lock); return 0; From a03cfad512ac24a35184d7d87ec0d5489e1cb763 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 12 Jan 2024 12:10:23 +0100 Subject: [PATCH 29/32] ALSA: oxygen: Fix right channel of capture volume mixer There was a typo in oxygen mixer code that didn't update the right channel value properly for the capture volume. Let's fix it. This trivial fix was originally reported on Bugzilla. Fixes: a3601560496d ("[ALSA] oxygen: add front panel controls") Cc: Link: https://bugzilla.kernel.org/show_bug.cgi?id=156561 Link: https://lore.kernel.org/r/20240112111023.6208-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 46705ec77b4810..eb3aca16359c58 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -718,7 +718,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl, oldreg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN); newreg = oldreg & ~0x0707; newreg = newreg | (value->value.integer.value[0] & 7); - newreg = newreg | ((value->value.integer.value[0] & 7) << 8); + newreg = newreg | ((value->value.integer.value[1] & 7) << 8); change = newreg != oldreg; if (change) oxygen_write_ac97(chip, 1, AC97_REC_GAIN, newreg); From 813c2f2925ee9c10dc4acd5aa7410cd3357e8da8 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 12 Jan 2024 15:27:49 +0200 Subject: [PATCH 30/32] ASoC: SOF: icp3-dtrace: Revert "Fix wrong kfree() usage" The offending patch introduces memory leak when there is no error, the memory allocated for the temporary storage is not freed up. As I have commented, the original code was correct and cleaner to follow but it was not obvious from the patch that it will introduce regression. Fixes: 8c91ca76f448 ("ASoC: SOF: icp3-dtrace: Fix wrong kfree() usage") Link: https://lore.kernel.org/all/aec61f67-6b4f-49e6-b458-c332983a0ad6@linux.intel.com/ Signed-off-by: Peter Ujfalusi Link: https://msgid.link/r/20240112132749.28970-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-dtrace.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index 93b189c2d2ee2f..0dca139322f3d2 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -137,7 +137,6 @@ static int trace_filter_parse(struct snd_sof_dev *sdev, char *string, dev_err(sdev->dev, "Parsing filter entry '%s' failed with %d\n", entry, entry_len); - kfree(*out); return -EINVAL; } } @@ -209,13 +208,13 @@ static ssize_t dfsentry_trace_filter_write(struct file *file, const char __user ret = ipc3_trace_update_filter(sdev, num_elems, elems); if (ret < 0) { dev_err(sdev->dev, "Filter update failed: %d\n", ret); - kfree(elems); goto error; } } ret = count; error: kfree(string); + kfree(elems); return ret; } From 301bda18ac735eaaad5823dbdd067b3b2728c780 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 12 Jan 2024 06:10:15 +0000 Subject: [PATCH 31/32] ASoC: audio-graph-card2: fix index check on graph_parse_node_multi_nm() commit d685aea5e0a8 ("ASoC: audio-graph-card2: fix off by one in graph_parse_node_multi_nm()") uses ">=" instead of ">" for index check, but it was wrong. The nm_idx will be increment at end of loop, thus, ">" is correct. while (1) { ... => if (*nm_idx > nm_max) break; ... (*nm_idx)++; } Without this patch, "Multi-Codec-1" sample on ${LINUX}/sound/soc/generic/audio-graph-card2-custom-sample.dtsi will be error. Signed-off-by: Kuninori Morimoto Link: https://msgid.link/r/87o7drdqux.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/audio-graph-card2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 9c94677f681a17..62606e20be9a3e 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -556,7 +556,7 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link, struct device_node *mcodec_port; int codec_idx; - if (*nm_idx >= nm_max) + if (*nm_idx > nm_max) break; mcpu_ep_n = of_get_next_child(mcpu_port, mcpu_ep_n); From 454abb80e26ab85323a30e52aa7b0ee9aae1d38a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Fri, 12 Jan 2024 12:33:49 +0100 Subject: [PATCH 32/32] ALSA: hda: Properly setup HDMI stream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 4005d1ba0a7e ("ASoC: soc-dai: don't call PCM audio ops if the stream is not supported") HDMI playback is broken with avs driver. This happens because for HDMI stream (unlike generic HDA one) channels_min for stream is not set when creating PCMs. Fix this by setting the value based on first available converter. Fixes: 4005d1ba0a7e ("ASoC: soc-dai: don't call PCM audio ops if the stream is not supported") Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20240112113349.2905328-1-amadeuszx.slawinski@linux.intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 200779296a1b8b..495d63101186fd 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2301,6 +2301,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num); for (idx = 0; idx < pcm_num; idx++) { + struct hdmi_spec_per_cvt *per_cvt; struct hda_pcm *info; struct hda_pcm_stream *pstr; @@ -2316,6 +2317,11 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; pstr->substreams = 1; pstr->ops = generic_ops; + + per_cvt = get_cvt(spec, 0); + pstr->channels_min = per_cvt->channels_min; + pstr->channels_max = per_cvt->channels_max; + /* pcm number is less than pcm_rec array size */ if (spec->pcm_used >= ARRAY_SIZE(spec->pcm_rec)) break;