sound/soc/bcm/bcm2835-i2s.c
Source file repositories/reference/linux-study-clean/sound/soc/bcm/bcm2835-i2s.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/bcm/bcm2835-i2s.c- Extension
.c- Size
- 24466 bytes
- Lines
- 932
- 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/bitops.hlinux/clk.hlinux/delay.hlinux/device.hlinux/init.hlinux/io.hlinux/module.hlinux/of_address.hlinux/slab.hsound/core.hsound/dmaengine_pcm.hsound/initval.hsound/pcm.hsound/pcm_params.hsound/soc.h
Detected Declarations
struct bcm2835_i2s_devfunction bcm2835_i2s_start_clockfunction bcm2835_i2s_stop_clockfunction bcm2835_i2s_clear_fifosfunction bcm2835_i2s_set_dai_fmtfunction bcm2835_i2s_set_dai_bclk_ratiofunction bcm2835_i2s_set_dai_tdm_slotfunction bcm2835_i2s_convert_slotfunction bcm2835_i2s_calc_channel_posfunction bcm2835_i2s_hw_paramsfunction bcm2835_i2s_preparefunction bcm2835_i2s_stopfunction bcm2835_i2s_triggerfunction bcm2835_i2s_startupfunction bcm2835_i2s_shutdownfunction bcm2835_i2s_dai_probefunction bcm2835_i2s_volatile_regfunction bcm2835_i2s_precious_regfunction bcm2835_i2s_probe
Annotated Snippet
struct bcm2835_i2s_dev {
struct device *dev;
struct snd_dmaengine_dai_dma_data dma_data[2];
unsigned int fmt;
unsigned int tdm_slots;
unsigned int rx_mask;
unsigned int tx_mask;
unsigned int slot_width;
unsigned int frame_length;
struct regmap *i2s_regmap;
struct clk *clk;
bool clk_prepared;
int clk_rate;
};
static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev)
{
unsigned int provider = dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
if (dev->clk_prepared)
return;
switch (provider) {
case SND_SOC_DAIFMT_BP_FP:
case SND_SOC_DAIFMT_BP_FC:
clk_prepare_enable(dev->clk);
dev->clk_prepared = true;
break;
default:
break;
}
}
static void bcm2835_i2s_stop_clock(struct bcm2835_i2s_dev *dev)
{
if (dev->clk_prepared)
clk_disable_unprepare(dev->clk);
dev->clk_prepared = false;
}
static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev,
bool tx, bool rx)
{
int timeout = 1000;
uint32_t syncval;
uint32_t csreg;
uint32_t i2s_active_state;
bool clk_was_prepared;
uint32_t off;
uint32_t clr;
off = tx ? BCM2835_I2S_TXON : 0;
off |= rx ? BCM2835_I2S_RXON : 0;
clr = tx ? BCM2835_I2S_TXCLR : 0;
clr |= rx ? BCM2835_I2S_RXCLR : 0;
/* Backup the current state */
regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg);
i2s_active_state = csreg & (BCM2835_I2S_RXON | BCM2835_I2S_TXON);
/* Start clock if not running */
clk_was_prepared = dev->clk_prepared;
if (!clk_was_prepared)
bcm2835_i2s_start_clock(dev);
/* Stop I2S module */
regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0);
/*
* Clear the FIFOs
* Requires at least 2 PCM clock cycles to take effect
*/
regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, clr, clr);
/* Wait for 2 PCM clock cycles */
/*
* Toggle the SYNC flag. After 2 PCM clock cycles it can be read back
* FIXME: This does not seem to work for slave mode!
*/
regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &syncval);
syncval &= BCM2835_I2S_SYNC;
regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
BCM2835_I2S_SYNC, ~syncval);
/* Wait for the SYNC flag changing it's state */
while (--timeout) {
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/clk.h`, `linux/delay.h`, `linux/device.h`, `linux/init.h`, `linux/io.h`, `linux/module.h`, `linux/of_address.h`.
- Detected declarations: `struct bcm2835_i2s_dev`, `function bcm2835_i2s_start_clock`, `function bcm2835_i2s_stop_clock`, `function bcm2835_i2s_clear_fifos`, `function bcm2835_i2s_set_dai_fmt`, `function bcm2835_i2s_set_dai_bclk_ratio`, `function bcm2835_i2s_set_dai_tdm_slot`, `function bcm2835_i2s_convert_slot`, `function bcm2835_i2s_calc_channel_pos`, `function bcm2835_i2s_hw_params`.
- 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.