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
59 .group = (SNDRV_CTL_ELEM_ACCESS_SPK_LED >> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1,
61 .mode = MODE_FOLLOW_MUTE,
65 .group = (SNDRV_CTL_ELEM_ACCESS_MIC_LED >> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1,
67 .mode = MODE_FOLLOW_MUTE,
84 SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1; in access_to_group()
108 struct snd_kcontrol *kctl = lctl->kctl; in snd_ctl_led_get()
113 info.id = kctl->id; in snd_ctl_led_get()
114 info.id.index += lctl->index_offset; in snd_ctl_led_get()
115 info.id.numid += lctl->index_offset; in snd_ctl_led_get()
116 result = kctl->info(kctl, &info); in snd_ctl_led_get()
118 return -1; in snd_ctl_led_get()
121 result = kctl->get(kctl, &value); in snd_ctl_led_get()
123 return -1; in snd_ctl_led_get()
140 struct snd_ctl_led *led; in snd_ctl_led_set_state() local
145 led = snd_ctl_led_get_by_access(access); in snd_ctl_led_set_state()
146 if (!led) in snd_ctl_led_set_state()
148 route = -1; in snd_ctl_led_set_state()
152 if (card && !snd_ctl_led_card_valid[card->number]) { in snd_ctl_led_set_state()
156 list_for_each_entry(lctl, &led->controls, list) { in snd_ctl_led_set_state()
157 if (lctl->kctl == kctl && lctl->index_offset == ioff) in snd_ctl_led_set_state()
164 lctl->card = card; in snd_ctl_led_set_state()
165 lctl->access = access; in snd_ctl_led_set_state()
166 lctl->kctl = kctl; in snd_ctl_led_set_state()
167 lctl->index_offset = ioff; in snd_ctl_led_set_state()
168 list_add(&lctl->list, &led->controls); in snd_ctl_led_set_state()
173 switch (led->mode) { in snd_ctl_led_set_state()
180 ledtrig_audio_set(led->trigger_type, route ? LED_OFF : LED_ON); in snd_ctl_led_set_state()
192 if (lctl->kctl == kctl && lctl->index_offset == ioff) in snd_ctl_led_find()
206 if (lctl && (access == 0 || access != lctl->access)) { in snd_ctl_led_remove()
207 ret = lctl->access; in snd_ctl_led_remove()
208 list_del(&lctl->list); in snd_ctl_led_remove()
226 vd = &kctl->vd[ioff]; in snd_ctl_led_notify()
227 access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK; in snd_ctl_led_notify()
235 vd = &kctl->vd[ioff]; in snd_ctl_led_notify()
236 access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK; in snd_ctl_led_notify()
253 down_write(&card->controls_rwsem); in snd_ctl_led_set_id()
257 vd = &kctl->vd[ioff]; in snd_ctl_led_set_id()
258 access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK; in snd_ctl_led_set_id()
260 err = -EXDEV; in snd_ctl_led_set_id()
263 new_access = vd->access & ~SNDRV_CTL_ELEM_ACCESS_LED_MASK; in snd_ctl_led_set_id()
266 if (new_access != vd->access) { in snd_ctl_led_set_id()
267 vd->access = new_access; in snd_ctl_led_set_id()
271 err = -ENOENT; in snd_ctl_led_set_id()
274 up_write(&card->controls_rwsem); in snd_ctl_led_set_id()
277 err = -ENXIO; in snd_ctl_led_set_id()
292 list_del(&lctl->list); in snd_ctl_led_ctl_destroy()
299 struct snd_ctl_led *led; in snd_ctl_led_clean() local
303 led = &snd_ctl_leds[group]; in snd_ctl_led_clean()
305 list_for_each_entry(lctl, &led->controls, list) in snd_ctl_led_clean()
306 if (!card || lctl->card == card) { in snd_ctl_led_clean()
316 struct snd_ctl_led *led; in snd_ctl_led_reset() local
323 return -ENXIO; in snd_ctl_led_reset()
329 return -ENXIO; in snd_ctl_led_reset()
331 led = &snd_ctl_leds[group]; in snd_ctl_led_reset()
333 list_for_each_entry(lctl, &led->controls, list) in snd_ctl_led_reset()
334 if (lctl->card == card) { in snd_ctl_led_reset()
335 vd = &lctl->kctl->vd[lctl->index_offset]; in snd_ctl_led_reset()
336 vd->access &= ~group_to_access(group); in snd_ctl_led_reset()
353 if (snd_BUG_ON(card->number < 0 || in snd_ctl_led_register()
354 card->number >= ARRAY_SIZE(snd_ctl_led_card_valid))) in snd_ctl_led_register()
357 snd_ctl_led_card_valid[card->number] = true; in snd_ctl_led_register()
359 /* the register callback is already called with held card->controls_rwsem */ in snd_ctl_led_register()
360 list_for_each_entry(kctl, &card->controls, list) in snd_ctl_led_register()
361 for (ioff = 0; ioff < kctl->count; ioff++) in snd_ctl_led_register()
371 snd_ctl_led_card_valid[card->number] = false; in snd_ctl_led_disconnect()
399 struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev); in mode_show() local
402 switch (led->mode) { in mode_show()
403 case MODE_FOLLOW_MUTE: str = "follow-mute"; break; in mode_show()
404 case MODE_FOLLOW_ROUTE: str = "follow-route"; break; in mode_show()
415 struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev); in mode_store() local
417 size_t l = min(count, sizeof(_buf) - 1); in mode_store()
418 enum snd_ctl_led_mode mode; in mode_store() local
423 mode = MODE_FOLLOW_MUTE; in mode_store()
425 mode = MODE_FOLLOW_ROUTE; in mode_store()
427 mode = MODE_OFF; in mode_store()
429 mode = MODE_ON; in mode_store()
434 led->mode = mode; in mode_store()
437 snd_ctl_led_set_state(NULL, group_to_access(led->group), NULL, 0); in mode_store()
444 struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev); in brightness_show() local
446 return sysfs_emit(buf, "%u\n", ledtrig_audio_get(led->trigger_type)); in brightness_show()
449 static DEVICE_ATTR_RW(mode);
493 val_size--; in parse_string()
501 val_size--; in parse_string()
524 * unsigned integer - numid (equivaled to numid=UINT)
525 * string - basic mixer name (equivalent to iface=MIXER,name=STR)
537 return -E2BIG; in set_led_id()
576 err = snd_ctl_led_set_id(led_card->number, &id, led_card->led->group, attach); in set_led_id()
607 err = snd_ctl_led_reset(led_card->number, led_card->led->group); in reset_store()
622 card = snd_card_ref(led_card->number); in list_show()
624 return -ENXIO; in list_show()
625 down_read(&card->controls_rwsem); in list_show()
627 if (snd_ctl_led_card_valid[led_card->number]) { in list_show()
628 list_for_each_entry(lctl, &led_card->led->controls, list) { in list_show()
629 if (lctl->card != card) in list_show()
634 lctl->kctl->id.numid + lctl->index_offset); in list_show()
638 up_read(&card->controls_rwsem); in list_show()
671 struct snd_ctl_led *led; in snd_ctl_led_sysfs_add() local
675 led = &snd_ctl_leds[group]; in snd_ctl_led_sysfs_add()
679 led_card->number = card->number; in snd_ctl_led_sysfs_add()
680 led_card->led = led; in snd_ctl_led_sysfs_add()
681 device_initialize(&led_card->dev); in snd_ctl_led_sysfs_add()
682 led_card->dev.release = snd_ctl_led_card_release; in snd_ctl_led_sysfs_add()
683 if (dev_set_name(&led_card->dev, "card%d", card->number) < 0) in snd_ctl_led_sysfs_add()
685 led_card->dev.parent = &led->dev; in snd_ctl_led_sysfs_add()
686 led_card->dev.groups = snd_ctl_led_card_attr_groups; in snd_ctl_led_sysfs_add()
687 if (device_add(&led_card->dev)) in snd_ctl_led_sysfs_add()
689 led->cards[card->number] = led_card; in snd_ctl_led_sysfs_add()
690 snprintf(link_name, sizeof(link_name), "led-%s", led->name); in snd_ctl_led_sysfs_add()
691 if (sysfs_create_link(&card->ctl_dev->kobj, &led_card->dev.kobj, in snd_ctl_led_sysfs_add()
693 dev_err(card->dev, in snd_ctl_led_sysfs_add()
695 __func__, card->number); in snd_ctl_led_sysfs_add()
696 if (sysfs_create_link(&led_card->dev.kobj, &card->card_dev.kobj, in snd_ctl_led_sysfs_add()
698 dev_err(card->dev, in snd_ctl_led_sysfs_add()
700 __func__, card->number); in snd_ctl_led_sysfs_add()
704 put_device(&led_card->dev); in snd_ctl_led_sysfs_add()
706 printk(KERN_ERR "snd_ctl_led: unable to add card%d", card->number); in snd_ctl_led_sysfs_add()
714 struct snd_ctl_led *led; in snd_ctl_led_sysfs_remove() local
718 led = &snd_ctl_leds[group]; in snd_ctl_led_sysfs_remove()
719 led_card = led->cards[card->number]; in snd_ctl_led_sysfs_remove()
722 snprintf(link_name, sizeof(link_name), "led-%s", led->name); in snd_ctl_led_sysfs_remove()
723 sysfs_remove_link(&card->ctl_dev->kobj, link_name); in snd_ctl_led_sysfs_remove()
724 sysfs_remove_link(&led_card->dev.kobj, "card"); in snd_ctl_led_sysfs_remove()
725 device_unregister(&led_card->dev); in snd_ctl_led_sysfs_remove()
726 led->cards[card->number] = NULL; in snd_ctl_led_sysfs_remove()
742 struct snd_ctl_led *led; in snd_ctl_led_init() local
748 dev_set_name(&snd_ctl_led_dev, "ctl-led"); in snd_ctl_led_init()
751 return -ENOMEM; in snd_ctl_led_init()
754 led = &snd_ctl_leds[group]; in snd_ctl_led_init()
755 INIT_LIST_HEAD(&led->controls); in snd_ctl_led_init()
756 device_initialize(&led->dev); in snd_ctl_led_init()
757 led->dev.parent = &snd_ctl_led_dev; in snd_ctl_led_init()
758 led->dev.release = snd_ctl_led_release; in snd_ctl_led_init()
759 led->dev.groups = snd_ctl_led_dev_attr_groups; in snd_ctl_led_init()
760 dev_set_name(&led->dev, led->name); in snd_ctl_led_init()
761 if (device_add(&led->dev)) { in snd_ctl_led_init()
762 put_device(&led->dev); in snd_ctl_led_init()
763 for (; group > 0; group--) { in snd_ctl_led_init()
764 led = &snd_ctl_leds[group - 1]; in snd_ctl_led_init()
765 device_unregister(&led->dev); in snd_ctl_led_init()
768 return -ENOMEM; in snd_ctl_led_init()
777 struct snd_ctl_led *led; in snd_ctl_led_exit() local
792 led = &snd_ctl_leds[group]; in snd_ctl_led_exit()
793 device_unregister(&led->dev); in snd_ctl_led_exit()