[PATCH 04/11] ASoC: SOF: amd: add ACP7.B/7.F PDM controller scan and pdata propagation

From: Vijendar Mukunda

Date: Thu Sep 10 2026 - 09:38:30 EST


Add acp_sof_scan_pdm_devices() to read the acp-audio-ep-port ACPI _DSD
property from the PDM child device on ACP7.B/7.F platforms. Value 4
selects PDM0 (ACP7X_PDM_DMIC0), value 5 selects PDM1 (ACP7X_PDM_DMIC1).
Unrecognized values are reported via dev_warn(). The selected controller
is stored in acp_dev_data.pdm_sel and propagated to the machine driver
via mach->pdata in amd_sof_machine_select() so the machine driver probe
can register the correct SOF DMIC DAI link.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@xxxxxxx>
---
sound/soc/amd/acp/soc_amd_sdw_common.h | 13 +++++++++++
sound/soc/sof/amd/acp-common.c | 17 ++++++++++++++
sound/soc/sof/amd/acp.c | 31 ++++++++++++++++++++++++++
sound/soc/sof/amd/acp.h | 10 +++++++++
4 files changed, 71 insertions(+)

diff --git a/sound/soc/amd/acp/soc_amd_sdw_common.h b/sound/soc/amd/acp/soc_amd_sdw_common.h
index 3930cc46fa58..17e4e97fb3d1 100644
--- a/sound/soc/amd/acp/soc_amd_sdw_common.h
+++ b/sound/soc/amd/acp/soc_amd_sdw_common.h
@@ -23,6 +23,19 @@
#define ACP71_PCI_REV 0x71
#define ACP72_PCI_REV 0x72

+/**
+ * struct amd_pdm_pdata - platform data passed via mach->pdata to machine driver
+ * @pdm_sel: active PDM controller (ACP7X_PDM_DMIC0 or ACP7X_PDM_DMIC1),
+ * non-zero when a PDM controller was identified via ACPI _DSD
+ *
+ * Carries the PDM controller selection for ACP7.B/7.F platforms, derived
+ * from the acp-audio-ep-port ACPI _DSD property and passed via mach->pdata
+ * to the machine driver.
+ */
+struct amd_pdm_pdata {
+ unsigned int pdm_sel;
+};
+
#define SOC_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
#define ASOC_SDW_FOUR_SPK BIT(4)
#define ASOC_SDW_ACP_DMIC BIT(5)
diff --git a/sound/soc/sof/amd/acp-common.c b/sound/soc/sof/amd/acp-common.c
index df656cdc1527..33540f7c421b 100644
--- a/sound/soc/sof/amd/acp-common.c
+++ b/sound/soc/sof/amd/acp-common.c
@@ -16,6 +16,7 @@
#include "acp.h"
#include "acp-dsp-offset.h"
#include <sound/sof/xtensa.h>
+#include "../../amd/acp/soc_amd_sdw_common.h"

/**
* amd_sof_ipc_dump() - This function is called when IPC tx times out.
@@ -177,6 +178,7 @@ struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
struct acp_dev_data *acp_data = sdev->pdata->hw_pdata;
const struct sof_dev_desc *desc = sof_pdata->desc;
struct snd_soc_acpi_mach *mach = NULL;
+ struct amd_pdm_pdata *pdm_pdata;

if (desc->machines)
mach = snd_soc_acpi_find_machine(desc->machines);
@@ -188,7 +190,22 @@ struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
}
}

+ mach = devm_kmemdup(sdev->dev, mach, sizeof(*mach), GFP_KERNEL);
+ if (!mach) {
+ dev_err(sdev->dev, "failed to allocate machine entry copy\n");
+ return NULL;
+ }
+
mach->mach_params.subsystem_rev = acp_data->pci_rev;
+
+ if (acp_data->pdm_sel) {
+ pdm_pdata = devm_kzalloc(sdev->dev, sizeof(*pdm_pdata), GFP_KERNEL);
+ if (!pdm_pdata)
+ return NULL;
+ pdm_pdata->pdm_sel = acp_data->pdm_sel;
+ mach->pdata = pdm_pdata;
+ }
+
sof_pdata->tplg_filename = mach->sof_tplg_filename;
sof_pdata->fw_filename = mach->fw_filename;

diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index 5570f3d1348d..37909f2d86a4 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -853,6 +853,31 @@ int amd_sof_acp_resume(struct snd_sof_dev *sdev)
}
EXPORT_SYMBOL_NS(amd_sof_acp_resume, "SND_SOC_SOF_AMD_COMMON");

+static void acp_sof_scan_pdm_devices(struct snd_sof_dev *sdev,
+ struct acpi_device *pdm_dev)
+{
+ struct acp_dev_data *acp_data = sdev->pdata->hw_pdata;
+ struct fwnode_handle *fwnode, *child;
+ u32 ep_port_val;
+
+ fwnode = acpi_fwnode_handle(pdm_dev);
+ child = fwnode_get_next_child_node(fwnode, NULL);
+ if (!child)
+ return;
+
+ if (!fwnode_property_read_u32(child, "acp-audio-ep-port", &ep_port_val)) {
+ if (ep_port_val == ACP_DEV_PORT_PDM)
+ acp_data->pdm_sel = ACP7X_PDM_DMIC0;
+ else if (ep_port_val == ACP_DEV_PORT_PDM2)
+ acp_data->pdm_sel = ACP7X_PDM_DMIC1;
+ else
+ dev_warn(sdev->dev,
+ "acp-audio-ep-port: unrecognized value %u\n",
+ ep_port_val);
+ }
+ fwnode_handle_put(child);
+}
+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_AMD_SOUNDWIRE)
static int acp_sof_scan_sdw_devices(struct snd_sof_dev *sdev, u64 addr)
{
@@ -1070,6 +1095,7 @@ int amd_sof_acp7x_probe(struct snd_sof_dev *sdev)
const struct sof_amd_acp_desc *chip;
const union acpi_object *obj;
struct acpi_device *adev;
+ struct acpi_device *pdm_dev;
unsigned int addr;
unsigned int irqflags;
int ret;
@@ -1123,6 +1149,11 @@ int amd_sof_acp7x_probe(struct snd_sof_dev *sdev)
}

if (adev) {
+ /* DMIC ACPI child address is 2 on ACP7x platforms */
+ pdm_dev = acpi_find_child_device(adev, ACP7X_DMIC_ADDR, 0);
+ if (pdm_dev)
+ acp_sof_scan_pdm_devices(sdev, pdm_dev);
+
if (!acpi_dev_get_property(adev, "acp-sof-signed-firmware-image",
ACPI_TYPE_INTEGER, &obj))
adata->acp_sof_signed_firmware_image = obj->integer.value;
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index 16d66b2eaa70..2326b9d2e4c6 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -125,6 +125,14 @@
#define ACP_SRAM_PAGE_COUNT 128
#define ACP6X_SDW_MAX_MANAGER_COUNT 2
#define ACP70_SDW_MAX_MANAGER_COUNT ACP6X_SDW_MAX_MANAGER_COUNT
+/* ACPI _DSD acp-audio-ep-port values for PDM controller selection */
+#define ACP_DEV_PORT_PDM 4
+#define ACP_DEV_PORT_PDM2 5
+/* ACPI child device address for the ACP7x PDM/DMIC device */
+#define ACP7X_DMIC_ADDR 2
+/* ACP7X PDM controller selection values for acp_dev_data.pdm_sel; 0 = not set */
+#define ACP7X_PDM_DMIC0 1
+#define ACP7X_PDM_DMIC1 2
#define ACP_DSP_MSG_SET 1
#define ACP_DSP_ACK_SET 1

@@ -279,6 +287,8 @@ struct acp_dev_data {
bool acp70_sdw0_wake_event;
/* acp70_sdw1_wake_event flag set to true when wake irq asserted for SW1 instance */
bool acp70_sdw1_wake_event;
+ /* PDM controller index selected from ACPI acp-audio-ep-port; passed to machine driver */
+ unsigned int pdm_sel;
unsigned int pci_rev;
int acp_sof_signed_firmware_image;
};
--
2.48.1