sound/soc/fsl/fsl_esai.c

Source file repositories/reference/linux-study-clean/sound/soc/fsl/fsl_esai.c

File Facts

System
Linux kernel
Corpus path
sound/soc/fsl/fsl_esai.c
Extension
.c
Size
33500 bytes
Lines
1212
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 fsl_esai_soc_data {
	bool reset_at_xrun;
};

/**
 * struct fsl_esai - ESAI private data
 * @dma_params_rx: DMA parameters for receive channel
 * @dma_params_tx: DMA parameters for transmit channel
 * @pdev: platform device pointer
 * @regmap: regmap handler
 * @coreclk: clock source to access register
 * @extalclk: esai clock source to derive HCK, SCK and FS
 * @fsysclk: system clock source to derive HCK, SCK and FS
 * @spbaclk: SPBA clock (optional, depending on SoC design)
 * @work: work to handle the reset operation
 * @soc: soc specific data
 * @lock: spin lock between hw_reset() and trigger()
 * @fifo_depth: depth of tx/rx FIFO
 * @slot_width: width of each DAI slot
 * @slots: number of slots
 * @tx_mask: slot mask for TX
 * @rx_mask: slot mask for RX
 * @channels: channel num for tx or rx
 * @hck_rate: clock rate of desired HCKx clock
 * @sck_rate: clock rate of desired SCKx clock
 * @hck_dir: the direction of HCKx pads
 * @sck_div: if using PSR/PM dividers for SCKx clock
 * @consumer_mode: if fully using DAI clock consumer mode
 * @synchronous: if using tx/rx synchronous mode
 * @name: driver name
 */
struct fsl_esai {
	struct snd_dmaengine_dai_dma_data dma_params_rx;
	struct snd_dmaengine_dai_dma_data dma_params_tx;
	struct platform_device *pdev;
	struct regmap *regmap;
	struct clk *coreclk;
	struct clk *extalclk;
	struct clk *fsysclk;
	struct clk *spbaclk;
	struct work_struct work;
	const struct fsl_esai_soc_data *soc;
	spinlock_t lock; /* Protect hw_reset and trigger */
	u32 fifo_depth;
	u32 slot_width;
	u32 slots;
	u32 tx_mask;
	u32 rx_mask;
	u32 channels[2];
	u32 hck_rate[2];
	u32 sck_rate[2];
	bool hck_dir[2];
	bool sck_div[2];
	bool consumer_mode;
	bool synchronous;
	char name[32];
};

static struct fsl_esai_soc_data fsl_esai_vf610 = {
	.reset_at_xrun = true,
};

static struct fsl_esai_soc_data fsl_esai_imx35 = {
	.reset_at_xrun = true,
};

static struct fsl_esai_soc_data fsl_esai_imx6ull = {
	.reset_at_xrun = false,
};

static irqreturn_t esai_isr(int irq, void *devid)
{
	struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
	struct platform_device *pdev = esai_priv->pdev;
	u32 esr;
	u32 saisr;

	regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
	regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);

	if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) &&
	    esai_priv->soc->reset_at_xrun) {
		dev_dbg(&pdev->dev, "reset module for xrun\n");
		regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
				   ESAI_xCR_xEIE_MASK, 0);
		regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
				   ESAI_xCR_xEIE_MASK, 0);
		schedule_work(&esai_priv->work);
	}

Annotation

Implementation Notes