diff options
25 files changed, 339 insertions, 242 deletions
diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml index 8c77e7f68ad7..76d5a437dc8f 100644 --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml @@ -40,6 +40,14 @@ properties: hardware that provides additional audio functionalities if present. The AFE will link to ADSP when the phandle is provided. + mediatek,accdet: + $ref: /schemas/types.yaml#/definitions/phandle + description: + The phandle to the MT6359 accessory detection block, which detects audio + jack insertion and removal. This property should only be present if the + accdet block is actually wired to the audio jack pins and to be used for + jack detection. + patternProperties: "^dai-link-[0-9]+$": type: object diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig index 157c124570c8..b9432052c638 100644 --- a/sound/soc/amd/acp/Kconfig +++ b/sound/soc/amd/acp/Kconfig @@ -28,6 +28,9 @@ config SND_SOC_AMD_ACP_LEGACY_COMMON config SND_SOC_AMD_ACP_I2S tristate +config SND_SOC_AMD_ACPI_MACH + tristate + config SND_SOC_AMD_ACP_PCM tristate select SND_SOC_ACPI if ACPI @@ -37,6 +40,7 @@ config SND_SOC_AMD_ACP_PCI depends on X86 && PCI depends on ACPI select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH help This options enables generic PCI driver for ACP device. @@ -47,6 +51,7 @@ config SND_AMD_ASOC_RENOIR select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH depends on X86 && PCI help This option enables Renoir I2S support on AMD platform. @@ -58,6 +63,7 @@ config SND_AMD_ASOC_REMBRANDT select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH depends on AMD_NODE depends on X86 && PCI help @@ -74,6 +80,7 @@ config SND_AMD_ASOC_ACP63 select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH help This option enables Acp6.3 I2S support on AMD platform. Say Y if you want to enable AUDIO on ACP6.3 @@ -88,6 +95,7 @@ config SND_AMD_ASOC_ACP70 select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH help This option enables Acp7.0 PDM support on AMD platform. Say Y if you want to enable AUDIO on ACP7.0 diff --git a/sound/soc/amd/acp/Makefile b/sound/soc/amd/acp/Makefile index 7c75892e678b..08220b9a3802 100644 --- a/sound/soc/amd/acp/Makefile +++ b/sound/soc/amd/acp/Makefile @@ -11,6 +11,7 @@ snd-acp-pdm-y := acp-pdm.o snd-acp-legacy-common-y := acp-legacy-common.o snd-acp-pci-y := acp-pci.o snd-amd-sdw-acpi-y := amd-sdw-acpi.o +snd-amd-acpi-mach-y := amd-acpi-mach.o #platform specific driver snd-acp-renoir-y := acp-renoir.o @@ -32,6 +33,7 @@ obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o obj-$(CONFIG_SND_SOC_AMD_ACP_PDM) += snd-acp-pdm.o obj-$(CONFIG_SND_SOC_AMD_ACP_LEGACY_COMMON) += snd-acp-legacy-common.o obj-$(CONFIG_SND_SOC_AMD_ACP_PCI) += snd-acp-pci.o +obj-$(CONFIG_SND_SOC_AMD_ACPI_MACH) += snd-amd-acpi-mach.o obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o obj-$(CONFIG_SND_AMD_ASOC_REMBRANDT) += snd-acp-rembrandt.o diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 255f90ca956a..b4d68484e06d 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -24,7 +24,50 @@ #define ACP63_PDM_ADDR 0x02 #define ACP70_PDM_ADDR 0x02 -const struct snd_acp_hw_ops acp_common_hw_ops = { +struct acp_resource rn_rsrc = { + .offset = 20, + .no_of_ctrls = 1, + .irqp_used = 0, + .irq_reg_offset = 0x1800, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x02052800, +}; +EXPORT_SYMBOL_NS_GPL(rn_rsrc, "SND_SOC_ACP_COMMON"); + +struct acp_resource rmb_rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x03802800, +}; +EXPORT_SYMBOL_NS_GPL(rmb_rsrc, "SND_SOC_ACP_COMMON"); + +struct acp_resource acp63_rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x03802800, +}; +EXPORT_SYMBOL_NS_GPL(acp63_rsrc, "SND_SOC_ACP_COMMON"); + +struct acp_resource acp70_rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .scratch_reg_offset = 0x10000, + .sram_pte_offset = 0x03800000, +}; +EXPORT_SYMBOL_NS_GPL(acp70_rsrc, "SND_SOC_ACP_COMMON"); + +static const struct snd_acp_hw_ops acp_common_hw_ops = { /* ACP hardware initilizations */ .acp_init = acp_init, .acp_deinit = acp_deinit, @@ -34,7 +77,6 @@ const struct snd_acp_hw_ops acp_common_hw_ops = { .en_interrupts = acp_enable_interrupts, .dis_interrupts = acp_disable_interrupts, }; -EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON"); irqreturn_t acp_irq_handler(int irq, void *data) { diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 9322379cb36f..1892fbdfc780 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -137,26 +137,26 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id chip->name = "acp_asoc_renoir"; chip->rsrc = &rn_rsrc; chip->acp_hw_ops_init = acp31_hw_ops_init; - chip->machines = snd_soc_acpi_amd_acp_machines; + chip->machines = &snd_soc_acpi_amd_acp_machines; break; case 0x6f: chip->name = "acp_asoc_rembrandt"; chip->rsrc = &rmb_rsrc; chip->acp_hw_ops_init = acp6x_hw_ops_init; - chip->machines = snd_soc_acpi_amd_rmb_acp_machines; + chip->machines = &snd_soc_acpi_amd_rmb_acp_machines; break; case 0x63: chip->name = "acp_asoc_acp63"; chip->rsrc = &acp63_rsrc; chip->acp_hw_ops_init = acp63_hw_ops_init; - chip->machines = snd_soc_acpi_amd_acp63_acp_machines; + chip->machines = &snd_soc_acpi_amd_acp63_acp_machines; break; case 0x70: case 0x71: chip->name = "acp_asoc_acp70"; chip->rsrc = &acp70_rsrc; chip->acp_hw_ops_init = acp70_hw_ops_init; - chip->machines = snd_soc_acpi_amd_acp70_acp_machines; + chip->machines = &snd_soc_acpi_amd_acp70_acp_machines; break; default: dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision); @@ -183,7 +183,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id IRQF_SHARED, "ACP_I2S_IRQ", chip); if (ret) { dev_err(&pci->dev, "ACP I2S IRQ request failed %d\n", ret); - return ret; + goto de_init; } check_acp_config(pci, chip); diff --git a/sound/soc/amd/acp/amd-acpi-mach.c b/sound/soc/amd/acp/amd-acpi-mach.c new file mode 100644 index 000000000000..d95047d2ee94 --- /dev/null +++ b/sound/soc/amd/acp/amd-acpi-mach.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * amd-acpi-match.c - tables and support for ACP platforms + * ACPI enumeration. + * + * Copyright 2025 Advanced Micro Devices, Inc. + */ + +#include <sound/soc-acpi.h> + +struct snd_soc_acpi_codecs amp_rt1019 = { + .num_codecs = 1, + .codecs = {"10EC1019"} +}; + +struct snd_soc_acpi_codecs amp_max = { + .num_codecs = 1, + .codecs = {"MX98360A"} +}; + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = { + { + .id = "10EC5682", + .drv_name = "acp3xalc56821019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + { + .id = "RTL5682", + .drv_name = "acp3xalc5682sm98360", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_max, + }, + { + .id = "RTL5682", + .drv_name = "acp3xalc5682s1019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + { + .id = "AMDI1019", + .drv_name = "renoir-acp", + }, + { + .id = "ESSX8336", + .drv_name = "acp3x-es83xx", + }, + {}, +}; +EXPORT_SYMBOL_NS_GPL(snd_soc_acpi_amd_acp_machines, "SND_SOC_ACP_COMMON"); + +struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines[] = { + { + .id = "10508825", + .drv_name = "rmb-nau8825-max", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_max, + }, + { + .id = "AMDI0007", + .drv_name = "rembrandt-acp", + }, + { + .id = "RTL5682", + .drv_name = "rmb-rt5682s-rt1019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + {}, +}; +EXPORT_SYMBOL_NS_GPL(snd_soc_acpi_amd_rmb_acp_machines, "SND_SOC_ACP_COMMON"); + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_acp_machines[] = { + { + .id = "AMDI0052", + .drv_name = "acp63-acp", + }, + {}, +}; +EXPORT_SYMBOL_NS_GPL(snd_soc_acpi_amd_acp63_acp_machines, "SND_SOC_ACP_COMMON"); + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = { + { + .id = "AMDI0029", + .drv_name = "acp70-acp", + }, + {}, +}; +EXPORT_SYMBOL_NS_GPL(snd_soc_acpi_amd_acp70_acp_machines, "SND_SOC_ACP_COMMON"); + +MODULE_DESCRIPTION("AMD ACP tables and support for ACPI enumeration"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Venkataprasad.potturu@amd.com"); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 796f8efd395c..863e74fcee43 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -238,120 +238,15 @@ enum acp_config { ACP_CONFIG_20, }; -struct acp_resource rn_rsrc = { - .offset = 20, - .no_of_ctrls = 1, - .irqp_used = 0, - .irq_reg_offset = 0x1800, - .scratch_reg_offset = 0x12800, - .sram_pte_offset = 0x02052800, -}; - -struct acp_resource rmb_rsrc = { - .offset = 0, - .no_of_ctrls = 2, - .irqp_used = 1, - .soc_mclk = true, - .irq_reg_offset = 0x1a00, - .scratch_reg_offset = 0x12800, - .sram_pte_offset = 0x03802800, -}; - -struct acp_resource acp63_rsrc = { - .offset = 0, - .no_of_ctrls = 2, - .irqp_used = 1, - .soc_mclk = true, - .irq_reg_offset = 0x1a00, - .scratch_reg_offset = 0x12800, - .sram_pte_offset = 0x03802800, -}; - -struct acp_resource acp70_rsrc = { - .offset = 0, - .no_of_ctrls = 2, - .irqp_used = 1, - .soc_mclk = true, - .irq_reg_offset = 0x1a00, - .scratch_reg_offset = 0x10000, - .sram_pte_offset = 0x03800000, -}; - -struct snd_soc_acpi_codecs amp_rt1019 = { - .num_codecs = 1, - .codecs = {"10EC1019"} -}; - -struct snd_soc_acpi_codecs amp_max = { - .num_codecs = 1, - .codecs = {"MX98360A"} -}; - -struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = { - { - .id = "10EC5682", - .drv_name = "acp3xalc56821019", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_rt1019, - }, - { - .id = "RTL5682", - .drv_name = "acp3xalc5682sm98360", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_max, - }, - { - .id = "RTL5682", - .drv_name = "acp3xalc5682s1019", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_rt1019, - }, - { - .id = "AMDI1019", - .drv_name = "renoir-acp", - }, - { - .id = "ESSX8336", - .drv_name = "acp3x-es83xx", - }, - {}, -}; - -struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines[] = { - { - .id = "10508825", - .drv_name = "rmb-nau8825-max", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_max, - }, - { - .id = "AMDI0007", - .drv_name = "rembrandt-acp", - }, - { - .id = "RTL5682", - .drv_name = "rmb-rt5682s-rt1019", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_rt1019, - }, - {}, -}; - -struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_acp_machines[] = { - { - .id = "AMDI0052", - .drv_name = "acp63-acp", - }, - {}, -}; - -struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = { - { - .id = "AMDI0029", - .drv_name = "acp70-acp", - }, - {}, -}; +extern struct acp_resource rn_rsrc; +extern struct acp_resource rmb_rsrc; +extern struct acp_resource acp63_rsrc; +extern struct acp_resource acp70_rsrc; + +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_acp_machines; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines; extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops; extern const struct snd_soc_dai_ops acp_dmic_dai_ops; diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c index 735a1e487c6f..b3158a84b87a 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -1441,7 +1441,6 @@ void cs35l56_remove(struct cs35l56_private *cs35l56) if (cs35l56->base.irq) devm_free_irq(cs35l56->base.dev, cs35l56->base.irq, &cs35l56->base); - flush_workqueue(cs35l56->dsp_wq); destroy_workqueue(cs35l56->dsp_wq); pm_runtime_dont_use_autosuspend(cs35l56->base.dev); diff --git a/sound/soc/codecs/mt6359-accdet.h b/sound/soc/codecs/mt6359-accdet.h index c234f2f4276a..78ada3a5bfae 100644 --- a/sound/soc/codecs/mt6359-accdet.h +++ b/sound/soc/codecs/mt6359-accdet.h @@ -123,6 +123,15 @@ struct mt6359_accdet { struct workqueue_struct *jd_workqueue; }; +#if IS_ENABLED(CONFIG_SND_SOC_MT6359_ACCDET) int mt6359_accdet_enable_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *jack); +#else +static inline int +mt6359_accdet_enable_jack_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack) +{ + return -EOPNOTSUPP; +} +#endif #endif diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index fc152496d5dc..a1ec881d7084 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -9,7 +9,6 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/delay.h> -#include <linux/gpio.h> #include <linux/i2c.h> #include <linux/regmap.h> #include <linux/of.h> diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index 09c6c1326833..d3d2e7f40170 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -14,7 +14,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/device.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/slab.h> #include <linux/module.h> #include <sound/core.h> @@ -22,17 +22,22 @@ #include <sound/initval.h> #include <sound/soc.h> -#include "pcm3008.h" +struct pcm3008 { + struct gpio_desc *dem0_pin; + struct gpio_desc *dem1_pin; + struct gpio_desc *pdad_pin; + struct gpio_desc *pdda_pin; +}; static int pcm3008_dac_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct pcm3008_setup_data *setup = component->dev->platform_data; + struct pcm3008 *pcm = component->dev->platform_data; - gpio_set_value_cansleep(setup->pdda_pin, - SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value_cansleep(pcm->pdda_pin, + SND_SOC_DAPM_EVENT_ON(event)); return 0; } @@ -42,10 +47,10 @@ static int pcm3008_adc_ev(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct pcm3008_setup_data *setup = component->dev->platform_data; + struct pcm3008 *pcm = component->dev->platform_data; - gpio_set_value_cansleep(setup->pdad_pin, - SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value_cansleep(pcm->pdad_pin, + SND_SOC_DAPM_EVENT_ON(event)); return 0; } @@ -106,11 +111,13 @@ static const struct snd_soc_component_driver soc_component_dev_pcm3008 = { static int pcm3008_codec_probe(struct platform_device *pdev) { - struct pcm3008_setup_data *setup = pdev->dev.platform_data; - int ret; + struct device *dev = &pdev->dev; + struct pcm3008 *pcm; - if (!setup) - return -EINVAL; + pcm = devm_kzalloc(dev, sizeof(*pcm), GFP_KERNEL); + if (!pcm) + return -ENOMEM; + platform_set_drvdata(pdev, pcm); /* DEM1 DEM0 DE-EMPHASIS_MODE * Low Low De-emphasis 44.1 kHz ON @@ -120,30 +127,26 @@ static int pcm3008_codec_probe(struct platform_device *pdev) */ /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */ - ret = devm_gpio_request_one(&pdev->dev, setup->dem0_pin, - GPIOF_OUT_INIT_HIGH, "codec_dem0"); - if (ret != 0) - return ret; + pcm->dem0_pin = devm_gpiod_get(dev, "dem0", GPIOD_OUT_HIGH); + if (IS_ERR(pcm->dem0_pin)) + return PTR_ERR(pcm->dem0_pin); /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */ - ret = devm_gpio_request_one(&pdev->dev, setup->dem1_pin, - GPIOF_OUT_INIT_LOW, "codec_dem1"); - if (ret != 0) - return ret; + pcm->dem1_pin = devm_gpiod_get(dev, "dem1", GPIOD_OUT_LOW); + if (IS_ERR(pcm->dem1_pin)) + return PTR_ERR(pcm->dem1_pin); /* Configure PDAD GPIO. */ - ret = devm_gpio_request_one(&pdev->dev, setup->pdad_pin, - GPIOF_OUT_INIT_LOW, "codec_pdad"); - if (ret != 0) - return ret; + pcm->pdad_pin = devm_gpiod_get(dev, "pdad", GPIOD_OUT_LOW); + if (IS_ERR(pcm->pdad_pin)) + return PTR_ERR(pcm->pdad_pin); /* Configure PDDA GPIO. */ - ret = devm_gpio_request_one(&pdev->dev, setup->pdda_pin, - GPIOF_OUT_INIT_LOW, "codec_pdda"); - if (ret != 0) - return ret; + pcm->pdda_pin = devm_gpiod_get(dev, "pdda", GPIOD_OUT_LOW); + if (IS_ERR(pcm->pdda_pin)) + return PTR_ERR(pcm->pdda_pin); - return devm_snd_soc_register_component(&pdev->dev, + return devm_snd_soc_register_component(dev, &soc_component_dev_pcm3008, &pcm3008_dai, 1); } diff --git a/sound/soc/codecs/pcm3008.h b/sound/soc/codecs/pcm3008.h deleted file mode 100644 index f7f4fbbd89db..000000000000 --- a/sound/soc/codecs/pcm3008.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * PCM3008 ALSA SoC Layer - * - * Author: Hugo Villeneuve - * Copyright (C) 2008 Lyrtech inc - */ - -#ifndef __LINUX_SND_SOC_PCM3008_H -#define __LINUX_SND_SOC_PCM3008_H - -struct pcm3008_setup_data { - unsigned dem0_pin; - unsigned dem1_pin; - unsigned pdad_pin; - unsigned pdda_pin; -}; - -#endif diff --git a/sound/soc/codecs/pcm6240.c b/sound/soc/codecs/pcm6240.c index 4ff39e0b95b2..b2bd2f172ae7 100644 --- a/sound/soc/codecs/pcm6240.c +++ b/sound/soc/codecs/pcm6240.c @@ -14,7 +14,7 @@ #include <linux/unaligned.h> #include <linux/firmware.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/module.h> #include <linux/of_irq.h> @@ -2035,10 +2035,8 @@ static const struct regmap_config pcmdevice_i2c_regmap = { static void pcmdevice_remove(struct pcmdevice_priv *pcm_dev) { - if (gpio_is_valid(pcm_dev->irq_info.gpio)) { - gpio_free(pcm_dev->irq_info.gpio); - free_irq(pcm_dev->irq_info.nmb, pcm_dev); - } + if (pcm_dev->irq) + free_irq(pcm_dev->irq, pcm_dev); mutex_destroy(&pcm_dev->codec_lock); } @@ -2109,7 +2107,7 @@ static int pcmdevice_i2c_probe(struct i2c_client *i2c) ndev = 1; dev_addrs[0] = i2c->addr; } - pcm_dev->irq_info.gpio = of_irq_get(np, 0); + pcm_dev->irq = of_irq_get(np, 0); for (i = 0; i < ndev; i++) pcm_dev->addr[i] = dev_addrs[i]; @@ -2132,22 +2130,10 @@ static int pcmdevice_i2c_probe(struct i2c_client *i2c) if (pcm_dev->chip_id == PCM1690) goto skip_interrupt; - if (gpio_is_valid(pcm_dev->irq_info.gpio)) { - dev_dbg(pcm_dev->dev, "irq-gpio = %d", pcm_dev->irq_info.gpio); - - ret = gpio_request(pcm_dev->irq_info.gpio, "PCMDEV-IRQ"); - if (!ret) { - int gpio = pcm_dev->irq_info.gpio; - - gpio_direction_input(gpio); - pcm_dev->irq_info.nmb = gpio_to_irq(gpio); - - } else - dev_err(pcm_dev->dev, "%s: GPIO %d request error\n", - __func__, pcm_dev->irq_info.gpio); + if (pcm_dev->irq) { + dev_dbg(pcm_dev->dev, "irq = %d", pcm_dev->irq); } else - dev_err(pcm_dev->dev, "Looking up irq-gpio failed %d\n", - pcm_dev->irq_info.gpio); + dev_err(pcm_dev->dev, "No irq provided\n"); skip_interrupt: ret = devm_snd_soc_register_component(&i2c->dev, diff --git a/sound/soc/codecs/pcm6240.h b/sound/soc/codecs/pcm6240.h index 1e125bb97286..2d8f9e798139 100644 --- a/sound/soc/codecs/pcm6240.h +++ b/sound/soc/codecs/pcm6240.h @@ -208,11 +208,6 @@ struct pcmdevice_regbin { struct pcmdevice_config_info **cfg_info; }; -struct pcmdevice_irqinfo { - int gpio; - int nmb; -}; - struct pcmdevice_priv { struct snd_soc_component *component; struct i2c_client *client; @@ -221,7 +216,7 @@ struct pcmdevice_priv { struct gpio_desc *hw_rst; struct regmap *regmap; struct pcmdevice_regbin regbin; - struct pcmdevice_irqinfo irq_info; + int irq; unsigned int addr[PCMDEVICE_MAX_I2C_DEVICES]; unsigned int chip_id; int cur_conf; diff --git a/sound/soc/codecs/sma1307.c b/sound/soc/codecs/sma1307.c index dac17da9cedd..f5c303d4bb62 100644 --- a/sound/soc/codecs/sma1307.c +++ b/sound/soc/codecs/sma1307.c @@ -1723,6 +1723,11 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil } data = kzalloc(fw->size, GFP_KERNEL); + if (!data) { + release_firmware(fw); + sma1307->set.status = false; + return; + } size = fw->size >> 2; memcpy(data, fw->data, fw->size); @@ -1736,6 +1741,12 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil sma1307->set.header = devm_kzalloc(sma1307->dev, sma1307->set.header_size, GFP_KERNEL); + if (!sma1307->set.header) { + kfree(data); + sma1307->set.status = false; + return; + } + memcpy(sma1307->set.header, data, sma1307->set.header_size * sizeof(int)); @@ -1751,6 +1762,13 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil sma1307->set.def = devm_kzalloc(sma1307->dev, sma1307->set.def_size * sizeof(int), GFP_KERNEL); + if (!sma1307->set.def) { + kfree(data); + kfree(sma1307->set.header); + sma1307->set.status = false; + return; + } + memcpy(sma1307->set.def, &data[sma1307->set.header_size], sma1307->set.def_size * sizeof(int)); @@ -1763,6 +1781,16 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil = devm_kzalloc(sma1307->dev, sma1307->set.mode_size * 2 * sizeof(int), GFP_KERNEL); + if (!sma1307->set.mode_set[i]) { + kfree(data); + kfree(sma1307->set.header); + kfree(sma1307->set.def); + for (int j = 0; j < i; j++) + kfree(sma1307->set.mode_set[j]); + sma1307->set.status = false; + return; + } + for (int j = 0; j < sma1307->set.mode_size; j++) { sma1307->set.mode_set[i][2 * j] = data[offset + ((num_mode + 1) * j)]; diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c index 1a50ff675244..191e067ed1c9 100644 --- a/sound/soc/codecs/tlv320adc3xxx.c +++ b/sound/soc/codecs/tlv320adc3xxx.c @@ -1493,8 +1493,7 @@ static void adc3xxx_i2c_remove(struct i2c_client *client) { struct adc3xxx *adc3xxx = i2c_get_clientdata(client); - if (adc3xxx->mclk) - clk_disable_unprepare(adc3xxx->mclk); + clk_disable_unprepare(adc3xxx->mclk); adc3xxx_free_gpio(adc3xxx); snd_soc_unregister_component(&client->dev); } diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c index e8d3fddbc7b1..ff8bb01edf42 100644 --- a/sound/soc/codecs/wcd937x.c +++ b/sound/soc/codecs/wcd937x.c @@ -2571,6 +2571,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component) ARRAY_SIZE(wcd9375_dapm_widgets)); if (ret < 0) { dev_err(component->dev, "Failed to add snd_ctls\n"); + wcd_clsh_ctrl_free(wcd937x->clsh_info); return ret; } @@ -2578,6 +2579,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component) ARRAY_SIZE(wcd9375_audio_map)); if (ret < 0) { dev_err(component->dev, "Failed to add routes\n"); + wcd_clsh_ctrl_free(wcd937x->clsh_info); return ret; } } diff --git a/sound/soc/mediatek/common/mtk-soc-card.h b/sound/soc/mediatek/common/mtk-soc-card.h index 3f6e24dd22df..a1d2794ac1f7 100644 --- a/sound/soc/mediatek/common/mtk-soc-card.h +++ b/sound/soc/mediatek/common/mtk-soc-card.h @@ -16,6 +16,7 @@ struct mtk_soc_card_data { const struct mtk_sof_priv *sof_priv; struct list_head sof_dai_link_list; struct mtk_platform_card_data *card_data; + struct snd_soc_component *accdet; void *mach_priv; }; diff --git a/sound/soc/mediatek/common/mtk-soundcard-driver.c b/sound/soc/mediatek/common/mtk-soundcard-driver.c index f4314dddc460..713a368f79cf 100644 --- a/sound/soc/mediatek/common/mtk-soundcard-driver.c +++ b/sound/soc/mediatek/common/mtk-soundcard-driver.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/of.h> +#include <linux/of_platform.h> #include <sound/soc.h> #include "mtk-dsp-sof-common.h" @@ -192,7 +193,9 @@ EXPORT_SYMBOL_GPL(mtk_soundcard_common_capture_ops); int mtk_soundcard_common_probe(struct platform_device *pdev) { - struct device_node *platform_node, *adsp_node; + struct device_node *platform_node, *adsp_node, *accdet_node; + struct snd_soc_component *accdet_comp; + struct platform_device *accdet_pdev; const struct mtk_soundcard_pdata *pdata; struct mtk_soc_card_data *soc_card_data; struct snd_soc_dai_link *orig_dai_link, *dai_link; @@ -250,6 +253,20 @@ int mtk_soundcard_common_probe(struct platform_device *pdev) soc_card_data->card_data->jacks = jacks; + accdet_node = of_parse_phandle(pdev->dev.of_node, "mediatek,accdet", 0); + if (accdet_node) { + accdet_pdev = of_find_device_by_node(accdet_node); + if (accdet_pdev) { + accdet_comp = snd_soc_lookup_component(&accdet_pdev->dev, NULL); + if (accdet_comp) + soc_card_data->accdet = accdet_comp; + else + dev_err(&pdev->dev, "No sound component found from mediatek,accdet property\n"); + } else { + dev_err(&pdev->dev, "No device found from mediatek,accdet property\n"); + } + } + platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); if (!platform_node) return dev_err_probe(&pdev->dev, -EINVAL, diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index 420b1427b71d..20dc9470ba76 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -17,6 +17,7 @@ #include "mt8188-afe-common.h" #include "../../codecs/nau8825.h" #include "../../codecs/mt6359.h" +#include "../../codecs/mt6359-accdet.h" #include "../../codecs/rt5682.h" #include "../common/mtk-afe-platform-driver.h" #include "../common/mtk-soundcard-driver.h" @@ -271,6 +272,17 @@ static struct snd_soc_jack_pin nau8825_jack_pins[] = { }, }; +static struct snd_soc_jack_pin mt8188_headset_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_kcontrol_new mt8188_dumb_spk_controls[] = { SOC_DAPM_PIN_SWITCH("Ext Spk"), }; @@ -506,6 +518,35 @@ static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) return 0; } +static int mt8188_mt6359_accdet_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_HEADSET]; + int ret; + + if (!soc_card_data->accdet) + return 0; + + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + jack, mt8188_headset_jack_pins, + ARRAY_SIZE(mt8188_headset_jack_pins)); + if (ret) { + dev_err(rtd->dev, "Headset Jack create failed: %d\n", ret); + return ret; + } + + ret = mt6359_accdet_enable_jack_detect(soc_card_data->accdet, jack); + if (ret) { + dev_err(rtd->dev, "Headset Jack enable failed: %d\n", ret); + return ret; + } + + return 0; +} + static int mt8188_mt6359_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *cmpnt_codec = @@ -518,6 +559,8 @@ static int mt8188_mt6359_init(struct snd_soc_pcm_runtime *rtd) /* mtkaif calibration */ mt8188_mt6359_mtkaif_calibration(rtd); + mt8188_mt6359_accdet_init(rtd); + return 0; } diff --git a/sound/soc/mediatek/mt8365/mt8365-afe-clk.c b/sound/soc/mediatek/mt8365/mt8365-afe-clk.c index 8a0af2ea8546..7078c01ba19b 100644 --- a/sound/soc/mediatek/mt8365/mt8365-afe-clk.c +++ b/sound/soc/mediatek/mt8365/mt8365-afe-clk.c @@ -49,8 +49,7 @@ int mt8365_afe_init_audio_clk(struct mtk_base_afe *afe) void mt8365_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk) { - if (clk) - clk_disable_unprepare(clk); + clk_disable_unprepare(clk); } int mt8365_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk, diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 403edd2fd8cf..4308a6cbb2e6 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -36,7 +36,7 @@ static inline int _soc_pcm_ret(struct snd_soc_pcm_runtime *rtd, /* is the current PCM operation for this FE ? */ #if 0 -static int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream) +static int snd_soc_dpcm_can_fe_update(struct snd_soc_pcm_runtime *fe, int stream) { if (fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) return 1; @@ -45,7 +45,7 @@ static int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream #endif /* is the current PCM operation for this BE ? */ -static int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe, +static int snd_soc_dpcm_can_be_update(struct snd_soc_pcm_runtime *fe, struct snd_soc_pcm_runtime *be, int stream) { if ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) || @@ -1632,7 +1632,7 @@ void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream, return; /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; if (be->dpcm[stream].users == 0) { @@ -1682,7 +1682,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) } /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; /* first time the dpcm is open ? */ @@ -2007,7 +2007,7 @@ void dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) snd_soc_dpcm_get_substream(be, stream); /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; /* only free hw when no longer used - check all FEs */ @@ -2073,7 +2073,7 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) be_substream = snd_soc_dpcm_get_substream(be, stream); /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; /* copy params for each dpcm */ @@ -2118,7 +2118,7 @@ unwind: be = dpcm->be; be_substream = snd_soc_dpcm_get_substream(be, stream); - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; /* only allow hw_free() if no connected FEs are running */ @@ -2188,7 +2188,7 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, snd_pcm_stream_lock_irqsave_nested(be_substream, flags); /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) goto next; dev_dbg(be->dev, "ASoC: trigger BE %s cmd %d\n", @@ -2465,7 +2465,7 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) snd_soc_dpcm_get_substream(be, stream); /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; if (!snd_soc_dpcm_can_be_prepared(fe, be, stream)) @@ -2623,7 +2623,7 @@ disconnect: struct snd_soc_pcm_runtime *be = dpcm->be; /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; if (be->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE || diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 318b141c00b3..5e3e4f14c392 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -7,7 +7,7 @@ // Author: Mark Brown <broonie@opensource.wolfsonmicro.com> // Liam Girdwood <lrg@slimlogic.co.uk> -#include <linux/platform_device.h> +#include <linux/device/faux.h> #include <linux/export.h> #include <linux/math.h> #include <sound/core.h> @@ -262,48 +262,38 @@ struct snd_soc_dai_link_component snd_soc_dummy_dlc = { }; EXPORT_SYMBOL_GPL(snd_soc_dummy_dlc); -static int snd_soc_dummy_probe(struct platform_device *pdev) +static int snd_soc_dummy_probe(struct faux_device *fdev) { int ret; - ret = devm_snd_soc_register_component(&pdev->dev, + ret = devm_snd_soc_register_component(&fdev->dev, &dummy_codec, &dummy_dai, 1); if (ret < 0) return ret; - ret = devm_snd_soc_register_component(&pdev->dev, &dummy_platform, + ret = devm_snd_soc_register_component(&fdev->dev, &dummy_platform, NULL, 0); return ret; } -static struct platform_driver soc_dummy_driver = { - .driver = { - .name = "snd-soc-dummy", - }, +static struct faux_device_ops soc_dummy_ops = { .probe = snd_soc_dummy_probe, }; -static struct platform_device *soc_dummy_dev; +static struct faux_device *soc_dummy_dev; int __init snd_soc_util_init(void) { - int ret; - - soc_dummy_dev = - platform_device_register_simple("snd-soc-dummy", -1, NULL, 0); - if (IS_ERR(soc_dummy_dev)) - return PTR_ERR(soc_dummy_dev); + soc_dummy_dev = faux_device_create("snd-soc-dummy", NULL, + &soc_dummy_ops); + if (!soc_dummy_dev) + return -ENODEV; - ret = platform_driver_register(&soc_dummy_driver); - if (ret != 0) - platform_device_unregister(soc_dummy_dev); - - return ret; + return 0; } void snd_soc_util_exit(void) { - platform_driver_unregister(&soc_dummy_driver); - platform_device_unregister(soc_dummy_dev); + faux_device_destroy(soc_dummy_dev); } diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c index 0aa93b948378..3c10e09976ad 100644 --- a/sound/soc/tegra/tegra210_adx.c +++ b/sound/soc/tegra/tegra210_adx.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -// SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. +// SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. // All rights reserved. // // tegra210_adx.c - Tegra210 ADX driver @@ -57,8 +57,8 @@ static int tegra210_adx_startup(struct snd_pcm_substream *substream, int err; /* Ensure if ADX status is disabled */ - err = regmap_read_poll_timeout_atomic(adx->regmap, TEGRA210_ADX_STATUS, - val, !(val & 0x1), 10, 10000); + err = regmap_read_poll_timeout(adx->regmap, TEGRA210_ADX_STATUS, + val, !(val & 0x1), 10, 10000); if (err < 0) { dev_err(dai->dev, "failed to stop ADX, err = %d\n", err); return err; diff --git a/sound/soc/ti/davinci-i2s.c b/sound/soc/ti/davinci-i2s.c index d682b98d6848..059967f0e632 100644 --- a/sound/soc/ti/davinci-i2s.c +++ b/sound/soc/ti/davinci-i2s.c @@ -892,8 +892,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) err_unregister_component: snd_soc_unregister_component(&pdev->dev); err_disable_ext_clk: - if (dev->ext_clk) - clk_disable_unprepare(dev->ext_clk); + clk_disable_unprepare(dev->ext_clk); err_disable_clk: clk_disable_unprepare(dev->clk); @@ -908,8 +907,7 @@ static void davinci_i2s_remove(struct platform_device *pdev) clk_disable_unprepare(dev->clk); - if (dev->ext_clk) - clk_disable_unprepare(dev->ext_clk); + clk_disable_unprepare(dev->ext_clk); } static const struct of_device_id davinci_i2s_match[] __maybe_unused = { |