sound/soc/meson/axg-pdm.c

Source file repositories/reference/linux-study-clean/sound/soc/meson/axg-pdm.c

File Facts

System
Linux kernel
Corpus path
sound/soc/meson/axg-pdm.c
Extension
.c
Size
17317 bytes
Lines
642
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 axg_pdm_lpf {
	unsigned int ds;
	unsigned int round_mode;
	const unsigned int *tap;
	unsigned int tap_num;
};

struct axg_pdm_hcic {
	unsigned int shift;
	unsigned int mult;
	unsigned int steps;
	unsigned int ds;
};

struct axg_pdm_hpf {
	unsigned int out_factor;
	unsigned int steps;
};

struct axg_pdm_filters {
	struct axg_pdm_hcic hcic;
	struct axg_pdm_hpf hpf;
	struct axg_pdm_lpf lpf[PDM_LPF_NUM];
};

struct axg_pdm_cfg {
	const struct axg_pdm_filters *filters;
	unsigned int sys_rate;
};

struct axg_pdm {
	const struct axg_pdm_cfg *cfg;
	struct regmap *map;
	struct clk *dclk;
	struct clk *sysclk;
	struct clk *pclk;
};

static void axg_pdm_enable(struct regmap *map)
{
	/* Reset AFIFO */
	regmap_update_bits(map, PDM_CTRL, PDM_CTRL_RST_FIFO, PDM_CTRL_RST_FIFO);
	regmap_update_bits(map, PDM_CTRL, PDM_CTRL_RST_FIFO, 0);

	/* Enable PDM */
	regmap_update_bits(map, PDM_CTRL, PDM_CTRL_EN, PDM_CTRL_EN);
}

static void axg_pdm_disable(struct regmap *map)
{
	regmap_update_bits(map, PDM_CTRL, PDM_CTRL_EN, 0);
}

static void axg_pdm_filters_enable(struct regmap *map, bool enable)
{
	unsigned int val = enable ? PDM_FILTER_EN : 0;

	regmap_update_bits(map, PDM_HCIC_CTRL1, PDM_FILTER_EN, val);
	regmap_update_bits(map, PDM_F1_CTRL, PDM_FILTER_EN, val);
	regmap_update_bits(map, PDM_F2_CTRL, PDM_FILTER_EN, val);
	regmap_update_bits(map, PDM_F3_CTRL, PDM_FILTER_EN, val);
	regmap_update_bits(map, PDM_HPF_CTRL, PDM_FILTER_EN, val);
}

static int axg_pdm_trigger(struct snd_pcm_substream *substream, int cmd,
			   struct snd_soc_dai *dai)
{
	struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		axg_pdm_enable(priv->map);
		return 0;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		axg_pdm_disable(priv->map);
		return 0;

	default:
		return -EINVAL;
	}
}

static unsigned int axg_pdm_get_os(struct axg_pdm *priv)
{
	const struct axg_pdm_filters *filters = priv->cfg->filters;

Annotation

Implementation Notes