drivers/media/usb/em28xx/em28xx-core.c
Source file repositories/reference/linux-study-clean/drivers/media/usb/em28xx/em28xx-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/usb/em28xx/em28xx-core.c- Extension
.c- Size
- 33102 bytes
- Lines
- 1305
- Domain
- Driver Families
- Bucket
- drivers/media
- 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.
- 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
em28xx.hlinux/init.hlinux/jiffies.hlinux/list.hlinux/module.hlinux/slab.hlinux/usb.hlinux/vmalloc.hsound/ac97_codec.hmedia/v4l2-common.h
Detected Declarations
struct em28xx_vol_itablestruct em28xx_vol_otablefunction em28xx_read_reg_reqfunction em28xx_read_reg_reqfunction em28xx_read_regfunction em28xx_write_regs_reqfunction em28xx_write_regsfunction em28xx_write_regfunction em28xx_write_reg_bitsfunction em28xx_toggle_reg_bitsfunction em28xx_is_ac97_readyfunction em28xx_read_ac97function em28xx_write_ac97function set_ac97_inputfunction em28xx_set_audio_sourcefunction em28xx_audio_analog_setfunction em28xx_audio_setupfunction em2828X_decoder_vmuxfunction em28xx_capture_startfunction em28xx_gpio_setfunction em28xx_set_modefunction em28xx_irq_callbackfunction em28xx_uninit_usb_xferfunction em28xx_stop_urbsfunction em28xx_alloc_urbsfunction em28xx_init_usb_xferfunction em28xx_register_extensionfunction em28xx_unregister_extensionfunction em28xx_init_extensionfunction em28xx_close_extensionfunction em28xx_suspend_extensionfunction em28xx_resume_extensionexport em28xx_read_regexport em28xx_write_regsexport em28xx_write_regexport em28xx_write_reg_bitsexport em28xx_toggle_reg_bitsexport em28xx_read_ac97export em28xx_write_ac97export em28xx_audio_analog_setexport em28xx_audio_setupexport em28xx_find_ledexport em2828X_decoder_vmuxexport em28xx_gpio_setexport em28xx_set_modeexport em28xx_uninit_usb_xferexport em28xx_stop_urbsexport em28xx_alloc_urbs
Annotated Snippet
struct em28xx_vol_itable {
enum em28xx_amux mux;
u8 reg;
};
static struct em28xx_vol_itable inputs[] = {
{ EM28XX_AMUX_VIDEO, AC97_VIDEO },
{ EM28XX_AMUX_LINE_IN, AC97_LINE },
{ EM28XX_AMUX_PHONE, AC97_PHONE },
{ EM28XX_AMUX_MIC, AC97_MIC },
{ EM28XX_AMUX_CD, AC97_CD },
{ EM28XX_AMUX_AUX, AC97_AUX },
{ EM28XX_AMUX_PCM_OUT, AC97_PCM },
};
static int set_ac97_input(struct em28xx *dev)
{
int ret, i;
enum em28xx_amux amux = dev->ctl_ainput;
/*
* EM28XX_AMUX_VIDEO2 is a special case used to indicate that
* em28xx should point to LINE IN, while AC97 should use VIDEO
*/
if (amux == EM28XX_AMUX_VIDEO2)
amux = EM28XX_AMUX_VIDEO;
/* Mute all entres but the one that were selected */
for (i = 0; i < ARRAY_SIZE(inputs); i++) {
if (amux == inputs[i].mux)
ret = em28xx_write_ac97(dev, inputs[i].reg, 0x0808);
else
ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000);
if (ret < 0)
dev_warn(&dev->intf->dev,
"couldn't setup AC97 register %d\n",
inputs[i].reg);
}
return 0;
}
static int em28xx_set_audio_source(struct em28xx *dev)
{
int ret;
u8 input;
if (dev->board.is_em2800) {
if (dev->ctl_ainput == EM28XX_AMUX_VIDEO)
input = EM2800_AUDIO_SRC_TUNER;
else
input = EM2800_AUDIO_SRC_LINE;
ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1);
if (ret < 0)
return ret;
}
if (dev->has_msp34xx) {
input = EM28XX_AUDIO_SRC_TUNER;
} else {
switch (dev->ctl_ainput) {
case EM28XX_AMUX_VIDEO:
input = EM28XX_AUDIO_SRC_TUNER;
break;
default:
input = EM28XX_AUDIO_SRC_LINE;
break;
}
}
if (dev->board.mute_gpio && dev->mute)
em28xx_gpio_set(dev, dev->board.mute_gpio);
else
em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio);
ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0);
if (ret < 0)
return ret;
usleep_range(10000, 11000);
switch (dev->audio_mode.ac97) {
case EM28XX_NO_AC97:
break;
default:
ret = set_ac97_input(dev);
}
return ret;
}
Annotation
- Immediate include surface: `em28xx.h`, `linux/init.h`, `linux/jiffies.h`, `linux/list.h`, `linux/module.h`, `linux/slab.h`, `linux/usb.h`, `linux/vmalloc.h`.
- Detected declarations: `struct em28xx_vol_itable`, `struct em28xx_vol_otable`, `function em28xx_read_reg_req`, `function em28xx_read_reg_req`, `function em28xx_read_reg`, `function em28xx_write_regs_req`, `function em28xx_write_regs`, `function em28xx_write_reg`, `function em28xx_write_reg_bits`, `function em28xx_toggle_reg_bits`.
- Atlas domain: Driver Families / drivers/media.
- 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.