sound/soc/au1x/psc-ac97.c
Source file repositories/reference/linux-study-clean/sound/soc/au1x/psc-ac97.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/au1x/psc-ac97.c- Extension
.c- Size
- 12662 bytes
- Lines
- 487
- 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.
- 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/slab.hlinux/device.hlinux/delay.hlinux/mutex.hlinux/suspend.hsound/core.hsound/pcm.hsound/initval.hsound/soc.hasm/mach-au1x00/au1000.hasm/mach-au1x00/au1xxx_psc.hpsc.h
Detected Declarations
function au1xpsc_ac97_readfunction au1xpsc_ac97_writefunction au1xpsc_ac97_warm_resetfunction au1xpsc_ac97_cold_resetfunction au1xpsc_ac97_hw_paramsfunction au1xpsc_ac97_triggerfunction au1xpsc_ac97_startupfunction au1xpsc_ac97_probefunction au1xpsc_ac97_drvprobefunction au1xpsc_ac97_drvremovefunction au1xpsc_ac97_drvsuspendfunction au1xpsc_ac97_drvresume
Annotated Snippet
if (stype == SNDRV_PCM_STREAM_PLAYBACK) {
r &= ~PSC_AC97CFG_TXSLOT_MASK;
r |= PSC_AC97CFG_TXSLOT_ENA(3);
r |= PSC_AC97CFG_TXSLOT_ENA(4);
} else {
r &= ~PSC_AC97CFG_RXSLOT_MASK;
r |= PSC_AC97CFG_RXSLOT_ENA(3);
r |= PSC_AC97CFG_RXSLOT_ENA(4);
}
/* do we need to poke the hardware? */
if (!(r ^ ro))
goto out;
/* ac97 engine is about to be disabled */
mutex_lock(&pscdata->lock);
/* disable AC97 device controller first... */
__raw_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
wmb(); /* drain writebuffer */
/* ...wait for it... */
t = 100;
while ((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t)
msleep(1);
if (!t)
printk(KERN_ERR "PSC-AC97: can't disable!\n");
/* ...write config... */
__raw_writel(r, AC97_CFG(pscdata));
wmb(); /* drain writebuffer */
/* ...enable the AC97 controller again... */
__raw_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
wmb(); /* drain writebuffer */
/* ...and wait for ready bit */
t = 100;
while ((!(__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t)
msleep(1);
if (!t)
printk(KERN_ERR "PSC-AC97: can't enable!\n");
mutex_unlock(&pscdata->lock);
pscdata->cfg = r;
pscdata->rate = params_rate(params);
}
out:
return 0;
}
static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
int ret, stype = substream->stream;
ret = 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
__raw_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata));
wmb(); /* drain writebuffer */
__raw_writel(AC97PCR_START(stype), AC97_PCR(pscdata));
wmb(); /* drain writebuffer */
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
__raw_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata));
wmb(); /* drain writebuffer */
while (__raw_readl(AC97_STAT(pscdata)) & AC97STAT_BUSY(stype))
asm volatile ("nop");
__raw_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata));
wmb(); /* drain writebuffer */
break;
default:
ret = -EINVAL;
}
return ret;
}
static int au1xpsc_ac97_startup(struct snd_pcm_substream *substream,
Annotation
- Immediate include surface: `linux/init.h`, `linux/module.h`, `linux/slab.h`, `linux/device.h`, `linux/delay.h`, `linux/mutex.h`, `linux/suspend.h`, `sound/core.h`.
- Detected declarations: `function au1xpsc_ac97_read`, `function au1xpsc_ac97_write`, `function au1xpsc_ac97_warm_reset`, `function au1xpsc_ac97_cold_reset`, `function au1xpsc_ac97_hw_params`, `function au1xpsc_ac97_trigger`, `function au1xpsc_ac97_startup`, `function au1xpsc_ac97_probe`, `function au1xpsc_ac97_drvprobe`, `function au1xpsc_ac97_drvremove`.
- 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.
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.