sound/soc/loongson/loongson1_ac97.c
Source file repositories/reference/linux-study-clean/sound/soc/loongson/loongson1_ac97.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/loongson/loongson1_ac97.c- Extension
.c- Size
- 12006 bytes
- Lines
- 399
- 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/bitfield.hlinux/dma-mapping.hlinux/init.hlinux/module.hlinux/platform_device.hlinux/regmap.hsound/dmaengine_pcm.hsound/pcm.hsound/pcm_params.hsound/soc.h
Detected Declarations
struct ls1x_ac97function ls1x_ac97_resetfunction ls1x_ac97_writefunction ls1x_ac97_readfunction ls1x_ac97_initfunction ls1x_ac97_hw_paramsfunction ls1x_ac97_dai_probefunction ls1x_ac97_probefunction ls1x_ac97_removefunction ls1x_ac97_suspendfunction ls1x_ac97_resume
Annotated Snippet
struct ls1x_ac97 {
void __iomem *reg_base;
struct regmap *regmap;
dma_addr_t tx_dma_base;
dma_addr_t rx_dma_base;
struct snd_dmaengine_dai_dma_data capture_dma_data;
struct snd_dmaengine_dai_dma_data playback_dma_data;
};
static struct ls1x_ac97 *ls1x_ac97;
static const struct regmap_config ls1x_ac97_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
};
static void ls1x_ac97_reset(struct snd_ac97 *ac97)
{
int val;
regmap_write(ls1x_ac97->regmap, AC97_CSR, CSR_RST_FORCE);
regmap_read_poll_timeout(ls1x_ac97->regmap, AC97_CSR, val,
!(val & CSR_RESUME), 0, LS1X_AC97_TIMEOUT);
}
static void ls1x_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
{
int tmp, ret;
tmp = FIELD_PREP(CODEC_ADR, reg) | FIELD_PREP(CODEC_DAT, val);
regmap_write(ls1x_ac97->regmap, AC97_CRAC, tmp);
ret = regmap_read_poll_timeout(ls1x_ac97->regmap, AC97_INTRAW, tmp,
(tmp & CW_DONE), 0, LS1X_AC97_TIMEOUT);
if (ret)
pr_err("timeout on AC97 write! %d\n", ret);
regmap_read(ls1x_ac97->regmap, AC97_INT_CW_CLR, &ret);
}
static unsigned short ls1x_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{
int val, ret;
val = CODEC_WR | FIELD_PREP(CODEC_ADR, reg);
regmap_write(ls1x_ac97->regmap, AC97_CRAC, val);
ret = regmap_read_poll_timeout(ls1x_ac97->regmap, AC97_INTRAW, val,
(val & CR_DONE), 0, LS1X_AC97_TIMEOUT);
if (ret) {
pr_err("timeout on AC97 read! %d\n", ret);
return ret;
}
regmap_read(ls1x_ac97->regmap, AC97_INT_CR_CLR, &ret);
regmap_read(ls1x_ac97->regmap, AC97_CRAC, &ret);
return (ret & CODEC_DAT);
}
static void ls1x_ac97_init(struct snd_ac97 *ac97)
{
writel(0, ls1x_ac97->reg_base + AC97_INTRAW);
writel(0, ls1x_ac97->reg_base + AC97_INTM);
/* Config output channels */
regmap_update_bits(ls1x_ac97->regmap, AC97_OCC0,
R_DMA_EN | R_FIFO_THRES | R_CH_EN |
L_DMA_EN | L_FIFO_THRES | L_CH_EN,
R_DMA_EN | R_FIFO_THRES_EMPTY | R_CH_EN |
L_DMA_EN | L_FIFO_THRES_EMPTY | L_CH_EN);
/* Config inputs channel */
regmap_update_bits(ls1x_ac97->regmap, AC97_ICC,
M_DMA_EN | M_FIFO_THRES | M_CH_EN |
R_DMA_EN | R_FIFO_THRES | R_CH_EN |
L_DMA_EN | L_FIFO_THRES | L_CH_EN,
M_DMA_EN | M_FIFO_THRES_FULL | M_CH_EN |
R_DMA_EN | R_FIFO_THRES_EMPTY | R_CH_EN |
L_DMA_EN | L_FIFO_THRES_EMPTY | L_CH_EN);
if (ac97->ext_id & AC97_EI_VRA) {
regmap_update_bits(ls1x_ac97->regmap, AC97_OCC0, R_VSR | L_VSR, R_VSR | L_VSR);
regmap_update_bits(ls1x_ac97->regmap, AC97_ICC, M_VSR, M_VSR);
}
}
static struct snd_ac97_bus_ops ls1x_ac97_ops = {
.reset = ls1x_ac97_reset,
.write = ls1x_ac97_write,
.read = ls1x_ac97_read,
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/dma-mapping.h`, `linux/init.h`, `linux/module.h`, `linux/platform_device.h`, `linux/regmap.h`, `sound/dmaengine_pcm.h`, `sound/pcm.h`.
- Detected declarations: `struct ls1x_ac97`, `function ls1x_ac97_reset`, `function ls1x_ac97_write`, `function ls1x_ac97_read`, `function ls1x_ac97_init`, `function ls1x_ac97_hw_params`, `function ls1x_ac97_dai_probe`, `function ls1x_ac97_probe`, `function ls1x_ac97_remove`, `function ls1x_ac97_suspend`.
- 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.