sound/soc/amd/raven/acp3x-i2s.c

Source file repositories/reference/linux-study-clean/sound/soc/amd/raven/acp3x-i2s.c

File Facts

System
Linux kernel
Corpus path
sound/soc/amd/raven/acp3x-i2s.c
Extension
.c
Size
8332 bytes
Lines
332
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

switch (rtd->i2s_instance) {
		case I2S_BT_INSTANCE:
			reg_val = mmACP_BTTDM_ITER;
			frmt_reg = mmACP_BTTDM_TXFRMT;
			break;
		case I2S_SP_INSTANCE:
		default:
			reg_val = mmACP_I2STDM_ITER;
			frmt_reg = mmACP_I2STDM_TXFRMT;
		}
	} else {
		switch (rtd->i2s_instance) {
		case I2S_BT_INSTANCE:
			reg_val = mmACP_BTTDM_IRER;
			frmt_reg = mmACP_BTTDM_RXFRMT;
			break;
		case I2S_SP_INSTANCE:
		default:
			reg_val = mmACP_I2STDM_IRER;
			frmt_reg = mmACP_I2STDM_RXFRMT;
		}
	}
	if (adata->tdm_mode) {
		val = rv_readl(rtd->acp3x_base + reg_val);
		rv_writel(val | 0x2, rtd->acp3x_base + reg_val);
		rv_writel(adata->tdm_fmt, rtd->acp3x_base + frmt_reg);
	}
	val = rv_readl(rtd->acp3x_base + reg_val);
	val &= ~ACP3x_ITER_IRER_SAMP_LEN_MASK;
	val = val | (rtd->xfer_resolution  << 3);
	rv_writel(val, rtd->acp3x_base + reg_val);
	return 0;
}

static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
				int cmd, struct snd_soc_dai *dai)
{
	struct i2s_stream_instance *rtd;
	u32 val, period_bytes, reg_val, ier_val, water_val;
	u32 buf_size, buf_reg;
	int ret;

	rtd = substream->runtime->private_data;
	period_bytes = frames_to_bytes(substream->runtime,
			substream->runtime->period_size);
	buf_size = frames_to_bytes(substream->runtime,
			substream->runtime->buffer_size);
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		rtd->bytescount = acp_get_byte_count(rtd,
						substream->stream);
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			switch (rtd->i2s_instance) {
			case I2S_BT_INSTANCE:
				water_val =
					mmACP_BT_TX_INTR_WATERMARK_SIZE;
				reg_val = mmACP_BTTDM_ITER;
				ier_val = mmACP_BTTDM_IER;
				buf_reg = mmACP_BT_TX_RINGBUFSIZE;
				break;
			case I2S_SP_INSTANCE:
			default:
				water_val =
					mmACP_I2S_TX_INTR_WATERMARK_SIZE;
				reg_val = mmACP_I2STDM_ITER;
				ier_val = mmACP_I2STDM_IER;
				buf_reg = mmACP_I2S_TX_RINGBUFSIZE;
			}
		} else {
			switch (rtd->i2s_instance) {
			case I2S_BT_INSTANCE:
				water_val =
					mmACP_BT_RX_INTR_WATERMARK_SIZE;
				reg_val = mmACP_BTTDM_IRER;
				ier_val = mmACP_BTTDM_IER;
				buf_reg = mmACP_BT_RX_RINGBUFSIZE;
				break;
			case I2S_SP_INSTANCE:
			default:
				water_val =
					mmACP_I2S_RX_INTR_WATERMARK_SIZE;
				reg_val = mmACP_I2STDM_IRER;
				ier_val = mmACP_I2STDM_IER;
				buf_reg = mmACP_I2S_RX_RINGBUFSIZE;
			}
		}
		rv_writel(period_bytes, rtd->acp3x_base + water_val);
		rv_writel(buf_size, rtd->acp3x_base + buf_reg);

Annotation

Implementation Notes