sound/soc/qcom/lpass-platform.c

Source file repositories/reference/linux-study-clean/sound/soc/qcom/lpass-platform.c

File Facts

System
Linux kernel
Corpus path
sound/soc/qcom/lpass-platform.c
Extension
.c
Size
41030 bytes
Lines
1397
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (ret) {
			kfree(data);
			dev_err(soc_runtime->dev, "error writing to rdmactl reg: %d\n", ret);
			return ret;
		}
		snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware);
		runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max;
		break;
	case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9:
	case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8:
		snd_soc_set_runtime_hwparams(substream, &lpass_platform_rxtx_hardware);
		runtime->dma_bytes = lpass_platform_rxtx_hardware.buffer_bytes_max;
		snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
		break;
	case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8:
		snd_soc_set_runtime_hwparams(substream, &lpass_platform_va_hardware);
		runtime->dma_bytes = lpass_platform_va_hardware.buffer_bytes_max;
		snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
		break;
	default:
		break;
	}
	ret = snd_pcm_hw_constraint_integer(runtime,
			SNDRV_PCM_HW_PARAM_PERIODS);
	if (ret < 0) {
		kfree(data);
		dev_err(soc_runtime->dev, "setting constraints failed: %d\n",
			ret);
		return -EINVAL;
	}

	return 0;
}

static int lpass_platform_pcmops_close(struct snd_soc_component *component,
				       struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *soc_runtime = snd_soc_substream_to_rtd(substream);
	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_runtime, 0);
	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
	const struct lpass_variant *v = drvdata->variant;
	struct lpass_pcm_data *data;
	unsigned int dai_id = cpu_dai->driver->id;

	data = runtime->private_data;

	switch (dai_id) {
	case MI2S_PRIMARY ... MI2S_QUINARY:
		drvdata->substream[data->dma_ch] = NULL;
		break;
	case LPASS_DP_RX:
		drvdata->hdmi_substream[data->dma_ch] = NULL;
		break;
	case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9:
	case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8:
		drvdata->rxtx_substream[data->dma_ch] = NULL;
		break;
	case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8:
		drvdata->va_substream[data->dma_ch] = NULL;
		break;
	default:
		break;
	}

	if (v->free_dma_channel)
		v->free_dma_channel(drvdata, data->dma_ch, dai_id);

	kfree(data);
	return 0;
}

static struct lpaif_dmactl *__lpass_get_dmactl_handle(const struct snd_pcm_substream *substream,
				     struct snd_soc_component *component)
{
	struct snd_soc_pcm_runtime *soc_runtime = snd_soc_substream_to_rtd(substream);
	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_runtime, 0);
	struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
	struct lpaif_dmactl *dmactl = NULL;

	switch (cpu_dai->driver->id) {
	case MI2S_PRIMARY ... MI2S_QUINARY:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			dmactl = drvdata->rd_dmactl;
		else
			dmactl = drvdata->wr_dmactl;
		break;
	case LPASS_DP_RX:
		dmactl = drvdata->hdmi_rd_dmactl;
		break;

Annotation

Implementation Notes