mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
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
This commit is contained in:
commit
0d587f354d
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user