sound/core/control_led.c
Source file repositories/reference/linux-study-clean/sound/core/control_led.c
File Facts
- System
- Linux kernel
- Corpus path
sound/core/control_led.c- Extension
.c- Size
- 20539 bytes
- Lines
- 787
- Domain
- Driver Families
- Bucket
- sound/core
- 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.
- 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/slab.hlinux/module.hlinux/leds.hsound/core.hsound/control.h
Detected Declarations
struct snd_ctl_led_cardstruct snd_ctl_ledstruct snd_ctl_led_ctlenum snd_ctl_led_modefunction access_to_groupfunction group_to_accessfunction snd_ctl_led_getfunction snd_ctl_led_set_statefunction list_for_each_entryfunction snd_ctl_led_removefunction snd_ctl_led_notifyfunction snd_ctl_led_set_idfunction snd_ctl_led_refreshfunction snd_ctl_led_ctl_destroyfunction snd_ctl_led_cleanfunction snd_ctl_led_resetfunction scoped_guardfunction list_for_each_entry_safefunction snd_ctl_led_registerfunction snd_ctl_led_disconnectfunction snd_ctl_led_card_releasefunction snd_ctl_led_releasefunction mode_storefunction brightness_showfunction set_led_idfunction attach_storefunction detach_storefunction reset_storefunction list_showfunction list_for_each_entryfunction snd_ctl_led_sysfs_addfunction snd_ctl_led_sysfs_removefunction snd_ctl_led_initfunction snd_ctl_led_exitmodule init snd_ctl_led_init
Annotated Snippet
if (device_add(&led_card->dev))
goto cerr;
led->cards[card->number] = led_card;
snprintf(link_name, sizeof(link_name), "led-%s", led->name);
if (sysfs_create_link(&card->ctl_dev->kobj, &led_card->dev.kobj,
link_name))
dev_err(card->dev,
"%s: can't create symlink to controlC%i device\n",
__func__, card->number);
if (sysfs_create_link(&led_card->dev.kobj, &card->card_dev.kobj,
"card"))
dev_err(card->dev,
"%s: can't create symlink to card%i\n",
__func__, card->number);
continue;
cerr:
put_device(&led_card->dev);
cerr2:
dev_err(card->dev, "snd_ctl_led: unable to add card%d", card->number);
}
}
static void snd_ctl_led_sysfs_remove(struct snd_card *card)
{
unsigned int group;
struct snd_ctl_led_card *led_card;
struct snd_ctl_led *led;
char link_name[32];
for (group = 0; group < MAX_LED; group++) {
led = &snd_ctl_leds[group];
led_card = led->cards[card->number];
if (!led_card)
continue;
snprintf(link_name, sizeof(link_name), "led-%s", led->name);
sysfs_remove_link(&card->ctl_dev->kobj, link_name);
sysfs_remove_link(&led_card->dev.kobj, "card");
device_unregister(&led_card->dev);
led->cards[card->number] = NULL;
}
}
/*
* Control layer registration
*/
static struct snd_ctl_layer_ops snd_ctl_led_lops = {
.module_name = SND_CTL_LAYER_MODULE_LED,
.lregister = snd_ctl_led_register,
.ldisconnect = snd_ctl_led_disconnect,
.lnotify = snd_ctl_led_notify,
};
static int __init snd_ctl_led_init(void)
{
struct snd_ctl_led *led;
unsigned int group;
led_trigger_register_simple("audio-mute", &snd_ctl_ledtrig_audio[LED_AUDIO_MUTE]);
led_trigger_register_simple("audio-micmute", &snd_ctl_ledtrig_audio[LED_AUDIO_MICMUTE]);
device_initialize(&snd_ctl_led_dev);
snd_ctl_led_dev.class = &sound_class;
snd_ctl_led_dev.release = snd_ctl_led_dev_release;
dev_set_name(&snd_ctl_led_dev, "ctl-led");
if (device_add(&snd_ctl_led_dev)) {
put_device(&snd_ctl_led_dev);
return -ENOMEM;
}
for (group = 0; group < MAX_LED; group++) {
led = &snd_ctl_leds[group];
INIT_LIST_HEAD(&led->controls);
device_initialize(&led->dev);
led->dev.parent = &snd_ctl_led_dev;
led->dev.release = snd_ctl_led_release;
led->dev.groups = snd_ctl_led_dev_attr_groups;
dev_set_name(&led->dev, led->name);
if (device_add(&led->dev)) {
put_device(&led->dev);
for (; group > 0; group--) {
led = &snd_ctl_leds[group - 1];
device_unregister(&led->dev);
}
device_unregister(&snd_ctl_led_dev);
return -ENOMEM;
}
}
snd_ctl_register_layer(&snd_ctl_led_lops);
return 0;
}
Annotation
- Immediate include surface: `linux/slab.h`, `linux/module.h`, `linux/leds.h`, `sound/core.h`, `sound/control.h`.
- Detected declarations: `struct snd_ctl_led_card`, `struct snd_ctl_led`, `struct snd_ctl_led_ctl`, `enum snd_ctl_led_mode`, `function access_to_group`, `function group_to_access`, `function snd_ctl_led_get`, `function snd_ctl_led_set_state`, `function list_for_each_entry`, `function snd_ctl_led_remove`.
- Atlas domain: Driver Families / sound/core.
- Implementation status: integration 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.