Lines Matching +full:led +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * LED state routines for driver control interface
14 MODULE_DESCRIPTION("ALSA control interface to LED trigger code.");
17 #define MAX_LED (((SNDRV_CTL_ELEM_ACCESS_MIC_LED - SNDRV_CTL_ELEM_ACCESS_SPK_LED) \
33 struct snd_ctl_led *led; member
42 enum snd_ctl_led_mode mode; member
60 .group = (SNDRV_CTL_ELEM_ACCESS_SPK_LED >> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1,
62 .mode = MODE_FOLLOW_MUTE,
66 .group = (SNDRV_CTL_ELEM_ACCESS_MIC_LED >> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1,
68 .mode = MODE_FOLLOW_MUTE,
85 SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1; in access_to_group()
109 struct snd_kcontrol *kctl = lctl->kctl; in snd_ctl_led_get()
114 info.id = kctl->id; in snd_ctl_led_get()
115 info.id.index += lctl->index_offset; in snd_ctl_led_get()
116 info.id.numid += lctl->index_offset; in snd_ctl_led_get()
117 result = kctl->info(kctl, &info); in snd_ctl_led_get()
119 return -1; in snd_ctl_led_get()
122 result = kctl->get(kctl, &value); in snd_ctl_led_get()
124 return -1; in snd_ctl_led_get()
141 struct snd_ctl_led *led; in snd_ctl_led_set_state() local
146 led = snd_ctl_led_get_by_access(access); in snd_ctl_led_set_state()
147 if (!led) in snd_ctl_led_set_state()
149 route = -1; in snd_ctl_led_set_state()
153 if (card && !snd_ctl_led_card_valid[card->number]) in snd_ctl_led_set_state()
155 list_for_each_entry(lctl, &led->controls, list) { in snd_ctl_led_set_state()
156 if (lctl->kctl == kctl && lctl->index_offset == ioff) in snd_ctl_led_set_state()
163 lctl->card = card; in snd_ctl_led_set_state()
164 lctl->access = access; in snd_ctl_led_set_state()
165 lctl->kctl = kctl; in snd_ctl_led_set_state()
166 lctl->index_offset = ioff; in snd_ctl_led_set_state()
167 list_add(&lctl->list, &led->controls); in snd_ctl_led_set_state()
172 switch (led->mode) { in snd_ctl_led_set_state()
179 struct led_trigger *trig = snd_ctl_ledtrig_audio[led->trigger_type]; in snd_ctl_led_set_state()
194 if (lctl->kctl == kctl && lctl->index_offset == ioff) in snd_ctl_led_find()
208 if (lctl && (access == 0 || access != lctl->access)) { in snd_ctl_led_remove()
209 ret = lctl->access; in snd_ctl_led_remove()
210 list_del(&lctl->list); in snd_ctl_led_remove()
227 vd = &kctl->vd[ioff]; in snd_ctl_led_notify()
228 access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK; in snd_ctl_led_notify()
236 vd = &kctl->vd[ioff]; in snd_ctl_led_notify()
237 access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK; in snd_ctl_led_notify()
255 return -ENXIO; in DEFINE_FREE()
256 guard(rwsem_write)(&card->controls_rwsem); in DEFINE_FREE()
259 return -ENOENT; in DEFINE_FREE()
261 vd = &kctl->vd[ioff]; in DEFINE_FREE()
262 access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK; in DEFINE_FREE()
264 return -EXDEV; in DEFINE_FREE()
265 new_access = vd->access & ~SNDRV_CTL_ELEM_ACCESS_LED_MASK; in DEFINE_FREE()
268 if (new_access != vd->access) { in DEFINE_FREE()
269 vd->access = new_access; in DEFINE_FREE()
285 list_del(&lctl->list); in snd_ctl_led_ctl_destroy()
293 struct snd_ctl_led *led; in snd_ctl_led_clean() local
296 led = &snd_ctl_leds[group]; in snd_ctl_led_clean()
297 list_for_each_entry_safe(lctl, _lctl, &led->controls, list) in snd_ctl_led_clean()
298 if (!card || lctl->card == card) in snd_ctl_led_clean()
307 struct snd_ctl_led *led; in snd_ctl_led_reset() local
313 return -ENXIO; in snd_ctl_led_reset()
317 return -ENXIO; in snd_ctl_led_reset()
318 led = &snd_ctl_leds[group]; in snd_ctl_led_reset()
319 list_for_each_entry_safe(lctl, _lctl, &led->controls, list) in snd_ctl_led_reset()
320 if (lctl->card == card) { in snd_ctl_led_reset()
321 vd = &lctl->kctl->vd[lctl->index_offset]; in snd_ctl_led_reset()
322 vd->access &= ~group_to_access(group); in snd_ctl_led_reset()
337 if (snd_BUG_ON(card->number < 0 || in snd_ctl_led_register()
338 card->number >= ARRAY_SIZE(snd_ctl_led_card_valid))) in snd_ctl_led_register()
341 snd_ctl_led_card_valid[card->number] = true; in snd_ctl_led_register()
342 /* the register callback is already called with held card->controls_rwsem */ in snd_ctl_led_register()
343 list_for_each_entry(kctl, &card->controls, list) in snd_ctl_led_register()
344 for (ioff = 0; ioff < kctl->count; ioff++) in snd_ctl_led_register()
354 snd_ctl_led_card_valid[card->number] = false; in snd_ctl_led_disconnect()
382 struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev); in mode_show() local
385 switch (led->mode) { in mode_show()
386 case MODE_FOLLOW_MUTE: str = "follow-mute"; break; in mode_show()
387 case MODE_FOLLOW_ROUTE: str = "follow-route"; break; in mode_show()
398 struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev); in mode_store() local
400 size_t l = min(count, sizeof(_buf) - 1); in mode_store()
401 enum snd_ctl_led_mode mode; in mode_store() local
406 mode = MODE_FOLLOW_MUTE; in mode_store()
408 mode = MODE_FOLLOW_ROUTE; in mode_store()
410 mode = MODE_OFF; in mode_store()
412 mode = MODE_ON; in mode_store()
417 led->mode = mode; in mode_store()
419 snd_ctl_led_set_state(NULL, group_to_access(led->group), NULL, 0); in mode_store()
426 struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev); in brightness_show() local
427 struct led_trigger *trig = snd_ctl_ledtrig_audio[led->trigger_type]; in brightness_show()
432 static DEVICE_ATTR_RW(mode);
476 val_size--; in parse_string()
484 val_size--; in parse_string()
507 * unsigned integer - numid (equivaled to numid=UINT)
508 * string - basic mixer name (equivalent to iface=MIXER,name=STR)
520 return -E2BIG; in set_led_id()
559 err = snd_ctl_led_set_id(led_card->number, &id, led_card->led->group, attach); in set_led_id()
590 err = snd_ctl_led_reset(led_card->number, led_card->led->group); in reset_store()
605 card = snd_card_ref(led_card->number); in list_show()
607 return -ENXIO; in list_show()
608 guard(rwsem_read)(&card->controls_rwsem); in list_show()
610 if (snd_ctl_led_card_valid[led_card->number]) { in list_show()
611 list_for_each_entry(lctl, &led_card->led->controls, list) { in list_show()
612 if (lctl->card != card) in list_show()
617 lctl->kctl->id.numid + lctl->index_offset); in list_show()
651 struct snd_ctl_led *led; in snd_ctl_led_sysfs_add() local
655 led = &snd_ctl_leds[group]; in snd_ctl_led_sysfs_add()
659 led_card->number = card->number; in snd_ctl_led_sysfs_add()
660 led_card->led = led; in snd_ctl_led_sysfs_add()
661 device_initialize(&led_card->dev); in snd_ctl_led_sysfs_add()
662 led_card->dev.release = snd_ctl_led_card_release; in snd_ctl_led_sysfs_add()
663 if (dev_set_name(&led_card->dev, "card%d", card->number) < 0) in snd_ctl_led_sysfs_add()
665 led_card->dev.parent = &led->dev; in snd_ctl_led_sysfs_add()
666 led_card->dev.groups = snd_ctl_led_card_attr_groups; in snd_ctl_led_sysfs_add()
667 if (device_add(&led_card->dev)) in snd_ctl_led_sysfs_add()
669 led->cards[card->number] = led_card; in snd_ctl_led_sysfs_add()
670 snprintf(link_name, sizeof(link_name), "led-%s", led->name); in snd_ctl_led_sysfs_add()
671 WARN(sysfs_create_link(&card->ctl_dev->kobj, &led_card->dev.kobj, link_name), in snd_ctl_led_sysfs_add()
672 "can't create symlink to controlC%i device\n", card->number); in snd_ctl_led_sysfs_add()
673 WARN(sysfs_create_link(&led_card->dev.kobj, &card->card_dev.kobj, "card"), in snd_ctl_led_sysfs_add()
674 "can't create symlink to card%i\n", card->number); in snd_ctl_led_sysfs_add()
678 put_device(&led_card->dev); in snd_ctl_led_sysfs_add()
680 dev_err(card->dev, "snd_ctl_led: unable to add card%d", card->number); in snd_ctl_led_sysfs_add()
688 struct snd_ctl_led *led; in snd_ctl_led_sysfs_remove() local
692 led = &snd_ctl_leds[group]; in snd_ctl_led_sysfs_remove()
693 led_card = led->cards[card->number]; in snd_ctl_led_sysfs_remove()
696 snprintf(link_name, sizeof(link_name), "led-%s", led->name); in snd_ctl_led_sysfs_remove()
697 sysfs_remove_link(&card->ctl_dev->kobj, link_name); in snd_ctl_led_sysfs_remove()
698 sysfs_remove_link(&led_card->dev.kobj, "card"); in snd_ctl_led_sysfs_remove()
699 device_unregister(&led_card->dev); in snd_ctl_led_sysfs_remove()
700 led->cards[card->number] = NULL; in snd_ctl_led_sysfs_remove()
716 struct snd_ctl_led *led; in snd_ctl_led_init() local
719 led_trigger_register_simple("audio-mute", &snd_ctl_ledtrig_audio[LED_AUDIO_MUTE]); in snd_ctl_led_init()
720 led_trigger_register_simple("audio-micmute", &snd_ctl_ledtrig_audio[LED_AUDIO_MICMUTE]); in snd_ctl_led_init()
725 dev_set_name(&snd_ctl_led_dev, "ctl-led"); in snd_ctl_led_init()
728 return -ENOMEM; in snd_ctl_led_init()
731 led = &snd_ctl_leds[group]; in snd_ctl_led_init()
732 INIT_LIST_HEAD(&led->controls); in snd_ctl_led_init()
733 device_initialize(&led->dev); in snd_ctl_led_init()
734 led->dev.parent = &snd_ctl_led_dev; in snd_ctl_led_init()
735 led->dev.release = snd_ctl_led_release; in snd_ctl_led_init()
736 led->dev.groups = snd_ctl_led_dev_attr_groups; in snd_ctl_led_init()
737 dev_set_name(&led->dev, led->name); in snd_ctl_led_init()
738 if (device_add(&led->dev)) { in snd_ctl_led_init()
739 put_device(&led->dev); in snd_ctl_led_init()
740 for (; group > 0; group--) { in snd_ctl_led_init()
741 led = &snd_ctl_leds[group - 1]; in snd_ctl_led_init()
742 device_unregister(&led->dev); in snd_ctl_led_init()
745 return -ENOMEM; in snd_ctl_led_init()
754 struct snd_ctl_led *led; in snd_ctl_led_exit() local
769 led = &snd_ctl_leds[group]; in snd_ctl_led_exit()
770 device_unregister(&led->dev); in snd_ctl_led_exit()
782 MODULE_ALIAS("ledtrig:audio-mute");
783 MODULE_ALIAS("ledtrig:audio-micmute");