sound/soc/ti/davinci-i2s.c
Source file repositories/reference/linux-study-clean/sound/soc/ti/davinci-i2s.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/ti/davinci-i2s.c- Extension
.c- Size
- 27226 bytes
- Lines
- 933
- 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.
- 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/init.hlinux/module.hlinux/device.hlinux/slab.hlinux/delay.hlinux/io.hlinux/clk.hsound/core.hsound/pcm.hsound/pcm_params.hsound/initval.hsound/soc.hsound/dmaengine_pcm.hedma-pcm.hdavinci-i2s.h
Detected Declarations
struct davinci_mcbsp_devfunction davinci_mcbsp_write_regfunction davinci_mcbsp_read_regfunction toggle_clockfunction davinci_mcbsp_startfunction davinci_mcbsp_stopfunction davinci_i2s_tdm_word_lengthfunction davinci_i2s_set_tdm_slotfunction davinci_i2s_set_dai_fmtfunction davinci_i2s_dai_set_clkdivfunction davinci_i2s_hw_paramsfunction davinci_i2s_preparefunction davinci_i2s_triggerfunction davinci_i2s_shutdownfunction davinci_i2s_dai_probefunction davinci_i2s_probefunction davinci_i2s_remove
Annotated Snippet
struct davinci_mcbsp_dev {
struct device *dev;
struct snd_dmaengine_dai_dma_data dma_data[2];
int dma_request[2];
void __iomem *base;
#define MOD_DSP_A 0
#define MOD_DSP_B 1
int mode;
u32 pcr;
struct clk *clk;
struct clk *ext_clk;
/*
* Combining both channels into 1 element will at least double the
* amount of time between servicing the dma channel, increase
* effiency, and reduce the chance of overrun/underrun. But,
* it will result in the left & right channels being swapped.
*
* If relabeling the left and right channels is not possible,
* you may want to let the codec know to swap them back.
*
* It may allow x10 the amount of time to service dma requests,
* if the codec is master and is using an unnecessarily fast bit clock
* (ie. tlvaic23b), independent of the sample rate. So, having an
* entire frame at once means it can be serviced at the sample rate
* instead of the bit clock rate.
*
* In the now unlikely case that an underrun still
* occurs, both the left and right samples will be repeated
* so that no pops are heard, and the left and right channels
* won't end up being swapped because of the underrun.
*/
unsigned enable_channel_combine:1;
unsigned int fmt;
int clk_div;
bool i2s_accurate_sck;
int tdm_slots;
int slot_width;
bool tx_framing_bit;
bool rx_framing_bit;
};
static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
int reg, u32 val)
{
__raw_writel(val, dev->base + reg);
}
static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg)
{
return __raw_readl(dev->base + reg);
}
static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback)
{
u32 m = playback ? DAVINCI_MCBSP_PCR_CLKXP : DAVINCI_MCBSP_PCR_CLKRP;
/* The clock needs to toggle to complete reset.
* So, fake it by toggling the clk polarity.
*/
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr ^ m);
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr);
}
static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
struct snd_pcm_substream *substream)
{
int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
u32 spcr;
u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
/* Enable transmitter or receiver */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
spcr |= mask;
if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM)) {
/* Start frame sync */
spcr |= DAVINCI_MCBSP_SPCR_FRST;
}
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
}
static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
{
u32 spcr;
/* Reset transmitter/receiver and sample rate/frame sync generators */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST);
Annotation
- Immediate include surface: `linux/init.h`, `linux/module.h`, `linux/device.h`, `linux/slab.h`, `linux/delay.h`, `linux/io.h`, `linux/clk.h`, `sound/core.h`.
- Detected declarations: `struct davinci_mcbsp_dev`, `function davinci_mcbsp_write_reg`, `function davinci_mcbsp_read_reg`, `function toggle_clock`, `function davinci_mcbsp_start`, `function davinci_mcbsp_stop`, `function davinci_i2s_tdm_word_length`, `function davinci_i2s_set_tdm_slot`, `function davinci_i2s_set_dai_fmt`, `function davinci_i2s_dai_set_clkdiv`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
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.