sound/soc/ti/omap-dmic.c

Source file repositories/reference/linux-study-clean/sound/soc/ti/omap-dmic.c

File Facts

System
Linux kernel
Corpus path
sound/soc/ti/omap-dmic.c
Extension
.c
Size
12069 bytes
Lines
520
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 omap_dmic {
	struct device *dev;
	void __iomem *io_base;
	struct clk *fclk;
	struct pm_qos_request pm_qos_req;
	int latency;
	int fclk_freq;
	int out_freq;
	int clk_div;
	int sysclk;
	int threshold;
	u32 ch_enabled;
	bool active;
	struct mutex mutex;

	struct snd_dmaengine_dai_dma_data dma_data;
};

static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
{
	writel_relaxed(val, dmic->io_base + reg);
}

static inline int omap_dmic_read(struct omap_dmic *dmic, u16 reg)
{
	return readl_relaxed(dmic->io_base + reg);
}

static inline void omap_dmic_start(struct omap_dmic *dmic)
{
	u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);

	/* Configure DMA controller */
	omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_SET_REG,
			OMAP_DMIC_DMA_ENABLE);

	omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, ctrl | dmic->ch_enabled);
}

static inline void omap_dmic_stop(struct omap_dmic *dmic)
{
	u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
	omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG,
			ctrl & ~OMAP_DMIC_UP_ENABLE_MASK);

	/* Disable DMA request generation */
	omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_CLR_REG,
			OMAP_DMIC_DMA_ENABLE);

}

static inline int dmic_is_enabled(struct omap_dmic *dmic)
{
	return omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG) &
						OMAP_DMIC_UP_ENABLE_MASK;
}

static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
				  struct snd_soc_dai *dai)
{
	struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);

	guard(mutex)(&dmic->mutex);

	if (snd_soc_dai_active(dai))
		return -EBUSY;

	dmic->active = 1;
	return 0;
}

static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,
				    struct snd_soc_dai *dai)
{
	struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);

	guard(mutex)(&dmic->mutex);

	cpu_latency_qos_remove_request(&dmic->pm_qos_req);

	if (!snd_soc_dai_active(dai))
		dmic->active = 0;
}

static int omap_dmic_select_divider(struct omap_dmic *dmic, int sample_rate)
{
	int divider = -EINVAL;

	/*
	 * 192KHz rate is only supported with 19.2MHz/3.84MHz clock

Annotation

Implementation Notes