sound/soc/atmel/atmel-i2s.c
Source file repositories/reference/linux-study-clean/sound/soc/atmel/atmel-i2s.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/atmel/atmel-i2s.c- Extension
.c- Size
- 20158 bytes
- Lines
- 743
- 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/init.hlinux/module.hlinux/device.hlinux/slab.hlinux/delay.hlinux/io.hlinux/clk.hlinux/mfd/syscon.hsound/core.hsound/pcm.hsound/pcm_params.hsound/initval.hsound/soc.hsound/dmaengine_pcm.h
Detected Declarations
struct atmel_i2s_gck_paramstruct atmel_i2s_devstruct atmel_i2s_capsstruct atmel_i2s_devfunction atmel_i2s_interruptfunction atmel_i2s_set_dai_fmtfunction atmel_i2s_preparefunction atmel_i2s_get_gck_paramfunction atmel_i2s_hw_paramsfunction atmel_i2s_switch_mck_generatorfunction atmel_i2s_triggerfunction atmel_i2s_dai_probefunction atmel_i2s_sama5d2_mck_initfunction atmel_i2s_probefunction atmel_i2s_remove
Annotated Snippet
struct atmel_i2s_gck_param {
int fs;
unsigned long mck;
int imckdiv;
int imckfs;
};
#define I2S_MCK_12M288 12288000UL
#define I2S_MCK_11M2896 11289600UL
#define I2S_MCK_6M144 6144000UL
/* mck = (32 * (imckfs+1) / (imckdiv+1)) * fs */
static const struct atmel_i2s_gck_param gck_params[] = {
/* mck = 6.144Mhz */
{ 8000, I2S_MCK_6M144, 1, 47}, /* mck = 768 fs */
/* mck = 12.288MHz */
{ 16000, I2S_MCK_12M288, 1, 47}, /* mck = 768 fs */
{ 24000, I2S_MCK_12M288, 3, 63}, /* mck = 512 fs */
{ 32000, I2S_MCK_12M288, 3, 47}, /* mck = 384 fs */
{ 48000, I2S_MCK_12M288, 7, 63}, /* mck = 256 fs */
{ 64000, I2S_MCK_12M288, 7, 47}, /* mck = 192 fs */
{ 96000, I2S_MCK_12M288, 7, 31}, /* mck = 128 fs */
{192000, I2S_MCK_12M288, 7, 15}, /* mck = 64 fs */
/* mck = 11.2896MHz */
{ 11025, I2S_MCK_11M2896, 1, 63}, /* mck = 1024 fs */
{ 22050, I2S_MCK_11M2896, 3, 63}, /* mck = 512 fs */
{ 44100, I2S_MCK_11M2896, 7, 63}, /* mck = 256 fs */
{ 88200, I2S_MCK_11M2896, 7, 31}, /* mck = 128 fs */
{176400, I2S_MCK_11M2896, 7, 15}, /* mck = 64 fs */
};
struct atmel_i2s_dev;
struct atmel_i2s_caps {
int (*mck_init)(struct atmel_i2s_dev *, struct device_node *np);
};
struct atmel_i2s_dev {
struct device *dev;
struct regmap *regmap;
struct clk *pclk;
struct clk *gclk;
struct snd_dmaengine_dai_dma_data playback;
struct snd_dmaengine_dai_dma_data capture;
unsigned int fmt;
const struct atmel_i2s_gck_param *gck_param;
const struct atmel_i2s_caps *caps;
int clk_use_no;
};
static irqreturn_t atmel_i2s_interrupt(int irq, void *dev_id)
{
struct atmel_i2s_dev *dev = dev_id;
unsigned int sr, imr, pending, ch, mask;
irqreturn_t ret = IRQ_NONE;
regmap_read(dev->regmap, ATMEL_I2SC_SR, &sr);
regmap_read(dev->regmap, ATMEL_I2SC_IMR, &imr);
pending = sr & imr;
if (!pending)
return IRQ_NONE;
if (pending & ATMEL_I2SC_INT_RXOR) {
mask = ATMEL_I2SC_SR_RXOR;
for (ch = 0; ch < ATMEL_I2SC_MAX_TDM_CHANNELS; ++ch) {
if (sr & ATMEL_I2SC_SR_RXORCH(ch)) {
mask |= ATMEL_I2SC_SR_RXORCH(ch);
dev_err(dev->dev,
"RX overrun on channel %d\n", ch);
}
}
regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask);
ret = IRQ_HANDLED;
}
if (pending & ATMEL_I2SC_INT_TXUR) {
mask = ATMEL_I2SC_SR_TXUR;
for (ch = 0; ch < ATMEL_I2SC_MAX_TDM_CHANNELS; ++ch) {
if (sr & ATMEL_I2SC_SR_TXURCH(ch)) {
mask |= ATMEL_I2SC_SR_TXURCH(ch);
dev_err(dev->dev,
"TX underrun on channel %d\n", ch);
}
}
regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask);
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`, `linux/mfd/syscon.h`.
- Detected declarations: `struct atmel_i2s_gck_param`, `struct atmel_i2s_dev`, `struct atmel_i2s_caps`, `struct atmel_i2s_dev`, `function atmel_i2s_interrupt`, `function atmel_i2s_set_dai_fmt`, `function atmel_i2s_prepare`, `function atmel_i2s_get_gck_param`, `function atmel_i2s_hw_params`, `function atmel_i2s_switch_mck_generator`.
- 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.