sound/soc/sunxi/sun4i-i2s.c

Source file repositories/reference/linux-study-clean/sound/soc/sunxi/sun4i-i2s.c

File Facts

System
Linux kernel
Corpus path
sound/soc/sunxi/sun4i-i2s.c
Extension
.c
Size
46896 bytes
Lines
1700
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 sun4i_i2s_quirks {
	bool				has_reset;
	u64				pcm_formats;
	unsigned int			reg_offset_txdata;	/* TX FIFO */
	const struct regmap_config	*sun4i_i2s_regmap;

	/* Register fields for i2s */
	struct reg_field		field_clkdiv_mclk_en;
	struct reg_field		field_fmt_wss;
	struct reg_field		field_fmt_sr;

	unsigned int			num_din_pins;
	unsigned int			num_dout_pins;

	const struct sun4i_i2s_clk_div	*bclk_dividers;
	unsigned int			num_bclk_dividers;
	const struct sun4i_i2s_clk_div	*mclk_dividers;
	unsigned int			num_mclk_dividers;

	unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *i2s);
	int	(*get_sr)(unsigned int width);
	int	(*get_wss)(unsigned int width);

	/*
	 * In the set_chan_cfg() function pointer:
	 * @slots: channels per frame + padding slots, regardless of format
	 * @slot_width: bits per sample + padding bits, regardless of format
	 */
	int	(*set_chan_cfg)(const struct sun4i_i2s *i2s,
				unsigned int channels,	unsigned int slots,
				unsigned int slot_width);
	int	(*set_fmt)(const struct sun4i_i2s *i2s, unsigned int fmt);
};

struct sun4i_i2s {
	struct clk	*bus_clk;
	struct clk	*mod_clk;
	struct regmap	*regmap;
	struct reset_control *rst;

	unsigned int	format;
	unsigned int	mclk_freq;
	unsigned int	slots;
	unsigned int	slot_width;

	struct snd_dmaengine_dai_dma_data	capture_dma_data;
	struct snd_dmaengine_dai_dma_data	playback_dma_data;

	/* Register fields for i2s */
	struct regmap_field	*field_clkdiv_mclk_en;
	struct regmap_field	*field_fmt_wss;
	struct regmap_field	*field_fmt_sr;

	const struct sun4i_i2s_quirks	*variant;
};

struct sun4i_i2s_clk_div {
	u8	div;
	u8	val;
};

static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
	{ .div = 2, .val = 0 },
	{ .div = 4, .val = 1 },
	{ .div = 6, .val = 2 },
	{ .div = 8, .val = 3 },
	{ .div = 12, .val = 4 },
	{ .div = 16, .val = 5 },
	/* TODO - extend divide ratio supported by newer SoCs */
};

static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
	{ .div = 1, .val = 0 },
	{ .div = 2, .val = 1 },
	{ .div = 4, .val = 2 },
	{ .div = 6, .val = 3 },
	{ .div = 8, .val = 4 },
	{ .div = 12, .val = 5 },
	{ .div = 16, .val = 6 },
	{ .div = 24, .val = 7 },
	/* TODO - extend divide ratio supported by newer SoCs */
};

static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
	{ .div = 1, .val = 1 },
	{ .div = 2, .val = 2 },
	{ .div = 4, .val = 3 },
	{ .div = 6, .val = 4 },
	{ .div = 8, .val = 5 },
	{ .div = 12, .val = 6 },

Annotation

Implementation Notes