summaryrefslogtreecommitdiff
path: root/sound/soc/intel
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel')
-rw-r--r--sound/soc/intel/atom/sst-mfld-dsp.h2
-rw-r--r--sound/soc/intel/atom/sst/sst.h2
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c14
-rw-r--r--sound/soc/intel/avs/boards/hdaudio.c8
-rw-r--r--sound/soc/intel/avs/pcm.c11
-rw-r--r--sound/soc/intel/avs/topology.c25
-rw-r--r--sound/soc/intel/avs/topology.h3
-rw-r--r--sound/soc/intel/boards/Kconfig1
-rw-r--r--sound/soc/intel/boards/sof_cirrus_common.c2
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-arl-match.c71
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-lnl-match.c71
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-mtl-match.c71
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-ptl-match.c85
-rw-r--r--sound/soc/intel/common/sof-function-topology-lib.c281
-rw-r--r--sound/soc/intel/common/sof-function-topology-lib.h3
15 files changed, 555 insertions, 95 deletions
diff --git a/sound/soc/intel/atom/sst-mfld-dsp.h b/sound/soc/intel/atom/sst-mfld-dsp.h
index c8f0816edb53..59606259a06e 100644
--- a/sound/soc/intel/atom/sst-mfld-dsp.h
+++ b/sound/soc/intel/atom/sst-mfld-dsp.h
@@ -189,7 +189,7 @@ struct ipc_dsp_hdr {
union ipc_header_high {
struct {
u32 msg_id:8; /* Message ID - Max 256 Message Types */
- u32 task_id:4; /* Task ID associated with this comand */
+ u32 task_id:4; /* Task ID associated with this command */
u32 drv_id:4; /* Identifier for the driver to track*/
u32 rsvd1:8; /* Reserved */
u32 result:4; /* Reserved */
diff --git a/sound/soc/intel/atom/sst/sst.h b/sound/soc/intel/atom/sst/sst.h
index c43946c5ecee..e24d9dad7ef6 100644
--- a/sound/soc/intel/atom/sst/sst.h
+++ b/sound/soc/intel/atom/sst/sst.h
@@ -182,7 +182,7 @@ struct sst_block {
* @pcm_substream : PCM substream
* @period_elapsed : PCM period elapsed callback
* @sfreq : stream sampling freq
- * @cumm_bytes : cummulative bytes decoded
+ * @cumm_bytes : cumulative bytes decoded
*/
struct stream_info {
unsigned int status;
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 73624e1b138a..de1ad168008b 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -254,6 +254,11 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
return 0;
}
+static void sst_unregister_platform_device(void *data)
+{
+ platform_device_unregister(data);
+}
+
static int sst_acpi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -342,7 +347,10 @@ static int sst_acpi_probe(struct platform_device *pdev)
pdata->platform);
return PTR_ERR(plat_dev);
}
-
+ ret = devm_add_action_or_reset(dev, sst_unregister_platform_device,
+ plat_dev);
+ if (ret)
+ return ret;
/*
* Create platform device for sst machine driver,
* pass machine info as pdata
@@ -355,6 +363,10 @@ static int sst_acpi_probe(struct platform_device *pdev)
return PTR_ERR(mdev);
}
+ ret = devm_add_action_or_reset(dev, sst_unregister_platform_device,
+ mdev);
+ if (ret)
+ return ret;
/* Fill sst platform data */
ctx->pdata = pdata;
strscpy(ctx->firmware_name, mach->fw_filename);
diff --git a/sound/soc/intel/avs/boards/hdaudio.c b/sound/soc/intel/avs/boards/hdaudio.c
index 2e15a293298d..c1d2d0082b14 100644
--- a/sound/soc/intel/avs/boards/hdaudio.c
+++ b/sound/soc/intel/avs/boards/hdaudio.c
@@ -147,17 +147,15 @@ static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm)
struct snd_soc_dai_link *links = NULL;
struct snd_soc_card *card = rtm->card;
struct hda_codec *codec;
- struct hda_pcm *pcm;
- int ret, pcm_count = 0;
+ int ret, pcm_count;
mach = dev_get_platdata(card->dev);
pdata = mach->pdata;
codec = pdata->codec;
+ pcm_count = list_count_nodes(&codec->pcm_list_head);
- if (list_empty(&codec->pcm_list_head))
+ if (!pcm_count)
return -EINVAL;
- list_for_each_entry(pcm, &codec->pcm_list_head, list)
- pcm_count++;
ret = avs_create_dai_links(card->dev, codec, pcm_count, &links);
if (ret < 0) {
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index ad25bd355769..2d7ced953fde 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -1065,7 +1065,7 @@ finalize:
return 0;
err_load_libs:
- avs_remove_topology(component);
+ snd_soc_tplg_component_remove(component);
return ret;
}
@@ -1083,7 +1083,7 @@ static void avs_component_remove(struct snd_soc_component *component)
mutex_unlock(&adev->comp_list_mutex);
if (mach->tplg_filename) {
- ret = avs_remove_topology(component);
+ ret = snd_soc_tplg_component_remove(component);
if (ret < 0)
dev_err(component->dev, "unload topology failed: %d\n", ret);
}
@@ -1614,7 +1614,7 @@ static int avs_component_hda_probe(struct snd_soc_component *component)
struct hda_codec *codec;
struct hda_pcm *pcm;
const char *cname;
- int pcm_count = 0, ret, i;
+ int pcm_count, ret, i;
mach = dev_get_platdata(component->card->dev);
if (!mach)
@@ -1622,10 +1622,9 @@ static int avs_component_hda_probe(struct snd_soc_component *component)
pdata = mach->pdata;
codec = pdata->codec;
- if (list_empty(&codec->pcm_list_head))
+ pcm_count = list_count_nodes(&codec->pcm_list_head);
+ if (!pcm_count)
return -EINVAL;
- list_for_each_entry(pcm, &codec->pcm_list_head, list)
- pcm_count++;
dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
GFP_KERNEL);
diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c
index 5d70be63a4a7..1085090d5a9c 100644
--- a/sound/soc/intel/avs/topology.c
+++ b/sound/soc/intel/avs/topology.c
@@ -2226,28 +2226,3 @@ struct avs_tplg *avs_tplg_new(struct snd_soc_component *comp)
return tplg;
}
-
-int avs_load_topology(struct snd_soc_component *comp, const char *filename)
-{
- const struct firmware *fw __free(firmware) = NULL;
- int ret;
-
- ret = request_firmware(&fw, filename, comp->dev);
- if (ret < 0) {
- dev_err(comp->dev, "request topology \"%s\" failed: %d\n", filename, ret);
- return ret;
- }
-
- ret = snd_soc_tplg_component_load(comp, &avs_tplg_ops, fw);
- if (ret < 0)
- dev_err(comp->dev, "load topology \"%s\" failed: %d\n", filename, ret);
-
- return ret;
-}
-
-int avs_remove_topology(struct snd_soc_component *comp)
-{
- snd_soc_tplg_component_remove(comp);
-
- return 0;
-}
diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h
index 189984ce7b51..25f3888a1939 100644
--- a/sound/soc/intel/avs/topology.h
+++ b/sound/soc/intel/avs/topology.h
@@ -233,7 +233,4 @@ struct avs_tplg_module {
extern const struct snd_soc_tplg_ops avs_tplg_ops;
struct avs_tplg *avs_tplg_new(struct snd_soc_component *comp);
-int avs_load_topology(struct snd_soc_component *comp, const char *filename);
-int avs_remove_topology(struct snd_soc_component *comp);
-
#endif
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index b795bcade8e9..919d3f5f5328 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -536,6 +536,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
imply SND_SOC_TAC5XX2_SDW
select SND_SOC_DMIC
select SND_SOC_INTEL_HDA_DSP_COMMON
+ select SND_SOC_SN624X_SDCA_SDW
imply SND_SOC_SDW_MOCKUP
help
Add support for Intel SoundWire-based platforms connected to
diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c
index a4ecb1f9a615..c7e77e20a096 100644
--- a/sound/soc/intel/boards/sof_cirrus_common.c
+++ b/sound/soc/intel/boards/sof_cirrus_common.c
@@ -151,7 +151,7 @@ static const char * const cs35l41_name_prefixes[] = { "WL", "WR", "TL", "TR" };
* UID 0x2 -> TL
* UID 0x3 -> TR
* Note: If there are less than 4 Amps, UIDs still map to WL/WR/TL/TR. Dynamic code will only create
- * dai links for UIDs which exist, and ignore non-existant ones. Only 2 or 4 amps are expected.
+ * dai links for UIDs which exist, and ignore non-existent ones. Only 2 or 4 amps are expected.
* Return number of codecs found.
*/
static int cs35l41_compute_codec_conf(void)
diff --git a/sound/soc/intel/common/soc-acpi-intel-arl-match.c b/sound/soc/intel/common/soc-acpi-intel-arl-match.c
index 1033f2d45c8a..575889a4c69b 100644
--- a/sound/soc/intel/common/soc-acpi-intel-arl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-arl-match.c
@@ -531,6 +531,63 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_machines[] = {
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_machines);
/* this table is used when there is no I2S codec present */
+
+/*
+ * Senary SN624x on Arrow Lake: one multi-function device on link 0.
+ * Separate mach entries per part ID (adr_d[] is AND, not OR). Amp endpoint
+ * is aggregated like the generic SOC_SDW_DAI_TYPE_AMP shape from
+ * find_acpi_adr_device().
+ */
+static const struct snd_soc_acpi_endpoint sn624x_endpoints[] = {
+ /* Jack */
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ /* Amp */
+ {
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+ },
+ /* DMIC */
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+#define SN624X_ARL_SINGLE_ADR(_sym, _adr) \
+static const struct snd_soc_acpi_adr_device _sym[] = { \
+ { \
+ .adr = (_adr), \
+ .num_endpoints = ARRAY_SIZE(sn624x_endpoints), \
+ .endpoints = sn624x_endpoints, \
+ .name_prefix = "sn624x", \
+ }, \
+}
+
+#define SN624X_ARL_LINK(_sym, _adr_arr) \
+static const struct snd_soc_acpi_link_adr _sym[] = { \
+ { \
+ .mask = BIT(0), \
+ .num_adr = ARRAY_SIZE(_adr_arr), \
+ .adr_d = _adr_arr, \
+ }, \
+ {} \
+}
+
+SN624X_ARL_SINGLE_ADR(sn6242_single_adr, 0x0000000496624201ull);
+SN624X_ARL_SINGLE_ADR(sn6244_single_adr, 0x0000000496624401ull);
+
+SN624X_ARL_LINK(arl_link_sn6242, sn6242_single_adr);
+SN624X_ARL_LINK(arl_link_sn6244, sn6244_single_adr);
+
struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
{
.link_mask = BIT(0) | BIT(2) | BIT(3),
@@ -624,6 +681,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
.sof_tplg_filename = "sof-arl-es9356.tplg",
.get_function_tplg_files = sof_sdw_get_tplg_files,
},
+ {
+ .link_mask = BIT(0),
+ .links = arl_link_sn6242,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-sn624x.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0),
+ .links = arl_link_sn6244,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-sn624x.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_sdw_machines);
diff --git a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c
index 62b8811395cb..cbf79eb2ec00 100644
--- a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c
@@ -685,6 +685,63 @@ static const struct snd_soc_acpi_link_adr lnl_sdw_rt712_vb_l2_rt1320_l1[] = {
};
/* this table is used when there is no I2S codec present */
+
+/*
+ * Senary SN624x on Lunar Lake: one multi-function device on link 0.
+ * Separate mach entries per part ID (adr_d[] is AND, not OR). Amp endpoint
+ * is aggregated like the generic SOC_SDW_DAI_TYPE_AMP shape from
+ * find_acpi_adr_device().
+ */
+static const struct snd_soc_acpi_endpoint sn624x_endpoints[] = {
+ /* Jack */
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ /* Amp */
+ {
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+ },
+ /* DMIC */
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+#define SN624X_LNL_SINGLE_ADR(_sym, _adr) \
+static const struct snd_soc_acpi_adr_device _sym[] = { \
+ { \
+ .adr = (_adr), \
+ .num_endpoints = ARRAY_SIZE(sn624x_endpoints), \
+ .endpoints = sn624x_endpoints, \
+ .name_prefix = "sn624x", \
+ }, \
+}
+
+#define SN624X_LNL_LINK(_sym, _adr_arr) \
+static const struct snd_soc_acpi_link_adr _sym[] = { \
+ { \
+ .mask = BIT(0), \
+ .num_adr = ARRAY_SIZE(_adr_arr), \
+ .adr_d = _adr_arr, \
+ }, \
+ {} \
+}
+
+SN624X_LNL_SINGLE_ADR(sn6242_single_adr, 0x0000000496624201ull);
+SN624X_LNL_SINGLE_ADR(sn6244_single_adr, 0x0000000496624401ull);
+
+SN624X_LNL_LINK(lnl_link_sn6242, sn6242_single_adr);
+SN624X_LNL_LINK(lnl_link_sn6244, sn6244_single_adr);
+
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = {
/* mockup tests need to be first */
@@ -806,6 +863,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = {
.sof_tplg_filename = "sof-lnl-rt713-l2-rt1320-l13.tplg",
.get_function_tplg_files = sof_sdw_get_tplg_files,
},
+ {
+ .link_mask = BIT(0),
+ .links = lnl_link_sn6242,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-lnl-sn624x.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0),
+ .links = lnl_link_sn6244,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-lnl-sn624x.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_lnl_sdw_machines);
diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
index 596582053d93..e89c5cfd6ed1 100644
--- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
@@ -1296,6 +1296,63 @@ static const struct snd_soc_acpi_link_adr mtl_cs35l63_x2_link1_link3_fb[] = {
};
/* this table is used when there is no I2S codec present */
+
+/*
+ * Senary SN624x on Meteor Lake: one multi-function device on link 0.
+ * Separate mach entries per part ID (adr_d[] is AND, not OR). Amp endpoint
+ * is aggregated like the generic SOC_SDW_DAI_TYPE_AMP shape from
+ * find_acpi_adr_device().
+ */
+static const struct snd_soc_acpi_endpoint sn624x_endpoints[] = {
+ /* Jack */
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ /* Amp */
+ {
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+ },
+ /* DMIC */
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+#define SN624X_MTL_SINGLE_ADR(_sym, _adr) \
+static const struct snd_soc_acpi_adr_device _sym[] = { \
+ { \
+ .adr = (_adr), \
+ .num_endpoints = ARRAY_SIZE(sn624x_endpoints), \
+ .endpoints = sn624x_endpoints, \
+ .name_prefix = "sn624x", \
+ }, \
+}
+
+#define SN624X_MTL_LINK(_sym, _adr_arr) \
+static const struct snd_soc_acpi_link_adr _sym[] = { \
+ { \
+ .mask = BIT(0), \
+ .num_adr = ARRAY_SIZE(_adr_arr), \
+ .adr_d = _adr_arr, \
+ }, \
+ {} \
+}
+
+SN624X_MTL_SINGLE_ADR(sn6242_single_adr, 0x0000000496624201ull);
+SN624X_MTL_SINGLE_ADR(sn6244_single_adr, 0x0000000496624401ull);
+
+SN624X_MTL_LINK(mtl_link_sn6242, sn6242_single_adr);
+SN624X_MTL_LINK(mtl_link_sn6244, sn6244_single_adr);
+
struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
/* mockup tests need to be first */
{
@@ -1503,6 +1560,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
.sof_tplg_filename = "sof-mtl-sdw-cs42l42-l0-max98363-l2.tplg",
.get_function_tplg_files = sof_sdw_get_tplg_files,
},
+ {
+ .link_mask = BIT(0),
+ .links = mtl_link_sn6242,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-sn624x.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0),
+ .links = mtl_link_sn6244,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-sn624x.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_sdw_machines);
diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c
index 756bbf82a326..0ce51c44bfe6 100644
--- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c
@@ -51,12 +51,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_machines[] = {
.drv_name = "ptl_es83x6_c1_h02",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &ptl_lt6911_hdmi,
+ .get_function_tplg_files = sof_i2s_get_tplg_files,
.sof_tplg_filename = "sof-ptl-es83x6-ssp1-hdmi-ssp02.tplg",
},
{
.comp_ids = &ptl_essx_83x6,
.drv_name = "sof-essx8336",
.sof_tplg_filename = "sof-ptl-es8336", /* the tplg suffix is added at run time */
+ .get_function_tplg_files = sof_i2s_get_tplg_files,
.tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
@@ -65,6 +67,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_machines[] = {
{
.id = "INTC10B0",
.drv_name = "ptl_lt6911_hdmi_ssp",
+ .get_function_tplg_files = sof_i2s_get_tplg_files,
.sof_tplg_filename = "sof-ptl-hdmi-ssp02.tplg",
},
{},
@@ -438,6 +441,66 @@ static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l3_rt1320_l3[] = {
};
/* this table is used when there is no I2S codec present */
+
+/*
+ * Senary SN624x on Panther Lake: one multi-function device on link 3.
+ * Separate mach entries per part ID (adr_d[] is AND, not OR). ADR version
+ * nibble 0x3 matches the silicon SoundWire version. Amp endpoint is
+ * aggregated like the generic SOC_SDW_DAI_TYPE_AMP shape from
+ * find_acpi_adr_device().
+ */
+static const struct snd_soc_acpi_endpoint sn624x_endpoints[] = {
+ /* Jack */
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ /* Amp */
+ {
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+ },
+ /* DMIC */
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+#define SN624X_PTL_SINGLE_ADR(_sym, _adr) \
+static const struct snd_soc_acpi_adr_device _sym[] = { \
+ { \
+ .adr = (_adr), \
+ .num_endpoints = ARRAY_SIZE(sn624x_endpoints), \
+ .endpoints = sn624x_endpoints, \
+ .name_prefix = "sn624x", \
+ }, \
+}
+
+#define SN624X_PTL_LINK(_sym, _adr_arr) \
+static const struct snd_soc_acpi_link_adr _sym[] = { \
+ { \
+ .mask = BIT(3), \
+ .num_adr = ARRAY_SIZE(_adr_arr), \
+ .adr_d = _adr_arr, \
+ }, \
+ {} \
+}
+
+SN624X_PTL_SINGLE_ADR(sn6242_single_adr, 0x0003300496624201ull);
+SN624X_PTL_SINGLE_ADR(sn6244_single_adr, 0x0003300496624401ull);
+SN624X_PTL_SINGLE_ADR(sn6247_single_adr, 0x0003300496624701ull);
+
+SN624X_PTL_LINK(ptl_link_sn6242, sn6242_single_adr);
+SN624X_PTL_LINK(ptl_link_sn6244, sn6244_single_adr);
+SN624X_PTL_LINK(ptl_link_sn6247, sn6247_single_adr);
+
struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = {
/* Order Priority: mockup > most links > most bit link-mask > alphabetical */
{
@@ -531,6 +594,28 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = {
.machine_check = snd_soc_acpi_intel_rt712_vb_no_function_topology,
.sof_tplg_filename = "sof-ptl-rt712-l3-rt1320-l3.tplg",
},
+
+ {
+ .link_mask = BIT(3),
+ .links = ptl_link_sn6242,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-sn624x.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(3),
+ .links = ptl_link_sn6244,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-sn624x.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(3),
+ .links = ptl_link_sn6247,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-sn624x.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_sdw_machines);
diff --git a/sound/soc/intel/common/sof-function-topology-lib.c b/sound/soc/intel/common/sof-function-topology-lib.c
index b6e5a40b78cc..57e089f8e721 100644
--- a/sound/soc/intel/common/sof-function-topology-lib.c
+++ b/sound/soc/intel/common/sof-function-topology-lib.c
@@ -19,6 +19,10 @@ enum tplg_device_id {
TPLG_DEVICE_SDCA_MIC,
TPLG_DEVICE_INTEL_PCH_DMIC,
TPLG_DEVICE_HDMI,
+ TPLG_DEVICE_SSP_JACK,
+ TPLG_DEVICE_SSP_AMP,
+ TPLG_DEVICE_SSP_BT,
+ TPLG_DEVICE_SSP_HDMI_IN,
TPLG_DEVICE_LOOPBACK_VIRTUAL,
TPLG_DEVICE_MAX
};
@@ -28,6 +32,137 @@ enum tplg_device_id {
#define SOF_INTEL_PLATFORM_NAME_MAX 4
+static int get_platform_name(struct snd_soc_card *card,
+ const struct snd_soc_acpi_mach *mach, char *platform)
+{
+ int ret;
+
+ ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform);
+ if (ret != 1) {
+ dev_err(card->dev, "Invalid platform name of tplg %s\n",
+ mach->sof_tplg_filename);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static bool tplg_files_exist(struct device *dev, const char *tplg_files)
+{
+ const struct firmware *fw;
+ int ret;
+
+ ret = firmware_request_nowarn(&fw, tplg_files, dev);
+ if (!ret) {
+ release_firmware(fw);
+ return true;
+ }
+
+ dev_warn(dev,
+ "Failed to open topology file: %s, you might need to\n",
+ tplg_files);
+ dev_warn(dev,
+ "download it from https://github.com/thesofproject/sof-bin/\n");
+ return false;
+}
+
+static char *get_tplg_filename(struct device *dev, const char *prefix,
+ const char *platform, const char *tplg_dev_name,
+ int dai_link_id, int tplg_dev)
+{
+ char *filename = NULL;
+
+ /*
+ * The tplg file naming rule is sof-<platform>-<function>-id<BE id number>.tplg
+ * where <platform> is required for functions that depend on NHLT blobs (e.g. DMIC/SSP)
+ * as the nhlt blob is platform dependent.
+ */
+ switch (tplg_dev) {
+ case TPLG_DEVICE_INTEL_PCH_DMIC:
+ case TPLG_DEVICE_SSP_JACK:
+ case TPLG_DEVICE_SSP_AMP:
+ case TPLG_DEVICE_SSP_BT:
+ case TPLG_DEVICE_SSP_HDMI_IN:
+ filename = devm_kasprintf(dev, GFP_KERNEL, "%s/sof-%s-%s-id%d.tplg",
+ prefix, platform, tplg_dev_name, dai_link_id);
+ break;
+ default:
+ filename = devm_kasprintf(dev, GFP_KERNEL, "%s/sof-%s-id%d.tplg",
+ prefix, tplg_dev_name, dai_link_id);
+ break;
+ }
+
+ return filename;
+}
+
+static int get_dmic_tplg_dev(struct device *dev, int dmic_num,
+ int *tplg_dev, char **tplg_dev_name)
+{
+ switch (dmic_num) {
+ case 2:
+ *tplg_dev_name = "dmic-2ch";
+ break;
+ case 4:
+ *tplg_dev_name = "dmic-4ch";
+ break;
+ default:
+ dev_warn(dev,
+ "unsupported number of dmics: %d\n",
+ dmic_num);
+ return -EINVAL;
+ }
+ *tplg_dev = TPLG_DEVICE_INTEL_PCH_DMIC;
+
+ return 0;
+}
+
+static int get_ssp_tplg_dev(struct device *dev, struct snd_soc_dai_link *dai_link,
+ u16 *hdmi_in_mask, int *tplg_dev, char **tplg_dev_name)
+{
+ unsigned int ssp_port;
+
+ if (sscanf(dai_link->name, "SSP%u", &ssp_port) != 1) {
+ dev_err(dev, "Can't get SSP port from dai_link->name %s\n", dai_link->name);
+ return -EINVAL;
+ }
+ if (strstr(dai_link->name, "Codec")) {
+ /*
+ * Assume DAI link 0 is jack which is true in all existing
+ * machine drivers
+ */
+ if (dai_link->id == 0) {
+ *tplg_dev = TPLG_DEVICE_SSP_JACK;
+ *tplg_dev_name = devm_kasprintf(dev, GFP_KERNEL,
+ "ssp%d-jack", ssp_port);
+ } else {
+ *tplg_dev = TPLG_DEVICE_SSP_AMP;
+ *tplg_dev_name = devm_kasprintf(dev, GFP_KERNEL,
+ "ssp%d-amp", ssp_port);
+ }
+ } else if (strstr(dai_link->name, "BT")) {
+ *tplg_dev = TPLG_DEVICE_SSP_BT;
+ *tplg_dev_name = devm_kasprintf(dev, GFP_KERNEL,
+ "ssp%d-bt", ssp_port);
+ } else if (strstr(dai_link->name, "HDMI")) {
+ *hdmi_in_mask |= BIT(ssp_port);
+ /* The number of HDMI in dai link is always 2 right now */
+ if (hweight16(*hdmi_in_mask) != 2)
+ return -EINVAL;
+
+ *tplg_dev = TPLG_DEVICE_SSP_HDMI_IN;
+ *tplg_dev_name = devm_kasprintf(dev, GFP_KERNEL,
+ "ssp%x-hdmiin", *hdmi_in_mask);
+ } else {
+ dev_warn(dev,
+ "unsupported SSP link %s\n", dai_link->name);
+ return -EINVAL;
+ }
+ if (!*tplg_dev_name)
+ return -ENOMEM;
+
+ return 0;
+}
+
int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach,
const char *prefix, const char ***tplg_files, bool best_effort)
{
@@ -38,20 +173,18 @@ int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_
*/
struct snd_soc_acpi_mach_params mach_params = card_mach->mach_params;
struct snd_soc_dai_link *dai_link;
- const struct firmware *fw;
char platform[SOF_INTEL_PLATFORM_NAME_MAX];
unsigned long tplg_mask = 0;
+ u16 hdmi_in_mask = 0;
int tplg_num = 0;
+ char *tplg_file;
int tplg_dev;
int ret;
int i;
- ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform);
- if (ret != 1) {
- dev_err(card->dev, "Invalid platform name %s of tplg %s\n",
- platform, mach->sof_tplg_filename);
- return -EINVAL;
- }
+ ret = get_platform_name(card, mach, platform);
+ if (ret < 0)
+ return ret;
for_each_card_prelinks(card, i, dai_link) {
char *tplg_dev_name;
@@ -70,23 +203,16 @@ int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_
tplg_dev = TPLG_DEVICE_SDCA_MIC;
tplg_dev_name = "sdca-mic";
} else if (strstr(dai_link->name, "dmic")) {
- switch (mach_params.dmic_num) {
- case 2:
- tplg_dev_name = "dmic-2ch";
- break;
- case 4:
- tplg_dev_name = "dmic-4ch";
- break;
- default:
- dev_warn(card->dev,
- "unsupported number of dmics: %d\n",
- mach_params.dmic_num);
+ if (get_dmic_tplg_dev(card->dev, mach_params.dmic_num,
+ &tplg_dev, &tplg_dev_name) < 0)
continue;
- }
- tplg_dev = TPLG_DEVICE_INTEL_PCH_DMIC;
} else if (strstr(dai_link->name, "iDisp")) {
tplg_dev = TPLG_DEVICE_HDMI;
tplg_dev_name = "hdmi-pcm5";
+ } else if (strstr(dai_link->name, "SSP")) {
+ if (get_ssp_tplg_dev(card->dev, dai_link, &hdmi_in_mask,
+ &tplg_dev, &tplg_dev_name) < 0)
+ continue;
} else if (strstr(dai_link->name, "Loopback_Virtual")) {
tplg_dev = TPLG_DEVICE_LOOPBACK_VIRTUAL;
/*
@@ -109,49 +235,100 @@ int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_
if (tplg_mask & BIT(tplg_dev))
continue;
- tplg_mask |= BIT(tplg_dev);
+ tplg_file = get_tplg_filename(card->dev, prefix, platform, tplg_dev_name,
+ dai_link->id, tplg_dev);
+ if (!tplg_file)
+ return -ENOMEM;
- /*
- * The tplg file naming rule is sof-<platform>-<function>-id<BE id number>.tplg
- * where <platform> is only required for the DMIC function as the nhlt blob
- * is platform dependent.
- */
- switch (tplg_dev) {
- case TPLG_DEVICE_INTEL_PCH_DMIC:
- (*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
- "%s/sof-%s-%s-id%d.tplg",
- prefix, platform,
- tplg_dev_name, dai_link->id);
- break;
- default:
- (*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
- "%s/sof-%s-id%d.tplg",
- prefix, tplg_dev_name,
- dai_link->id);
- break;
+ /* Check presence of sub-topologies */
+ if (!tplg_files_exist(card->dev, tplg_file)) {
+ devm_kfree(card->dev, tplg_file);
+ if (best_effort)
+ continue;
+
+ return 0;
}
- if (!(*tplg_files)[tplg_num])
- return -ENOMEM;
+
+ tplg_mask |= BIT(tplg_dev);
+
+ (*tplg_files)[tplg_num] = tplg_file;
tplg_num++;
}
dev_dbg(card->dev, "tplg_mask %#lx tplg_num %d\n", tplg_mask, tplg_num);
- /* Check presence of sub-topologies */
- for (i = 0; i < tplg_num; i++) {
- ret = firmware_request_nowarn(&fw, (*tplg_files)[i], card->dev);
- if (!ret) {
- release_firmware(fw);
+ return tplg_num;
+}
+EXPORT_SYMBOL_GPL(sof_sdw_get_tplg_files);
+
+int sof_i2s_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach,
+ const char *prefix, const char ***tplg_files, bool best_effort)
+{
+ struct snd_soc_acpi_mach_params mach_params = mach->mach_params;
+ struct snd_soc_dai_link *dai_link;
+ char platform[SOF_INTEL_PLATFORM_NAME_MAX];
+ unsigned long tplg_mask = 0;
+ u16 hdmi_in_mask = 0;
+ int tplg_num = 0;
+ char *tplg_file;
+ int tplg_dev;
+ int ret;
+ int i;
+
+ ret = get_platform_name(card, mach, platform);
+ if (ret < 0)
+ return ret;
+
+ for_each_card_prelinks(card, i, dai_link) {
+ char *tplg_dev_name;
+
+ dev_dbg(card->dev, "dai_link %s id %d\n", dai_link->name, dai_link->id);
+ if (strstr(dai_link->name, "SSP")) {
+ if (get_ssp_tplg_dev(card->dev, dai_link, &hdmi_in_mask,
+ &tplg_dev, &tplg_dev_name) < 0)
+ continue;
+ } else if (strstr(dai_link->name, "dmic")) {
+ if (get_dmic_tplg_dev(card->dev, mach_params.dmic_num,
+ &tplg_dev, &tplg_dev_name) < 0)
+ continue;
+ } else if (strstr(dai_link->name, "iDisp")) {
+ tplg_dev = TPLG_DEVICE_HDMI;
+ tplg_dev_name = "hdmi-pcm5";
} else {
- dev_warn(card->dev,
- "Failed to open topology file: %s, you might need to\n",
- (*tplg_files)[i]);
- dev_warn(card->dev,
- "download it from https://github.com/thesofproject/sof-bin/\n");
+ /* The dai link is not supported by separated tplg yet */
+ dev_dbg(card->dev,
+ "dai_link %s is not supported by separated tplg yet\n",
+ dai_link->name);
+ if (best_effort)
+ continue;
+
+ return 0;
+ }
+ if (tplg_mask & BIT(tplg_dev))
+ continue;
+
+ tplg_file = get_tplg_filename(card->dev, prefix, platform, tplg_dev_name,
+ dai_link->id, tplg_dev);
+ if (!tplg_file)
+ return -ENOMEM;
+
+ /* Check presence of sub-topologies */
+ if (!tplg_files_exist(card->dev, tplg_file)) {
+ devm_kfree(card->dev, tplg_file);
+ if (best_effort)
+ continue;
+
return 0;
}
+
+ tplg_mask |= BIT(tplg_dev);
+
+ (*tplg_files)[tplg_num] = tplg_file;
+ tplg_num++;
}
+ dev_dbg(card->dev, "tplg_mask %#lx tplg_num %d\n", tplg_mask, tplg_num);
+
return tplg_num;
}
-EXPORT_SYMBOL_GPL(sof_sdw_get_tplg_files);
+EXPORT_SYMBOL_GPL(sof_i2s_get_tplg_files);
diff --git a/sound/soc/intel/common/sof-function-topology-lib.h b/sound/soc/intel/common/sof-function-topology-lib.h
index f358f8c52d78..9755e9770968 100644
--- a/sound/soc/intel/common/sof-function-topology-lib.h
+++ b/sound/soc/intel/common/sof-function-topology-lib.h
@@ -12,4 +12,7 @@
int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach,
const char *prefix, const char ***tplg_files, bool best_effort);
+int sof_i2s_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach,
+ const char *prefix, const char ***tplg_files, bool best_effort);
+
#endif