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

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

File Facts

System
Linux kernel
Corpus path
sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
Extension
.c
Size
94346 bytes
Lines
3006
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, "%s() error: no more asys irq\n",
				__func__);
			return -EBUSY;
		}
	}

	return 0;
}

static void mt8186_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 mt8186_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];
	int irq_id = memif->irq_usage;

	memif->substream = NULL;
	afe_priv->irq_cnt[id] = 0;
	afe_priv->xrun_assert[id] = 0;

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

static int mt8186_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);
	int id = snd_soc_rtd_to_cpu(rtd, 0)->id;
	unsigned int channels = params_channels(params);
	unsigned int rate = params_rate(params);
	int ret;

	ret = mtk_afe_fe_hw_params(substream, params, dai);
	if (ret)
		return ret;

	/* channel merge configuration, enable control is in UL5_IN_MUX */
	if (id == MT8186_MEMIF_VUL3) {
		int update_cnt = 8;
		unsigned int val = 0;
		unsigned int mask = 0;
		int fs_mode = mt8186_rate_transform(afe->dev, rate, id);

		/* set rate, channel, update cnt, disable sgen */
		val = fs_mode << CM1_FS_SELECT_SFT |
			(channels - 1) << CHANNEL_MERGE0_CHNUM_SFT |
			update_cnt << CHANNEL_MERGE0_UPDATE_CNT_SFT;
		mask = CM1_FS_SELECT_MASK_SFT |
			CHANNEL_MERGE0_CHNUM_MASK_SFT |
			CHANNEL_MERGE0_UPDATE_CNT_MASK_SFT;
		regmap_update_bits(afe->regmap, AFE_CM1_CON, mask, val);
	}

	return 0;
}

static int mt8186_fe_hw_free(struct snd_pcm_substream *substream,
			     struct snd_soc_dai *dai)
{
	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
	int ret;

	ret = mtk_afe_fe_hw_free(substream, dai);
	if (ret) {
		dev_err(afe->dev, "%s failed\n", __func__);
		return ret;
	}

	return 0;
}

static int mt8186_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);

Annotation

Implementation Notes