summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2023-04-20 14:49:22 +0100
committerMark Brown <broonie@kernel.org>2023-04-20 14:49:22 +0100
commit0d587f354dcf3616542d6ec3239fb65ed7187735 (patch)
tree3355fba2ab4d31bfe95e9d8db9229eb5283f91fc /sound
parenta9e42d9e8b4be36a1e0dde0285a9ff36b2e06a46 (diff)
parentdc5a3e60a4b5974a0cb5bf2c5df70a490dce9df2 (diff)
downloadlinux-0d587f354dcf3616542d6ec3239fb65ed7187735.tar.gz
ASoC: Intel: boards: updates for 6.4
Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>: Preparation of ALC712 support with different types of SoundWire devices per link, new RaptorLake SoundWire device, better error handling for Cirrus devices and cosmetic changes for Max98373. Bard Liao (3): ASoC: Intel: sof_sdw: set codec_num = 1 if the device is not aggregated ASoC: Intel: sof_sdw: support different devices on the same sdw link ASoC: Intel: sof_sdw: append codec type to dai link name Curtis Malainey (1): ASoC: Intel: sof_cirrus_common: Guard against missing buses Yong Zhi (2): ASoC: Intel: sof_sdw: remove late_probe flag in struct sof_sdw_codec_info ASoC: Intel: sof_sdw_max98373: change sof_sdw_mx8373_late_probe to static call apoorv (1): ASoC: Intel: soc-acpi: Add entry for rt711-sdca-sdw at link 2 in RPL match table sound/soc/intel/boards/sof_cirrus_common.c | 7 +- sound/soc/intel/boards/sof_sdw.c | 181 ++++++++++++------ sound/soc/intel/boards/sof_sdw_common.h | 3 - sound/soc/intel/boards/sof_sdw_max98373.c | 22 +-- .../intel/common/soc-acpi-intel-rpl-match.c | 17 +- 5 files changed, 152 insertions(+), 78 deletions(-) -- 2.37.2
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/intel/boards/sof_cirrus_common.c7
-rw-r--r--sound/soc/intel/boards/sof_sdw.c181
-rw-r--r--sound/soc/intel/boards/sof_sdw_common.h3
-rw-r--r--sound/soc/intel/boards/sof_sdw_max98373.c22
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-rpl-match.c17
5 files changed, 152 insertions, 78 deletions
diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c
index 851c516c8f5b..8b8b07e4f2fe 100644
--- a/sound/soc/intel/boards/sof_cirrus_common.c
+++ b/sound/soc/intel/boards/sof_cirrus_common.c
@@ -168,11 +168,16 @@ static int cs35l41_compute_codec_conf(void)
continue;
}
physdev = get_device(acpi_get_first_physical_node(adev));
+ acpi_dev_put(adev);
+ if (!physdev) {
+ pr_devel("Cannot find physical node for HID %s UID %u (%s)\n", CS35L41_HID,
+ uid, cs35l41_name_prefixes[uid]);
+ return 0;
+ }
cs35l41_components[sz].name = dev_name(physdev);
cs35l41_components[sz].dai_name = CS35L41_CODEC_DAI;
cs35l41_codec_conf[sz].dlc.name = dev_name(physdev);
cs35l41_codec_conf[sz].name_prefix = cs35l41_name_prefixes[uid];
- acpi_dev_put(adev);
sz++;
}
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index 6897705a193c..6faf4a43eaf5 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -621,7 +621,6 @@ static struct sof_sdw_codec_info codec_info_list[] = {
.direction = {true, true},
.dai_name = "max98373-aif1",
.init = sof_sdw_mx8373_init,
- .codec_card_late_probe = sof_sdw_mx8373_late_probe,
.codec_type = SOF_SDW_CODEC_TYPE_AMP,
},
{
@@ -733,34 +732,36 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li
int stream;
u64 adr;
- adr = link->adr_d->adr;
- codec_index = find_codec_info_part(adr);
- if (codec_index < 0)
- return codec_index;
+ for (i = 0; i < link->num_adr; i++) {
+ adr = link->adr_d[i].adr;
+ codec_index = find_codec_info_part(adr);
+ if (codec_index < 0)
+ return codec_index;
- if (codec_info_list[codec_index].codec_type < _codec_type)
- dev_warn(dev,
- "Unexpected address table ordering. Expected order: jack -> amp -> mic\n");
+ if (codec_info_list[codec_index].codec_type < _codec_type)
+ dev_warn(dev,
+ "Unexpected address table ordering. Expected order: jack -> amp -> mic\n");
- _codec_type = codec_info_list[codec_index].codec_type;
+ _codec_type = codec_info_list[codec_index].codec_type;
- endpoint = link->adr_d->endpoints;
+ endpoint = link->adr_d[i].endpoints;
- /* count DAI number for playback and capture */
- for_each_pcm_streams(stream) {
- if (!codec_info_list[codec_index].direction[stream])
- continue;
+ /* count DAI number for playback and capture */
+ for_each_pcm_streams(stream) {
+ if (!codec_info_list[codec_index].direction[stream])
+ continue;
- (*sdw_cpu_dai_num)++;
+ (*sdw_cpu_dai_num)++;
- /* count BE for each non-aggregated slave or group */
- if (!endpoint->aggregated || no_aggregation ||
- !group_visited[endpoint->group_id])
- (*sdw_be_num)++;
- }
+ /* count BE for each non-aggregated slave or group */
+ if (!endpoint->aggregated || no_aggregation ||
+ !group_visited[endpoint->group_id])
+ (*sdw_be_num)++;
+ }
- if (endpoint->aggregated)
- group_visited[endpoint->group_id] = true;
+ if (endpoint->aggregated)
+ group_visited[endpoint->group_id] = true;
+ }
}
return 0;
@@ -830,17 +831,19 @@ static int create_codec_dai_name(struct device *dev,
int offset,
struct snd_soc_codec_conf *codec_conf,
int codec_count,
- int *codec_conf_index)
+ int *codec_conf_index,
+ int adr_index)
{
+ int _codec_index = -1;
int i;
/* sanity check */
- if (*codec_conf_index + link->num_adr > codec_count) {
+ if (*codec_conf_index + link->num_adr - adr_index > codec_count) {
dev_err(dev, "codec_conf: out-of-bounds access requested\n");
return -EINVAL;
}
- for (i = 0; i < link->num_adr; i++) {
+ for (i = adr_index; i < link->num_adr; i++) {
unsigned int sdw_version, unique_id, mfg_id;
unsigned int link_id, part_id, class_id;
int codec_index, comp_index;
@@ -856,7 +859,7 @@ static int create_codec_dai_name(struct device *dev,
part_id = SDW_PART_ID(adr);
class_id = SDW_CLASS_ID(adr);
- comp_index = i + offset;
+ comp_index = i - adr_index + offset;
if (is_unique_device(link, sdw_version, mfg_id, part_id,
class_id, i)) {
codec_str = "sdw:%01x:%04x:%04x:%02x";
@@ -878,6 +881,11 @@ static int create_codec_dai_name(struct device *dev,
codec_index = find_codec_info_part(adr);
if (codec_index < 0)
return codec_index;
+ if (_codec_index != -1 && codec_index != _codec_index) {
+ dev_dbg(dev, "Different devices on the same sdw link\n");
+ break;
+ }
+ _codec_index = codec_index;
codec[comp_index].dai_name =
codec_info_list[codec_index].dai_name;
@@ -944,16 +952,16 @@ static int set_codec_init_func(struct snd_soc_card *card,
static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
struct device *dev, int *cpu_dai_id, int *cpu_dai_num,
int *codec_num, unsigned int *group_id,
- bool *group_generated)
+ bool *group_generated, int adr_index)
{
const struct snd_soc_acpi_adr_device *adr_d;
const struct snd_soc_acpi_link_adr *adr_next;
bool no_aggregation;
int index = 0;
+ int i;
no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION;
- *codec_num = adr_link->num_adr;
- adr_d = adr_link->adr_d;
+ adr_d = &adr_link->adr_d[adr_index];
/* make sure the link mask has a single bit set */
if (!is_power_of_2(adr_link->mask))
@@ -962,12 +970,21 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
cpu_dai_id[index++] = ffs(adr_link->mask) - 1;
if (!adr_d->endpoints->aggregated || no_aggregation) {
*cpu_dai_num = 1;
+ *codec_num = 1;
*group_id = 0;
return 0;
}
*group_id = adr_d->endpoints->group_id;
+ /* Count endpoints with the same group_id in the adr_link */
+ *codec_num = 0;
+ for (i = 0; i < adr_link->num_adr; i++) {
+ if (adr_link->adr_d[i].endpoints->aggregated &&
+ adr_link->adr_d[i].endpoints->group_id == *group_id)
+ (*codec_num)++;
+ }
+
/* gather other link ID of slaves in the same group */
for (adr_next = adr_link + 1; adr_next && adr_next->num_adr;
adr_next++) {
@@ -988,7 +1005,11 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
}
cpu_dai_id[index++] = ffs(adr_next->mask) - 1;
- *codec_num += adr_next->num_adr;
+ for (i = 0; i < adr_next->num_adr; i++) {
+ if (adr_next->adr_d[i].endpoints->aggregated &&
+ adr_next->adr_d[i].endpoints->group_id == *group_id)
+ (*codec_num)++;
+ }
}
/*
@@ -1001,6 +1022,8 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
return 0;
}
+static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"};
+
static int create_sdw_dailink(struct snd_soc_card *card,
struct device *dev, int *link_index,
struct snd_soc_dai_link *dai_links,
@@ -1011,7 +1034,9 @@ static int create_sdw_dailink(struct snd_soc_card *card,
struct snd_soc_codec_conf *codec_conf,
int codec_count, int *link_id,
int *codec_conf_index,
- bool *ignore_pch_dmic)
+ bool *ignore_pch_dmic,
+ bool append_codec_type,
+ int adr_index)
{
const struct snd_soc_acpi_link_adr *link_next;
struct snd_soc_dai_link_component *codecs;
@@ -1027,7 +1052,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
int k;
ret = get_slave_info(link, dev, cpu_dai_id, &cpu_dai_num, &codec_num,
- &group_id, group_generated);
+ &group_id, group_generated, adr_index);
if (ret)
return ret;
@@ -1050,7 +1075,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
continue;
ret = create_codec_dai_name(dev, link_next, codecs, codec_idx,
- codec_conf, codec_count, codec_conf_index);
+ codec_conf, codec_count, codec_conf_index, adr_index);
if (ret < 0)
return ret;
@@ -1060,7 +1085,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
}
/* find codec info to create BE DAI */
- codec_index = find_codec_info_part(link->adr_d[0].adr);
+ codec_index = find_codec_info_part(link->adr_d[adr_index].adr);
if (codec_index < 0)
return codec_index;
@@ -1087,14 +1112,22 @@ static int create_sdw_dailink(struct snd_soc_card *card,
static const char * const sdw_stream_name[] = {
"SDW%d-Playback",
"SDW%d-Capture",
+ "SDW%d-Playback-%s",
+ "SDW%d-Capture-%s",
};
if (!codec_info_list[codec_index].direction[stream])
continue;
/* create stream name according to first link id */
- name = devm_kasprintf(dev, GFP_KERNEL,
- sdw_stream_name[stream], cpu_dai_id[0]);
+ if (append_codec_type) {
+ name = devm_kasprintf(dev, GFP_KERNEL,
+ sdw_stream_name[stream + 2], cpu_dai_id[0],
+ type_strings[codec_info_list[codec_index].codec_type]);
+ } else {
+ name = devm_kasprintf(dev, GFP_KERNEL,
+ sdw_stream_name[stream], cpu_dai_id[0]);
+ }
if (!name)
return -ENOMEM;
@@ -1210,6 +1243,7 @@ static int sof_card_dai_links_create(struct device *dev,
const struct snd_soc_acpi_link_adr *adr_link;
struct snd_soc_dai_link_component *cpus;
struct snd_soc_codec_conf *codec_conf;
+ bool append_codec_type = false;
bool ignore_pch_dmic = false;
int codec_conf_count;
int codec_conf_index = 0;
@@ -1301,31 +1335,54 @@ static int sof_card_dai_links_create(struct device *dev,
for (i = 0; i < SDW_MAX_GROUPS; i++)
group_generated[i] = false;
- /* generate DAI links by each sdw link */
for (; adr_link->num_adr; adr_link++) {
- const struct snd_soc_acpi_endpoint *endpoint;
-
- endpoint = adr_link->adr_d->endpoints;
- if (endpoint->aggregated && !endpoint->group_id) {
- dev_err(dev, "invalid group id on link %x",
- adr_link->mask);
- continue;
+ /*
+ * If there are two or more different devices on the same sdw link, we have to
+ * append the codec type to the dai link name to prevent duplicated dai link name.
+ * The same type devices on the same sdw link will be in the same
+ * snd_soc_acpi_adr_device array. They won't be described in different adr_links.
+ */
+ for (i = 0; i < adr_link->num_adr; i++) {
+ for (j = 0; j < i; j++) {
+ if ((SDW_PART_ID(adr_link->adr_d[i].adr) !=
+ SDW_PART_ID(adr_link->adr_d[j].adr)) ||
+ (SDW_MFG_ID(adr_link->adr_d[i].adr) !=
+ SDW_MFG_ID(adr_link->adr_d[i].adr))) {
+ append_codec_type = true;
+ goto out;
+ }
+ }
}
+ }
+out:
- /* this group has been generated */
- if (endpoint->aggregated &&
- group_generated[endpoint->group_id])
- continue;
+ /* generate DAI links by each sdw link */
+ for (adr_link = mach_params->links ; adr_link->num_adr; adr_link++) {
+ for (i = 0; i < adr_link->num_adr; i++) {
+ const struct snd_soc_acpi_endpoint *endpoint;
- ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num,
- sdw_cpu_dai_num, cpus, adr_link,
- &cpu_id, group_generated,
- codec_conf, codec_conf_count,
- &be_id, &codec_conf_index,
- &ignore_pch_dmic);
- if (ret < 0) {
- dev_err(dev, "failed to create dai link %d", link_index);
- return ret;
+ endpoint = adr_link->adr_d[i].endpoints;
+ if (endpoint->aggregated && !endpoint->group_id) {
+ dev_err(dev, "invalid group id on link %x",
+ adr_link->mask);
+ continue;
+ }
+
+ /* this group has been generated */
+ if (endpoint->aggregated &&
+ group_generated[endpoint->group_id])
+ continue;
+
+ ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num,
+ sdw_cpu_dai_num, cpus, adr_link,
+ &cpu_id, group_generated,
+ codec_conf, codec_conf_count,
+ &be_id, &codec_conf_index,
+ &ignore_pch_dmic, append_codec_type, i);
+ if (ret < 0) {
+ dev_err(dev, "failed to create dai link %d", link_index);
+ return ret;
+ }
}
}
@@ -1490,12 +1547,12 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card)
int i;
for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
- if (!codec_info_list[i].late_probe)
- continue;
+ if (codec_info_list[i].codec_card_late_probe) {
+ ret = codec_info_list[i].codec_card_late_probe(card);
- ret = codec_info_list[i].codec_card_late_probe(card);
- if (ret < 0)
- return ret;
+ if (ret < 0)
+ return ret;
+ }
}
if (ctx->idisp_codec)
diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h
index 350010b0e5f4..081ab7eac5b6 100644
--- a/sound/soc/intel/boards/sof_sdw_common.h
+++ b/sound/soc/intel/boards/sof_sdw_common.h
@@ -74,7 +74,6 @@ struct sof_sdw_codec_info {
bool playback);
int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
- bool late_probe;
int (*codec_card_late_probe)(struct snd_soc_card *card);
};
@@ -159,8 +158,6 @@ int sof_sdw_mx8373_init(struct snd_soc_card *card,
struct sof_sdw_codec_info *info,
bool playback);
-int sof_sdw_mx8373_late_probe(struct snd_soc_card *card);
-
/* RT5682 support */
int sof_sdw_rt5682_init(struct snd_soc_card *card,
const struct snd_soc_acpi_link_adr *link,
diff --git a/sound/soc/intel/boards/sof_sdw_max98373.c b/sound/soc/intel/boards/sof_sdw_max98373.c
index 77a3f32db11e..3d7df58c0f1d 100644
--- a/sound/soc/intel/boards/sof_sdw_max98373.c
+++ b/sound/soc/intel/boards/sof_sdw_max98373.c
@@ -120,6 +120,16 @@ static const struct snd_soc_ops max_98373_sdw_ops = {
.shutdown = sdw_shutdown,
};
+static int mx8373_sdw_late_probe(struct snd_soc_card *card)
+{
+ struct snd_soc_dapm_context *dapm = &card->dapm;
+
+ /* Disable Left and Right Spk pin after boot */
+ snd_soc_dapm_disable_pin(dapm, "Left Spk");
+ snd_soc_dapm_disable_pin(dapm, "Right Spk");
+ return snd_soc_dapm_sync(dapm);
+}
+
int sof_sdw_mx8373_init(struct snd_soc_card *card,
const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
@@ -130,19 +140,9 @@ int sof_sdw_mx8373_init(struct snd_soc_card *card,
if (info->amp_num == 2)
dai_links->init = spk_init;
- info->late_probe = true;
+ info->codec_card_late_probe = mx8373_sdw_late_probe;
dai_links->ops = &max_98373_sdw_ops;
return 0;
}
-
-int sof_sdw_mx8373_late_probe(struct snd_soc_card *card)
-{
- struct snd_soc_dapm_context *dapm = &card->dapm;
-
- /* Disable Left and Right Spk pin after boot */
- snd_soc_dapm_disable_pin(dapm, "Left Spk");
- snd_soc_dapm_disable_pin(dapm, "Right Spk");
- return snd_soc_dapm_sync(dapm);
-}
diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
index 13cbd8e9d41f..749d371a86ae 100644
--- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
@@ -284,6 +284,15 @@ static const struct snd_soc_acpi_link_adr rpl_sdw_rt1316_link12_rt714_link0[] =
{}
};
+static const struct snd_soc_acpi_link_adr rplp_crb[] = {
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt711_sdca_2_adr),
+ .adr_d = rt711_sdca_2_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_codecs rpl_rt5682_hp = {
.num_codecs = 2,
.codecs = {"10EC5682", "RTL5682"},
@@ -348,7 +357,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = {
.link_mask = 0x1, /* link0 required */
.links = rpl_rvp,
.drv_name = "sof_sdw",
- .sof_tplg_filename = "sof-rpl-rt711.tplg",
+ .sof_tplg_filename = "sof-rpl-rt711-l0.tplg",
+ },
+ {
+ .link_mask = 0x4, /* link2 required */
+ .links = rplp_crb,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-rpl-rt711-l2.tplg",
},
{},
};