sound/isa/wss/wss_lib.c
Source file repositories/reference/linux-study-clean/sound/isa/wss/wss_lib.c
File Facts
- System
- Linux kernel
- Corpus path
sound/isa/wss/wss_lib.c- Extension
.c- Size
- 61196 bytes
- Lines
- 2146
- Domain
- Driver Families
- Bucket
- sound/isa
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/delay.hlinux/pm.hlinux/init.hlinux/interrupt.hlinux/slab.hlinux/ioport.hlinux/module.hlinux/io.hsound/core.hsound/wss.hsound/pcm_params.hsound/tlv.hasm/dma.hasm/irq.h
Detected Declarations
function snd_wss_xratefunction wss_outbfunction wss_inbfunction snd_wss_waitfunction snd_wss_doutfunction snd_wss_outfunction snd_wss_infunction snd_cs4236_ext_outfunction snd_cs4236_ext_infunction snd_wss_debugfunction snd_wss_busy_waitfunction snd_wss_mce_upfunction snd_wss_mce_downfunction snd_wss_get_countfunction snd_wss_triggerfunction snd_wss_get_ratefunction snd_wss_get_formatfunction snd_wss_calibrate_mutefunction snd_wss_playback_formatfunction scoped_guardfunction snd_wss_capture_formatfunction snd_wss_timer_resolutionfunction snd_wss_timer_startfunction snd_wss_timer_stopfunction snd_wss_initfunction scoped_guardfunction snd_wss_openfunction snd_wss_closefunction snd_wss_timer_openfunction snd_wss_timer_closefunction snd_wss_playback_hw_paramsfunction snd_wss_playback_preparefunction snd_wss_capture_hw_paramsfunction snd_wss_capture_preparefunction snd_wss_overrangefunction scoped_guardfunction snd_wss_interruptfunction snd_wss_playback_pointerfunction snd_wss_capture_pointerfunction snd_ad1848_probefunction snd_wss_probefunction snd_wss_playback_openfunction snd_wss_capture_openfunction snd_wss_playback_closefunction snd_wss_capture_closefunction snd_wss_thinkpad_twiddlefunction snd_wss_suspendfunction scoped_guard
Annotated Snippet
if (time_after(jiffies, end_time)) {
dev_err(chip->card->dev,
"mce_down - auto calibration time out (2)\n");
return;
}
msleep(1);
}
dev_dbg(chip->card->dev, "(2) jiffies = %lu\n", jiffies);
/* check condition up to 100 ms */
end_time = jiffies + msecs_to_jiffies(100);
while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
if (time_after(jiffies, end_time)) {
dev_err(chip->card->dev,
"mce_down - auto calibration time out (3)\n");
return;
}
msleep(1);
}
dev_dbg(chip->card->dev, "(3) jiffies = %lu\n", jiffies);
dev_dbg(chip->card->dev, "mce_down - exit = 0x%x\n",
wss_inb(chip, CS4231P(REGSEL)));
}
EXPORT_SYMBOL(snd_wss_mce_down);
static unsigned int snd_wss_get_count(unsigned char format, unsigned int size)
{
switch (format & 0xe0) {
case CS4231_LINEAR_16:
case CS4231_LINEAR_16_BIG:
size >>= 1;
break;
case CS4231_ADPCM_16:
return size >> 2;
}
if (format & CS4231_STEREO)
size >>= 1;
return size;
}
static int snd_wss_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct snd_wss *chip = snd_pcm_substream_chip(substream);
int result = 0;
unsigned int what;
struct snd_pcm_substream *s;
int do_start;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
do_start = 1; break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
do_start = 0; break;
default:
return -EINVAL;
}
what = 0;
snd_pcm_group_for_each_entry(s, substream) {
if (s == chip->playback_substream) {
what |= CS4231_PLAYBACK_ENABLE;
snd_pcm_trigger_done(s, substream);
} else if (s == chip->capture_substream) {
what |= CS4231_RECORD_ENABLE;
snd_pcm_trigger_done(s, substream);
}
}
guard(spinlock)(&chip->reg_lock);
if (do_start) {
chip->image[CS4231_IFACE_CTRL] |= what;
if (chip->trigger)
chip->trigger(chip, what, 1);
} else {
chip->image[CS4231_IFACE_CTRL] &= ~what;
if (chip->trigger)
chip->trigger(chip, what, 0);
}
snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
#if 0
snd_wss_debug(chip);
#endif
return result;
}
/*
Annotation
- Immediate include surface: `linux/delay.h`, `linux/pm.h`, `linux/init.h`, `linux/interrupt.h`, `linux/slab.h`, `linux/ioport.h`, `linux/module.h`, `linux/io.h`.
- Detected declarations: `function snd_wss_xrate`, `function wss_outb`, `function wss_inb`, `function snd_wss_wait`, `function snd_wss_dout`, `function snd_wss_out`, `function snd_wss_in`, `function snd_cs4236_ext_out`, `function snd_cs4236_ext_in`, `function snd_wss_debug`.
- Atlas domain: Driver Families / sound/isa.
- Implementation status: integration 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.