sound/soc/rockchip/rockchip_pdm.c

Source file repositories/reference/linux-study-clean/sound/soc/rockchip/rockchip_pdm.c

File Facts

System
Linux kernel
Corpus path
sound/soc/rockchip/rockchip_pdm.c
Extension
.c
Size
16067 bytes
Lines
721
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 rk_pdm_dev {
	struct device *dev;
	struct clk *clk;
	struct clk *hclk;
	struct regmap *regmap;
	struct snd_dmaengine_dai_dma_data capture_dma_data;
	struct reset_control *reset;
	enum rk_pdm_version version;
};

struct rk_pdm_clkref {
	unsigned int sr;
	unsigned int clk;
	unsigned int clk_out;
};

struct rk_pdm_ds_ratio {
	unsigned int ratio;
	unsigned int sr;
};

static struct rk_pdm_clkref clkref[] = {
	{ 8000, 40960000, 2048000 },
	{ 11025, 56448000, 2822400 },
	{ 12000, 61440000, 3072000 },
	{ 8000, 98304000, 2048000 },
	{ 12000, 98304000, 3072000 },
};

static struct rk_pdm_ds_ratio ds_ratio[] = {
	{ 0, 192000 },
	{ 0, 176400 },
	{ 0, 128000 },
	{ 1, 96000 },
	{ 1, 88200 },
	{ 1, 64000 },
	{ 2, 48000 },
	{ 2, 44100 },
	{ 2, 32000 },
	{ 3, 24000 },
	{ 3, 22050 },
	{ 3, 16000 },
	{ 4, 12000 },
	{ 4, 11025 },
	{ 4, 8000 },
};

static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr,
				unsigned int *clk_src, unsigned int *clk_out)
{
	unsigned int i, count, clk, div, rate;

	clk = 0;
	if (!sr)
		return clk;

	count = ARRAY_SIZE(clkref);
	for (i = 0; i < count; i++) {
		if (sr % clkref[i].sr)
			continue;
		div = sr / clkref[i].sr;
		if ((div & (div - 1)) == 0) {
			*clk_out = clkref[i].clk_out;
			rate = clk_round_rate(pdm->clk, clkref[i].clk);
			if (rate != clkref[i].clk)
				continue;
			clk = clkref[i].clk;
			*clk_src = clkref[i].clk;
			break;
		}
	}

	if (!clk) {
		clk = clk_round_rate(pdm->clk, PDM_SIGNOFF_CLK_RATE);
		*clk_src = clk;
	}
	return clk;
}

static unsigned int get_pdm_ds_ratio(unsigned int sr)
{
	unsigned int i, count, ratio;

	ratio = 0;
	if (!sr)
		return ratio;

	count = ARRAY_SIZE(ds_ratio);
	for (i = 0; i < count; i++) {
		if (sr == ds_ratio[i].sr)

Annotation

Implementation Notes