sound/soc/atmel/mchp-spdiftx.c
Source file repositories/reference/linux-study-clean/sound/soc/atmel/mchp-spdiftx.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/atmel/mchp-spdiftx.c- Extension
.c- Size
- 23543 bytes
- Lines
- 904
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/bitfield.hlinux/clk.hlinux/io.hlinux/module.hlinux/pm_runtime.hlinux/spinlock.hsound/asoundef.hsound/dmaengine_pcm.hsound/pcm_params.hsound/soc.h
Detected Declarations
struct mchp_spdiftx_mixer_controlstruct mchp_spdiftx_devfunction mchp_spdiftx_readable_regfunction mchp_spdiftx_writeable_regfunction mchp_spdiftx_precious_regfunction mchp_spdiftx_is_runningfunction mchp_spdiftx_channel_status_writefunction mchp_spdiftx_user_data_writefunction mchp_spdiftx_interruptfunction mchp_spdiftx_dai_startupfunction mchp_spdiftx_dai_shutdownfunction mchp_spdiftx_triggerfunction mchp_spdiftx_hw_paramsfunction mchp_spdiftx_hw_freefunction mchp_spdiftx_infofunction mchp_spdiftx_cs_getfunction mchp_spdiftx_cs_putfunction mchp_spdiftx_cs_maskfunction mchp_spdiftx_subcode_getfunction mchp_spdiftx_subcode_putfunction mchp_spdiftx_dai_probefunction mchp_spdiftx_runtime_suspendfunction mchp_spdiftx_runtime_resumefunction mchp_spdiftx_probefunction mchp_spdiftx_remove
Annotated Snippet
struct mchp_spdiftx_mixer_control {
unsigned char ch_stat[SPDIFTX_CS_BITS / 8];
unsigned char user_data[SPDIFTX_UD_BITS / 8];
spinlock_t lock; /* exclusive access to control data */
};
struct mchp_spdiftx_dev {
struct mchp_spdiftx_mixer_control control;
struct snd_dmaengine_dai_dma_data playback;
struct device *dev;
struct regmap *regmap;
struct clk *pclk;
struct clk *gclk;
unsigned int fmt;
unsigned int suspend_irq;
};
static inline int mchp_spdiftx_is_running(struct mchp_spdiftx_dev *dev)
{
u32 mr;
regmap_read(dev->regmap, SPDIFTX_MR, &mr);
return !!(mr & SPDIFTX_MR_TXEN_ENABLE);
}
static void mchp_spdiftx_channel_status_write(struct mchp_spdiftx_dev *dev)
{
struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
u32 val;
int i;
for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat) / 4; i++) {
val = (ctrl->ch_stat[(i * 4) + 0] << 0) |
(ctrl->ch_stat[(i * 4) + 1] << 8) |
(ctrl->ch_stat[(i * 4) + 2] << 16) |
(ctrl->ch_stat[(i * 4) + 3] << 24);
regmap_write(dev->regmap, SPDIFTX_CH1S(i), val);
}
}
static void mchp_spdiftx_user_data_write(struct mchp_spdiftx_dev *dev)
{
struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
u32 val;
int i;
for (i = 0; i < ARRAY_SIZE(ctrl->user_data) / 4; i++) {
val = (ctrl->user_data[(i * 4) + 0] << 0) |
(ctrl->user_data[(i * 4) + 1] << 8) |
(ctrl->user_data[(i * 4) + 2] << 16) |
(ctrl->user_data[(i * 4) + 3] << 24);
regmap_write(dev->regmap, SPDIFTX_CH1UD(i), val);
}
}
static irqreturn_t mchp_spdiftx_interrupt(int irq, void *dev_id)
{
struct mchp_spdiftx_dev *dev = dev_id;
struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
u32 sr, imr, pending, idr = 0;
regmap_read(dev->regmap, SPDIFTX_ISR, &sr);
regmap_read(dev->regmap, SPDIFTX_IMR, &imr);
pending = sr & imr;
if (!pending)
return IRQ_NONE;
if (pending & SPDIFTX_IR_TXUDR) {
dev_warn(dev->dev, "underflow detected\n");
idr |= SPDIFTX_IR_TXUDR;
}
if (pending & SPDIFTX_IR_TXOVR) {
dev_warn(dev->dev, "overflow detected\n");
idr |= SPDIFTX_IR_TXOVR;
}
if (pending & SPDIFTX_IR_UDRDY) {
spin_lock(&ctrl->lock);
mchp_spdiftx_user_data_write(dev);
spin_unlock(&ctrl->lock);
idr |= SPDIFTX_IR_UDRDY;
}
if (pending & SPDIFTX_IR_CSRDY) {
spin_lock(&ctrl->lock);
mchp_spdiftx_channel_status_write(dev);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/io.h`, `linux/module.h`, `linux/pm_runtime.h`, `linux/spinlock.h`, `sound/asoundef.h`, `sound/dmaengine_pcm.h`.
- Detected declarations: `struct mchp_spdiftx_mixer_control`, `struct mchp_spdiftx_dev`, `function mchp_spdiftx_readable_reg`, `function mchp_spdiftx_writeable_reg`, `function mchp_spdiftx_precious_reg`, `function mchp_spdiftx_is_running`, `function mchp_spdiftx_channel_status_write`, `function mchp_spdiftx_user_data_write`, `function mchp_spdiftx_interrupt`, `function mchp_spdiftx_dai_startup`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.