Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions include/sound/soc_sdw_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ struct asoc_sdw_codec_info {
const int dai_num;
struct asoc_sdw_aux_info auxs[SOC_SDW_MAX_AUX_NUM];
const int aux_num;
/* Force AMP-style name_prefix handling (append AMP index) even if MIC/Jack DAIs exist */
const bool is_amp;

int (*codec_card_late_probe)(struct snd_soc_card *card);

Expand Down
100 changes: 0 additions & 100 deletions sound/soc/intel/common/soc-acpi-intel-ptl-match.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,31 +134,6 @@ static const struct snd_soc_acpi_endpoint spk_6_endpoint = {
.group_id = 1,
};

/*
* Multi-function codecs with three endpoints created for
* headset, amp and dmic functions.
*/
static const struct snd_soc_acpi_endpoint rt_mf_endpoints[] = {
{
.num = 0,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{
.num = 1,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{
.num = 2,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
};

static const struct snd_soc_acpi_endpoint jack_dmic_endpoints[] = {
/* Jack Endpoint */
{
Expand Down Expand Up @@ -365,33 +340,6 @@ static const struct snd_soc_acpi_adr_device rt722_0_agg_adr[] = {
}
};

static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = {
{
.adr = 0x000030025d072201ull,
.num_endpoints = ARRAY_SIZE(rt_mf_endpoints),
.endpoints = rt_mf_endpoints,
.name_prefix = "rt722"
}
};

static const struct snd_soc_acpi_adr_device rt722_1_single_adr[] = {
{
.adr = 0x000130025d072201ull,
.num_endpoints = ARRAY_SIZE(rt_mf_endpoints),
.endpoints = rt_mf_endpoints,
.name_prefix = "rt722"
}
};

static const struct snd_soc_acpi_adr_device rt722_3_single_adr[] = {
{
.adr = 0x000330025d072201ull,
.num_endpoints = ARRAY_SIZE(rt_mf_endpoints),
.endpoints = rt_mf_endpoints,
.name_prefix = "rt722"
}
};

static const struct snd_soc_acpi_adr_device rt1320_1_group1_adr[] = {
{
.adr = 0x000130025D132001ull,
Expand Down Expand Up @@ -479,33 +427,6 @@ static const struct snd_soc_acpi_link_adr ptl_cs42l43_l2_cs35l56x6_l13[] = {
{}
};

static const struct snd_soc_acpi_link_adr ptl_rt722_only[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(rt722_0_single_adr),
.adr_d = rt722_0_single_adr,
},
{}
};

static const struct snd_soc_acpi_link_adr ptl_rt722_l1[] = {
{
.mask = BIT(1),
.num_adr = ARRAY_SIZE(rt722_1_single_adr),
.adr_d = rt722_1_single_adr,
},
{}
};

static const struct snd_soc_acpi_link_adr ptl_rt722_l3[] = {
{
.mask = BIT(3),
.num_adr = ARRAY_SIZE(rt722_3_single_adr),
.adr_d = rt722_3_single_adr,
},
{}
};

static const struct snd_soc_acpi_link_adr ptl_rt722_l0_rt1320_l23[] = {
{
.mask = BIT(0),
Expand Down Expand Up @@ -698,20 +619,6 @@ 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(0),
.links = ptl_rt722_only,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-ptl-rt722.tplg",
.get_function_tplg_files = sof_sdw_get_tplg_files,
},
{
.link_mask = BIT(1),
.links = ptl_rt722_l1,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-ptl-rt722.tplg",
.get_function_tplg_files = sof_sdw_get_tplg_files,
},
{
.link_mask = BIT(3),
.links = ptl_sdw_rt712_vb_l3_rt1320_l3,
Expand All @@ -720,13 +627,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = {
.sof_tplg_filename = "sof-ptl-rt712-l3-rt1320-l3.tplg",
.get_function_tplg_files = sof_sdw_get_tplg_files,
},
{
.link_mask = BIT(3),
.links = ptl_rt722_l3,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-ptl-rt722.tplg",
.get_function_tplg_files = sof_sdw_get_tplg_files,
},
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_sdw_machines);
46 changes: 43 additions & 3 deletions sound/soc/sdw_utils/soc_sdw_rt_dmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@

#include <linux/device.h>
#include <linux/errno.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/soc_sdw_utils.h>
#include <sound/sdca_function.h>

int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
struct snd_soc_component *component;
struct sdw_slave *sdw_peripheral = NULL;
char *mic_name;
int rt1320_dmic_num = 0, part_id, i;

component = dai->component;

Expand All @@ -32,9 +37,44 @@ int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da
if (!mic_name)
return -ENOMEM;

card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s mic:%s", card->components,
mic_name);
/*
* If there is any rt1320/rt1321 DMIC belonging to this card, try to count the `cfg-mics`
* to be used in card->components.
* Note: The rt1320 drivers register the peripheral dev to component->dev, so get the
* sdw_peripheral from component->dev.
*/
if (is_sdw_slave(component->dev))
sdw_peripheral = dev_to_sdw_dev(component->dev);
if (sdw_peripheral &&
(sdw_peripheral->id.part_id == 0x1320 || sdw_peripheral->id.part_id == 0x1321)) {
part_id = sdw_peripheral->id.part_id;
/*
* This rtd init callback is called once, so count the rt1320/rt1321 with SDCA
* function SmartMic type in this card.
*/
for_each_card_components(card, component) {
if (!is_sdw_slave(component->dev))
Comment on lines +40 to +56
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

The comment and logic assume this rtd_init helper is called only once, but the caller guards rtd_init_done per codec DAI (not per card). On platforms with multiple rt1320/rt1321 peripherals exposing the MIC DAI, this can append cfg-mics: multiple times to card->components. Consider either (1) making the update idempotent (skip if cfg-mics: already present), or (2) tracking a per-card flag (e.g., via card private data) so the cfg-mics token is set exactly once.

Copilot uses AI. Check for mistakes.
continue;
sdw_peripheral = dev_to_sdw_dev(component->dev);
if (sdw_peripheral->id.part_id != part_id)
continue;
for (i = 0; i < sdw_peripheral->sdca_data.num_functions; i++) {
if (sdw_peripheral->sdca_data.function[i].type ==
SDCA_FUNCTION_TYPE_SMART_MIC) {
rt1320_dmic_num++;
break;
}
}
}
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s mic:%s cfg-mics:%d", card->components,
mic_name, rt1320_dmic_num);
Comment on lines +69 to +71
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

The cfg-mics:%d token is appended inside the per-DAI rtd_init callback. If this init runs more than once on the same card (e.g. multiple MIC DAIs using this helper), card->components can end up with repeated cfg-mics: entries, which is hard for UCM/userspace to interpret. Consider only setting cfg-mics once (e.g. check if it’s already present in card->components, or store a per-card flag in driver data).

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

rtd_init_done will be set once the DAI rtd_init callback is called. And "in theory", there will not be 2 SDW DMIC enabled in a device. But, yeah, it is a potential issue.

} else {
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s mic:%s", card->components,
mic_name);
}

if (!card->components)
return -ENOMEM;

Expand Down
26 changes: 24 additions & 2 deletions sound/soc/sdw_utils/soc_sdw_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
{
.part_id = 0x1320,
.name_prefix = "rt1320",
.is_amp = true,
.dais = {
{
.direction = {true, false},
Expand All @@ -334,12 +335,23 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.widgets = generic_spk_widgets,
.num_widgets = ARRAY_SIZE(generic_spk_widgets),
},
{
.direction = {false, true},
.dai_name = "rt1320-aif2",
.component_name = "rt1320",
.dai_type = SOC_SDW_DAI_TYPE_MIC,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
.rtd_init = asoc_sdw_rt_dmic_rtd_init,
.widgets = generic_dmic_widgets,
.num_widgets = ARRAY_SIZE(generic_dmic_widgets),
},
},
.dai_num = 1,
.dai_num = 2,
},
Comment on lines 319 to 350
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

rt1321 (part_id 0x1321) is also supported by the rt1320-sdw driver (it registers an SDW ID for 0x1321 and exposes the same rt1320-aif2 capture DAI). This change adds the DMIC DAI + AMP override only for part_id 0x1320, so systems reporting 0x1321 may still miss the MIC endpoint and/or AMP-style naming. Consider mirroring the new MIC DAI and is_amp handling for the 0x1321 entry as well if the hardware exposes SmartMic/DMIC.

Copilot uses AI. Check for mistakes.
{
.part_id = 0x1321,
.name_prefix = "rt1320",
.is_amp = true,
.dais = {
{
.direction = {true, false},
Expand All @@ -355,8 +367,18 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.widgets = generic_spk_widgets,
.num_widgets = ARRAY_SIZE(generic_spk_widgets),
},
{
.direction = {false, true},
.dai_name = "rt1320-aif2",
.component_name = "rt1320",
.dai_type = SOC_SDW_DAI_TYPE_MIC,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
.rtd_init = asoc_sdw_rt_dmic_rtd_init,
.widgets = generic_dmic_widgets,
.num_widgets = ARRAY_SIZE(generic_dmic_widgets),
},
},
.dai_num = 1,
.dai_num = 2,
},
{
.part_id = 0x714,
Expand Down
10 changes: 10 additions & 0 deletions sound/soc/sof/intel/hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,16 @@ static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev,
return NULL;
}

/*
* codec_info_list[].is_amp is a codec-level override: for multi-function
* codecs we must treat the whole codec as an AMP when it is described as
* such in the codec info table, even if some endpoints were detected as
* non-AMP above. Callers/UCM rely on this to keep name_prefix and AMP
* indexing stable and backwards compatible.
*/
if (codec_info_list[i].is_amp)
is_amp = true;

adr_dev[index].adr = ((u64)sdw_device->id.class_id & 0xFF) |
((u64)sdw_device->id.part_id & 0xFFFF) << 8 |
((u64)sdw_device->id.mfg_id & 0xFFFF) << 24 |
Expand Down
Loading