sound/soc/intel/boards/sof_sdw.c

Source file repositories/reference/linux-study-clean/sound/soc/intel/boards/sof_sdw.c

File Facts

System
Linux kernel
Corpus path
sound/soc/intel/boards/sof_sdw.c
Extension
.c
Size
41015 bytes
Lines
1566
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (sof_end->name_prefix) {
			(*codec_conf)->dlc.name = sof_end->codec_name;
			(*codec_conf)->name_prefix = sof_end->name_prefix;
			(*codec_conf)++;
		}

		if (sof_end->include_sidecar && sof_end->codec_info->add_sidecar) {
			ret = sof_end->codec_info->add_sidecar(card, dai_links, codec_conf);
			if (ret)
				return ret;
		}
	}

	/*
	 * The dai_type is used to select function topologies. Since the topology stream name
	 * and DAI link name use partial matching, unconditionally appending the dai_type provides
	 * necessary selection metadata without breaking existing topologies. Although
	 * ctx->append_dai_type is not checked here, we overwrite it to ensure consistency in case
	 * it is referenced elsewhere.
	 */
	ctx->append_dai_type = true;
	for_each_pcm_streams(stream) {
		static const char * const sdw_stream_name[] = {
			"SDW%d-Playback-%s",
			"SDW%d-Capture-%s",
		};
		struct snd_soc_dai_link_ch_map *codec_maps;
		struct snd_soc_dai_link_component *codecs;
		struct snd_soc_dai_link_component *cpus;
		struct snd_soc_dai_link_component *platform;
		int num_cpus = hweight32(sof_dai->link_mask[stream]);
		int num_codecs = sof_dai->num_devs[stream];
		int playback, capture;
		int cur_link = 0;
		int i = 0, j = 0;
		char *name;

		if (!sof_dai->num_devs[stream])
			continue;

		sof_end = list_first_entry(&sof_dai->endpoints,
					   struct asoc_sdw_endpoint, list);

		*be_id = sof_end->dai_info->dailink[stream];
		if (*be_id < 0) {
			dev_err(dev, "Invalid dailink id %d\n", *be_id);
			return -EINVAL;
		}

		/* create stream name according to first link id */
		name = devm_kasprintf(dev, GFP_KERNEL,
				      sdw_stream_name[stream],
				      ffs(sof_end->link_mask) - 1,
				      type_strings[sof_end->dai_info->dai_type]);
		if (!name)
			return -ENOMEM;

		cpus = devm_kcalloc(dev, num_cpus, sizeof(*cpus), GFP_KERNEL);
		if (!cpus)
			return -ENOMEM;

		codecs = devm_kcalloc(dev, num_codecs, sizeof(*codecs), GFP_KERNEL);
		if (!codecs)
			return -ENOMEM;

		platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL);
		if (!platform)
			return -ENOMEM;

		codec_maps = devm_kcalloc(dev, num_codecs, sizeof(*codec_maps), GFP_KERNEL);
		if (!codec_maps)
			return -ENOMEM;

		list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
			if (!sof_end->dai_info->direction[stream])
				continue;

			if (cur_link != sof_end->link_mask) {
				int link_num = ffs(sof_end->link_mask) - 1;
				int pin_num = intel_ctx->sdw_pin_index[link_num]++;

				cur_link = sof_end->link_mask;

				cpus[i].dai_name = devm_kasprintf(dev, GFP_KERNEL,
								  "SDW%d Pin%d",
								  link_num, pin_num);
				if (!cpus[i].dai_name)
					return -ENOMEM;
				i++;
			}

Annotation

Implementation Notes