sound/soc/atmel/mchp-i2s-mcc.c
Source file repositories/reference/linux-study-clean/sound/soc/atmel/mchp-i2s-mcc.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/atmel/mchp-i2s-mcc.c- Extension
.c- Size
- 32191 bytes
- Lines
- 1139
- 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.hlinux/lcm.hlinux/of.hsound/core.hsound/pcm.hsound/pcm_params.hsound/initval.hsound/soc.hsound/dmaengine_pcm.h
Detected Declarations
struct mchp_i2s_mcc_soc_datastruct mchp_i2s_mcc_devfunction mchp_i2s_mcc_interruptfunction mchp_i2s_mcc_set_sysclkfunction mchp_i2s_mcc_set_bclk_ratiofunction mchp_i2s_mcc_set_dai_fmtfunction mchp_i2s_mcc_set_dai_tdm_slotfunction mchp_i2s_mcc_clk_get_rate_difffunction mchp_i2s_mcc_config_divsfunction mchp_i2s_mcc_is_runningfunction mchp_i2s_mcc_period_to_maxburstfunction mchp_i2s_mcc_hw_paramsfunction mchp_i2s_mcc_hw_freefunction mchp_i2s_mcc_triggerfunction mchp_i2s_mcc_startupfunction mchp_i2s_mcc_dai_probefunction mchp_i2s_mcc_soc_data_parsefunction mchp_i2s_mcc_probefunction mchp_i2s_mcc_remove
Annotated Snippet
struct mchp_i2s_mcc_soc_data {
unsigned int data_pin_pair_num;
bool has_fifo;
};
struct mchp_i2s_mcc_dev {
struct wait_queue_head wq_txrdy;
struct wait_queue_head wq_rxrdy;
struct device *dev;
struct regmap *regmap;
struct clk *pclk;
struct clk *gclk;
const struct mchp_i2s_mcc_soc_data *soc;
struct snd_dmaengine_dai_dma_data playback;
struct snd_dmaengine_dai_dma_data capture;
unsigned int fmt;
unsigned int sysclk;
unsigned int frame_length;
int tdm_slots;
int channels;
u8 tdm_data_pair;
unsigned int gclk_use:1;
unsigned int gclk_running:1;
unsigned int tx_rdy:1;
unsigned int rx_rdy:1;
};
static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id)
{
struct mchp_i2s_mcc_dev *dev = dev_id;
u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0, idrb = 0;
irqreturn_t ret = IRQ_NONE;
regmap_read(dev->regmap, MCHP_I2SMCC_IMRA, &imra);
regmap_read(dev->regmap, MCHP_I2SMCC_ISRA, &sra);
pendinga = imra & sra;
regmap_read(dev->regmap, MCHP_I2SMCC_IMRB, &imrb);
regmap_read(dev->regmap, MCHP_I2SMCC_ISRB, &srb);
pendingb = imrb & srb;
if (!pendinga && !pendingb)
return IRQ_NONE;
/*
* Tx/Rx ready interrupts are enabled when stopping only, to assure
* availability and to disable clocks if necessary
*/
if (dev->soc->has_fifo) {
idrb |= pendingb & (MCHP_I2SMCC_INT_TXFFRDY |
MCHP_I2SMCC_INT_RXFFRDY);
} else {
idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) |
MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
}
if (idra || idrb)
ret = IRQ_HANDLED;
if ((!dev->soc->has_fifo &&
(imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) &&
(imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) ==
(idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) ||
(dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_TXFFRDY)) {
dev->tx_rdy = 1;
wake_up_interruptible(&dev->wq_txrdy);
}
if ((!dev->soc->has_fifo &&
(imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) &&
(imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) ==
(idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) ||
(dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_RXFFRDY)) {
dev->rx_rdy = 1;
wake_up_interruptible(&dev->wq_rxrdy);
}
if (dev->soc->has_fifo)
regmap_write(dev->regmap, MCHP_I2SMCC_IDRB, idrb);
else
regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
return ret;
}
static int mchp_i2s_mcc_set_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);
dev_dbg(dev->dev, "%s() clk_id=%d freq=%u dir=%d\n",
__func__, clk_id, freq, dir);
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 mchp_i2s_mcc_soc_data`, `struct mchp_i2s_mcc_dev`, `function mchp_i2s_mcc_interrupt`, `function mchp_i2s_mcc_set_sysclk`, `function mchp_i2s_mcc_set_bclk_ratio`, `function mchp_i2s_mcc_set_dai_fmt`, `function mchp_i2s_mcc_set_dai_tdm_slot`, `function mchp_i2s_mcc_clk_get_rate_diff`, `function mchp_i2s_mcc_config_divs`, `function mchp_i2s_mcc_is_running`.
- 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.