sound/pci/echoaudio/layla24_dsp.c
Source file repositories/reference/linux-study-clean/sound/pci/echoaudio/layla24_dsp.c
File Facts
- System
- Linux kernel
- Corpus path
sound/pci/echoaudio/layla24_dsp.c- Extension
.c- Size
- 9558 bytes
- Lines
- 382
- Domain
- Driver Families
- Bucket
- sound/pci
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
function init_hwfunction set_mixer_defaultsfunction detect_input_clocksfunction load_asicfunction set_sample_ratefunction set_input_clockfunction switch_asicfunction dsp_set_digital_mode
Annotated Snippet
if (rate > 50000) {
base_rate = rate >> 1;
control_reg |= GML_DOUBLE_SPEED_MODE;
} else {
base_rate = rate;
}
if (base_rate < 25000)
base_rate = 25000;
if (wait_handshake(chip))
return -EIO;
chip->comm_page->sample_rate =
cpu_to_le32(LAYLA24_MAGIC_NUMBER / base_rate - 2);
clear_handshake(chip);
send_vector(chip, DSP_VC_SET_LAYLA24_FREQUENCY_REG);
}
control_reg |= clock;
chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */
chip->sample_rate = rate;
dev_dbg(chip->card->dev,
"set_sample_rate: %d clock %d\n", rate, control_reg);
return write_control_reg(chip, control_reg, false);
}
static int set_input_clock(struct echoaudio *chip, u16 clock)
{
u32 control_reg, clocks_from_dsp;
/* Mask off the clock select bits */
control_reg = le32_to_cpu(chip->comm_page->control_register) &
GML_CLOCK_CLEAR_MASK;
clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
/* Pick the new clock */
switch (clock) {
case ECHO_CLOCK_INTERNAL:
chip->input_clock = ECHO_CLOCK_INTERNAL;
return set_sample_rate(chip, chip->sample_rate);
case ECHO_CLOCK_SPDIF:
if (chip->digital_mode == DIGITAL_MODE_ADAT)
return -EAGAIN;
control_reg |= GML_SPDIF_CLOCK;
/* Layla24 doesn't support 96KHz S/PDIF */
control_reg &= ~GML_DOUBLE_SPEED_MODE;
break;
case ECHO_CLOCK_WORD:
control_reg |= GML_WORD_CLOCK;
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
control_reg |= GML_DOUBLE_SPEED_MODE;
else
control_reg &= ~GML_DOUBLE_SPEED_MODE;
break;
case ECHO_CLOCK_ADAT:
if (chip->digital_mode != DIGITAL_MODE_ADAT)
return -EAGAIN;
control_reg |= GML_ADAT_CLOCK;
control_reg &= ~GML_DOUBLE_SPEED_MODE;
break;
default:
dev_err(chip->card->dev,
"Input clock 0x%x not supported for Layla24\n", clock);
return -EINVAL;
}
chip->input_clock = clock;
return write_control_reg(chip, control_reg, true);
}
/* Depending on what digital mode you want, Layla24 needs different ASICs
loaded. This function checks the ASIC needed for the new mode and sees
if it matches the one already loaded. */
static int switch_asic(struct echoaudio *chip, short asic)
{
s8 *monitors;
/* Check to see if this is already loaded */
if (asic != chip->asic_code) {
monitors = kmemdup(chip->comm_page->monitors,
MONITOR_ARRAY_SIZE, GFP_KERNEL);
if (! monitors)
Annotation
- Detected declarations: `function init_hw`, `function set_mixer_defaults`, `function detect_input_clocks`, `function load_asic`, `function set_sample_rate`, `function set_input_clock`, `function switch_asic`, `function dsp_set_digital_mode`.
- Atlas domain: Driver Families / sound/pci.
- Implementation status: source implementation candidate.
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.