From db91ad81a2545eb82aa47d0306bc3e1adb05e336 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 6 Mar 2025 13:31:38 +0800 Subject: [PATCH 01/16] ASoC: dt-bindings: fsl,imx-asrc: Document audio graph port This device can be used in conjunction with audio-graph-card to provide an endpoint for binding with the other side of the audio link. Signed-off-by: Shengjiu Wang Reviewed-by: Frank Li Reviewed-by: "Rob Herring (Arm)" Link: https://patch.msgid.link/20250306053138.1914956-1-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl,imx-asrc.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml index abac5084d63b..85799f83e65f 100644 --- a/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml +++ b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml @@ -77,6 +77,10 @@ properties: power-domains: maxItems: 1 + port: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + fsl,asrc-rate: $ref: /schemas/types.yaml#/definitions/uint32 description: The mutual sample rate used by DPCM Back Ends @@ -174,4 +178,12 @@ examples: "txa", "txb", "txc"; fsl,asrc-rate = <48000>; fsl,asrc-width = <16>; + + port { + playback-only; + + asrc_endpoint: endpoint { + remote-endpoint = <&fe00_ep>; + }; + }; }; -- 2.50.1 From ad5a0970f86d82e39ebd06d45a1f7aa48a1316f8 Mon Sep 17 00:00:00 2001 From: Vitaliy Shevtsov Date: Tue, 4 Mar 2025 16:56:37 +0500 Subject: [PATCH 02/16] ASoC: cs35l41: check the return value from spi_setup() Currently the return value from spi_setup() is not checked for a failure. It is unlikely it will ever fail in this particular case but it is still better to add this check for the sake of completeness and correctness. This is cheap since it is performed once when the device is being probed. Handle spi_setup() return value. Found by Linux Verification Center (linuxtesting.org) with Svace. Fixes: 872fc0b6bde8 ("ASoC: cs35l41: Set the max SPI speed for the whole device") Signed-off-by: Vitaliy Shevtsov Link: https://patch.msgid.link/20250304115643.2748-1-v.shevtsov@mt-integration.ru Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l41-spi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c index a6db44520c06..f9b6bf7bea9c 100644 --- a/sound/soc/codecs/cs35l41-spi.c +++ b/sound/soc/codecs/cs35l41-spi.c @@ -32,13 +32,16 @@ static int cs35l41_spi_probe(struct spi_device *spi) const struct regmap_config *regmap_config = &cs35l41_regmap_spi; struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(&spi->dev); struct cs35l41_private *cs35l41; + int ret; cs35l41 = devm_kzalloc(&spi->dev, sizeof(struct cs35l41_private), GFP_KERNEL); if (!cs35l41) return -ENOMEM; spi->max_speed_hz = CS35L41_SPI_MAX_FREQ; - spi_setup(spi); + ret = spi_setup(spi); + if (ret < 0) + return ret; spi_set_drvdata(spi, cs35l41); cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); -- 2.50.1 From 89be3c15a58b2ccf31e969223c8ac93ca8932d81 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Fri, 28 Feb 2025 16:14:30 +0000 Subject: [PATCH 03/16] ASoC: qcom: sm8250: explicitly set format in sm8250_be_hw_params_fixup() Setting format to s16le is required for compressed playback on compatible soundcards. Cc: Srinivas Kandagatla Signed-off-by: Alexey Klimov Link: https://patch.msgid.link/20250228161430.373961-1-alexey.klimov@linaro.org Signed-off-by: Mark Brown --- sound/soc/qcom/sm8250.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c index 45e0c33fc3f3..9039107972e2 100644 --- a/sound/soc/qcom/sm8250.c +++ b/sound/soc/qcom/sm8250.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -39,9 +40,11 @@ static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); rate->min = rate->max = 48000; channels->min = channels->max = 2; + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); return 0; } -- 2.50.1 From ac5b4a24f16f2f56b5cc5092969930b867274edc Mon Sep 17 00:00:00 2001 From: Naveen Manohar Date: Tue, 11 Mar 2025 08:31:01 +0800 Subject: [PATCH 04/16] ASoC: Intel: soc-acpi-intel-ptl-match: Add cs42l43 support Patch adds driver data & match table for cs42l43 multi-function codec on PTL-RVP at sdw link3. Signed-off-by: Naveen Manohar Reviewed-by: Liam Girdwood Signed-off-by: Bard Liao Link: https://patch.msgid.link/20250311003101.80967-1-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- .../intel/common/soc-acpi-intel-ptl-match.c | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c index a07526eb802b..6603d8de501c 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -185,6 +185,33 @@ static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = { }, }; +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = { { .adr = 0x00023001fa424301ull, @@ -236,6 +263,15 @@ static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = { } }; +static const struct snd_soc_acpi_adr_device cs42l43_3_adr[] = { + { + .adr = 0x00033001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { { .adr = 0x000030025D071101ull, @@ -390,6 +426,14 @@ static const struct snd_soc_acpi_link_adr ptl_cs42l43_l2_cs35l56x6_l13[] = { {} }; +static const struct snd_soc_acpi_link_adr ptl_cs42l43_l3[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs42l43_3_adr), + .adr_d = cs42l43_3_adr, + } +}; + static const struct snd_soc_acpi_link_adr ptl_rt722_only[] = { { .mask = BIT(0), @@ -531,6 +575,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-ptl-rt711.tplg", }, + { + .link_mask = BIT(3), + .links = ptl_cs42l43_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-cs42l43-l3.tplg", + }, { .link_mask = BIT(3), .links = ptl_rt721_l3, -- 2.50.1 From c3d5d331c96f35c6425f7dcfa5c60cf9a5055d0e Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:48 +0530 Subject: [PATCH 05/16] ASoC: amd: acp: Remove redundant acp70 chip->name As acp71 platform driver uses acp70 platform driver, remove the redundant chip->name. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-2-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index e0fc42d939d3..dcd92d716e78 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -89,8 +89,6 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id chip->name = "acp_asoc_acp63"; break; case 0x70: - chip->name = "acp_asoc_acp70"; - break; case 0x71: chip->name = "acp_asoc_acp70"; break; -- 2.50.1 From 8ae746fe51041484e52eba99bed15a444c7d4372 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:49 +0530 Subject: [PATCH 06/16] ASoC: amd: acp: Implement acp_common_hw_ops support for acp platforms Implement acp common hardware ops for acp_init and acp_deinit funcions to support commons ops for all platforms. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-3-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-legacy-common.c | 50 +++++++++++++++++++++++++++ sound/soc/amd/acp/acp-pci.c | 13 ++++--- sound/soc/amd/acp/amd.h | 36 +++++++++++++++++++ 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 89f5cda18a23..f87a2da8c641 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -21,6 +21,12 @@ #define ACP63_PDM_ADDR 0x02 #define ACP70_PDM_ADDR 0x02 +const struct snd_acp_hw_ops acp_common_hw_ops = { + /* ACP hardware initilizations */ + .acp_init = acp_init, + .acp_deinit = acp_deinit, +}; +EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON"); void acp_enable_interrupts(struct acp_dev_data *adata) { struct acp_resource *rsrc = adata->rsrc; @@ -463,5 +469,49 @@ void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip) } EXPORT_SYMBOL_NS_GPL(check_acp_config, "SND_SOC_ACP_COMMON"); +struct snd_acp_hw_ops acp31_common_hw_ops; +EXPORT_SYMBOL_NS_GPL(acp31_common_hw_ops, "SND_SOC_ACP_COMMON"); +int acp31_hw_ops_init(struct acp_chip_info *chip) +{ + memcpy(&acp31_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); + chip->acp_hw_ops = &acp31_common_hw_ops; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp31_hw_ops_init, "SND_SOC_ACP_COMMON"); + +struct snd_acp_hw_ops acp6x_common_hw_ops; +EXPORT_SYMBOL_NS_GPL(acp6x_common_hw_ops, "SND_SOC_ACP_COMMON"); +int acp6x_hw_ops_init(struct acp_chip_info *chip) +{ + memcpy(&acp6x_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); + chip->acp_hw_ops = &acp6x_common_hw_ops; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp6x_hw_ops_init, "SND_SOC_ACP_COMMON"); + +struct snd_acp_hw_ops acp63_common_hw_ops; +EXPORT_SYMBOL_NS_GPL(acp63_common_hw_ops, "SND_SOC_ACP_COMMON"); +int acp63_hw_ops_init(struct acp_chip_info *chip) +{ + memcpy(&acp63_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); + chip->acp_hw_ops = &acp63_common_hw_ops; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp63_hw_ops_init, "SND_SOC_ACP_COMMON"); + +struct snd_acp_hw_ops acp70_common_hw_ops; +EXPORT_SYMBOL_NS_GPL(acp70_common_hw_ops, "SND_SOC_ACP_COMMON"); +int acp70_hw_ops_init(struct acp_chip_info *chip) +{ + memcpy(&acp70_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); + chip->acp_hw_ops = &acp70_common_hw_ops; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp70_hw_ops_init, "SND_SOC_ACP_COMMON"); + MODULE_DESCRIPTION("AMD ACP legacy common features"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index dcd92d716e78..b5eabd0280bc 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -81,16 +81,20 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id switch (pci->revision) { case 0x01: chip->name = "acp_asoc_renoir"; + chip->acp_hw_ops_init = acp31_hw_ops_init; break; case 0x6f: chip->name = "acp_asoc_rembrandt"; + chip->acp_hw_ops_init = acp6x_hw_ops_init; break; case 0x63: chip->name = "acp_asoc_acp63"; + chip->acp_hw_ops_init = acp63_hw_ops_init; break; case 0x70: case 0x71: chip->name = "acp_asoc_acp70"; + chip->acp_hw_ops_init = acp70_hw_ops_init; break; default: dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision); @@ -112,7 +116,8 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id goto unregister_dmic_dev; } - ret = acp_init(chip); + chip->acp_hw_ops_init(chip); + ret = acp_hw_init(chip); if (ret) goto unregister_dmic_dev; @@ -179,7 +184,7 @@ static int __maybe_unused snd_acp_suspend(struct device *dev) int ret; chip = dev_get_drvdata(dev); - ret = acp_deinit(chip); + ret = acp_hw_deinit(chip); if (ret) dev_err(dev, "ACP de-init failed\n"); return ret; @@ -193,7 +198,7 @@ static int __maybe_unused snd_acp_resume(struct device *dev) int ret; chip = dev_get_drvdata(dev); - ret = acp_init(chip); + ret = acp_hw_init(chip); if (ret) dev_err(dev, "ACP init failed\n"); if (chip->chip_pdev) { @@ -222,7 +227,7 @@ static void acp_pci_remove(struct pci_dev *pci) platform_device_unregister(dmic_dev); if (pdev) platform_device_unregister(pdev); - ret = acp_deinit(chip); + ret = acp_hw_deinit(chip); if (ret) dev_err(&pci->dev, "ACP de-init failed\n"); } diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index c921bcabbcec..3c06567e112c 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -142,6 +142,8 @@ struct acp_chip_info { char *name; /* Platform name */ unsigned int acp_rev; /* ACP Revision id */ void __iomem *base; /* ACP memory PCI base */ + struct snd_acp_hw_ops *acp_hw_ops; + int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ @@ -203,6 +205,17 @@ struct acp_dev_data { unsigned int flag; }; +/** + * struct snd_acp_hw_ops - ACP PCI driver platform specific ops + * @acp_init: ACP initialization + * @acp_deinit: ACP de-initialization + */ +struct snd_acp_hw_ops { + /* ACP hardware initilizations */ + int (*acp_init)(struct acp_chip_info *chip); + int (*acp_deinit)(struct acp_chip_info *chip); +}; + enum acp_config { ACP_CONFIG_0 = 0, ACP_CONFIG_1, @@ -239,6 +252,15 @@ int acp_init(struct acp_chip_info *chip); int acp_deinit(struct acp_chip_info *chip); void acp_enable_interrupts(struct acp_dev_data *adata); void acp_disable_interrupts(struct acp_dev_data *adata); + +extern struct snd_acp_hw_ops acp31_common_hw_ops; +extern struct snd_acp_hw_ops acp6x_common_hw_ops; +extern struct snd_acp_hw_ops acp63_common_hw_ops; +extern struct snd_acp_hw_ops acp70_common_hw_ops; +extern int acp31_hw_ops_init(struct acp_chip_info *chip); +extern int acp6x_hw_ops_init(struct acp_chip_info *chip); +extern int acp63_hw_ops_init(struct acp_chip_info *chip); +extern int acp70_hw_ops_init(struct acp_chip_info *chip); /* Machine configuration */ int snd_amd_acp_find_config(struct pci_dev *pci); @@ -252,6 +274,20 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream, void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip); +static inline int acp_hw_init(struct acp_chip_info *chip) +{ + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->acp_init) + return chip->acp_hw_ops->acp_init(chip); + return -EOPNOTSUPP; +} + +static inline int acp_hw_deinit(struct acp_chip_info *chip) +{ + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->acp_deinit) + return chip->acp_hw_ops->acp_deinit(chip); + return -EOPNOTSUPP; +} + static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction) { u64 byte_count = 0, low = 0, high = 0; -- 2.50.1 From e2cda461765692757cd5c3b1fc80bd260ffe1394 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:50 +0530 Subject: [PATCH 07/16] ASoC: amd: acp: Refactor dmic-codec platform device creation Refactor dmic-codec platform driver creation using helper function. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-4-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 49 +++++++++++++++++++++++++------------ sound/soc/amd/acp/amd.h | 1 + 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index b5eabd0280bc..549e95415ab2 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -26,7 +26,6 @@ #define ACP3x_REG_START 0x1240000 #define ACP3x_REG_END 0x125C000 -static struct platform_device *dmic_dev; static struct platform_device *pdev; static const struct resource acp_res[] = { @@ -44,6 +43,26 @@ static const struct resource acp_res[] = { }, }; +static int create_acp_platform_devs(struct pci_dev *pci, struct acp_chip_info *chip) +{ + int ret; + + if (chip->is_pdm_dev && chip->is_pdm_config) { + chip->dmic_codec_dev = platform_device_register_data(&pci->dev, + "dmic-codec", + PLATFORM_DEVID_NONE, + NULL, 0); + if (IS_ERR(chip->dmic_codec_dev)) { + dev_err(&pci->dev, "failed to create DMIC device\n"); + ret = PTR_ERR(chip->dmic_codec_dev); + goto err; + } + } + return 0; +err: + return ret; +} + static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { struct platform_device_info pdevinfo; @@ -102,33 +121,33 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id goto release_regions; } chip->flag = flag; - dmic_dev = platform_device_register_data(dev, "dmic-codec", PLATFORM_DEVID_NONE, NULL, 0); - if (IS_ERR(dmic_dev)) { - dev_err(dev, "failed to create DMIC device\n"); - ret = PTR_ERR(dmic_dev); - goto release_regions; - } addr = pci_resource_start(pci, 0); chip->base = devm_ioremap(&pci->dev, addr, pci_resource_len(pci, 0)); if (!chip->base) { ret = -ENOMEM; - goto unregister_dmic_dev; + goto release_regions; } chip->acp_hw_ops_init(chip); ret = acp_hw_init(chip); if (ret) - goto unregister_dmic_dev; + goto release_regions; check_acp_config(pci, chip); if (!chip->is_pdm_dev && !chip->is_i2s_config) goto skip_pdev_creation; + ret = create_acp_platform_devs(pci, chip); + if (ret < 0) { + dev_err(&pci->dev, "ACP platform devices creation failed\n"); + goto de_init; + } + res = devm_kcalloc(&pci->dev, num_res, sizeof(struct resource), GFP_KERNEL); if (!res) { ret = -ENOMEM; - goto unregister_dmic_dev; + goto de_init; } for (i = 0; i < num_res; i++, res_acp++) { @@ -156,7 +175,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id if (IS_ERR(pdev)) { dev_err(&pci->dev, "cannot register %s device\n", pdevinfo.name); ret = PTR_ERR(pdev); - goto unregister_dmic_dev; + goto de_init; } skip_pdev_creation: @@ -168,8 +187,8 @@ skip_pdev_creation: pm_runtime_allow(&pci->dev); return ret; -unregister_dmic_dev: - platform_device_unregister(dmic_dev); +de_init: + acp_hw_deinit(chip); release_regions: pci_release_regions(pci); disable_pci: @@ -223,8 +242,8 @@ static void acp_pci_remove(struct pci_dev *pci) chip = pci_get_drvdata(pci); pm_runtime_forbid(&pci->dev); pm_runtime_get_noresume(&pci->dev); - if (dmic_dev) - platform_device_unregister(dmic_dev); + if (chip->dmic_codec_dev) + platform_device_unregister(chip->dmic_codec_dev); if (pdev) platform_device_unregister(pdev); ret = acp_hw_deinit(chip); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 3c06567e112c..9511995da591 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -145,6 +145,7 @@ struct acp_chip_info { struct snd_acp_hw_ops *acp_hw_ops; int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; + struct platform_device *dmic_codec_dev; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ bool is_pdm_config; /* flag set to true when PDM configuration is selected from BIOS */ -- 2.50.1 From a8b9d2d7376d2caf74c0ffbf9bc71b98ed9d1a01 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:51 +0530 Subject: [PATCH 08/16] ASoC: amd: acp: Refactor acp platform device creation Refactor acp platform device creation logic and remove unused acp resource (acp_res) structure. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-5-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 119 ++++++++++++++++++------------------ sound/soc/amd/acp/amd.h | 4 ++ 2 files changed, 62 insertions(+), 61 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 549e95415ab2..0ffef70ab979 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -26,27 +26,56 @@ #define ACP3x_REG_START 0x1240000 #define ACP3x_REG_END 0x125C000 -static struct platform_device *pdev; - -static const struct resource acp_res[] = { - { - .start = 0, - .end = ACP3x_REG_END - ACP3x_REG_START, - .name = "acp_mem", - .flags = IORESOURCE_MEM, - }, - { - .start = 0, - .end = 0, - .name = "acp_dai_irq", - .flags = IORESOURCE_IRQ, - }, -}; +static void acp_fill_platform_dev_info(struct platform_device_info *pdevinfo, + struct device *parent, + struct fwnode_handle *fw_node, + char *name, unsigned int id, + const struct resource *res, + unsigned int num_res, + const void *data, + size_t size_data) +{ + pdevinfo->name = name; + pdevinfo->id = id; + pdevinfo->parent = parent; + pdevinfo->num_res = num_res; + pdevinfo->res = res; + pdevinfo->data = data; + pdevinfo->size_data = size_data; + pdevinfo->fwnode = fw_node; +} -static int create_acp_platform_devs(struct pci_dev *pci, struct acp_chip_info *chip) +static int create_acp_platform_devs(struct pci_dev *pci, struct acp_chip_info *chip, u32 addr) { + struct platform_device_info pdevinfo; + struct device *parent; int ret; + parent = &pci->dev; + + if (chip->is_i2s_config || chip->is_pdm_dev) { + chip->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL); + if (!chip->res) { + ret = -ENOMEM; + goto err; + } + chip->res->flags = IORESOURCE_MEM; + chip->res->start = addr; + chip->res->end = addr + (ACP3x_REG_END - ACP3x_REG_START); + memset(&pdevinfo, 0, sizeof(pdevinfo)); + } + + memset(&pdevinfo, 0, sizeof(pdevinfo)); + acp_fill_platform_dev_info(&pdevinfo, parent, NULL, chip->name, + 0, chip->res, 1, chip, sizeof(*chip)); + + chip->acp_plat_dev = platform_device_register_full(&pdevinfo); + if (IS_ERR(chip->acp_plat_dev)) { + dev_err(&pci->dev, + "cannot register %s device\n", pdevinfo.name); + ret = PTR_ERR(chip->acp_plat_dev); + goto err; + } if (chip->is_pdm_dev && chip->is_pdm_config) { chip->dmic_codec_dev = platform_device_register_data(&pci->dev, "dmic-codec", @@ -55,22 +84,21 @@ static int create_acp_platform_devs(struct pci_dev *pci, struct acp_chip_info *c if (IS_ERR(chip->dmic_codec_dev)) { dev_err(&pci->dev, "failed to create DMIC device\n"); ret = PTR_ERR(chip->dmic_codec_dev); - goto err; + goto unregister_acp_plat_dev; } } return 0; +unregister_acp_plat_dev: + platform_device_unregister(chip->acp_plat_dev); err: return ret; } static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { - struct platform_device_info pdevinfo; struct device *dev = &pci->dev; - const struct resource *res_acp; struct acp_chip_info *chip; - struct resource *res; - unsigned int flag, addr, num_res, i; + unsigned int flag, addr; int ret; flag = snd_amd_acp_find_config(pci); @@ -94,8 +122,6 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id pci_set_master(pci); - res_acp = acp_res; - num_res = ARRAY_SIZE(acp_res); chip->acp_rev = pci->revision; switch (pci->revision) { case 0x01: @@ -129,6 +155,8 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id goto release_regions; } + chip->addr = addr; + chip->acp_hw_ops_init(chip); ret = acp_hw_init(chip); if (ret) @@ -138,48 +166,16 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id if (!chip->is_pdm_dev && !chip->is_i2s_config) goto skip_pdev_creation; - ret = create_acp_platform_devs(pci, chip); + ret = create_acp_platform_devs(pci, chip, addr); if (ret < 0) { dev_err(&pci->dev, "ACP platform devices creation failed\n"); goto de_init; } - res = devm_kcalloc(&pci->dev, num_res, sizeof(struct resource), GFP_KERNEL); - if (!res) { - ret = -ENOMEM; - goto de_init; - } - - for (i = 0; i < num_res; i++, res_acp++) { - res[i].name = res_acp->name; - res[i].flags = res_acp->flags; - res[i].start = addr + res_acp->start; - res[i].end = addr + res_acp->end; - if (res_acp->flags == IORESOURCE_IRQ) { - res[i].start = pci->irq; - res[i].end = res[i].start; - } - } - - memset(&pdevinfo, 0, sizeof(pdevinfo)); - - pdevinfo.name = chip->name; - pdevinfo.id = 0; - pdevinfo.parent = &pci->dev; - pdevinfo.num_res = num_res; - pdevinfo.res = &res[0]; - pdevinfo.data = chip; - pdevinfo.size_data = sizeof(*chip); - - pdev = platform_device_register_full(&pdevinfo); - if (IS_ERR(pdev)) { - dev_err(&pci->dev, "cannot register %s device\n", pdevinfo.name); - ret = PTR_ERR(pdev); - goto de_init; - } + chip->chip_pdev = chip->acp_plat_dev; + chip->dev = &chip->acp_plat_dev->dev; skip_pdev_creation: - chip->chip_pdev = pdev; dev_set_drvdata(&pci->dev, chip); pm_runtime_set_autosuspend_delay(&pci->dev, 2000); pm_runtime_use_autosuspend(&pci->dev); @@ -244,8 +240,9 @@ static void acp_pci_remove(struct pci_dev *pci) pm_runtime_get_noresume(&pci->dev); if (chip->dmic_codec_dev) platform_device_unregister(chip->dmic_codec_dev); - if (pdev) - platform_device_unregister(pdev); + if (chip->acp_plat_dev) + platform_device_unregister(chip->acp_plat_dev); + ret = acp_hw_deinit(chip); if (ret) dev_err(&pci->dev, "ACP de-init failed\n"); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 9511995da591..be1aa405a14a 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -140,12 +140,16 @@ struct acp_chip_info { char *name; /* Platform name */ + struct resource *res; + struct device *dev; unsigned int acp_rev; /* ACP Revision id */ void __iomem *base; /* ACP memory PCI base */ struct snd_acp_hw_ops *acp_hw_ops; int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; struct platform_device *dmic_codec_dev; + struct platform_device *acp_plat_dev; + u32 addr; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ bool is_pdm_config; /* flag set to true when PDM configuration is selected from BIOS */ -- 2.50.1 From 6e60db74b69c29b528c8d10d86108f78f2995dcb Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:52 +0530 Subject: [PATCH 09/16] ASoC: amd: acp: Refactor acp machine select Refactor and move acp machine select function from acp platform driver to acp pci driver and assign platform specific acpi machines to chip->machines. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-6-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-legacy-common.c | 28 +++++++++ sound/soc/amd/acp/acp-pci.c | 7 +++ sound/soc/amd/acp/acp-platform.c | 28 --------- sound/soc/amd/acp/acp-rembrandt.c | 32 ----------- sound/soc/amd/acp/acp-renoir.c | 42 -------------- sound/soc/amd/acp/acp63.c | 10 ---- sound/soc/amd/acp/acp70.c | 10 ---- sound/soc/amd/acp/amd.h | 81 ++++++++++++++++++++++++++- 8 files changed, 114 insertions(+), 124 deletions(-) diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index f87a2da8c641..886615798b93 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -16,6 +16,8 @@ #include #include +#include "../mach-config.h" + #define ACP_RENOIR_PDM_ADDR 0x02 #define ACP_REMBRANDT_PDM_ADDR 0x03 #define ACP63_PDM_ADDR 0x02 @@ -350,6 +352,32 @@ int acp_deinit(struct acp_chip_info *chip) return 0; } EXPORT_SYMBOL_NS_GPL(acp_deinit, "SND_SOC_ACP_COMMON"); +int acp_machine_select(struct acp_chip_info *chip) +{ + struct snd_soc_acpi_mach *mach; + int size, platform; + + if (chip->flag == FLAG_AMD_LEGACY_ONLY_DMIC) { + platform = chip->acp_rev; + chip->mach_dev = platform_device_register_data(chip->dev, "acp-pdm-mach", + PLATFORM_DEVID_NONE, &platform, + sizeof(platform)); + } else { + size = sizeof(*chip->machines); + mach = snd_soc_acpi_find_machine(chip->machines); + if (!mach) { + dev_err(chip->dev, "warning: No matching ASoC machine driver found\n"); + return -EINVAL; + } + mach->mach_params.subsystem_rev = chip->acp_rev; + chip->mach_dev = platform_device_register_data(chip->dev, mach->drv_name, + PLATFORM_DEVID_NONE, mach, size); + } + if (IS_ERR(chip->mach_dev)) + dev_warn(chip->dev, "Unable to register Machine device\n"); + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp_machine_select, "SND_SOC_ACP_COMMON"); static void check_acp3x_config(struct acp_chip_info *chip) { diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 0ffef70ab979..99297a388ed7 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -127,19 +127,23 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id case 0x01: chip->name = "acp_asoc_renoir"; chip->acp_hw_ops_init = acp31_hw_ops_init; + chip->machines = snd_soc_acpi_amd_acp_machines; break; case 0x6f: chip->name = "acp_asoc_rembrandt"; chip->acp_hw_ops_init = acp6x_hw_ops_init; + chip->machines = snd_soc_acpi_amd_rmb_acp_machines; break; case 0x63: chip->name = "acp_asoc_acp63"; chip->acp_hw_ops_init = acp63_hw_ops_init; + chip->machines = snd_soc_acpi_amd_acp63_acp_machines; break; case 0x70: case 0x71: chip->name = "acp_asoc_acp70"; chip->acp_hw_ops_init = acp70_hw_ops_init; + chip->machines = snd_soc_acpi_amd_acp70_acp_machines; break; default: dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision); @@ -175,6 +179,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id chip->chip_pdev = chip->acp_plat_dev; chip->dev = &chip->acp_plat_dev->dev; + acp_machine_select(chip); skip_pdev_creation: dev_set_drvdata(&pci->dev, chip); pm_runtime_set_autosuspend_delay(&pci->dev, 2000); @@ -242,6 +247,8 @@ static void acp_pci_remove(struct pci_dev *pci) platform_device_unregister(chip->dmic_codec_dev); if (chip->acp_plat_dev) platform_device_unregister(chip->acp_plat_dev); + if (chip->mach_dev) + platform_device_unregister(chip->mach_dev); ret = acp_hw_deinit(chip); if (ret) diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index aa330aeeb301..7d6abff28b23 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -21,7 +21,6 @@ #include #include "amd.h" -#include "../mach-config.h" #include "acp-mach.h" #define DRV_NAME "acp_i2s_dma" @@ -108,33 +107,6 @@ static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = { .periods_max = CAPTURE_MAX_NUM_PERIODS, }; -int acp_machine_select(struct acp_dev_data *adata) -{ - struct snd_soc_acpi_mach *mach; - int size, platform; - - if (adata->flag == FLAG_AMD_LEGACY_ONLY_DMIC) { - platform = adata->acp_rev; - adata->mach_dev = platform_device_register_data(adata->dev, "acp-pdm-mach", - PLATFORM_DEVID_NONE, &platform, - sizeof(platform)); - } else { - size = sizeof(*adata->machines); - mach = snd_soc_acpi_find_machine(adata->machines); - if (!mach) { - dev_err(adata->dev, "warning: No matching ASoC machine driver found\n"); - return -EINVAL; - } - mach->mach_params.subsystem_rev = adata->acp_rev; - adata->mach_dev = platform_device_register_data(adata->dev, mach->drv_name, - PLATFORM_DEVID_NONE, mach, size); - } - if (IS_ERR(adata->mach_dev)) - dev_warn(adata->dev, "Unable to register Machine device\n"); - return 0; -} -EXPORT_SYMBOL_NS_GPL(acp_machine_select, "SND_SOC_ACP_COMMON"); - static irqreturn_t i2s_irq_handler(int irq, void *data) { struct acp_dev_data *adata = data; diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index e727754a8231..eb09878c0d5c 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -44,36 +44,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x03802800, }; -static struct snd_soc_acpi_codecs amp_rt1019 = { - .num_codecs = 1, - .codecs = {"10EC1019"} -}; - -static struct snd_soc_acpi_codecs amp_max = { - .num_codecs = 1, - .codecs = {"MX98360A"} -}; - -static 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, - }, - {}, -}; - static struct snd_soc_dai_driver acp_rmb_dai[] = { { .name = "acp-i2s-sp", @@ -230,8 +200,6 @@ static int rembrandt_audio_probe(struct platform_device *pdev) adata->acp_rev = chip->acp_rev; adata->flag = chip->flag; adata->is_i2s_config = chip->is_i2s_config; - adata->machines = snd_soc_acpi_amd_rmb_acp_machines; - acp_machine_select(adata); dev_set_drvdata(dev, adata); diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index ca2b74283d8f..2b47c6bfc9e7 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -36,45 +36,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x02052800, }; -static struct snd_soc_acpi_codecs amp_rt1019 = { - .num_codecs = 1, - .codecs = {"10EC1019"} -}; - -static struct snd_soc_acpi_codecs amp_max = { - .num_codecs = 1, - .codecs = {"MX98360A"} -}; - -static 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", - }, - {}, -}; static struct snd_soc_dai_driver acp_renoir_dai[] = { { @@ -188,9 +149,6 @@ static int renoir_audio_probe(struct platform_device *pdev) adata->acp_rev = chip->acp_rev; adata->flag = chip->flag; - adata->machines = snd_soc_acpi_amd_acp_machines; - acp_machine_select(adata); - dev_set_drvdata(dev, adata); acp_enable_interrupts(adata); acp_platform_register(dev); diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index 4187a8968de7..76a26b82e3ad 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -62,14 +62,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x03802800, }; -static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_acp_machines[] = { - { - .id = "AMDI0052", - .drv_name = "acp63-acp", - }, - {}, -}; - static struct snd_soc_dai_driver acp63_dai[] = { { .name = "acp-i2s-sp", @@ -259,8 +251,6 @@ static int acp63_audio_probe(struct platform_device *pdev) adata->acp_rev = chip->acp_rev; adata->flag = chip->flag; adata->is_i2s_config = chip->is_i2s_config; - adata->machines = snd_soc_acpi_amd_acp63_acp_machines; - acp_machine_select(adata); dev_set_drvdata(dev, adata); if (chip->is_i2s_config && rsrc.soc_mclk) { diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index 7f4ec3bfaeab..3e603c5f736a 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -40,14 +40,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x03800000, }; -static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = { - { - .id = "AMDI0029", - .drv_name = "acp70-acp", - }, - {}, -}; - static struct snd_soc_dai_driver acp70_dai[] = { { .name = "acp-i2s-sp", @@ -187,10 +179,8 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) adata->dai_driver = acp70_dai; adata->num_dai = ARRAY_SIZE(acp70_dai); adata->rsrc = &rsrc; - adata->machines = snd_soc_acpi_amd_acp70_acp_machines; adata->acp_rev = chip->acp_rev; adata->flag = chip->flag; - acp_machine_select(adata); dev_set_drvdata(dev, adata); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index be1aa405a14a..b7a1b4aa8fef 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -149,6 +149,8 @@ struct acp_chip_info { struct platform_device *chip_pdev; struct platform_device *dmic_codec_dev; struct platform_device *acp_plat_dev; + struct platform_device *mach_dev; + struct snd_soc_acpi_mach *machines; u32 addr; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ @@ -195,7 +197,6 @@ struct acp_dev_data { struct list_head stream_list; spinlock_t acp_lock; - struct snd_soc_acpi_mach *machines; struct platform_device *mach_dev; u32 bclk_div; @@ -245,13 +246,89 @@ enum acp_config { ACP_CONFIG_20, }; +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 const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops; extern const struct snd_soc_dai_ops acp_dmic_dai_ops; int acp_platform_register(struct device *dev); int acp_platform_unregister(struct device *dev); -int acp_machine_select(struct acp_dev_data *adata); +int acp_machine_select(struct acp_chip_info *chip); int acp_init(struct acp_chip_info *chip); int acp_deinit(struct acp_chip_info *chip); -- 2.50.1 From aaf7a668bb3814f084f9f6f673567f6aa316632f Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:53 +0530 Subject: [PATCH 10/16] ASoC: amd: acp: Add new interrupt handle callbacks in acp_common_hw_ops Add new interrupt handle callbacks in acp_common_hw_ops. Refactor and move interrupt handler registration form platform driver to pci driver. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-7-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-i2s.c | 4 +- sound/soc/amd/acp/acp-legacy-common.c | 79 +++++++++++++++++++++++---- sound/soc/amd/acp/acp-pci.c | 29 +++++++--- sound/soc/amd/acp/acp-pdm.c | 12 ++-- sound/soc/amd/acp/acp-platform.c | 50 +++-------------- sound/soc/amd/acp/acp-rembrandt.c | 15 ++++- sound/soc/amd/acp/acp-renoir.c | 15 ++++- sound/soc/amd/acp/acp63.c | 15 ++++- sound/soc/amd/acp/acp70.c | 15 ++++- sound/soc/amd/acp/amd.h | 29 +++++++++- sound/soc/amd/acp/chip_offset_byte.h | 12 ++-- 11 files changed, 184 insertions(+), 91 deletions(-) diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c index 89e99ed4275a..2f458c76f9fc 100644 --- a/sound/soc/amd/acp/acp-i2s.c +++ b/sound/soc/amd/acp/acp-i2s.c @@ -617,7 +617,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | BIT(BT_RX_THRESHOLD(rsrc->offset)) | BIT(I2S_TX_THRESHOLD(rsrc->offset)) | @@ -625,7 +625,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d BIT(HS_RX_THRESHOLD(rsrc->offset)) | BIT(HS_TX_THRESHOLD(rsrc->offset)); - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); return 0; } diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 886615798b93..13fddce8df56 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -27,26 +27,76 @@ const struct snd_acp_hw_ops acp_common_hw_ops = { /* ACP hardware initilizations */ .acp_init = acp_init, .acp_deinit = acp_deinit, + + /* ACP Interrupts*/ + .irq = acp_irq_handler, + .en_interrupts = acp_enable_interrupts, + .dis_interrupts = acp_disable_interrupts, }; EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON"); -void acp_enable_interrupts(struct acp_dev_data *adata) + +irqreturn_t acp_irq_handler(int irq, void *data) { + struct acp_chip_info *chip = data; + struct acp_dev_data *adata = chip->adata; struct acp_resource *rsrc = adata->rsrc; + struct acp_stream *stream; + u16 i2s_flag = 0; + u32 ext_intr_stat, ext_intr_stat1; + + if (adata->rsrc->no_of_ctrls == 2) + ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1))); + + ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); + + spin_lock(&adata->acp_lock); + list_for_each_entry(stream, &adata->stream_list, list) { + if (ext_intr_stat & stream->irq_bit) { + writel(stream->irq_bit, + ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); + snd_pcm_period_elapsed(stream->substream); + i2s_flag = 1; + } + if (adata->rsrc->no_of_ctrls == 2) { + if (ext_intr_stat1 & stream->irq_bit) { + writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip, + (rsrc->irqp_used - 1))); + snd_pcm_period_elapsed(stream->substream); + i2s_flag = 1; + } + } + } + spin_unlock(&adata->acp_lock); + if (i2s_flag) + return IRQ_HANDLED; + + return IRQ_NONE; +} + +int acp_enable_interrupts(struct acp_chip_info *chip) +{ + struct acp_resource *rsrc; u32 ext_intr_ctrl; - writel(0x01, ACP_EXTERNAL_INTR_ENB(adata)); - ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + rsrc = chip->rsrc; + writel(0x01, ACP_EXTERNAL_INTR_ENB(chip)); + ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_intr_ctrl |= ACP_ERROR_MASK; - writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); + + return 0; } EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, "SND_SOC_ACP_COMMON"); -void acp_disable_interrupts(struct acp_dev_data *adata) +int acp_disable_interrupts(struct acp_chip_info *chip) { - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc; + + rsrc = chip->rsrc; + writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); + writel(0x00, ACP_EXTERNAL_INTR_ENB(chip)); - writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); - writel(0x00, ACP_EXTERNAL_INTR_ENB(adata)); + return 0; } EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, "SND_SOC_ACP_COMMON"); @@ -90,19 +140,23 @@ void restore_acp_pdm_params(struct snd_pcm_substream *substream, struct acp_dev_data *adata) { struct snd_soc_dai *dai; + struct device *dev; + struct acp_chip_info *chip; struct snd_soc_pcm_runtime *soc_runtime; u32 ext_int_ctrl; soc_runtime = snd_soc_substream_to_rtd(substream); dai = snd_soc_rtd_to_cpu(soc_runtime, 0); + dev = dai->component->dev; + chip = dev_get_platdata(dev); /* Programming channel mask and sampling rate */ writel(adata->ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR); /* Enabling ACP Pdm interuppts */ - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0)); ext_int_ctrl |= PDM_DMA_INTR_MASK; - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0)); set_acp_pdm_clk(substream, dai); } EXPORT_SYMBOL_NS_GPL(restore_acp_pdm_params, "SND_SOC_ACP_COMMON"); @@ -113,6 +167,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, struct device *dev = dai->component->dev; struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_resource *rsrc = adata->rsrc; + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream = substream->runtime->private_data; u32 reg_dma_size, reg_fifo_size, reg_fifo_addr; u32 phy_addr, acp_fifo_addr, ext_int_ctrl; @@ -185,7 +240,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | BIT(BT_RX_THRESHOLD(rsrc->offset)) | BIT(I2S_TX_THRESHOLD(rsrc->offset)) | @@ -193,7 +248,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, BIT(HS_RX_THRESHOLD(rsrc->offset)) | BIT(HS_TX_THRESHOLD(rsrc->offset)); - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); return 0; } diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 99297a388ed7..1ef9faba1d8a 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -26,6 +26,15 @@ #define ACP3x_REG_START 0x1240000 #define ACP3x_REG_END 0x125C000 +static irqreturn_t irq_handler(int irq, void *data) +{ + struct acp_chip_info *chip = data; + + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->irq) + return chip->acp_hw_ops->irq(irq, chip); + + return IRQ_NONE; +} static void acp_fill_platform_dev_info(struct platform_device_info *pdevinfo, struct device *parent, struct fwnode_handle *fw_node, @@ -166,6 +175,13 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id if (ret) goto release_regions; + ret = devm_request_irq(dev, pci->irq, irq_handler, + IRQF_SHARED, "ACP_I2S_IRQ", chip); + if (ret) { + dev_err(&pci->dev, "ACP I2S IRQ request failed %d\n", ret); + return ret; + } + check_acp_config(pci, chip); if (!chip->is_pdm_dev && !chip->is_i2s_config) goto skip_pdev_creation; @@ -213,20 +229,17 @@ static int __maybe_unused snd_acp_suspend(struct device *dev) static int __maybe_unused snd_acp_resume(struct device *dev) { struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct device child; int ret; chip = dev_get_drvdata(dev); ret = acp_hw_init(chip); if (ret) dev_err(dev, "ACP init failed\n"); - if (chip->chip_pdev) { - child = chip->chip_pdev->dev; - adata = dev_get_drvdata(&child); - if (adata) - acp_enable_interrupts(adata); - } + + ret = acp_hw_en_interrupts(chip); + if (ret) + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; } diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c index d4855da05b6a..9a820ef3bf46 100644 --- a/sound/soc/amd/acp/acp-pdm.c +++ b/sound/soc/amd/acp/acp-pdm.c @@ -145,7 +145,7 @@ static int acp_dmic_dai_startup(struct snd_pcm_substream *substream, { struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); u32 ext_int_ctrl; stream->dai_id = DMIC_INSTANCE; @@ -154,9 +154,9 @@ static int acp_dmic_dai_startup(struct snd_pcm_substream *substream, stream->reg_offset = ACP_REGION2_OFFSET; /* Enable DMIC Interrupts */ - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0)); ext_int_ctrl |= PDM_DMA_INTR_MASK; - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0)); return 0; } @@ -165,13 +165,13 @@ static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); u32 ext_int_ctrl; /* Disable DMIC interrupts */ - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0)); ext_int_ctrl &= ~PDM_DMA_INTR_MASK; - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0)); } const struct snd_soc_dai_ops acp_dmic_dai_ops = { diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index 7d6abff28b23..9b181fb5861c 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -107,43 +107,6 @@ static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = { .periods_max = CAPTURE_MAX_NUM_PERIODS, }; -static irqreturn_t i2s_irq_handler(int irq, void *data) -{ - struct acp_dev_data *adata = data; - struct acp_resource *rsrc = adata->rsrc; - struct acp_stream *stream; - u16 i2s_flag = 0; - u32 ext_intr_stat, ext_intr_stat1; - - if (adata->rsrc->no_of_ctrls == 2) - ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(adata, (rsrc->irqp_used - 1))); - - ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); - - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { - if (ext_intr_stat & stream->irq_bit) { - writel(stream->irq_bit, - ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); - snd_pcm_period_elapsed(stream->substream); - i2s_flag = 1; - } - if (adata->rsrc->no_of_ctrls == 2) { - if (ext_intr_stat1 & stream->irq_bit) { - writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(adata, - (rsrc->irqp_used - 1))); - snd_pcm_period_elapsed(stream->substream); - i2s_flag = 1; - } - } - } - spin_unlock(&adata->acp_lock); - if (i2s_flag) - return IRQ_HANDLED; - - return IRQ_NONE; -} - void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream) { struct acp_resource *rsrc = adata->rsrc; @@ -278,7 +241,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs } runtime->private_data = stream; - writel(1, ACP_EXTERNAL_INTR_ENB(adata)); + writel(1, ACP_EXTERNAL_INTR_ENB(chip)); spin_lock_irq(&adata->acp_lock); list_add_tail(&stream->list, &adata->stream_list); @@ -363,16 +326,17 @@ static const struct snd_soc_component_driver acp_pcm_component = { int acp_platform_register(struct device *dev) { struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip; struct snd_soc_dai_driver; unsigned int status; - status = devm_request_irq(dev, adata->i2s_irq, i2s_irq_handler, - IRQF_SHARED, "ACP_I2S_IRQ", adata); - if (status) { - dev_err(dev, "ACP I2S IRQ request failed\n"); - return status; + chip = dev_get_platdata(dev); + if (!chip || !chip->base) { + dev_err(dev, "ACP chip data is NULL\n"); + return -ENODEV; } + chip->adata = adata; status = devm_snd_soc_register_component(dev, &acp_pcm_component, adata->dai_driver, adata->num_dai); diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index eb09878c0d5c..13633b3f3730 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -192,6 +192,7 @@ static int rembrandt_audio_probe(struct platform_device *pdev) return -ENODEV; } + chip->rsrc = &rsrc; adata->i2s_irq = res->start; adata->dev = dev; adata->dai_driver = acp_rmb_dai; @@ -208,7 +209,11 @@ static int rembrandt_audio_probe(struct platform_device *pdev) if (ret) return ret; } - acp_enable_interrupts(adata); + ret = acp_hw_en_interrupts(chip); + if (ret) { + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; + } acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); @@ -221,9 +226,13 @@ static int rembrandt_audio_probe(struct platform_device *pdev) static void rembrandt_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); + int ret; + + ret = acp_hw_dis_interrupts(chip); + if (ret) + dev_err(dev, "ACP dis-interrupts failed\n"); - acp_disable_interrupts(adata); acp_platform_unregister(dev); pm_runtime_disable(&pdev->dev); } diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 2b47c6bfc9e7..94ecb17684b7 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -142,6 +142,7 @@ static int renoir_audio_probe(struct platform_device *pdev) return ret; adata->i2s_irq = ret; + chip->rsrc = &rsrc; adata->dev = dev; adata->dai_driver = acp_renoir_dai; adata->num_dai = ARRAY_SIZE(acp_renoir_dai); @@ -150,7 +151,11 @@ static int renoir_audio_probe(struct platform_device *pdev) adata->flag = chip->flag; dev_set_drvdata(dev, adata); - acp_enable_interrupts(adata); + ret = acp_hw_en_interrupts(chip); + if (ret) { + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; + } acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); @@ -164,9 +169,13 @@ static int renoir_audio_probe(struct platform_device *pdev) static void renoir_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); + int ret; + + ret = acp_hw_dis_interrupts(chip); + if (ret) + dev_err(dev, "ACP dis-interrupts failed\n"); - acp_disable_interrupts(adata); acp_platform_unregister(dev); } diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index 76a26b82e3ad..e38ad9f7fb48 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -243,6 +243,7 @@ static int acp63_audio_probe(struct platform_device *pdev) return -ENODEV; } + chip->rsrc = &rsrc; adata->i2s_irq = res->start; adata->dev = dev; adata->dai_driver = acp63_dai; @@ -258,7 +259,11 @@ static int acp63_audio_probe(struct platform_device *pdev) if (ret) return ret; } - acp_enable_interrupts(adata); + ret = acp_hw_en_interrupts(chip); + if (ret) { + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; + } acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); @@ -271,9 +276,13 @@ static int acp63_audio_probe(struct platform_device *pdev) static void acp63_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); + int ret; + + ret = acp_hw_dis_interrupts(chip); + if (ret) + dev_err(dev, "ACP dis-interrupts failed\n"); - acp_disable_interrupts(adata); acp_platform_unregister(dev); pm_runtime_disable(&pdev->dev); } diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index 3e603c5f736a..be4302a5a584 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -174,6 +174,7 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) return -ENODEV; } + chip->rsrc = &rsrc; adata->i2s_irq = res->start; adata->dev = dev; adata->dai_driver = acp70_dai; @@ -190,7 +191,11 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to set I2S master clock as 196.608MHz\n"); return ret; } - acp_enable_interrupts(adata); + ret = acp_hw_en_interrupts(chip); + if (ret) { + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; + } acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); @@ -203,9 +208,13 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) static void acp_acp70_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); + int ret; + + ret = acp_hw_dis_interrupts(chip); + if (ret) + dev_err(dev, "ACP dis-interrupts failed\n"); - acp_disable_interrupts(adata); acp_platform_unregister(dev); pm_runtime_disable(&pdev->dev); } diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index b7a1b4aa8fef..4beaa9cae352 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -147,10 +147,12 @@ struct acp_chip_info { struct snd_acp_hw_ops *acp_hw_ops; int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; + struct acp_resource *rsrc; /* Platform specific resources*/ struct platform_device *dmic_codec_dev; struct platform_device *acp_plat_dev; struct platform_device *mach_dev; struct snd_soc_acpi_mach *machines; + struct acp_dev_data *adata; u32 addr; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ @@ -215,11 +217,19 @@ struct acp_dev_data { * struct snd_acp_hw_ops - ACP PCI driver platform specific ops * @acp_init: ACP initialization * @acp_deinit: ACP de-initialization + * @irq: ACP irq handler + * @en_interrupts: ACP enable interrupts + * @dis_interrupts: ACP disable interrupts */ struct snd_acp_hw_ops { /* ACP hardware initilizations */ int (*acp_init)(struct acp_chip_info *chip); int (*acp_deinit)(struct acp_chip_info *chip); + + /* ACP Interrupts*/ + irqreturn_t (*irq)(int irq, void *data); + int (*en_interrupts)(struct acp_chip_info *chip); + int (*dis_interrupts)(struct acp_chip_info *chip); }; enum acp_config { @@ -332,8 +342,9 @@ int acp_machine_select(struct acp_chip_info *chip); int acp_init(struct acp_chip_info *chip); int acp_deinit(struct acp_chip_info *chip); -void acp_enable_interrupts(struct acp_dev_data *adata); -void acp_disable_interrupts(struct acp_dev_data *adata); +int acp_enable_interrupts(struct acp_chip_info *chip); +int acp_disable_interrupts(struct acp_chip_info *chip); +irqreturn_t acp_irq_handler(int irq, void *data); extern struct snd_acp_hw_ops acp31_common_hw_ops; extern struct snd_acp_hw_ops acp6x_common_hw_ops; @@ -370,6 +381,20 @@ static inline int acp_hw_deinit(struct acp_chip_info *chip) return -EOPNOTSUPP; } +static inline int acp_hw_en_interrupts(struct acp_chip_info *chip) +{ + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->en_interrupts) + return chip->acp_hw_ops->en_interrupts(chip); + return -EOPNOTSUPP; +} + +static inline int acp_hw_dis_interrupts(struct acp_chip_info *chip) +{ + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->dis_interrupts) + chip->acp_hw_ops->dis_interrupts(chip); + return -EOPNOTSUPP; +} + static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction) { u64 byte_count = 0, low = 0, high = 0; diff --git a/sound/soc/amd/acp/chip_offset_byte.h b/sound/soc/amd/acp/chip_offset_byte.h index 117ea63e85c6..82275c9de53a 100644 --- a/sound/soc/amd/acp/chip_offset_byte.h +++ b/sound/soc/amd/acp/chip_offset_byte.h @@ -29,13 +29,13 @@ #define ACP_PIN_CONFIG 0x1440 #define ACP3X_PIN_CONFIG 0x1400 -#define ACP_EXTERNAL_INTR_REG_ADDR(adata, offset, ctrl) \ - (adata->acp_base + adata->rsrc->irq_reg_offset + offset + (ctrl * 0x04)) +#define ACP_EXTERNAL_INTR_REG_ADDR(chip, offset, ctrl) \ + (chip->base + chip->rsrc->irq_reg_offset + offset + (ctrl * 0x04)) -#define ACP_EXTERNAL_INTR_ENB(adata) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x0, 0x0) -#define ACP_EXTERNAL_INTR_CNTL(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x4, ctrl) -#define ACP_EXTERNAL_INTR_STAT(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, \ - (0x4 + (adata->rsrc->no_of_ctrls * 0x04)), ctrl) +#define ACP_EXTERNAL_INTR_ENB(chip) ACP_EXTERNAL_INTR_REG_ADDR(chip, 0x0, 0x0) +#define ACP_EXTERNAL_INTR_CNTL(chip, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(chip, 0x4, ctrl) +#define ACP_EXTERNAL_INTR_STAT(chip, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(chip, \ + (0x4 + (chip->rsrc->no_of_ctrls * 0x04)), ctrl) /* Registers from ACP_AUDIO_BUFFERS block */ -- 2.50.1 From e3933683b25e2cc94485da4909e3338e1a177b39 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:54 +0530 Subject: [PATCH 11/16] ASoC: amd: acp: Remove redundant acp_dev_data structure Move acp_dev_data structure members to acp_chip_info structure to avoid using common members in each structure and remove redundant acp_dev_data structure. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-8-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-i2s.c | 181 +++++++++++++------------- sound/soc/amd/acp/acp-legacy-common.c | 107 ++++++++------- sound/soc/amd/acp/acp-pdm.c | 41 +++--- sound/soc/amd/acp/acp-platform.c | 70 +++++----- sound/soc/amd/acp/acp-rembrandt.c | 53 ++------ sound/soc/amd/acp/acp-renoir.c | 50 ++----- sound/soc/amd/acp/acp63.c | 58 +++------ sound/soc/amd/acp/acp70.c | 50 ++----- sound/soc/amd/acp/amd.h | 86 +++++------- 9 files changed, 276 insertions(+), 420 deletions(-) diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c index 2f458c76f9fc..a38409dd1d34 100644 --- a/sound/soc/amd/acp/acp-i2s.c +++ b/sound/soc/amd/acp/acp-i2s.c @@ -31,14 +31,10 @@ #define ACP63_LRCLK_DIV_FIELD GENMASK(12, 2) #define ACP63_BCLK_DIV_FIELD GENMASK(23, 13) -static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id) +static inline void acp_set_i2s_clk(struct acp_chip_info *chip, int dai_id) { u32 i2s_clk_reg, val; - struct acp_chip_info *chip; - struct device *dev; - dev = adata->dev; - chip = dev_get_platdata(dev); switch (dai_id) { case I2S_SP_INSTANCE: i2s_clk_reg = ACP_I2STDM0_MSTRCLKGEN; @@ -55,36 +51,37 @@ static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id) } val = I2S_MASTER_MODE_ENABLE; - if (adata->tdm_mode) + if (chip->tdm_mode) val |= BIT(1); switch (chip->acp_rev) { case ACP63_PCI_ID: case ACP70_PCI_ID: case ACP71_PCI_ID: - val |= FIELD_PREP(ACP63_LRCLK_DIV_FIELD, adata->lrclk_div); - val |= FIELD_PREP(ACP63_BCLK_DIV_FIELD, adata->bclk_div); + val |= FIELD_PREP(ACP63_LRCLK_DIV_FIELD, chip->lrclk_div); + val |= FIELD_PREP(ACP63_BCLK_DIV_FIELD, chip->bclk_div); break; default: - val |= FIELD_PREP(LRCLK_DIV_FIELD, adata->lrclk_div); - val |= FIELD_PREP(BCLK_DIV_FIELD, adata->bclk_div); + val |= FIELD_PREP(LRCLK_DIV_FIELD, chip->lrclk_div); + val |= FIELD_PREP(BCLK_DIV_FIELD, chip->bclk_div); } - writel(val, adata->acp_base + i2s_clk_reg); + writel(val, chip->base + i2s_clk_reg); } static int acp_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { - struct acp_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai); + struct device *dev = cpu_dai->component->dev; + struct acp_chip_info *chip = dev_get_platdata(dev); int mode; mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK; switch (mode) { case SND_SOC_DAIFMT_I2S: - adata->tdm_mode = TDM_DISABLE; + chip->tdm_mode = TDM_DISABLE; break; case SND_SOC_DAIFMT_DSP_A: - adata->tdm_mode = TDM_ENABLE; + chip->tdm_mode = TDM_ENABLE; break; default: return -EINVAL; @@ -96,7 +93,6 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas int slots, int slot_width) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = snd_soc_dai_get_drvdata(dai); struct acp_chip_info *chip; struct acp_stream *stream; int slot_len, no_of_slots; @@ -157,35 +153,35 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas slots = no_of_slots; - spin_lock_irq(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock_irq(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { switch (chip->acp_rev) { case ACP_RN_PCI_ID: case ACP_RMB_PCI_ID: if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK) - adata->tdm_tx_fmt[stream->dai_id - 1] = + chip->tdm_tx_fmt[stream->dai_id - 1] = FRM_LEN | (slots << 15) | (slot_len << 18); else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE) - adata->tdm_rx_fmt[stream->dai_id - 1] = + chip->tdm_rx_fmt[stream->dai_id - 1] = FRM_LEN | (slots << 15) | (slot_len << 18); break; case ACP63_PCI_ID: case ACP70_PCI_ID: case ACP71_PCI_ID: if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK) - adata->tdm_tx_fmt[stream->dai_id - 1] = + chip->tdm_tx_fmt[stream->dai_id - 1] = FRM_LEN | (slots << 13) | (slot_len << 18); else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE) - adata->tdm_rx_fmt[stream->dai_id - 1] = + chip->tdm_rx_fmt[stream->dai_id - 1] = FRM_LEN | (slots << 13) | (slot_len << 18); break; default: dev_err(dev, "Unknown chip revision %d\n", chip->acp_rev); - spin_unlock_irq(&adata->acp_lock); + spin_unlock_irq(&chip->acp_lock); return -EINVAL; } } - spin_unlock_irq(&adata->acp_lock); + spin_unlock_irq(&chip->acp_lock); return 0; } @@ -193,15 +189,15 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata; + struct acp_chip_info *chip; struct acp_resource *rsrc; u32 val; u32 xfer_resolution; u32 reg_val, fmt_reg, tdm_fmt; u32 lrclk_div_val, bclk_div_val; - adata = snd_soc_dai_get_drvdata(dai); - rsrc = adata->rsrc; + chip = dev_get_platdata(dev); + rsrc = chip->rsrc; /* These values are as per Hardware Spec */ switch (params_format(params)) { @@ -240,7 +236,7 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; } - adata->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution; + chip->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution; } else { switch (dai->driver->id) { case I2S_BT_INSTANCE: @@ -259,22 +255,22 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; } - adata->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution; + chip->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution; } - val = readl(adata->acp_base + reg_val); + val = readl(chip->base + reg_val); val &= ~ACP3x_ITER_IRER_SAMP_LEN_MASK; val = val | (xfer_resolution << 3); - writel(val, adata->acp_base + reg_val); + writel(val, chip->base + reg_val); - if (adata->tdm_mode) { - val = readl(adata->acp_base + reg_val); - writel(val | BIT(1), adata->acp_base + reg_val); + if (chip->tdm_mode) { + val = readl(chip->base + reg_val); + writel(val | BIT(1), chip->base + reg_val); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - tdm_fmt = adata->tdm_tx_fmt[dai->driver->id - 1]; + tdm_fmt = chip->tdm_tx_fmt[dai->driver->id - 1]; else - tdm_fmt = adata->tdm_rx_fmt[dai->driver->id - 1]; - writel(tdm_fmt, adata->acp_base + fmt_reg); + tdm_fmt = chip->tdm_rx_fmt[dai->driver->id - 1]; + writel(tdm_fmt, chip->base + fmt_reg); } if (rsrc->soc_mclk) { @@ -377,8 +373,8 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ default: break; } - adata->lrclk_div = lrclk_div_val; - adata->bclk_div = bclk_div_val; + chip->lrclk_div = lrclk_div_val; + chip->bclk_div = bclk_div_val; } return 0; } @@ -387,8 +383,8 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct { struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); - struct acp_resource *rsrc = adata->rsrc; + struct acp_chip_info *chip = dev_get_platdata(dev); + struct acp_resource *rsrc = chip->rsrc; u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg; period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size); @@ -398,20 +394,20 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - stream->bytescount = acp_get_byte_count(adata, stream->dai_id, substream->stream); + stream->bytescount = acp_get_byte_count(chip, stream->dai_id, substream->stream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { switch (dai->driver->id) { case I2S_BT_INSTANCE: - water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(adata); + water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(chip); reg_val = ACP_BTTDM_ITER; ier_val = ACP_BTTDM_IER; - buf_reg = ACP_BT_TX_RINGBUFSIZE(adata); + buf_reg = ACP_BT_TX_RINGBUFSIZE(chip); break; case I2S_SP_INSTANCE: - water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(adata); + water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(chip); reg_val = ACP_I2STDM_ITER; ier_val = ACP_I2STDM_IER; - buf_reg = ACP_I2S_TX_RINGBUFSIZE(adata); + buf_reg = ACP_I2S_TX_RINGBUFSIZE(chip); break; case I2S_HS_INSTANCE: water_val = ACP_HS_TX_INTR_WATERMARK_SIZE; @@ -426,16 +422,16 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct } else { switch (dai->driver->id) { case I2S_BT_INSTANCE: - water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(adata); + water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(chip); reg_val = ACP_BTTDM_IRER; ier_val = ACP_BTTDM_IER; - buf_reg = ACP_BT_RX_RINGBUFSIZE(adata); + buf_reg = ACP_BT_RX_RINGBUFSIZE(chip); break; case I2S_SP_INSTANCE: - water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(adata); + water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(chip); reg_val = ACP_I2STDM_IRER; ier_val = ACP_I2STDM_IER; - buf_reg = ACP_I2S_RX_RINGBUFSIZE(adata); + buf_reg = ACP_I2S_RX_RINGBUFSIZE(chip); break; case I2S_HS_INSTANCE: water_val = ACP_HS_RX_INTR_WATERMARK_SIZE; @@ -449,14 +445,14 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct } } - writel(period_bytes, adata->acp_base + water_val); - writel(buf_size, adata->acp_base + buf_reg); + writel(period_bytes, chip->base + water_val); + writel(buf_size, chip->base + buf_reg); if (rsrc->soc_mclk) - acp_set_i2s_clk(adata, dai->driver->id); - val = readl(adata->acp_base + reg_val); + acp_set_i2s_clk(chip, dai->driver->id); + val = readl(chip->base + reg_val); val = val | BIT(0); - writel(val, adata->acp_base + reg_val); - writel(1, adata->acp_base + ier_val); + writel(val, chip->base + reg_val); + writel(1, chip->base + ier_val); return 0; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: @@ -493,19 +489,19 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct return -EINVAL; } } - val = readl(adata->acp_base + reg_val); + val = readl(chip->base + reg_val); val = val & ~BIT(0); - writel(val, adata->acp_base + reg_val); - - if (!(readl(adata->acp_base + ACP_BTTDM_ITER) & BIT(0)) && - !(readl(adata->acp_base + ACP_BTTDM_IRER) & BIT(0))) - writel(0, adata->acp_base + ACP_BTTDM_IER); - if (!(readl(adata->acp_base + ACP_I2STDM_ITER) & BIT(0)) && - !(readl(adata->acp_base + ACP_I2STDM_IRER) & BIT(0))) - writel(0, adata->acp_base + ACP_I2STDM_IER); - if (!(readl(adata->acp_base + ACP_HSTDM_ITER) & BIT(0)) && - !(readl(adata->acp_base + ACP_HSTDM_IRER) & BIT(0))) - writel(0, adata->acp_base + ACP_HSTDM_IER); + writel(val, chip->base + reg_val); + + if (!(readl(chip->base + ACP_BTTDM_ITER) & BIT(0)) && + !(readl(chip->base + ACP_BTTDM_IRER) & BIT(0))) + writel(0, chip->base + ACP_BTTDM_IER); + if (!(readl(chip->base + ACP_I2STDM_ITER) & BIT(0)) && + !(readl(chip->base + ACP_I2STDM_IRER) & BIT(0))) + writel(0, chip->base + ACP_I2STDM_IER); + if (!(readl(chip->base + ACP_HSTDM_ITER) & BIT(0)) && + !(readl(chip->base + ACP_HSTDM_IRER) & BIT(0))) + writel(0, chip->base + ACP_HSTDM_IER); return 0; default: return -EINVAL; @@ -517,9 +513,8 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); - struct acp_chip_info *chip; - struct acp_resource *rsrc = adata->rsrc; + struct acp_chip_info *chip = dev_get_platdata(dev); + struct acp_resource *rsrc = chip->rsrc; struct acp_stream *stream = substream->runtime->private_data; u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0; u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl; @@ -529,56 +524,56 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d switch (dai->driver->id) { case I2S_SP_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata); + reg_dma_size = ACP_I2S_TX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + SP_PB_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_I2S_TX_FIFOADDR(adata); - reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata); + reg_fifo_addr = ACP_I2S_TX_FIFOADDR(chip); + reg_fifo_size = ACP_I2S_TX_FIFOSIZE(chip); if (chip->acp_rev >= ACP70_PCI_ID) phy_addr = ACP7x_I2S_SP_TX_MEM_WINDOW_START; else phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_I2S_TX_RINGBUFADDR(chip)); } else { - reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata); + reg_dma_size = ACP_I2S_RX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + SP_CAPT_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata); - reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata); + reg_fifo_addr = ACP_I2S_RX_FIFOADDR(chip); + reg_fifo_size = ACP_I2S_RX_FIFOSIZE(chip); if (chip->acp_rev >= ACP70_PCI_ID) phy_addr = ACP7x_I2S_SP_RX_MEM_WINDOW_START; else phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_I2S_RX_RINGBUFADDR(chip)); } break; case I2S_BT_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - reg_dma_size = ACP_BT_TX_DMA_SIZE(adata); + reg_dma_size = ACP_BT_TX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + BT_PB_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata); - reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata); + reg_fifo_addr = ACP_BT_TX_FIFOADDR(chip); + reg_fifo_size = ACP_BT_TX_FIFOSIZE(chip); if (chip->acp_rev >= ACP70_PCI_ID) phy_addr = ACP7x_I2S_BT_TX_MEM_WINDOW_START; else phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_BT_TX_RINGBUFADDR(chip)); } else { - reg_dma_size = ACP_BT_RX_DMA_SIZE(adata); + reg_dma_size = ACP_BT_RX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + BT_CAPT_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata); - reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata); + reg_fifo_addr = ACP_BT_RX_FIFOADDR(chip); + reg_fifo_size = ACP_BT_RX_FIFOSIZE(chip); if (chip->acp_rev >= ACP70_PCI_ID) phy_addr = ACP7x_I2S_BT_RX_MEM_WINDOW_START; else phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_BT_RX_RINGBUFADDR(chip)); } break; case I2S_HS_INSTANCE: @@ -593,7 +588,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d phy_addr = ACP7x_I2S_HS_TX_MEM_WINDOW_START; else phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR); + writel(phy_addr, chip->base + ACP_HS_TX_RINGBUFADDR); } else { reg_dma_size = ACP_HS_RX_DMA_SIZE; acp_fifo_addr = rsrc->sram_pte_offset + @@ -605,7 +600,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d phy_addr = ACP7x_I2S_HS_RX_MEM_WINDOW_START; else phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR); + writel(phy_addr, chip->base + ACP_HS_RX_RINGBUFADDR); } break; default: @@ -613,9 +608,9 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d return -EINVAL; } - writel(DMA_SIZE, adata->acp_base + reg_dma_size); - writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); - writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); + writel(DMA_SIZE, chip->base + reg_dma_size); + writel(acp_fifo_addr, chip->base + reg_fifo_addr); + writel(FIFO_SIZE, chip->base + reg_fifo_size); ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | @@ -634,8 +629,8 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d { struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); - struct acp_resource *rsrc = adata->rsrc; + struct acp_chip_info *chip = dev_get_platdata(dev); + struct acp_resource *rsrc = chip->rsrc; unsigned int dir = substream->stream; unsigned int irq_bit = 0; diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 13fddce8df56..988b7a17b2f4 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -38,26 +38,25 @@ EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON"); irqreturn_t acp_irq_handler(int irq, void *data) { struct acp_chip_info *chip = data; - struct acp_dev_data *adata = chip->adata; - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc = chip->rsrc; struct acp_stream *stream; u16 i2s_flag = 0; u32 ext_intr_stat, ext_intr_stat1; - if (adata->rsrc->no_of_ctrls == 2) + if (rsrc->no_of_ctrls == 2) ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1))); ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { if (ext_intr_stat & stream->irq_bit) { writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); snd_pcm_period_elapsed(stream->substream); i2s_flag = 1; } - if (adata->rsrc->no_of_ctrls == 2) { + if (chip->rsrc->no_of_ctrls == 2) { if (ext_intr_stat1 & stream->irq_bit) { writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1))); @@ -66,7 +65,7 @@ irqreturn_t acp_irq_handler(int irq, void *data) } } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); if (i2s_flag) return IRQ_HANDLED; @@ -106,7 +105,7 @@ static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct acp_stream *stream = runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); u32 physical_addr, pdm_size, period_bytes; @@ -115,43 +114,40 @@ static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream, physical_addr = stream->reg_offset + MEM_WINDOW_START; /* Init ACP PDM Ring buffer */ - writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR); - writel(pdm_size, adata->acp_base + ACP_WOV_RX_RINGBUFSIZE); - writel(period_bytes, adata->acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE); - writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL); + writel(physical_addr, chip->base + ACP_WOV_RX_RINGBUFADDR); + writel(pdm_size, chip->base + ACP_WOV_RX_RINGBUFSIZE); + writel(period_bytes, chip->base + ACP_WOV_RX_INTR_WATERMARK_SIZE); + writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL); } static void set_acp_pdm_clk(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); unsigned int pdm_ctrl; /* Enable default ACP PDM clk */ - writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL); - pdm_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL); + writel(PDM_CLK_FREQ_MASK, chip->base + ACP_WOV_CLK_CTRL); + pdm_ctrl = readl(chip->base + ACP_WOV_MISC_CTRL); pdm_ctrl |= PDM_MISC_CTRL_MASK; - writel(pdm_ctrl, adata->acp_base + ACP_WOV_MISC_CTRL); + writel(pdm_ctrl, chip->base + ACP_WOV_MISC_CTRL); set_acp_pdm_ring_buffer(substream, dai); } void restore_acp_pdm_params(struct snd_pcm_substream *substream, - struct acp_dev_data *adata) + struct acp_chip_info *chip) { struct snd_soc_dai *dai; - struct device *dev; - struct acp_chip_info *chip; struct snd_soc_pcm_runtime *soc_runtime; u32 ext_int_ctrl; soc_runtime = snd_soc_substream_to_rtd(substream); dai = snd_soc_rtd_to_cpu(soc_runtime, 0); - dev = dai->component->dev; - chip = dev_get_platdata(dev); + /* Programming channel mask and sampling rate */ - writel(adata->ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); - writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR); + writel(chip->ch_mask, chip->base + ACP_WOV_PDM_NO_OF_CHANNELS); + writel(PDM_DEC_64, chip->base + ACP_WOV_PDM_DECIMATION_FACTOR); /* Enabling ACP Pdm interuppts */ ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0)); @@ -165,9 +161,8 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); - struct acp_resource *rsrc = adata->rsrc; struct acp_chip_info *chip = dev_get_platdata(dev); + struct acp_resource *rsrc = chip->rsrc; struct acp_stream *stream = substream->runtime->private_data; u32 reg_dma_size, reg_fifo_size, reg_fifo_addr; u32 phy_addr, acp_fifo_addr, ext_int_ctrl; @@ -176,40 +171,40 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, switch (dai->driver->id) { case I2S_SP_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata); + reg_dma_size = ACP_I2S_TX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + SP_PB_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_I2S_TX_FIFOADDR(adata); - reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata); + reg_fifo_addr = ACP_I2S_TX_FIFOADDR(chip); + reg_fifo_size = ACP_I2S_TX_FIFOSIZE(chip); phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_I2S_TX_RINGBUFADDR(chip)); } else { - reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata); + reg_dma_size = ACP_I2S_RX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + SP_CAPT_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata); - reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata); + reg_fifo_addr = ACP_I2S_RX_FIFOADDR(chip); + reg_fifo_size = ACP_I2S_RX_FIFOSIZE(chip); phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_I2S_RX_RINGBUFADDR(chip)); } break; case I2S_BT_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - reg_dma_size = ACP_BT_TX_DMA_SIZE(adata); + reg_dma_size = ACP_BT_TX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + BT_PB_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata); - reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata); + reg_fifo_addr = ACP_BT_TX_FIFOADDR(chip); + reg_fifo_size = ACP_BT_TX_FIFOSIZE(chip); phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_BT_TX_RINGBUFADDR(chip)); } else { - reg_dma_size = ACP_BT_RX_DMA_SIZE(adata); + reg_dma_size = ACP_BT_RX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + BT_CAPT_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata); - reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata); + reg_fifo_addr = ACP_BT_RX_FIFOADDR(chip); + reg_fifo_size = ACP_BT_RX_FIFOSIZE(chip); phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_BT_RX_RINGBUFADDR(chip)); } break; case I2S_HS_INSTANCE: @@ -220,7 +215,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, reg_fifo_addr = ACP_HS_TX_FIFOADDR; reg_fifo_size = ACP_HS_TX_FIFOSIZE; phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR); + writel(phy_addr, chip->base + ACP_HS_TX_RINGBUFADDR); } else { reg_dma_size = ACP_HS_RX_DMA_SIZE; acp_fifo_addr = rsrc->sram_pte_offset + @@ -228,7 +223,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, reg_fifo_addr = ACP_HS_RX_FIFOADDR; reg_fifo_size = ACP_HS_RX_FIFOSIZE; phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR); + writel(phy_addr, chip->base + ACP_HS_RX_RINGBUFADDR); } break; default: @@ -236,9 +231,9 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, return -EINVAL; } - writel(DMA_SIZE, adata->acp_base + reg_dma_size); - writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); - writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); + writel(DMA_SIZE, chip->base + reg_dma_size); + writel(acp_fifo_addr, chip->base + reg_fifo_addr); + writel(FIFO_SIZE, chip->base + reg_fifo_size); ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | @@ -253,7 +248,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, } int restore_acp_i2s_params(struct snd_pcm_substream *substream, - struct acp_dev_data *adata, + struct acp_chip_info *chip, struct acp_stream *stream) { struct snd_soc_dai *dai; @@ -263,7 +258,7 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream, soc_runtime = snd_soc_substream_to_rtd(substream); dai = snd_soc_rtd_to_cpu(soc_runtime, 0); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - tdm_fmt = adata->tdm_tx_fmt[stream->dai_id - 1]; + tdm_fmt = chip->tdm_tx_fmt[stream->dai_id - 1]; switch (stream->dai_id) { case I2S_BT_INSTANCE: reg_val = ACP_BTTDM_ITER; @@ -281,9 +276,9 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream, pr_err("Invalid dai id %x\n", stream->dai_id); return -EINVAL; } - val = adata->xfer_tx_resolution[stream->dai_id - 1] << 3; + val = chip->xfer_tx_resolution[stream->dai_id - 1] << 3; } else { - tdm_fmt = adata->tdm_rx_fmt[stream->dai_id - 1]; + tdm_fmt = chip->tdm_rx_fmt[stream->dai_id - 1]; switch (stream->dai_id) { case I2S_BT_INSTANCE: reg_val = ACP_BTTDM_IRER; @@ -301,13 +296,13 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream, pr_err("Invalid dai id %x\n", stream->dai_id); return -EINVAL; } - val = adata->xfer_rx_resolution[stream->dai_id - 1] << 3; + val = chip->xfer_rx_resolution[stream->dai_id - 1] << 3; } - writel(val, adata->acp_base + reg_val); - if (adata->tdm_mode == TDM_ENABLE) { - writel(tdm_fmt, adata->acp_base + fmt_reg); - val = readl(adata->acp_base + reg_val); - writel(val | 0x2, adata->acp_base + reg_val); + writel(val, chip->base + reg_val); + if (chip->tdm_mode == TDM_ENABLE) { + writel(tdm_fmt, chip->base + fmt_reg); + val = readl(chip->base + reg_val); + writel(val | 0x2, chip->base + reg_val); } return set_acp_i2s_dma_fifo(substream, dai); } diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c index 9a820ef3bf46..1bfc34c2aa53 100644 --- a/sound/soc/amd/acp/acp-pdm.c +++ b/sound/soc/amd/acp/acp-pdm.c @@ -30,17 +30,16 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream, { struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_chip_info *chip; u32 physical_addr, size_dmic, period_bytes; unsigned int dmic_ctrl; chip = dev_get_platdata(dev); /* Enable default DMIC clk */ - writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL); - dmic_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL); + writel(PDM_CLK_FREQ_MASK, chip->base + ACP_WOV_CLK_CTRL); + dmic_ctrl = readl(chip->base + ACP_WOV_MISC_CTRL); dmic_ctrl |= PDM_MISC_CTRL_MASK; - writel(dmic_ctrl, adata->acp_base + ACP_WOV_MISC_CTRL); + writel(dmic_ctrl, chip->base + ACP_WOV_MISC_CTRL); period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size); @@ -53,10 +52,10 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream, physical_addr = stream->reg_offset + MEM_WINDOW_START; /* Init DMIC Ring buffer */ - writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR); - writel(size_dmic, adata->acp_base + ACP_WOV_RX_RINGBUFSIZE); - writel(period_bytes, adata->acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE); - writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL); + writel(physical_addr, chip->base + ACP_WOV_RX_RINGBUFADDR); + writel(size_dmic, chip->base + ACP_WOV_RX_RINGBUFSIZE); + writel(period_bytes, chip->base + ACP_WOV_RX_INTR_WATERMARK_SIZE); + writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL); return 0; } @@ -65,7 +64,7 @@ static int acp_dmic_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); unsigned int dma_enable; int ret = 0; @@ -73,27 +72,27 @@ static int acp_dmic_dai_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - dma_enable = readl(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE); + dma_enable = readl(chip->base + ACP_WOV_PDM_DMA_ENABLE); if (!(dma_enable & DMA_EN_MASK)) { - writel(PDM_ENABLE, adata->acp_base + ACP_WOV_PDM_ENABLE); - writel(PDM_ENABLE, adata->acp_base + ACP_WOV_PDM_DMA_ENABLE); + writel(PDM_ENABLE, chip->base + ACP_WOV_PDM_ENABLE); + writel(PDM_ENABLE, chip->base + ACP_WOV_PDM_DMA_ENABLE); } - ret = readl_poll_timeout_atomic(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE, + ret = readl_poll_timeout_atomic(chip->base + ACP_WOV_PDM_DMA_ENABLE, dma_enable, (dma_enable & DMA_EN_MASK), DELAY_US, PDM_TIMEOUT); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - dma_enable = readl(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE); + dma_enable = readl(chip->base + ACP_WOV_PDM_DMA_ENABLE); if ((dma_enable & DMA_EN_MASK)) { - writel(PDM_DISABLE, adata->acp_base + ACP_WOV_PDM_ENABLE); - writel(PDM_DISABLE, adata->acp_base + ACP_WOV_PDM_DMA_ENABLE); + writel(PDM_DISABLE, chip->base + ACP_WOV_PDM_ENABLE); + writel(PDM_DISABLE, chip->base + ACP_WOV_PDM_DMA_ENABLE); } - ret = readl_poll_timeout_atomic(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE, + ret = readl_poll_timeout_atomic(chip->base + ACP_WOV_PDM_DMA_ENABLE, dma_enable, !(dma_enable & DMA_EN_MASK), DELAY_US, PDM_TIMEOUT); break; @@ -109,7 +108,7 @@ static int acp_dmic_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hwparams, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); unsigned int channels, ch_mask; channels = params_channels(hwparams); @@ -128,14 +127,14 @@ static int acp_dmic_hwparams(struct snd_pcm_substream *substream, return -EINVAL; } - adata->ch_mask = ch_mask; + chip->ch_mask = ch_mask; if (params_format(hwparams) != SNDRV_PCM_FORMAT_S32_LE) { dev_err(dai->dev, "Invalid format:%d\n", params_format(hwparams)); return -EINVAL; } - writel(ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); - writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR); + writel(ch_mask, chip->base + ACP_WOV_PDM_NO_OF_CHANNELS); + writel(PDM_DEC_64, chip->base + ACP_WOV_PDM_DECIMATION_FACTOR); return 0; } diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index 9b181fb5861c..8d61e1991e4f 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -107,37 +107,37 @@ static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = { .periods_max = CAPTURE_MAX_NUM_PERIODS, }; -void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream) +void config_pte_for_stream(struct acp_chip_info *chip, struct acp_stream *stream) { - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc = chip->rsrc; u32 reg_val; reg_val = rsrc->sram_pte_offset; stream->reg_offset = 0x02000000; - writel((reg_val + GRP1_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1); - writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); + writel((reg_val + GRP1_OFFSET) | BIT(31), chip->base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1); + writel(PAGE_SIZE_4K_ENABLE, chip->base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); - writel((reg_val + GRP2_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2); - writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2); + writel((reg_val + GRP2_OFFSET) | BIT(31), chip->base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2); + writel(PAGE_SIZE_4K_ENABLE, chip->base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2); - writel(reg_val | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_5); - writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5); + writel(reg_val | BIT(31), chip->base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_5); + writel(PAGE_SIZE_4K_ENABLE, chip->base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5); - writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL); + writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL); } EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, "SND_SOC_ACP_COMMON"); -void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size) +void config_acp_dma(struct acp_chip_info *chip, struct acp_stream *stream, int size) { struct snd_pcm_substream *substream = stream->substream; - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc = chip->rsrc; dma_addr_t addr = substream->dma_buffer.addr; int num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); u32 low, high, val; u16 page_idx; - switch (adata->acp_rev) { + switch (chip->acp_rev) { case ACP70_PCI_ID: case ACP71_PCI_ID: switch (stream->dai_id) { @@ -163,7 +163,7 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s val = 0x6000; break; default: - dev_err(adata->dev, "Invalid dai id %x\n", stream->dai_id); + dev_err(chip->dev, "Invalid dai id %x\n", stream->dai_id); return; } break; @@ -176,9 +176,9 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s /* Load the low address of page int ACP SRAM through SRBM */ low = lower_32_bits(addr); high = upper_32_bits(addr); - writel(low, adata->acp_base + rsrc->scratch_reg_offset + val); + writel(low, chip->base + rsrc->scratch_reg_offset + val); high |= BIT(31); - writel(high, adata->acp_base + rsrc->scratch_reg_offset + val + 4); + writel(high, chip->base + rsrc->scratch_reg_offset + val + 4); /* Move to next physically contiguous page */ val += 8; @@ -191,7 +191,6 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs { struct snd_pcm_runtime *runtime = substream->runtime; struct device *dev = component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_chip_info *chip; struct acp_stream *stream; int ret; @@ -201,7 +200,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs return -ENOMEM; stream->substream = substream; - chip = dev_get_platdata(dev); + chip = dev_get_drvdata(dev->parent); switch (chip->acp_rev) { case ACP63_PCI_ID: case ACP70_PCI_ID: @@ -243,9 +242,9 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs writel(1, ACP_EXTERNAL_INTR_ENB(chip)); - spin_lock_irq(&adata->acp_lock); - list_add_tail(&stream->list, &adata->stream_list); - spin_unlock_irq(&adata->acp_lock); + spin_lock_irq(&chip->acp_lock); + list_add_tail(&stream->list, &chip->stream_list); + spin_unlock_irq(&chip->acp_lock); return ret; } @@ -254,13 +253,14 @@ static int acp_dma_hw_params(struct snd_soc_component *component, struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct acp_dev_data *adata = snd_soc_component_get_drvdata(component); + struct device *dev = component->dev; + struct acp_chip_info *chip = dev_get_drvdata(dev->parent); struct acp_stream *stream = substream->runtime->private_data; u64 size = params_buffer_bytes(params); /* Configure ACP DMA block with params */ - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, size); return 0; } @@ -269,7 +269,7 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct device *dev = component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_drvdata(dev->parent); struct acp_stream *stream = substream->runtime->private_data; u32 pos, buffersize; u64 bytescount; @@ -277,7 +277,7 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_soc_component *component, buffersize = frames_to_bytes(substream->runtime, substream->runtime->buffer_size); - bytescount = acp_get_byte_count(adata, stream->dai_id, substream->stream); + bytescount = acp_get_byte_count(chip, stream->dai_id, substream->stream); if (bytescount > stream->bytescount) bytescount -= stream->bytescount; @@ -301,13 +301,13 @@ static int acp_dma_close(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct device *dev = component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_drvdata(dev->parent); struct acp_stream *stream = substream->runtime->private_data; /* Remove entry from list */ - spin_lock_irq(&adata->acp_lock); + spin_lock_irq(&chip->acp_lock); list_del(&stream->list); - spin_unlock_irq(&adata->acp_lock); + spin_unlock_irq(&chip->acp_lock); kfree(stream); return 0; @@ -325,7 +325,6 @@ static const struct snd_soc_component_driver acp_pcm_component = { int acp_platform_register(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_chip_info *chip; struct snd_soc_dai_driver; unsigned int status; @@ -336,17 +335,16 @@ int acp_platform_register(struct device *dev) return -ENODEV; } - chip->adata = adata; status = devm_snd_soc_register_component(dev, &acp_pcm_component, - adata->dai_driver, - adata->num_dai); + chip->dai_driver, + chip->num_dai); if (status) { dev_err(dev, "Fail to register acp i2s component\n"); return status; } - INIT_LIST_HEAD(&adata->stream_list); - spin_lock_init(&adata->acp_lock); + INIT_LIST_HEAD(&chip->stream_list); + spin_lock_init(&chip->acp_lock); return 0; } @@ -354,10 +352,6 @@ EXPORT_SYMBOL_NS_GPL(acp_platform_register, "SND_SOC_ACP_COMMON"); int acp_platform_unregister(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); - - if (adata->mach_dev) - platform_device_unregister(adata->mach_dev); return 0; } EXPORT_SYMBOL_NS_GPL(acp_platform_unregister, "SND_SOC_ACP_COMMON"); diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index 13633b3f3730..dfb18d5cdc7a 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -157,8 +157,6 @@ static int rembrandt_audio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct resource *res; u32 ret; chip = dev_get_platdata(&pdev->dev); @@ -172,37 +170,10 @@ static int rembrandt_audio_probe(struct platform_device *pdev) return -ENODEV; } - adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); - if (!adata) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); - return -ENODEV; - } - - adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!adata->acp_base) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); - return -ENODEV; - } - + chip->dev = dev; chip->rsrc = &rsrc; - adata->i2s_irq = res->start; - adata->dev = dev; - adata->dai_driver = acp_rmb_dai; - adata->num_dai = ARRAY_SIZE(acp_rmb_dai); - adata->rsrc = &rsrc; - adata->acp_rev = chip->acp_rev; - adata->flag = chip->flag; - adata->is_i2s_config = chip->is_i2s_config; - - dev_set_drvdata(dev, adata); + chip->dai_driver = acp_rmb_dai; + chip->num_dai = ARRAY_SIZE(acp_rmb_dai); if (chip->is_i2s_config && rsrc.soc_mclk) { ret = acp6x_master_clock_generate(dev); @@ -239,30 +210,30 @@ static void rembrandt_audio_remove(struct platform_device *pdev) static int __maybe_unused rmb_pcm_resume(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; struct snd_pcm_substream *substream; snd_pcm_uframes_t buf_in_frames; u64 buf_size; - if (adata->is_i2s_config && adata->rsrc->soc_mclk) + if (chip->is_i2s_config && chip->rsrc->soc_mclk) acp6x_master_clock_generate(dev); - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { substream = stream->substream; if (substream && substream->runtime) { buf_in_frames = (substream->runtime->buffer_size); buf_size = frames_to_bytes(substream->runtime, buf_in_frames); - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, buf_size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, buf_size); if (stream->dai_id) - restore_acp_i2s_params(substream, adata, stream); + restore_acp_i2s_params(substream, chip, stream); else - restore_acp_pdm_params(substream, adata); + restore_acp_pdm_params(substream, chip); } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); return 0; } diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 94ecb17684b7..2037af67509a 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -108,8 +108,6 @@ static int renoir_audio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct resource *res; int ret; chip = dev_get_platdata(&pdev->dev); @@ -123,39 +121,17 @@ static int renoir_audio_probe(struct platform_device *pdev) return -ENODEV; } - adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); - if (!adata) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); - return -ENODEV; - } - - adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!adata->acp_base) - return -ENOMEM; - - ret = platform_get_irq_byname(pdev, "acp_dai_irq"); - if (ret < 0) - return ret; - adata->i2s_irq = ret; - + chip->dev = dev; chip->rsrc = &rsrc; - adata->dev = dev; - adata->dai_driver = acp_renoir_dai; - adata->num_dai = ARRAY_SIZE(acp_renoir_dai); - adata->rsrc = &rsrc; - adata->acp_rev = chip->acp_rev; - adata->flag = chip->flag; - - dev_set_drvdata(dev, adata); + chip->dai_driver = acp_renoir_dai; + chip->num_dai = ARRAY_SIZE(acp_renoir_dai); + ret = acp_hw_en_interrupts(chip); if (ret) { dev_err(dev, "ACP en-interrupts failed\n"); return ret; } + acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); @@ -181,27 +157,27 @@ static void renoir_audio_remove(struct platform_device *pdev) static int __maybe_unused rn_pcm_resume(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; struct snd_pcm_substream *substream; snd_pcm_uframes_t buf_in_frames; u64 buf_size; - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { substream = stream->substream; if (substream && substream->runtime) { buf_in_frames = (substream->runtime->buffer_size); buf_size = frames_to_bytes(substream->runtime, buf_in_frames); - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, buf_size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, buf_size); if (stream->dai_id) - restore_acp_i2s_params(substream, adata, stream); + restore_acp_i2s_params(substream, chip, stream); else - restore_acp_pdm_params(substream, adata); + restore_acp_pdm_params(substream, chip); } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); return 0; } diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index e38ad9f7fb48..49786e1a214f 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -153,7 +153,7 @@ static struct snd_soc_dai_driver acp63_dai[] = { }, }; -static int acp63_i2s_master_clock_generate(struct acp_dev_data *adata) +static int acp63_i2s_master_clock_generate(struct acp_chip_info *chip) { int rc; u32 data; @@ -208,8 +208,6 @@ static int acp63_audio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct resource *res; int ret; chip = dev_get_platdata(&pdev->dev); @@ -223,39 +221,13 @@ static int acp63_audio_probe(struct platform_device *pdev) return -ENODEV; } - adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); - if (!adata) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); - return -ENODEV; - } - - adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!adata->acp_base) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); - return -ENODEV; - } - + chip->dev = dev; chip->rsrc = &rsrc; - adata->i2s_irq = res->start; - adata->dev = dev; - adata->dai_driver = acp63_dai; - adata->num_dai = ARRAY_SIZE(acp63_dai); - adata->rsrc = &rsrc; - adata->acp_rev = chip->acp_rev; - adata->flag = chip->flag; - adata->is_i2s_config = chip->is_i2s_config; - dev_set_drvdata(dev, adata); + chip->dai_driver = acp63_dai; + chip->num_dai = ARRAY_SIZE(acp63_dai); if (chip->is_i2s_config && rsrc.soc_mclk) { - ret = acp63_i2s_master_clock_generate(adata); + ret = acp63_i2s_master_clock_generate(chip); if (ret) return ret; } @@ -289,30 +261,30 @@ static void acp63_audio_remove(struct platform_device *pdev) static int __maybe_unused acp63_pcm_resume(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; struct snd_pcm_substream *substream; snd_pcm_uframes_t buf_in_frames; u64 buf_size; - if (adata->is_i2s_config && adata->rsrc->soc_mclk) - acp63_i2s_master_clock_generate(adata); + if (chip->is_i2s_config && chip->rsrc->soc_mclk) + acp63_i2s_master_clock_generate(chip); - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { substream = stream->substream; if (substream && substream->runtime) { buf_in_frames = (substream->runtime->buffer_size); buf_size = frames_to_bytes(substream->runtime, buf_in_frames); - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, buf_size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, buf_size); if (stream->dai_id) - restore_acp_i2s_params(substream, adata, stream); + restore_acp_i2s_params(substream, chip, stream); else - restore_acp_pdm_params(substream, adata); + restore_acp_pdm_params(substream, chip); } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); return 0; } diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index be4302a5a584..c1b546df5e67 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -135,8 +135,6 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct resource *res; int ret; chip = dev_get_platdata(&pdev->dev); @@ -154,36 +152,10 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) return -ENODEV; } - adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); - if (!adata) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); - return -ENODEV; - } - - adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!adata->acp_base) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); - return -ENODEV; - } - + chip->dev = dev; chip->rsrc = &rsrc; - adata->i2s_irq = res->start; - adata->dev = dev; - adata->dai_driver = acp70_dai; - adata->num_dai = ARRAY_SIZE(acp70_dai); - adata->rsrc = &rsrc; - adata->acp_rev = chip->acp_rev; - adata->flag = chip->flag; - - dev_set_drvdata(dev, adata); + chip->dai_driver = acp70_dai; + chip->num_dai = ARRAY_SIZE(acp70_dai); /* Set clk7 DFS clock divider register value to get mclk as 196.608MHz*/ ret = amd_smn_write(0, CLK7_CLK0_DFS_CNTL_N1, CLK0_DIVIDER); @@ -221,27 +193,27 @@ static void acp_acp70_audio_remove(struct platform_device *pdev) static int __maybe_unused acp70_pcm_resume(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; struct snd_pcm_substream *substream; snd_pcm_uframes_t buf_in_frames; u64 buf_size; - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { substream = stream->substream; if (substream && substream->runtime) { buf_in_frames = (substream->runtime->buffer_size); buf_size = frames_to_bytes(substream->runtime, buf_in_frames); - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, buf_size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, buf_size); if (stream->dai_id) - restore_acp_i2s_params(substream, adata, stream); + restore_acp_i2s_params(substream, chip, stream); else - restore_acp_pdm_params(substream, adata); + restore_acp_pdm_params(substream, chip); } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); return 0; } diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 4beaa9cae352..084d9db1b65c 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -142,22 +142,34 @@ struct acp_chip_info { char *name; /* Platform name */ struct resource *res; struct device *dev; + struct snd_soc_dai_driver *dai_driver; + unsigned int acp_rev; /* ACP Revision id */ void __iomem *base; /* ACP memory PCI base */ struct snd_acp_hw_ops *acp_hw_ops; int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; struct acp_resource *rsrc; /* Platform specific resources*/ + struct list_head stream_list; + spinlock_t acp_lock; /* Used to protect stream_list */ struct platform_device *dmic_codec_dev; struct platform_device *acp_plat_dev; struct platform_device *mach_dev; struct snd_soc_acpi_mach *machines; - struct acp_dev_data *adata; + int num_dai; u32 addr; + u32 bclk_div; + u32 lrclk_div; + u32 ch_mask; + u32 tdm_tx_fmt[3]; + u32 tdm_rx_fmt[3]; + u32 xfer_tx_resolution[3]; + u32 xfer_rx_resolution[3]; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ bool is_pdm_config; /* flag set to true when PDM configuration is selected from BIOS */ bool is_i2s_config; /* flag set to true when I2S configuration is selected from BIOS */ + bool tdm_mode; }; struct acp_stream { @@ -183,36 +195,6 @@ struct acp_resource { u64 sram_pte_offset; }; -struct acp_dev_data { - char *name; - struct device *dev; - void __iomem *acp_base; - unsigned int i2s_irq; - unsigned int acp_rev; /* ACP Revision id */ - - bool tdm_mode; - bool is_i2s_config; - /* SOC specific dais */ - struct snd_soc_dai_driver *dai_driver; - int num_dai; - - struct list_head stream_list; - spinlock_t acp_lock; - - struct platform_device *mach_dev; - - u32 bclk_div; - u32 lrclk_div; - - struct acp_resource *rsrc; - u32 ch_mask; - u32 tdm_tx_fmt[3]; - u32 tdm_rx_fmt[3]; - u32 xfer_tx_resolution[3]; - u32 xfer_rx_resolution[3]; - unsigned int flag; -}; - /** * struct snd_acp_hw_ops - ACP PCI driver platform specific ops * @acp_init: ACP initialization @@ -357,13 +339,13 @@ extern int acp70_hw_ops_init(struct acp_chip_info *chip); /* Machine configuration */ int snd_amd_acp_find_config(struct pci_dev *pci); -void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream); -void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size); +void config_pte_for_stream(struct acp_chip_info *chip, struct acp_stream *stream); +void config_acp_dma(struct acp_chip_info *chip, struct acp_stream *stream, int size); void restore_acp_pdm_params(struct snd_pcm_substream *substream, - struct acp_dev_data *adata); + struct acp_chip_info *chip); int restore_acp_i2s_params(struct snd_pcm_substream *substream, - struct acp_dev_data *adata, struct acp_stream *stream); + struct acp_chip_info *chip, struct acp_stream *stream); void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip); @@ -395,48 +377,48 @@ static inline int acp_hw_dis_interrupts(struct acp_chip_info *chip) return -EOPNOTSUPP; } -static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction) +static inline u64 acp_get_byte_count(struct acp_chip_info *chip, int dai_id, int direction) { u64 byte_count = 0, low = 0, high = 0; if (direction == SNDRV_PCM_STREAM_PLAYBACK) { switch (dai_id) { case I2S_BT_INSTANCE: - high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(adata)); - low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW(adata)); + high = readl(chip->base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(chip)); + low = readl(chip->base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW(chip)); break; case I2S_SP_INSTANCE: - high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(adata)); - low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(adata)); + high = readl(chip->base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(chip)); + low = readl(chip->base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(chip)); break; case I2S_HS_INSTANCE: - high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH); - low = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_LOW); + high = readl(chip->base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH); + low = readl(chip->base + ACP_HS_TX_LINEARPOSITIONCNTR_LOW); break; default: - dev_err(adata->dev, "Invalid dai id %x\n", dai_id); + dev_err(chip->dev, "Invalid dai id %x\n", dai_id); goto POINTER_RETURN_BYTES; } } else { switch (dai_id) { case I2S_BT_INSTANCE: - high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(adata)); - low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW(adata)); + high = readl(chip->base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(chip)); + low = readl(chip->base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW(chip)); break; case I2S_SP_INSTANCE: - high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(adata)); - low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(adata)); + high = readl(chip->base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(chip)); + low = readl(chip->base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(chip)); break; case I2S_HS_INSTANCE: - high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH); - low = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_LOW); + high = readl(chip->base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH); + low = readl(chip->base + ACP_HS_RX_LINEARPOSITIONCNTR_LOW); break; case DMIC_INSTANCE: - high = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH); - low = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW); + high = readl(chip->base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH); + low = readl(chip->base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW); break; default: - dev_err(adata->dev, "Invalid dai id %x\n", dai_id); + dev_err(chip->dev, "Invalid dai id %x\n", dai_id); goto POINTER_RETURN_BYTES; } } -- 2.50.1 From a95a1dbbd3d64adf392fed13c8eef4f72b4e5b90 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:55 +0530 Subject: [PATCH 12/16] ASoC: amd: acp: Move spin_lock and list initialization to acp-pci driver Move spin_lock and linked list initialization from platform driver to acp-pci driver. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-9-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 3 +++ sound/soc/amd/acp/acp-platform.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 1ef9faba1d8a..8bb93ca18053 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -196,6 +196,9 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id chip->dev = &chip->acp_plat_dev->dev; acp_machine_select(chip); + + INIT_LIST_HEAD(&chip->stream_list); + spin_lock_init(&chip->acp_lock); skip_pdev_creation: dev_set_drvdata(&pci->dev, chip); pm_runtime_set_autosuspend_delay(&pci->dev, 2000); diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index 8d61e1991e4f..b3eddf76aaa4 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -343,9 +343,6 @@ int acp_platform_register(struct device *dev) return status; } - INIT_LIST_HEAD(&chip->stream_list); - spin_lock_init(&chip->acp_lock); - return 0; } EXPORT_SYMBOL_NS_GPL(acp_platform_register, "SND_SOC_ACP_COMMON"); -- 2.50.1 From c8b5f251f0e53edab220ac4edf444120815fed3c Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:56 +0530 Subject: [PATCH 13/16] ASoC: amd: acp: Remove white line Remove white line in renoir platform driver. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-10-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-renoir.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 2037af67509a..970ca613a439 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -36,7 +36,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x02052800, }; - static struct snd_soc_dai_driver acp_renoir_dai[] = { { .name = "acp-i2s-sp", -- 2.50.1 From f8b4f3f525e82d78079a6ebbde68e4a0d79fd1c0 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:57 +0530 Subject: [PATCH 14/16] ASoC: amd: acp: Refactor acp70 platform resource structure Refactor acp70 platform resource private structure to amd.h header file. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-11-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 1 + sound/soc/amd/acp/acp70.c | 11 ----------- sound/soc/amd/acp/amd.h | 10 ++++++++++ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 8bb93ca18053..6728eee29993 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -151,6 +151,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id 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; break; diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index c1b546df5e67..1a89f8a3724f 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -30,16 +30,6 @@ #define CLK7_CLK0_DFS_CNTL_N1 0X0006C1A4 #define CLK0_DIVIDER 0X19 -static struct acp_resource 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, -}; - static struct snd_soc_dai_driver acp70_dai[] = { { .name = "acp-i2s-sp", @@ -153,7 +143,6 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) } chip->dev = dev; - chip->rsrc = &rsrc; chip->dai_driver = acp70_dai; chip->num_dai = ARRAY_SIZE(acp70_dai); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 084d9db1b65c..979d8b8801a3 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -238,6 +238,16 @@ enum acp_config { ACP_CONFIG_20, }; +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"} -- 2.50.1 From d08220b6e32e88655f54b497fd45a3982b59093c Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:58 +0530 Subject: [PATCH 15/16] ASoC: amd: acp: Refactor acp63 platform resource structure Refactor acp63 platform resource private structure to amd.h header file. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-12-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 1 + sound/soc/amd/acp/acp63.c | 13 +------------ sound/soc/amd/acp/amd.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 6728eee29993..3df665ca1b0b 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -145,6 +145,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id 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; break; diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index 49786e1a214f..53c013a64854 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -52,16 +52,6 @@ union clk_pll_req_no { u32 clk_pll_req_no_reg; }; -static struct acp_resource 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, -}; - static struct snd_soc_dai_driver acp63_dai[] = { { .name = "acp-i2s-sp", @@ -222,11 +212,10 @@ static int acp63_audio_probe(struct platform_device *pdev) } chip->dev = dev; - chip->rsrc = &rsrc; chip->dai_driver = acp63_dai; chip->num_dai = ARRAY_SIZE(acp63_dai); - if (chip->is_i2s_config && rsrc.soc_mclk) { + if (chip->is_i2s_config && chip->rsrc->soc_mclk) { ret = acp63_i2s_master_clock_generate(chip); if (ret) return ret; diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 979d8b8801a3..075659fb3314 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -238,6 +238,16 @@ enum acp_config { ACP_CONFIG_20, }; +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, -- 2.50.1 From ee7ab0fd540877fceb3d51f87016e6531d86406f Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:59 +0530 Subject: [PATCH 16/16] ASoC: amd: acp: Refactor rembrant platform resource structure Refactor rembrandt platform resource private structure to amd.h header fle. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-13-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 1 + sound/soc/amd/acp/acp-rembrandt.c | 13 +------------ sound/soc/amd/acp/amd.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 3df665ca1b0b..6dd905e75f1d 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -140,6 +140,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id 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; break; diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index dfb18d5cdc7a..21614e2e1b6c 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -34,16 +34,6 @@ #define MP1_C2PMSG_85 0x3B10A54 #define MP1_C2PMSG_93 0x3B10A74 -static struct acp_resource 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, -}; - static struct snd_soc_dai_driver acp_rmb_dai[] = { { .name = "acp-i2s-sp", @@ -171,11 +161,10 @@ static int rembrandt_audio_probe(struct platform_device *pdev) } chip->dev = dev; - chip->rsrc = &rsrc; chip->dai_driver = acp_rmb_dai; chip->num_dai = ARRAY_SIZE(acp_rmb_dai); - if (chip->is_i2s_config && rsrc.soc_mclk) { + if (chip->is_i2s_config && chip->rsrc->soc_mclk) { ret = acp6x_master_clock_generate(dev); if (ret) return ret; diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 075659fb3314..0cb6d2abf832 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -238,6 +238,16 @@ enum acp_config { ACP_CONFIG_20, }; +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, -- 2.50.1