sound/pci/emu10k1/io.c
Source file repositories/reference/linux-study-clean/sound/pci/emu10k1/io.c
File Facts
- System
- Linux kernel
- Corpus path
sound/pci/emu10k1/io.c- Extension
.c- Size
- 19560 bytes
- Lines
- 717
- Domain
- Driver Families
- Bucket
- sound/pci
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/time.hsound/core.hsound/emu10k1.hlinux/delay.hlinux/export.hp17v.h
Detected Declarations
function Copyrightfunction snd_emu10k1_ptr_readfunction scoped_guardfunction snd_emu10k1_ptr_writefunction snd_emu10k1_ptr_write_multiplefunction snd_emu10k1_ptr20_readfunction snd_emu10k1_ptr20_writefunction snd_emu10k1_spi_writefunction snd_emu10k1_i2c_writefunction snd_emu1010_fpga_write_lockedfunction snd_emu1010_fpga_writefunction snd_emu1010_fpga_write_lockfunction snd_emu1010_fpga_readfunction snd_emu1010_fpga_link_dst_src_writefunction snd_emu1010_fpga_link_dst_src_readfunction snd_emu1010_get_raw_ratefunction snd_emu1010_update_clockfunction snd_emu1010_load_firmware_entryfunction snd_emu10k1_intr_enablefunction snd_emu10k1_intr_disablefunction snd_emu10k1_voice_intr_enablefunction snd_emu10k1_voice_intr_disablefunction snd_emu10k1_voice_intr_ackfunction snd_emu10k1_voice_half_loop_intr_enablefunction snd_emu10k1_voice_half_loop_intr_disablefunction snd_emu10k1_voice_half_loop_intr_ackfunction snd_emu10k1_voice_set_loop_stopfunction snd_emu10k1_voice_clear_loop_stopfunction snd_emu10k1_voice_set_loop_stop_multiplefunction snd_emu10k1_voice_clear_loop_stop_multiplefunction snd_emu10k1_voice_clear_loop_stop_multiple_atomicfunction snd_emu10k1_waitfunction snd_emu10k1_ac97_readfunction snd_emu10k1_ac97_writeexport snd_emu10k1_ptr_readexport snd_emu10k1_ptr_writeexport snd_emu10k1_ptr_write_multiple
Annotated Snippet
if (!(tmp & 0x10000)) {
result = 0;
break;
}
}
if (result) {
/* Timed out */
return 1;
}
snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */
return 0;
}
/* The ADC does not support i2c read, so only write is implemented */
int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
u32 reg,
u32 value)
{
u32 tmp;
int timeout = 0;
int status;
int retry;
if ((reg > 0x7f) || (value > 0x1ff)) {
dev_err(emu->card->dev, "i2c_write: invalid values.\n");
return -EINVAL;
}
/* This function is not re-entrant, so protect against it. */
guard(spinlock)(&emu->i2c_lock);
tmp = reg << 25 | value << 16;
/* This controls the I2C connected to the WM8775 ADC Codec */
snd_emu10k1_ptr20_write(emu, P17V_I2C_1, 0, tmp);
tmp = snd_emu10k1_ptr20_read(emu, P17V_I2C_1, 0); /* write post */
for (retry = 0; retry < 10; retry++) {
/* Send the data to i2c */
tmp = 0;
tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
snd_emu10k1_ptr20_write(emu, P17V_I2C_ADDR, 0, tmp);
/* Wait till the transaction ends */
while (1) {
mdelay(1);
status = snd_emu10k1_ptr20_read(emu, P17V_I2C_ADDR, 0);
timeout++;
if ((status & I2C_A_ADC_START) == 0)
break;
if (timeout > 1000) {
dev_warn(emu->card->dev,
"emu10k1:I2C:timeout status=0x%x\n",
status);
break;
}
}
//Read back and see if the transaction is successful
if ((status & I2C_A_ADC_ABORT) == 0)
break;
}
if (retry == 10) {
dev_err(emu->card->dev, "Writing to ADC failed!\n");
dev_err(emu->card->dev, "status=0x%x, reg=%d, value=%d\n",
status, reg, value);
/* dump_stack(); */
return -EINVAL;
}
return 0;
}
static void snd_emu1010_fpga_write_locked(struct snd_emu10k1 *emu, u32 reg, u32 value)
{
if (snd_BUG_ON(reg > 0x3f))
return;
reg += 0x40; /* 0x40 upwards are registers. */
if (snd_BUG_ON(value > 0x3f)) /* 0 to 0x3f are values */
return;
outw(reg, emu->port + A_GPIO);
udelay(10);
outw(reg | 0x80, emu->port + A_GPIO); /* High bit clocks the value into the fpga. */
udelay(10);
outw(value, emu->port + A_GPIO);
udelay(10);
outw(value | 0x80 , emu->port + A_GPIO); /* High bit clocks the value into the fpga. */
udelay(10);
Annotation
- Immediate include surface: `linux/time.h`, `sound/core.h`, `sound/emu10k1.h`, `linux/delay.h`, `linux/export.h`, `p17v.h`.
- Detected declarations: `function Copyright`, `function snd_emu10k1_ptr_read`, `function scoped_guard`, `function snd_emu10k1_ptr_write`, `function snd_emu10k1_ptr_write_multiple`, `function snd_emu10k1_ptr20_read`, `function snd_emu10k1_ptr20_write`, `function snd_emu10k1_spi_write`, `function snd_emu10k1_i2c_write`, `function snd_emu1010_fpga_write_locked`.
- Atlas domain: Driver Families / sound/pci.
- Implementation status: integration 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.