sound/soc/sprd/sprd-mcdt.c

Source file repositories/reference/linux-study-clean/sound/soc/sprd/sprd-mcdt.c

File Facts

System
Linux kernel
Corpus path
sound/soc/sprd/sprd-mcdt.c
Extension
.c
Size
23003 bytes
Lines
973
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

struct sprd_mcdt_dev {
	struct device *dev;
	void __iomem *base;
	spinlock_t lock;
	struct sprd_mcdt_chan chan[MCDT_CHANNEL_NUM];
};

static LIST_HEAD(sprd_mcdt_chan_list);
static DEFINE_MUTEX(sprd_mcdt_list_mutex);

static void sprd_mcdt_update(struct sprd_mcdt_dev *mcdt, u32 reg, u32 val,
			     u32 mask)
{
	u32 orig = readl_relaxed(mcdt->base + reg);
	u32 tmp;

	tmp = (orig & ~mask) | val;
	writel_relaxed(tmp, mcdt->base + reg);
}

static void sprd_mcdt_dac_set_watermark(struct sprd_mcdt_dev *mcdt, u8 channel,
					u32 full, u32 empty)
{
	u32 reg = MCDT_DAC0_WTMK + channel * 4;
	u32 water_mark =
		(empty << MCDT_CH_FIFO_AE_SHIFT) & MCDT_CH_FIFO_AE_MASK;

	water_mark |= full & MCDT_CH_FIFO_AF_MASK;
	sprd_mcdt_update(mcdt, reg, water_mark,
			 MCDT_CH_FIFO_AE_MASK | MCDT_CH_FIFO_AF_MASK);
}

static void sprd_mcdt_adc_set_watermark(struct sprd_mcdt_dev *mcdt, u8 channel,
					u32 full, u32 empty)
{
	u32 reg = MCDT_ADC0_WTMK + channel * 4;
	u32 water_mark =
		(empty << MCDT_CH_FIFO_AE_SHIFT) & MCDT_CH_FIFO_AE_MASK;

	water_mark |= full & MCDT_CH_FIFO_AF_MASK;
	sprd_mcdt_update(mcdt, reg, water_mark,
			 MCDT_CH_FIFO_AE_MASK | MCDT_CH_FIFO_AF_MASK);
}

static void sprd_mcdt_dac_dma_enable(struct sprd_mcdt_dev *mcdt, u8 channel,
				     bool enable)
{
	u32 shift = MCDT_DAC_DMA_SHIFT + channel;

	if (enable)
		sprd_mcdt_update(mcdt, MCDT_DMA_EN, BIT(shift), BIT(shift));
	else
		sprd_mcdt_update(mcdt, MCDT_DMA_EN, 0, BIT(shift));
}

static void sprd_mcdt_adc_dma_enable(struct sprd_mcdt_dev *mcdt, u8 channel,
				     bool enable)
{
	if (enable)
		sprd_mcdt_update(mcdt, MCDT_DMA_EN, BIT(channel), BIT(channel));
	else
		sprd_mcdt_update(mcdt, MCDT_DMA_EN, 0, BIT(channel));
}

static void sprd_mcdt_ap_int_enable(struct sprd_mcdt_dev *mcdt, u8 channel,
				    bool enable)
{
	if (enable)
		sprd_mcdt_update(mcdt, MCDT_INT_MSK_CFG0, BIT(channel),
				 BIT(channel));
	else
		sprd_mcdt_update(mcdt, MCDT_INT_MSK_CFG0, 0, BIT(channel));
}

static void sprd_mcdt_dac_write_fifo(struct sprd_mcdt_dev *mcdt, u8 channel,
				     u32 val)
{
	u32 reg = MCDT_CH0_TXD + channel * 4;

	writel_relaxed(val, mcdt->base + reg);
}

static void sprd_mcdt_adc_read_fifo(struct sprd_mcdt_dev *mcdt, u8 channel,
				    u32 *val)
{
	u32 reg = MCDT_CH0_RXD + channel * 4;

	*val = readl_relaxed(mcdt->base + reg);
}

Annotation

Implementation Notes