Unverified Commit 0d587f35 authored by Mark Brown's avatar Mark Brown
Browse files

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
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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++;
	}

+119 −62
Original line number Diff line number Diff line
@@ -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,7 +732,8 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li
		int stream;
		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);
			if (codec_index < 0)
				return codec_index;
@@ -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;

		endpoint = link->adr_d->endpoints;
			endpoint = link->adr_d[i].endpoints;

			/* count DAI number for playback and capture */
			for_each_pcm_streams(stream) {
@@ -762,6 +762,7 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li
			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 */
		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,11 +1335,33 @@ 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++) {
		/*
		 * 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;

		endpoint = adr_link->adr_d->endpoints;
			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);
@@ -1322,12 +1378,13 @@ static int sof_card_dai_links_create(struct device *dev,
						 &cpu_id, group_generated,
						 codec_conf, codec_conf_count,
						 &be_id, &codec_conf_index,
					 &ignore_pch_dmic);
						 &ignore_pch_dmic, append_codec_type, i);
			if (ret < 0) {
				dev_err(dev, "failed to create dai link %d", link_index);
				return ret;
			}
		}
	}

SSP:
	/* SSP */
@@ -1490,13 +1547,13 @@ 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);

			if (ret < 0)
				return ret;
		}
	}

	if (ctx->idisp_codec)
		ret = sof_sdw_hdmi_card_late_probe(card);
+0 −3
Original line number Diff line number Diff line
@@ -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,
+11 −11
Original line number Diff line number Diff line
@@ -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);
}
+16 −1
Original line number Diff line number Diff line
@@ -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",
	},
	{},
};