Commit 0d587f35 authored by Mark Brown's avatar Mark Brown

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
parents a9e42d9e dc5a3e60
...@@ -168,11 +168,16 @@ static int cs35l41_compute_codec_conf(void) ...@@ -168,11 +168,16 @@ static int cs35l41_compute_codec_conf(void)
continue; continue;
} }
physdev = get_device(acpi_get_first_physical_node(adev)); 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].name = dev_name(physdev);
cs35l41_components[sz].dai_name = CS35L41_CODEC_DAI; cs35l41_components[sz].dai_name = CS35L41_CODEC_DAI;
cs35l41_codec_conf[sz].dlc.name = dev_name(physdev); cs35l41_codec_conf[sz].dlc.name = dev_name(physdev);
cs35l41_codec_conf[sz].name_prefix = cs35l41_name_prefixes[uid]; cs35l41_codec_conf[sz].name_prefix = cs35l41_name_prefixes[uid];
acpi_dev_put(adev);
sz++; sz++;
} }
......
...@@ -621,7 +621,6 @@ static struct sof_sdw_codec_info codec_info_list[] = { ...@@ -621,7 +621,6 @@ static struct sof_sdw_codec_info codec_info_list[] = {
.direction = {true, true}, .direction = {true, true},
.dai_name = "max98373-aif1", .dai_name = "max98373-aif1",
.init = sof_sdw_mx8373_init, .init = sof_sdw_mx8373_init,
.codec_card_late_probe = sof_sdw_mx8373_late_probe,
.codec_type = SOF_SDW_CODEC_TYPE_AMP, .codec_type = SOF_SDW_CODEC_TYPE_AMP,
}, },
{ {
...@@ -733,7 +732,8 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li ...@@ -733,7 +732,8 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li
int stream; int stream;
u64 adr; u64 adr;
adr = link->adr_d->adr; for (i = 0; i < link->num_adr; i++) {
adr = link->adr_d[i].adr;
codec_index = find_codec_info_part(adr); codec_index = find_codec_info_part(adr);
if (codec_index < 0) if (codec_index < 0)
return codec_index; return codec_index;
...@@ -744,7 +744,7 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li ...@@ -744,7 +744,7 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li
_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 */ /* count DAI number for playback and capture */
for_each_pcm_streams(stream) { for_each_pcm_streams(stream) {
...@@ -762,6 +762,7 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li ...@@ -762,6 +762,7 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li
if (endpoint->aggregated) if (endpoint->aggregated)
group_visited[endpoint->group_id] = true; group_visited[endpoint->group_id] = true;
} }
}
return 0; return 0;
} }
...@@ -830,17 +831,19 @@ static int create_codec_dai_name(struct device *dev, ...@@ -830,17 +831,19 @@ static int create_codec_dai_name(struct device *dev,
int offset, int offset,
struct snd_soc_codec_conf *codec_conf, struct snd_soc_codec_conf *codec_conf,
int codec_count, int codec_count,
int *codec_conf_index) int *codec_conf_index,
int adr_index)
{ {
int _codec_index = -1;
int i; int i;
/* sanity check */ /* 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"); dev_err(dev, "codec_conf: out-of-bounds access requested\n");
return -EINVAL; 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 sdw_version, unique_id, mfg_id;
unsigned int link_id, part_id, class_id; unsigned int link_id, part_id, class_id;
int codec_index, comp_index; int codec_index, comp_index;
...@@ -856,7 +859,7 @@ static int create_codec_dai_name(struct device *dev, ...@@ -856,7 +859,7 @@ static int create_codec_dai_name(struct device *dev,
part_id = SDW_PART_ID(adr); part_id = SDW_PART_ID(adr);
class_id = SDW_CLASS_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, if (is_unique_device(link, sdw_version, mfg_id, part_id,
class_id, i)) { class_id, i)) {
codec_str = "sdw:%01x:%04x:%04x:%02x"; codec_str = "sdw:%01x:%04x:%04x:%02x";
...@@ -878,6 +881,11 @@ static int create_codec_dai_name(struct device *dev, ...@@ -878,6 +881,11 @@ static int create_codec_dai_name(struct device *dev,
codec_index = find_codec_info_part(adr); codec_index = find_codec_info_part(adr);
if (codec_index < 0) if (codec_index < 0)
return codec_index; 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[comp_index].dai_name =
codec_info_list[codec_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, ...@@ -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, 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, struct device *dev, int *cpu_dai_id, int *cpu_dai_num,
int *codec_num, unsigned int *group_id, 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_adr_device *adr_d;
const struct snd_soc_acpi_link_adr *adr_next; const struct snd_soc_acpi_link_adr *adr_next;
bool no_aggregation; bool no_aggregation;
int index = 0; int index = 0;
int i;
no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION;
*codec_num = adr_link->num_adr; adr_d = &adr_link->adr_d[adr_index];
adr_d = adr_link->adr_d;
/* make sure the link mask has a single bit set */ /* make sure the link mask has a single bit set */
if (!is_power_of_2(adr_link->mask)) 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, ...@@ -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; cpu_dai_id[index++] = ffs(adr_link->mask) - 1;
if (!adr_d->endpoints->aggregated || no_aggregation) { if (!adr_d->endpoints->aggregated || no_aggregation) {
*cpu_dai_num = 1; *cpu_dai_num = 1;
*codec_num = 1;
*group_id = 0; *group_id = 0;
return 0; return 0;
} }
*group_id = adr_d->endpoints->group_id; *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 */ /* gather other link ID of slaves in the same group */
for (adr_next = adr_link + 1; adr_next && adr_next->num_adr; for (adr_next = adr_link + 1; adr_next && adr_next->num_adr;
adr_next++) { adr_next++) {
...@@ -988,7 +1005,11 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link, ...@@ -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; 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, ...@@ -1001,6 +1022,8 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
return 0; return 0;
} }
static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"};
static int create_sdw_dailink(struct snd_soc_card *card, static int create_sdw_dailink(struct snd_soc_card *card,
struct device *dev, int *link_index, struct device *dev, int *link_index,
struct snd_soc_dai_link *dai_links, struct snd_soc_dai_link *dai_links,
...@@ -1011,7 +1034,9 @@ static int create_sdw_dailink(struct snd_soc_card *card, ...@@ -1011,7 +1034,9 @@ static int create_sdw_dailink(struct snd_soc_card *card,
struct snd_soc_codec_conf *codec_conf, struct snd_soc_codec_conf *codec_conf,
int codec_count, int *link_id, int codec_count, int *link_id,
int *codec_conf_index, 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; const struct snd_soc_acpi_link_adr *link_next;
struct snd_soc_dai_link_component *codecs; struct snd_soc_dai_link_component *codecs;
...@@ -1027,7 +1052,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, ...@@ -1027,7 +1052,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
int k; int k;
ret = get_slave_info(link, dev, cpu_dai_id, &cpu_dai_num, &codec_num, 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) if (ret)
return ret; return ret;
...@@ -1050,7 +1075,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, ...@@ -1050,7 +1075,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
continue; continue;
ret = create_codec_dai_name(dev, link_next, codecs, codec_idx, 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) if (ret < 0)
return ret; return ret;
...@@ -1060,7 +1085,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, ...@@ -1060,7 +1085,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
} }
/* find codec info to create BE DAI */ /* 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) if (codec_index < 0)
return codec_index; return codec_index;
...@@ -1087,14 +1112,22 @@ static int create_sdw_dailink(struct snd_soc_card *card, ...@@ -1087,14 +1112,22 @@ static int create_sdw_dailink(struct snd_soc_card *card,
static const char * const sdw_stream_name[] = { static const char * const sdw_stream_name[] = {
"SDW%d-Playback", "SDW%d-Playback",
"SDW%d-Capture", "SDW%d-Capture",
"SDW%d-Playback-%s",
"SDW%d-Capture-%s",
}; };
if (!codec_info_list[codec_index].direction[stream]) if (!codec_info_list[codec_index].direction[stream])
continue; continue;
/* create stream name according to first link id */ /* create stream name according to first link id */
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, name = devm_kasprintf(dev, GFP_KERNEL,
sdw_stream_name[stream], cpu_dai_id[0]); sdw_stream_name[stream], cpu_dai_id[0]);
}
if (!name) if (!name)
return -ENOMEM; return -ENOMEM;
...@@ -1210,6 +1243,7 @@ static int sof_card_dai_links_create(struct device *dev, ...@@ -1210,6 +1243,7 @@ static int sof_card_dai_links_create(struct device *dev,
const struct snd_soc_acpi_link_adr *adr_link; const struct snd_soc_acpi_link_adr *adr_link;
struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link_component *cpus;
struct snd_soc_codec_conf *codec_conf; struct snd_soc_codec_conf *codec_conf;
bool append_codec_type = false;
bool ignore_pch_dmic = false; bool ignore_pch_dmic = false;
int codec_conf_count; int codec_conf_count;
int codec_conf_index = 0; int codec_conf_index = 0;
...@@ -1301,11 +1335,33 @@ static int sof_card_dai_links_create(struct device *dev, ...@@ -1301,11 +1335,33 @@ static int sof_card_dai_links_create(struct device *dev,
for (i = 0; i < SDW_MAX_GROUPS; i++) for (i = 0; i < SDW_MAX_GROUPS; i++)
group_generated[i] = false; group_generated[i] = false;
/* generate DAI links by each sdw link */
for (; adr_link->num_adr; adr_link++) { for (; adr_link->num_adr; adr_link++) {
/*
* 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:
/* 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; const struct snd_soc_acpi_endpoint *endpoint;
endpoint = adr_link->adr_d->endpoints; endpoint = adr_link->adr_d[i].endpoints;
if (endpoint->aggregated && !endpoint->group_id) { if (endpoint->aggregated && !endpoint->group_id) {
dev_err(dev, "invalid group id on link %x", dev_err(dev, "invalid group id on link %x",
adr_link->mask); adr_link->mask);
...@@ -1322,12 +1378,13 @@ static int sof_card_dai_links_create(struct device *dev, ...@@ -1322,12 +1378,13 @@ static int sof_card_dai_links_create(struct device *dev,
&cpu_id, group_generated, &cpu_id, group_generated,
codec_conf, codec_conf_count, codec_conf, codec_conf_count,
&be_id, &codec_conf_index, &be_id, &codec_conf_index,
&ignore_pch_dmic); &ignore_pch_dmic, append_codec_type, i);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "failed to create dai link %d", link_index); dev_err(dev, "failed to create dai link %d", link_index);
return ret; return ret;
} }
} }
}
SSP: SSP:
/* SSP */ /* SSP */
...@@ -1490,13 +1547,13 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card) ...@@ -1490,13 +1547,13 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card)
int i; int i;
for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
if (!codec_info_list[i].late_probe) if (codec_info_list[i].codec_card_late_probe) {
continue;
ret = codec_info_list[i].codec_card_late_probe(card); ret = codec_info_list[i].codec_card_late_probe(card);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
}
if (ctx->idisp_codec) if (ctx->idisp_codec)
ret = sof_sdw_hdmi_card_late_probe(card); ret = sof_sdw_hdmi_card_late_probe(card);
......
...@@ -74,7 +74,6 @@ struct sof_sdw_codec_info { ...@@ -74,7 +74,6 @@ struct sof_sdw_codec_info {
bool playback); bool playback);
int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 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); int (*codec_card_late_probe)(struct snd_soc_card *card);
}; };
...@@ -159,8 +158,6 @@ int sof_sdw_mx8373_init(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, struct sof_sdw_codec_info *info,
bool playback); bool playback);
int sof_sdw_mx8373_late_probe(struct snd_soc_card *card);
/* RT5682 support */ /* RT5682 support */
int sof_sdw_rt5682_init(struct snd_soc_card *card, int sof_sdw_rt5682_init(struct snd_soc_card *card,
const struct snd_soc_acpi_link_adr *link, const struct snd_soc_acpi_link_adr *link,
......
...@@ -120,6 +120,16 @@ static const struct snd_soc_ops max_98373_sdw_ops = { ...@@ -120,6 +120,16 @@ static const struct snd_soc_ops max_98373_sdw_ops = {
.shutdown = sdw_shutdown, .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, int sof_sdw_mx8373_init(struct snd_soc_card *card,
const struct snd_soc_acpi_link_adr *link, const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links, struct snd_soc_dai_link *dai_links,
...@@ -130,19 +140,9 @@ int sof_sdw_mx8373_init(struct snd_soc_card *card, ...@@ -130,19 +140,9 @@ int sof_sdw_mx8373_init(struct snd_soc_card *card,
if (info->amp_num == 2) if (info->amp_num == 2)
dai_links->init = spk_init; 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; dai_links->ops = &max_98373_sdw_ops;
return 0; 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);
}
...@@ -284,6 +284,15 @@ static const struct snd_soc_acpi_link_adr rpl_sdw_rt1316_link12_rt714_link0[] = ...@@ -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 = { static const struct snd_soc_acpi_codecs rpl_rt5682_hp = {
.num_codecs = 2, .num_codecs = 2,
.codecs = {"10EC5682", "RTL5682"}, .codecs = {"10EC5682", "RTL5682"},
...@@ -348,7 +357,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { ...@@ -348,7 +357,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = {
.link_mask = 0x1, /* link0 required */ .link_mask = 0x1, /* link0 required */
.links = rpl_rvp, .links = rpl_rvp,
.drv_name = "sof_sdw", .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",
}, },
{}, {},
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment