sound/soc/dwc/dwc-i2s.c
Source file repositories/reference/linux-study-clean/sound/soc/dwc/dwc-i2s.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/dwc/dwc-i2s.c- Extension
.c- Size
- 27522 bytes
- Lines
- 1102
- 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.
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/device.hlinux/init.hlinux/io.hlinux/interrupt.hlinux/mfd/syscon.hlinux/module.hlinux/reset.hlinux/slab.hlinux/pm_runtime.hsound/designware_i2s.hsound/pcm.hsound/pcm_params.hsound/soc.hsound/dmaengine_pcm.hlocal.h
Detected Declarations
function Copyrightfunction i2s_read_regfunction i2s_disable_channelsfunction i2s_clear_irqsfunction i2s_disable_irqsfunction i2s_enable_irqsfunction i2s_irq_handlerfunction i2s_enable_dmafunction i2s_disable_dmafunction i2s_startfunction i2s_stopfunction dw_i2s_startupfunction dw_i2s_configfunction dw_i2s_hw_paramsfunction dw_i2s_preparefunction dw_i2s_triggerfunction dw_i2s_set_fmtfunction dw_i2s_set_tdm_slotfunction dw_i2s_dai_probefunction dw_i2s_runtime_suspendfunction dw_i2s_runtime_resumefunction dw_i2s_suspendfunction dw_i2s_resumefunction for_each_component_daisfunction dw_configure_daifunction dw_configure_dai_by_pdfunction dw_configure_dai_by_dtfunction jh7110_i2s_crg_master_initfunction jh7110_i2s_crg_slave_initfunction jh7110_i2srx_crg_initfunction jh7110_i2stx0_clk_cfgfunction dw_i2s_probefunction dw_i2s_remove
Annotated Snippet
if ((isr[i] & ISR_TXFE) && (i == 0) && dev->use_pio) {
dw_pcm_push_tx(dev);
irq_valid = true;
}
/*
* Data available. Retrieve samples from FIFO
* NOTE: Only two channels supported
*/
if ((isr[i] & ISR_RXDA) && (i == 0) && dev->use_pio) {
dw_pcm_pop_rx(dev);
irq_valid = true;
}
/* Error Handling: TX */
if (isr[i] & ISR_TXFO) {
dev_err_ratelimited(dev->dev, "TX overrun (ch_id=%d)\n", i);
irq_valid = true;
}
/* Error Handling: TX */
if (isr[i] & ISR_RXFO) {
dev_err_ratelimited(dev->dev, "RX overrun (ch_id=%d)\n", i);
irq_valid = true;
}
}
if (irq_valid)
return IRQ_HANDLED;
else
return IRQ_NONE;
}
static void i2s_enable_dma(struct dw_i2s_dev *dev, u32 stream)
{
u32 dma_reg = i2s_read_reg(dev->i2s_base, I2S_DMACR);
/* Enable DMA handshake for stream */
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
dma_reg |= I2S_DMAEN_TXBLOCK;
else
dma_reg |= I2S_DMAEN_RXBLOCK;
i2s_write_reg(dev->i2s_base, I2S_DMACR, dma_reg);
}
static void i2s_disable_dma(struct dw_i2s_dev *dev, u32 stream)
{
u32 dma_reg = i2s_read_reg(dev->i2s_base, I2S_DMACR);
/* Disable DMA handshake for stream */
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
dma_reg &= ~I2S_DMAEN_TXBLOCK;
i2s_write_reg(dev->i2s_base, I2S_RTXDMA, 1);
} else {
dma_reg &= ~I2S_DMAEN_RXBLOCK;
i2s_write_reg(dev->i2s_base, I2S_RRXDMA, 1);
}
i2s_write_reg(dev->i2s_base, I2S_DMACR, dma_reg);
}
static void i2s_start(struct dw_i2s_dev *dev,
struct snd_pcm_substream *substream)
{
struct i2s_clk_config_data *config = &dev->config;
u32 reg = IER_IEN;
if (dev->tdm_slots) {
reg |= (dev->tdm_slots - 1) << IER_TDM_SLOTS_SHIFT;
reg |= IER_INTF_TYPE;
reg |= dev->frame_offset << IER_FRAME_OFF_SHIFT;
}
i2s_write_reg(dev->i2s_base, IER, reg);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
i2s_write_reg(dev->i2s_base, ITER, 1);
else
i2s_write_reg(dev->i2s_base, IRER, 1);
if (!(dev->use_pio || dev->is_jh7110))
i2s_enable_dma(dev, substream->stream);
i2s_enable_irqs(dev, substream->stream, config->chan_nr);
i2s_write_reg(dev->i2s_base, CER, 1);
}
static void i2s_stop(struct dw_i2s_dev *dev,
struct snd_pcm_substream *substream)
Annotation
- Immediate include surface: `linux/clk.h`, `linux/device.h`, `linux/init.h`, `linux/io.h`, `linux/interrupt.h`, `linux/mfd/syscon.h`, `linux/module.h`, `linux/reset.h`.
- Detected declarations: `function Copyright`, `function i2s_read_reg`, `function i2s_disable_channels`, `function i2s_clear_irqs`, `function i2s_disable_irqs`, `function i2s_enable_irqs`, `function i2s_irq_handler`, `function i2s_enable_dma`, `function i2s_disable_dma`, `function i2s_start`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.