sound/soc/starfive/jh7110_pwmdac.c

Source file repositories/reference/linux-study-clean/sound/soc/starfive/jh7110_pwmdac.c

File Facts

System
Linux kernel
Corpus path
sound/soc/starfive/jh7110_pwmdac.c
Extension
.c
Size
13463 bytes
Lines
529
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 jh7110_pwmdac_cfg {
	enum JH7110_PWMDAC_SHIFT_VAL shift;
	enum JH7110_PWMDAC_DUTY_CYCLE_VAL duty_cycle;
	u16 cnt_n;
	enum JH7110_PWMDAC_DATA_CHANGE_VAL data_change;
	enum JH7110_PWMDAC_DATA_MODE_VAL data_mode;
	enum JH7110_PWMDAC_DATA_SHIFT_VAL data_shift;
};

struct jh7110_pwmdac_dev {
	void __iomem *base;
	resource_size_t	mapbase;
	struct jh7110_pwmdac_cfg cfg;

	struct clk_bulk_data clks[2];
	struct reset_control *rst_apb;
	struct device *dev;
	struct snd_dmaengine_dai_dma_data play_dma_data;
	u32 saved_ctrl;
};

static inline void jh7110_pwmdac_write_reg(void __iomem *io_base, int reg, u32 val)
{
	writel(val, io_base + reg);
}

static inline u32 jh7110_pwmdac_read_reg(void __iomem *io_base, int reg)
{
	return readl(io_base + reg);
}

static void jh7110_pwmdac_set_enable(struct jh7110_pwmdac_dev *dev, bool enable)
{
	u32 value;

	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
	if (enable)
		value |= JH7110_PWMDAC_ENABLE;
	else
		value &= ~JH7110_PWMDAC_ENABLE;

	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
}

static void jh7110_pwmdac_set_shift(struct jh7110_pwmdac_dev *dev)
{
	u32 value;

	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
	if (dev->cfg.shift == PWMDAC_SHIFT_8)
		value &= ~JH7110_PWMDAC_SHIFT;
	else if (dev->cfg.shift == PWMDAC_SHIFT_10)
		value |= JH7110_PWMDAC_SHIFT;

	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
}

static void jh7110_pwmdac_set_duty_cycle(struct jh7110_pwmdac_dev *dev)
{
	u32 value;

	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
	value &= ~JH7110_PWMDAC_DUTY_CYCLE_MASK;
	value |= (dev->cfg.duty_cycle & 0x3) << JH7110_PWMDAC_DUTY_CYCLE_SHIFT;

	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
}

static void jh7110_pwmdac_set_cnt_n(struct jh7110_pwmdac_dev *dev)
{
	u32 value;

	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
	value &= ~JH7110_PWMDAC_CNT_N_MASK;
	value |= ((dev->cfg.cnt_n - 1) & 0x1ff) << JH7110_PWMDAC_CNT_N_SHIFT;

	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
}

static void jh7110_pwmdac_set_data_change(struct jh7110_pwmdac_dev *dev)
{
	u32 value;

	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
	if (dev->cfg.data_change == NO_CHANGE)
		value &= ~JH7110_PWMDAC_DATA_CHANGE;
	else if (dev->cfg.data_change == CHANGE)
		value |= JH7110_PWMDAC_DATA_CHANGE;

	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);

Annotation

Implementation Notes