ASoC: add rt1320/rt1321 dmic dai and fix the wrong name prefix

Bard Liao <yung-chuan.liao@linux.intel.com> says:

The new rt722 + rt1320 configuration uses the DMIC on the rt1320.
This series adds support for such configurations, where the DMIC is
provided by the rt1320 instead of the rt722.
This commit is contained in:
Mark Brown 2026-03-26 16:22:45 +00:00
commit 52dac22f0a
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
5 changed files with 79 additions and 105 deletions

View File

@ -83,6 +83,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);

View File

@ -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 */
{
@ -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,
@ -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),
@ -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,
@ -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);

View File

@ -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;
@ -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))
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);
} else {
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s mic:%s", card->components,
mic_name);
}
if (!card->components)
return -ENOMEM;

View File

@ -331,6 +331,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.vendor_id = 0x025d,
.part_id = 0x1320,
.name_prefix = "rt1320",
.is_amp = true,
.dais = {
{
.direction = {true, false},
@ -346,13 +347,24 @@ 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,
},
{
.vendor_id = 0x025d,
.part_id = 0x1321,
.name_prefix = "rt1320",
.is_amp = true,
.dais = {
{
.direction = {true, false},
@ -368,8 +380,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,
},
{
.vendor_id = 0x025d,

View File

@ -1232,6 +1232,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 |