Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 77 additions & 9 deletions sound/soc/sdw_utils/soc_sdw_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1391,14 +1391,71 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d
}
EXPORT_SYMBOL_NS(asoc_sdw_init_simple_dai_link, "SND_SOC_SDW_UTILS");

/**
* is_sdca_aux_dev_present - Check if an SDCA aux device is present on the SDW peripheral
* @dev: Device pointer
* @aux_codec_name: Aux codec name from the codec info (e.g. "snd_soc_sdca.HID.2")
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example aux codec name here ("snd_soc_sdca.HID.2") doesn’t match how aux codec names are defined in this file (e.g. codec_info_list uses "snd_soc_sdca.HID"). Please update the example/description to reflect the actual expected format.

Suggested change
* @aux_codec_name: Aux codec name from the codec info (e.g. "snd_soc_sdca.HID.2")
* @aux_codec_name: Aux codec name from the codec info (e.g. "snd_soc_sdca.HID")

Copilot uses AI. Check for mistakes.
* @adr_link: ACPI link address
* @adr_index: Index of the ACPI link address
*
* Return: 1 if the aux is present, 0 if the aux is not present, or negative error code.
*/
static int is_sdca_aux_dev_present(struct device *dev,
const char *aux_codec_name,
const struct snd_soc_acpi_link_adr *adr_link,
int adr_index)
{
struct sdw_slave *slave;
struct device *sdw_dev;
const char *sdw_codec_name;
int ret = 0;
int i;

if (!aux_codec_name)
return 0;

sdw_codec_name = _asoc_sdw_get_codec_name(dev, adr_link, adr_index);
if (!sdw_codec_name)
return -ENOMEM;

sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_codec_name);
if (!sdw_dev) {
dev_err(dev, "codec %s not found\n", sdw_codec_name);
return -EINVAL;
}
Comment on lines +1421 to +1425
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the SoundWire codec device isn’t found on the bus, returning -EINVAL will fail the machine driver probe permanently. For probe ordering races this should typically return -EPROBE_DEFER (and ideally avoid dev_err noise), consistent with other sdw_utils users of bus_find_device_by_name (e.g. sound/soc/sdw_utils/soc_sdw_rt711.c:148-151).

Copilot uses AI. Check for mistakes.

slave = dev_to_sdw_dev(sdw_dev);

if (!slave->sdca_data.interface_revision) {
dev_warn(dev, "No SDCA properties, assuming aux '%s' present\n", aux_codec_name);
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning is emitted against the card device; using &slave->dev would be more consistent with is_sdca_endpoint_present() (which reports SDCA property issues on the slave device) and makes logs easier to attribute to the right peripheral.

Suggested change
dev_warn(dev, "No SDCA properties, assuming aux '%s' present\n", aux_codec_name);
dev_warn(&slave->dev, "No SDCA properties, assuming aux '%s' present\n",
aux_codec_name);

Copilot uses AI. Check for mistakes.
ret = 1;
goto put_dev;
}

for (i = 0; i < slave->sdca_data.num_functions; i++) {
const char *fname = slave->sdca_data.function[i].name;

if (fname && strstr(aux_codec_name, fname)) {
ret = 1;
goto put_dev;
}
}

dev_dbg(dev, "SDCA function for aux '%s' NOT FOUND on slave, skipping\n", aux_codec_name);

put_dev:
put_device(sdw_dev);
return ret;
}

int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
int *num_devs, int *num_ends, int *num_aux)
{
struct device *dev = card->dev;
struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
const struct snd_soc_acpi_link_adr *adr_link;
int i;
int i, j, ret;

for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
*num_devs += adr_link->num_adr;
Expand All @@ -1413,7 +1470,14 @@ int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
if (!codec_info)
return -EINVAL;

*num_aux += codec_info->aux_num;
for (j = 0; j < codec_info->aux_num; j++) {
ret = is_sdca_aux_dev_present(dev, codec_info->auxs[j].codec_name,
adr_link, i);
if (ret < 0)
return ret;
if (ret)
(*num_aux)++;
}
}
}

Expand Down Expand Up @@ -1461,20 +1525,16 @@ int asoc_sdw_get_dai_type(u32 type)
}
EXPORT_SYMBOL_NS(asoc_sdw_get_dai_type, "SND_SOC_SDW_UTILS");

/*
* Check if the SDCA endpoint is present by the SDW peripheral
*
/**
* is_sdca_endpoint_present - Check if an SDCA endpoint is present on the SDW peripheral
* @dev: Device pointer
* @codec_info: Codec info pointer
* @adr_link: ACPI link address
* @adr_index: Index of the ACPI link address
* @end_index: Index of the endpoint
*
* Return: 1 if the endpoint is present,
* 0 if the endpoint is not present,
* negative error code.
* Return: 1 if the endpoint is present, 0 if the endpoint is not present, or negative error code.
*/

static int is_sdca_endpoint_present(struct device *dev,
struct asoc_sdw_codec_info *codec_info,
const struct snd_soc_acpi_link_adr *adr_link,
Expand Down Expand Up @@ -1576,6 +1636,14 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
for (j = 0; j < codec_info->aux_num; j++) {
struct snd_soc_component *component;

ret = is_sdca_aux_dev_present(dev, codec_info->auxs[j].codec_name,
adr_link, i);
if (ret < 0)
return ret;

if (ret == 0)
continue;

component = snd_soc_lookup_component_by_name(codec_info->auxs[j].codec_name);
if (component) {
dev_dbg(dev, "%s found component %s for aux name %s\n",
Expand Down
Loading