sound/soc/sophgo/cv1800b-tdm.c

Source file repositories/reference/linux-study-clean/sound/soc/sophgo/cv1800b-tdm.c

File Facts

System
Linux kernel
Corpus path
sound/soc/sophgo/cv1800b-tdm.c
Extension
.c
Size
20088 bytes
Lines
717
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

struct cv1800b_i2s {
	void __iomem *base;
	struct clk *clk;
	struct clk *sysclk;
	struct device *dev;
	struct snd_dmaengine_dai_dma_data playback_dma;
	struct snd_dmaengine_dai_dma_data capture_dma;
	u32 mclk_rate;
	bool bclk_ratio_fixed;
	u32 bclk_ratio;

};

static void cv1800b_setup_dma_struct(struct cv1800b_i2s *i2s,
				     phys_addr_t phys_base)
{
	i2s->playback_dma.addr = phys_base + CV1800B_TX_WR_PORT;
	i2s->playback_dma.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	i2s->playback_dma.fifo_size = TX_FIFO_SIZE;
	i2s->playback_dma.maxburst = TX_MAX_BURST;

	i2s->capture_dma.addr = phys_base + CV1800B_RX_RD_PORT;
	i2s->capture_dma.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	i2s->capture_dma.fifo_size = RX_FIFO_SIZE;
	i2s->capture_dma.maxburst = RX_MAX_BURST;
}

static const struct snd_dmaengine_pcm_config cv1800b_i2s_pcm_config = {
	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
};

static void cv1800b_reset_fifo(struct cv1800b_i2s *i2s)
{
	u32 val;

	val = readl(i2s->base + CV1800B_FIFO_RESET);
	val = u32_replace_bits(val, 1, FIFO_RX_RESET_MASK);
	val = u32_replace_bits(val, 1, FIFO_TX_RESET_MASK);
	writel(val, i2s->base + CV1800B_FIFO_RESET);

	usleep_range(10, 20);

	val = readl(i2s->base + CV1800B_FIFO_RESET);
	val = u32_replace_bits(val, 0, FIFO_RX_RESET_MASK);
	val = u32_replace_bits(val, 0, FIFO_TX_RESET_MASK);
	writel(val, i2s->base + CV1800B_FIFO_RESET);
}

static void cv1800b_reset_i2s(struct cv1800b_i2s *i2s)
{
	u32 val;

	val = readl(i2s->base + CV1800B_I2S_RESET);
	val = u32_replace_bits(val, 1, RST_I2S_RESET_RX_MASK);
	val = u32_replace_bits(val, 1, RST_I2S_RESET_TX_MASK);
	writel(val, i2s->base + CV1800B_I2S_RESET);

	usleep_range(10, 20);

	val = readl(i2s->base + CV1800B_I2S_RESET);
	val = u32_replace_bits(val, 0, RST_I2S_RESET_RX_MASK);
	val = u32_replace_bits(val, 0, RST_I2S_RESET_TX_MASK);
	writel(val, i2s->base + CV1800B_I2S_RESET);
}

static void cv1800b_set_mclk_div(struct cv1800b_i2s *i2s, u32 mclk_div)
{
	u32 val;

	val = readl(i2s->base + CV1800B_CLK_CTRL1);
	val = u32_replace_bits(val, mclk_div, CLK_MCLK_DIV_MASK);
	writel(val, i2s->base + CV1800B_CLK_CTRL1);
	dev_dbg(i2s->dev, "mclk_div is set to %u\n", mclk_div);
}

static void cv1800b_set_tx_mode(struct cv1800b_i2s *i2s, bool is_tx)
{
	u32 val;

	val = readl(i2s->base + CV1800B_BLK_MODE_SETTING);
	val = u32_replace_bits(val, is_tx, BLK_TX_MODE_MASK);
	writel(val, i2s->base + CV1800B_BLK_MODE_SETTING);
	dev_dbg(i2s->dev, "tx_mode is set to %u\n", is_tx);
}

static int cv1800b_set_bclk_div(struct cv1800b_i2s *i2s, u32 bclk_div)
{
	u32 val;

	if (bclk_div == 0 || bclk_div > 0xFFFF)

Annotation

Implementation Notes