sound/isa/ad1816a/ad1816a_lib.c
Source file repositories/reference/linux-study-clean/sound/isa/ad1816a/ad1816a_lib.c
File Facts
- System
- Linux kernel
- Corpus path
sound/isa/ad1816a/ad1816a_lib.c- Extension
.c- Size
- 27676 bytes
- Lines
- 881
- Domain
- Driver Families
- Bucket
- sound/isa
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/init.hlinux/interrupt.hlinux/slab.hlinux/ioport.hlinux/io.hsound/core.hsound/tlv.hsound/ad1816a.hasm/dma.h
Detected Declarations
function Copyrightfunction snd_ad1816a_infunction snd_ad1816a_outfunction snd_ad1816a_out_maskfunction snd_ad1816a_readfunction snd_ad1816a_writefunction snd_ad1816a_write_maskfunction snd_ad1816a_get_formatfunction snd_ad1816a_openfunction snd_ad1816a_closefunction snd_ad1816a_triggerfunction snd_ad1816a_playback_triggerfunction snd_ad1816a_capture_triggerfunction snd_ad1816a_playback_preparefunction snd_ad1816a_capture_preparefunction snd_ad1816a_playback_pointerfunction snd_ad1816a_capture_pointerfunction snd_ad1816a_interruptfunction scoped_guardfunction scoped_guardfunction snd_ad1816a_timer_closefunction snd_ad1816a_timer_openfunction snd_ad1816a_timer_resolutionfunction snd_ad1816a_timer_startfunction snd_ad1816a_timer_stopfunction snd_ad1816a_playback_openfunction snd_ad1816a_capture_openfunction snd_ad1816a_playback_closefunction snd_ad1816a_capture_closefunction snd_ad1816a_initfunction snd_ad1816a_suspendfunction snd_ad1816a_resumefunction snd_ad1816a_probefunction snd_ad1816a_createfunction snd_ad1816a_pcmfunction snd_ad1816a_timerfunction snd_ad1816a_info_muxfunction snd_ad1816a_get_muxfunction snd_ad1816a_put_muxfunction snd_ad1816a_info_singlefunction snd_ad1816a_get_singlefunction snd_ad1816a_put_singlefunction snd_ad1816a_info_doublefunction snd_ad1816a_get_doublefunction snd_ad1816a_put_doublefunction snd_ad1816a_mixer
Annotated Snippet
scoped_guard(spinlock, &chip->lock) {
cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00;
/* if (what & AD1816A_PLAYBACK_ENABLE) */
/* That is not valid, because playback and capture enable
* are the same bit pattern, just to different addresses
*/
if (!iscapture)
snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
AD1816A_PLAYBACK_ENABLE, cmd);
else
snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
AD1816A_CAPTURE_ENABLE, cmd);
}
break;
default:
dev_warn(chip->card->dev, "invalid trigger mode 0x%x.\n", what);
error = -EINVAL;
}
return error;
}
static int snd_ad1816a_playback_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
return snd_ad1816a_trigger(chip, AD1816A_PLAYBACK_ENABLE,
SNDRV_PCM_STREAM_PLAYBACK, cmd, 0);
}
static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
return snd_ad1816a_trigger(chip, AD1816A_CAPTURE_ENABLE,
SNDRV_PCM_STREAM_CAPTURE, cmd, 1);
}
static int snd_ad1816a_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int size, rate;
guard(spinlock_irqsave)(&chip->lock);
chip->p_dma_size = size = snd_pcm_lib_buffer_bytes(substream);
snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
AD1816A_PLAYBACK_ENABLE | AD1816A_PLAYBACK_PIO, 0x00);
snd_dma_program(chip->dma1, runtime->dma_addr, size,
DMA_MODE_WRITE | DMA_AUTOINIT);
rate = runtime->rate;
if (chip->clock_freq)
rate = (rate * 33000) / chip->clock_freq;
snd_ad1816a_write(chip, AD1816A_PLAYBACK_SAMPLE_RATE, rate);
snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
AD1816A_FMT_ALL | AD1816A_FMT_STEREO,
snd_ad1816a_get_format(chip, runtime->format,
runtime->channels));
snd_ad1816a_write(chip, AD1816A_PLAYBACK_BASE_COUNT,
snd_pcm_lib_period_bytes(substream) / 4 - 1);
return 0;
}
static int snd_ad1816a_capture_prepare(struct snd_pcm_substream *substream)
{
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int size, rate;
guard(spinlock_irqsave)(&chip->lock);
chip->c_dma_size = size = snd_pcm_lib_buffer_bytes(substream);
snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
AD1816A_CAPTURE_ENABLE | AD1816A_CAPTURE_PIO, 0x00);
snd_dma_program(chip->dma2, runtime->dma_addr, size,
DMA_MODE_READ | DMA_AUTOINIT);
rate = runtime->rate;
if (chip->clock_freq)
rate = (rate * 33000) / chip->clock_freq;
snd_ad1816a_write(chip, AD1816A_CAPTURE_SAMPLE_RATE, rate);
snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
AD1816A_FMT_ALL | AD1816A_FMT_STEREO,
snd_ad1816a_get_format(chip, runtime->format,
runtime->channels));
snd_ad1816a_write(chip, AD1816A_CAPTURE_BASE_COUNT,
Annotation
- Immediate include surface: `linux/delay.h`, `linux/init.h`, `linux/interrupt.h`, `linux/slab.h`, `linux/ioport.h`, `linux/io.h`, `sound/core.h`, `sound/tlv.h`.
- Detected declarations: `function Copyright`, `function snd_ad1816a_in`, `function snd_ad1816a_out`, `function snd_ad1816a_out_mask`, `function snd_ad1816a_read`, `function snd_ad1816a_write`, `function snd_ad1816a_write_mask`, `function snd_ad1816a_get_format`, `function snd_ad1816a_open`, `function snd_ad1816a_close`.
- Atlas domain: Driver Families / sound/isa.
- 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.