Skip to content

Commit 0386d76

Browse files
vijendarmukundabroonie
authored andcommitted
ASoC: amd: ps: refactor acp device configuration read logic
Refactor acp device configuration read logic and use common function to scan SoundWire devices. Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com> Link: https://msgid.link/r/20240214104014.1144668-1-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent cf88ab4 commit 0386d76

3 files changed

Lines changed: 78 additions & 126 deletions

File tree

sound/soc/amd/Kconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,26 @@ config SND_SOC_AMD_RPL_ACP6x
132132
Say m if you have such a device.
133133
If unsure select "N".
134134

135+
config SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE
136+
tristate
137+
select SOUNDWIRE_AMD if SND_SOC_AMD_SOUNDWIRE != n
138+
select SND_AMD_SOUNDWIRE_ACPI if ACPI
139+
140+
config SND_SOC_AMD_SOUNDWIRE
141+
tristate "Support for SoundWire based AMD platforms"
142+
default SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE
143+
depends on SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE
144+
depends on ACPI && SOUNDWIRE
145+
depends on !(SOUNDWIRE=m && SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE=y)
146+
help
147+
This adds support for SoundWire for AMD platforms.
148+
Say Y if you want to enable SoundWire links with SOF.
149+
If unsure select "N".
150+
135151
config SND_SOC_AMD_PS
136152
tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support"
137153
select SND_AMD_ACP_CONFIG
154+
select SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE
138155
depends on X86 && PCI && ACPI
139156
help
140157
This option enables Audio Coprocessor i.e ACP v6.3 support on

sound/soc/amd/ps/acp63.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Copyright (C) 2022, 2023 Advanced Micro Devices, Inc. All rights reserved.
66
*/
77

8+
#include <linux/soundwire/sdw_amd.h>
89
#include <sound/acp63_chip_offset_byte.h>
910

1011
#define ACP_DEVICE_ID 0x15E2
@@ -263,6 +264,11 @@ struct sdw_dma_ring_buf_reg {
263264
* @sdw0_dev_index: SoundWire Manager-0 platform device index
264265
* @sdw1_dev_index: SoundWire Manager-1 platform device index
265266
* @sdw_dma_dev_index: SoundWire DMA controller platform device index
267+
* @info: SoundWire AMD information found in ACPI tables
268+
* @is_sdw_dev: flag set to true when any SoundWire manager instances are available
269+
* @is_pdm_dev: flag set to true when ACP PDM controller exists
270+
* @is_pdm_config: flat set to true when PDM configuration is selected from BIOS
271+
* @is_sdw_config: flag set to true when SDW configuration is selected from BIOS
266272
* @sdw0-dma_intr_stat: DMA interrupt status array for SoundWire manager-SW0 instance
267273
* @sdw_dma_intr_stat: DMA interrupt status array for SoundWire manager-SW1 instance
268274
* @acp_reset: flag set to true when bus reset is applied across all
@@ -282,6 +288,11 @@ struct acp63_dev_data {
282288
u16 sdw0_dev_index;
283289
u16 sdw1_dev_index;
284290
u16 sdw_dma_dev_index;
291+
struct sdw_amd_acpi_info info;
292+
bool is_sdw_dev;
293+
bool is_pdm_dev;
294+
bool is_pdm_config;
295+
bool is_sdw_config;
285296
u16 sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS];
286297
u16 sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS];
287298
bool acp_reset;

sound/soc/amd/ps/pci-ps.c

Lines changed: 50 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -237,163 +237,88 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
237237
return IRQ_NONE;
238238
}
239239

240-
static int sdw_amd_scan_controller(struct device *dev)
240+
#if IS_ENABLED(CONFIG_SND_SOC_AMD_SOUNDWIRE)
241+
static int acp_scan_sdw_devices(struct device *dev, u64 addr)
241242
{
243+
struct acpi_device *sdw_dev;
242244
struct acp63_dev_data *acp_data;
243-
struct fwnode_handle *link;
244-
char name[32];
245-
u32 sdw_manager_bitmap;
246-
u8 count = 0;
247-
u32 acp_sdw_power_mode = 0;
248-
int index;
249-
int ret;
250245

251246
acp_data = dev_get_drvdata(dev);
252-
/*
253-
* Current implementation is based on MIPI DisCo 2.0 spec.
254-
* Found controller, find links supported.
255-
*/
256-
ret = fwnode_property_read_u32_array((acp_data->sdw_fw_node), "mipi-sdw-manager-list",
257-
&sdw_manager_bitmap, 1);
258-
259-
if (ret) {
260-
dev_dbg(dev, "Failed to read mipi-sdw-manager-list: %d\n", ret);
261-
return -EINVAL;
262-
}
263-
count = hweight32(sdw_manager_bitmap);
264-
/* Check count is within bounds */
265-
if (count > AMD_SDW_MAX_MANAGERS) {
266-
dev_err(dev, "Manager count %d exceeds max %d\n", count, AMD_SDW_MAX_MANAGERS);
267-
return -EINVAL;
268-
}
247+
if (!addr)
248+
return -ENODEV;
269249

270-
if (!count) {
271-
dev_dbg(dev, "No SoundWire Managers detected\n");
272-
return -EINVAL;
273-
}
274-
dev_dbg(dev, "ACPI reports %d SoundWire Manager devices\n", count);
275-
acp_data->sdw_manager_count = count;
276-
for (index = 0; index < count; index++) {
277-
scnprintf(name, sizeof(name), "mipi-sdw-link-%d-subproperties", index);
278-
link = fwnode_get_named_child_node(acp_data->sdw_fw_node, name);
279-
if (!link) {
280-
dev_err(dev, "Manager node %s not found\n", name);
281-
return -EIO;
282-
}
250+
sdw_dev = acpi_find_child_device(ACPI_COMPANION(dev), addr, 0);
251+
if (!sdw_dev)
252+
return -ENODEV;
283253

284-
ret = fwnode_property_read_u32(link, "amd-sdw-power-mode", &acp_sdw_power_mode);
285-
if (ret)
286-
return ret;
287-
/*
288-
* when SoundWire configuration is selected from acp pin config,
289-
* based on manager instances count, acp init/de-init sequence should be
290-
* executed as part of PM ops only when Bus reset is applied for the active
291-
* SoundWire manager instances.
292-
*/
293-
if (acp_sdw_power_mode != AMD_SDW_POWER_OFF_MODE) {
294-
acp_data->acp_reset = false;
295-
return 0;
296-
}
297-
}
254+
acp_data->info.handle = sdw_dev->handle;
255+
acp_data->info.count = AMD_SDW_MAX_MANAGERS;
256+
return amd_sdw_scan_controller(&acp_data->info);
257+
}
258+
#else
259+
static int acp_scan_sdw_devices(struct device *dev, u64 addr)
260+
{
298261
return 0;
299262
}
263+
#endif
300264

301-
static int get_acp63_device_config(u32 config, struct pci_dev *pci, struct acp63_dev_data *acp_data)
265+
static int get_acp63_device_config(struct pci_dev *pci, struct acp63_dev_data *acp_data)
302266
{
303-
struct acpi_device *dmic_dev;
304-
struct acpi_device *sdw_dev;
267+
struct acpi_device *pdm_dev;
305268
const union acpi_object *obj;
269+
u32 config;
306270
bool is_dmic_dev = false;
307271
bool is_sdw_dev = false;
308272
int ret;
309273

310-
dmic_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0);
311-
if (dmic_dev) {
312-
/* is_dmic_dev flag will be set when ACP PDM controller device exists */
313-
if (!acpi_dev_get_property(dmic_dev, "acp-audio-device-type",
314-
ACPI_TYPE_INTEGER, &obj) &&
315-
obj->integer.value == ACP_DMIC_DEV)
316-
is_dmic_dev = true;
317-
}
318-
319-
sdw_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_SDW_ADDR, 0);
320-
if (sdw_dev) {
321-
acp_data->sdw_fw_node = acpi_fwnode_handle(sdw_dev);
322-
ret = sdw_amd_scan_controller(&pci->dev);
323-
/* is_sdw_dev flag will be set when SoundWire Manager device exists */
324-
if (!ret)
325-
is_sdw_dev = true;
326-
}
327-
if (!is_dmic_dev && !is_sdw_dev)
328-
return -ENODEV;
329-
dev_dbg(&pci->dev, "Audio Mode %d\n", config);
274+
config = readl(acp_data->acp63_base + ACP_PIN_CONFIG);
330275
switch (config) {
331276
case ACP_CONFIG_4:
332277
case ACP_CONFIG_5:
333278
case ACP_CONFIG_10:
334279
case ACP_CONFIG_11:
335-
if (is_dmic_dev) {
336-
acp_data->pdev_config = ACP63_PDM_DEV_CONFIG;
337-
acp_data->pdev_count = ACP63_PDM_MODE_DEVS;
338-
}
280+
acp_data->is_pdm_config = true;
339281
break;
340282
case ACP_CONFIG_2:
341283
case ACP_CONFIG_3:
342-
if (is_sdw_dev) {
343-
switch (acp_data->sdw_manager_count) {
344-
case 1:
345-
acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
346-
acp_data->pdev_count = ACP63_SDW0_MODE_DEVS;
347-
break;
348-
case 2:
349-
acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
350-
acp_data->pdev_count = ACP63_SDW0_SDW1_MODE_DEVS;
351-
break;
352-
default:
353-
return -EINVAL;
354-
}
355-
}
284+
acp_data->is_sdw_config = true;
356285
break;
357286
case ACP_CONFIG_6:
358287
case ACP_CONFIG_7:
359288
case ACP_CONFIG_12:
360289
case ACP_CONFIG_8:
361290
case ACP_CONFIG_13:
362291
case ACP_CONFIG_14:
363-
if (is_dmic_dev && is_sdw_dev) {
364-
switch (acp_data->sdw_manager_count) {
365-
case 1:
366-
acp_data->pdev_config = ACP63_SDW_PDM_DEV_CONFIG;
367-
acp_data->pdev_count = ACP63_SDW0_PDM_MODE_DEVS;
368-
break;
369-
case 2:
370-
acp_data->pdev_config = ACP63_SDW_PDM_DEV_CONFIG;
371-
acp_data->pdev_count = ACP63_SDW0_SDW1_PDM_MODE_DEVS;
372-
break;
373-
default:
374-
return -EINVAL;
375-
}
376-
} else if (is_dmic_dev) {
377-
acp_data->pdev_config = ACP63_PDM_DEV_CONFIG;
378-
acp_data->pdev_count = ACP63_PDM_MODE_DEVS;
379-
} else if (is_sdw_dev) {
380-
switch (acp_data->sdw_manager_count) {
381-
case 1:
382-
acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
383-
acp_data->pdev_count = ACP63_SDW0_MODE_DEVS;
384-
break;
385-
case 2:
386-
acp_data->pdev_config = ACP63_SDW_DEV_CONFIG;
387-
acp_data->pdev_count = ACP63_SDW0_SDW1_MODE_DEVS;
388-
break;
389-
default:
390-
return -EINVAL;
391-
}
392-
}
292+
acp_data->is_pdm_config = true;
293+
acp_data->is_sdw_config = true;
393294
break;
394295
default:
395296
break;
396297
}
298+
299+
if (acp_data->is_pdm_config) {
300+
pdm_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0);
301+
if (pdm_dev) {
302+
/* is_dmic_dev flag will be set when ACP PDM controller device exists */
303+
if (!acpi_dev_get_property(pdm_dev, "acp-audio-device-type",
304+
ACPI_TYPE_INTEGER, &obj) &&
305+
obj->integer.value == ACP_DMIC_DEV)
306+
is_dmic_dev = true;
307+
}
308+
}
309+
310+
if (acp_data->is_sdw_config) {
311+
ret = acp_scan_sdw_devices(&pci->dev, ACP63_SDW_ADDR);
312+
if (!ret && acp_data->info.link_mask)
313+
is_sdw_dev = true;
314+
}
315+
316+
acp_data->is_pdm_dev = is_dmic_dev;
317+
acp_data->is_sdw_dev = is_sdw_dev;
318+
if (!is_dmic_dev && !is_sdw_dev) {
319+
dev_dbg(&pci->dev, "No PDM or SoundWire manager devices found\n");
320+
return -ENODEV;
321+
}
397322
return 0;
398323
}
399324

@@ -576,7 +501,6 @@ static int snd_acp63_probe(struct pci_dev *pci,
576501
struct acp63_dev_data *adata;
577502
u32 addr;
578503
u32 irqflags, flag;
579-
int val;
580504
int ret;
581505

582506
irqflags = IRQF_SHARED;
@@ -637,8 +561,7 @@ static int snd_acp63_probe(struct pci_dev *pci,
637561
dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
638562
goto de_init;
639563
}
640-
val = readl(adata->acp63_base + ACP_PIN_CONFIG);
641-
ret = get_acp63_device_config(val, pci, adata);
564+
ret = get_acp63_device_config(pci, adata);
642565
/* ACP PCI driver probe should be continued even PDM or SoundWire Devices are not found */
643566
if (ret) {
644567
dev_dbg(&pci->dev, "get acp device config failed:%d\n", ret);
@@ -740,4 +663,5 @@ module_pci_driver(ps_acp63_driver);
740663
MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
741664
MODULE_AUTHOR("Syed.SabaKareem@amd.com");
742665
MODULE_DESCRIPTION("AMD ACP Pink Sardine PCI driver");
666+
MODULE_IMPORT_NS(SND_AMD_SOUNDWIRE_ACPI);
743667
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)