sound/soc/intel/avs/probes.c

Source file repositories/reference/linux-study-clean/sound/soc/intel/avs/probes.c

File Facts

System
Linux kernel
Corpus path
sound/soc/intel/avs/probes.c
Extension
.c
Size
8788 bytes
Lines
315
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 (!adev->num_probe_streams) {
			avs_dsp_delete_probe(adev);
			avs_dsp_enable_d0ix(adev);
		}
	}

	snd_hdac_stream_cleanup(hdac_stream(host_stream));
	hdac_stream(host_stream)->prepared = 0;
	snd_hdac_ext_stream_release(host_stream, HDAC_EXT_STREAM_TYPE_HOST);

	snd_compr_free_pages(cstream);
	adev->extractor = NULL;

	return ret;
}

static int avs_probe_compr_set_params(struct snd_compr_stream *cstream,
				      struct snd_compr_params *params, struct snd_soc_dai *dai)
{
	struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream);
	struct snd_compr_runtime *rtd = cstream->runtime;
	struct avs_dev *adev = to_avs_dev(dai->dev);
	unsigned int format_val;
	int bps, ret;

	hdac_stream(host_stream)->bufsize = 0;
	hdac_stream(host_stream)->period_bytes = 0;
	hdac_stream(host_stream)->format_val = 0;
	cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG;
	cstream->dma_buffer.dev.dev = adev->dev;

	ret = snd_compr_malloc_pages(cstream, rtd->buffer_size);
	if (ret < 0)
		return ret;
	bps = snd_pcm_format_physical_width((__force snd_pcm_format_t)params->codec.format);
	if (bps < 0)
		return bps;
	format_val = snd_hdac_stream_format(params->codec.ch_out, bps, params->codec.sample_rate);
	ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
	if (ret < 0)
		return ret;
	ret = snd_hdac_stream_setup(hdac_stream(host_stream), false);
	if (ret < 0)
		return ret;

	hdac_stream(host_stream)->prepared = 1;

	if (!adev->num_probe_streams) {
		union avs_connector_node_id node_id;

		/* D0ix not allowed during probing. */
		ret = avs_dsp_disable_d0ix(adev);
		if (ret)
			return ret;

		node_id.vindex = hdac_stream(host_stream)->stream_tag - 1;
		node_id.dma_type = AVS_DMA_HDA_HOST_INPUT;

		ret = avs_dsp_init_probe(adev, params, bps, node_id, rtd->dma_bytes);
		if (ret < 0) {
			dev_err(dai->dev, "probe init failed: %d\n", ret);
			avs_dsp_enable_d0ix(adev);
			return ret;
		}
	}

	adev->num_probe_streams++;
	return 0;
}

static int avs_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd,
				   struct snd_soc_dai *dai)
{
	struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream);
	struct avs_dev *adev = to_avs_dev(dai->dev);
	struct hdac_bus *bus = &adev->base.core;
	unsigned long cookie;

	if (!hdac_stream(host_stream)->prepared)
		return -EPIPE;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
	case SNDRV_PCM_TRIGGER_RESUME:
		spin_lock_irqsave(&bus->reg_lock, cookie);
		snd_hdac_stream_start(hdac_stream(host_stream));
		spin_unlock_irqrestore(&bus->reg_lock, cookie);
		break;

Annotation

Implementation Notes