sound/soc/mediatek/mt8196/mt8196-afe-pcm.c

Source file repositories/reference/linux-study-clean/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c

File Facts

System
Linux kernel
Corpus path
sound/soc/mediatek/mt8196/mt8196-afe-pcm.c
Extension
.c
Size
89868 bytes
Lines
2520
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 (irq_id != afe->irqs_size) {
			/* link */
			memif->irq_usage = irq_id;
		} else {
			dev_err(afe->dev, "no more asys irq\n");
			ret = -EBUSY;
		}
	}
	return ret;
}

static void mt8196_fe_shutdown(struct snd_pcm_substream *substream,
			       struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
	int memif_num = cpu_dai->id;
	struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
	int irq_id = memif->irq_usage;

	dev_dbg(afe->dev, "memif_num: %d.\n", memif_num);

	memif->substream = NULL;

	if (!memif->const_irq) {
		mtk_dynamic_irq_release(afe, irq_id);
		memif->irq_usage = -1;
		memif->substream = NULL;
	}
}

static int mt8196_fe_hw_params(struct snd_pcm_substream *substream,
			       struct snd_pcm_hw_params *params,
			       struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
	unsigned int channels = params_channels(params);
	struct mt8196_afe_private *afe_priv = afe->platform_priv;
	int id = snd_soc_rtd_to_cpu(rtd, 0)->id;
	struct mtk_base_afe_memif *memif = &afe->memif[id];
	const struct mtk_base_memif_data *data = memif->data;
	int cm;

	afe_priv->cm_channels = channels;

	/* set channels */
	if (data->ch_num_shift >= 0) {
		regmap_update_bits(afe->regmap, data->ch_num_reg,
				   data->ch_num_maskbit << data->ch_num_shift,
				   channels << data->ch_num_shift);
	}

	switch (id) {
	case MT8196_MEMIF_VUL8:
	case MT8196_MEMIF_VUL_CM0:
		cm = CM0;
		break;
	case MT8196_MEMIF_VUL9:
	case MT8196_MEMIF_VUL_CM1:
		cm = CM1;
		break;
	case MT8196_MEMIF_VUL10:
	case MT8196_MEMIF_VUL_CM2:
		cm = CM2;
		break;
	default:
		cm = CM0;
		break;
	}

	afe_priv->cm_rate[cm] = params_rate(params);

	return mtk_afe_fe_hw_params(substream, params, dai);
}

static int mt8196_fe_trigger(struct snd_pcm_substream *substream, int cmd,
			     struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct snd_pcm_runtime *const runtime = substream->runtime;
	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
	int id = snd_soc_rtd_to_cpu(rtd, 0)->id;
	struct mtk_base_afe_memif *memif = &afe->memif[id];
	int irq_id = memif->irq_usage;
	struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id];
	const struct mtk_base_irq_data *irq_data = irqs->irq_data;
	unsigned int counter = runtime->period_size;
	unsigned int rate = runtime->rate;

Annotation

Implementation Notes