// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  LED state routines for driver control interface
 *  Copyright (c) 2021 by Jaroslav Kysela <perex@perex.cz>
 */

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/leds.h>
#include <sound/core.h>
#include <sound/control.h>

MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("ALSA control interface to LED trigger code.");
MODULE_LICENSE("GPL");

#define MAX_LED (((SNDRV_CTL_ELEM_ACCESS_MIC_LED - SNDRV_CTL_ELEM_ACCESS_SPK_LED) \
			>> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) + 1)

#define to_led_card_dev(_dev) \
	container_of(_dev, struct snd_ctl_led_card, dev)

enum snd_ctl_led_mode {
	 MODE_FOLLOW_MUTE = 0,
	 MODE_FOLLOW_ROUTE,
	 MODE_OFF,
	 MODE_ON,
};

struct snd_ctl_led_card {
	struct device dev;
	int number;
	struct snd_ctl_led *led;
};

struct snd_ctl_led {
	struct device dev;
	struct list_head controls;
	const char *name;
	unsigned int group;
	enum led_audio trigger_type;
	enum snd_ctl_led_mode mode;
	struct snd_ctl_led_card *cards[SNDRV_CARDS];
};

struct snd_ctl_led_ctl {
	struct list_head list;
	struct snd_card *card;
	unsigned int access;
	struct snd_kcontrol *kctl;
	unsigned int index_offset;
};

static DEFINE_MUTEX(snd_ctl_led_mutex);
static bool snd_ctl_led_card_valid[SNDRV_CARDS];
static struct led_trigger *snd_ctl_ledtrig_audio[NUM_AUDIO_LEDS];
static struct snd_ctl_led snd_ctl_leds[MAX_LED] = {
	{
		.name = "speaker",
		.group = (SNDRV_CTL_ELEM_ACCESS_SPK_LED >> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1,
		.trigger_type = LED_AUDIO_MUTE,
		.mode = MODE_FOLLOW_MUTE,
	},
	{
		.name = "mic",
		.group = (SNDRV_CTL_ELEM_ACCESS_MIC_LED >> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1,
		.trigger_type = LED_AUDIO_MICMUTE,
		.mode = MODE_FOLLOW_MUTE,
	},
};

static void snd_ctl_led_sysfs_add(struct snd_card *card);
static void snd_ctl_led_sysfs_remove(struct snd_card *card);

#define UPDATE_ROUTE(route, cb) \
	do { \
		int route2 = (cb); \
		if (route2 >= 0) \
			route = route < 0 ? route2 : (route | route2); \
	} while (0)

static inline unsigned int access_to_group(unsigned int access)
{
	return ((access & SNDRV_CTL_ELEM_ACCESS_LED_MASK) >>
				SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1;
}

static inline unsigned int group_to_access(unsigned int group)
{
	return (group + 1) << SNDRV_CTL_ELEM_ACCESS_LED_SHIFT;
}

static struct snd_ctl_led *snd_ctl_led_get_by_access(unsigned int access)
{
	unsigned int group = access_to_group(access);
	if (group >= MAX_LED)
		return NULL;
	return &snd_ctl_leds[group];
}

/*
 * A note for callers:
 *   The two static variables info and value are protected using snd_ctl_led_mutex.
 */
static int snd_ctl_led_get(struct snd_ctl_led_ctl *lctl)
{
	static struct snd_ctl_elem_info info;
	static struct snd_ctl_elem_value value;
	struct snd_kcontrol *kctl = lctl->kctl;
	unsigned int i;
	int result;

	memset(&info, 0, sizeof(info));
	info.id = kctl->id;
	info.id.index += lctl->index_offset;
	info.id.numid += lctl->index_offset;
	result = kctl->info(kctl, &info);
	if (result < 0)
		return -1;
	memset(&value, 0, sizeof(value));
	value.id = info.id;
	result = kctl->get(kctl, &value);
	if (result < 0)
		return -1;
	if (info.type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
	    info.type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
		for (i = 0; i < info.count; i++)
			if (value.value.integer.value[i] != info.value.integer.min)
				return 1;
	} else if (info.type == SNDRV_CTL_ELEM_TYPE_INTEGER64) {
		for (i = 0; i < info.count; i++)
			if (value.value.integer64.value[i] != info.value.integer64.min)
				return 1;
	}
	return 0;
}

static void snd_ctl_led_set_state(struct snd_card *card, unsigned int access,
				  struct snd_kcontrol *kctl, unsigned int ioff)
{
	struct snd_ctl_led *led;
	struct snd_ctl_led_ctl *lctl;
	int route;
	bool found;

	led = snd_ctl_led_get_by_access(access);
	if (!led)
		return;
	route = -1;
	found = false;
	scoped_guard(mutex, &snd_ctl_led_mutex) {
		/* the card may not be registered (active) at this point */
		if (card && !snd_ctl_led_card_valid[card->number])
			return;
		list_for_each_entry(lctl, &led->controls, list) {
			if (lctl->kctl == kctl && lctl->index_offset == ioff)
				found = true;
			UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
		}
		if (!found && kctl && card) {
			lctl = kzalloc(sizeof(*lctl), GFP_KERNEL);
			if (lctl) {
				lctl->card = card;
				lctl->access = access;
				lctl->kctl = kctl;
				lctl->index_offset = ioff;
				list_add(&lctl->list, &led->controls);
				UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
			}
		}
	}
	switch (led->mode) {
	case MODE_OFF:		route = 1; break;
	case MODE_ON:		route = 0; break;
	case MODE_FOLLOW_ROUTE:	if (route >= 0) route ^= 1; break;
	case MODE_FOLLOW_MUTE:	/* noop */ break;
	}
	if (route >= 0) {
		struct led_trigger *trig = snd_ctl_ledtrig_audio[led->trigger_type];

		led_trigger_event(trig, route ? LED_OFF : LED_ON);
	}
}

static struct snd_ctl_led_ctl *snd_ctl_led_find(struct snd_kcontrol *kctl, unsigned int ioff)
{
	struct list_head *controls;
	struct snd_ctl_led_ctl *lctl;
	unsigned int group;

	for (group = 0; group < MAX_LED; group++) {
		controls = &snd_ctl_leds[group].controls;
		list_for_each_entry(lctl, controls, list)
			if (lctl->kctl == kctl && lctl->index_offset == ioff)
				return lctl;
	}
	return NULL;
}

static unsigned int snd_ctl_led_remove(struct snd_kcontrol *kctl, unsigned int ioff,
				       unsigned int access)
{
	struct snd_ctl_led_ctl *lctl;
	unsigned int ret = 0;

	guard(mutex)(&snd_ctl_led_mutex);
	lctl = snd_ctl_led_find(kctl, ioff);
	if (lctl && (access == 0 || access != lctl->access)) {
		ret = lctl->access;
		list_del(&lctl->list);
		kfree(lctl);
	}
	return ret;
}

static void snd_ctl_led_notify(struct snd_card *card, unsigned int mask,
			       struct snd_kcontrol *kctl, unsigned int ioff)
{
	struct snd_kcontrol_volatile *vd;
	unsigned int access, access2;

	if (mask == SNDRV_CTL_EVENT_MASK_REMOVE) {
		access = snd_ctl_led_remove(kctl, ioff, 0);
		if (access)
			snd_ctl_led_set_state(card, access, NULL, 0);
	} else if (mask & SNDRV_CTL_EVENT_MASK_INFO) {
		vd = &kctl->vd[ioff];
		access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
		access2 = snd_ctl_led_remove(kctl, ioff, access);
		if (access2)
			snd_ctl_led_set_state(card, access2, NULL, 0);
		if (access)
			snd_ctl_led_set_state(card, access, kctl, ioff);
	} else if ((mask & (SNDRV_CTL_EVENT_MASK_ADD |
			    SNDRV_CTL_EVENT_MASK_VALUE)) != 0) {
		vd = &kctl->vd[ioff];
		access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
		if (access)
			snd_ctl_led_set_state(card, access, kctl, ioff);
	}
}

DEFINE_FREE(snd_card_unref, struct snd_card *, if (_T) snd_card_unref(_T))

static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id,
			      unsigned int group, bool set)
{
	struct snd_card *card __free(snd_card_unref) = NULL;
	struct snd_kcontrol *kctl;
	struct snd_kcontrol_volatile *vd;
	unsigned int ioff, access, new_access;

	card = snd_card_ref(card_number);
	if (!card)
		return -ENXIO;
	guard(rwsem_write)(&card->controls_rwsem);
	kctl = snd_ctl_find_id_locked(card, id);
	if (!kctl)
		return -ENOENT;
	ioff = snd_ctl_get_ioff(kctl, id);
	vd = &kctl->vd[ioff];
	access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
	if (access != 0 && access != group_to_access(group))
		return -EXDEV;
	new_access = vd->access & ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
	if (set)
		new_access |= group_to_access(group);
	if (new_access != vd->access) {
		vd->access = new_access;
		snd_ctl_led_notify(card, SNDRV_CTL_EVENT_MASK_INFO, kctl, ioff);
	}
	return 0;
}

static void snd_ctl_led_refresh(void)
{
	unsigned int group;

	for (group = 0; group < MAX_LED; group++)
		snd_ctl_led_set_state(NULL, group_to_access(group), NULL, 0);
}

static void snd_ctl_led_ctl_destroy(struct snd_ctl_led_ctl *lctl)
{
	list_del(&lctl->list);
	kfree(lctl);
}

static void snd_ctl_led_clean(struct snd_card *card)
{
	unsigned int group;
	struct snd_ctl_led_ctl *lctl, *_lctl;
	struct snd_ctl_led *led;

	for (group = 0; group < MAX_LED; group++) {
		led = &snd_ctl_leds[group];
		list_for_each_entry_safe(lctl, _lctl, &led->controls, list)
			if (!card || lctl->card == card)
				snd_ctl_led_ctl_destroy(lctl);
	}
}

static int snd_ctl_led_reset(int card_number, unsigned int group)
{
	struct snd_card *card __free(snd_card_unref) = NULL;
	struct snd_ctl_led_ctl *lctl, *_lctl;
	struct snd_ctl_led *led;
	struct snd_kcontrol_volatile *vd;
	bool change = false;

	card = snd_card_ref(card_number);
	if (!card)
		return -ENXIO;

	scoped_guard(mutex, &snd_ctl_led_mutex) {
		if (!snd_ctl_led_card_valid[card_number])
			return -ENXIO;
		led = &snd_ctl_leds[group];
		list_for_each_entry_safe(lctl, _lctl, &led->controls, list)
			if (lctl->card == card) {
				vd = &lctl->kctl->vd[lctl->index_offset];
				vd->access &= ~group_to_access(group);
				snd_ctl_led_ctl_destroy(lctl);
				change = true;
			}
	}
	if (change)
		snd_ctl_led_set_state(NULL, group_to_access(group), NULL, 0);
	return 0;
}

static void snd_ctl_led_register(struct snd_card *card)
{
	struct snd_kcontrol *kctl;
	unsigned int ioff;

	if (snd_BUG_ON(card->number < 0 ||
		       card->number >= ARRAY_SIZE(snd_ctl_led_card_valid)))
		return;
	scoped_guard(mutex, &snd_ctl_led_mutex)
		snd_ctl_led_card_valid[card->number] = true;
	/* the register callback is already called with held card->controls_rwsem */
	list_for_each_entry(kctl, &card->controls, list)
		for (ioff = 0; ioff < kctl->count; ioff++)
			snd_ctl_led_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, kctl, ioff);
	snd_ctl_led_refresh();
	snd_ctl_led_sysfs_add(card);
}

static void snd_ctl_led_disconnect(struct snd_card *card)
{
	snd_ctl_led_sysfs_remove(card);
	scoped_guard(mutex, &snd_ctl_led_mutex) {
		snd_ctl_led_card_valid[card->number] = false;
		snd_ctl_led_clean(card);
	}
	snd_ctl_led_refresh();
}

static void snd_ctl_led_card_release(struct device *dev)
{
	struct snd_ctl_led_card *led_card = to_led_card_dev(dev);

	kfree(led_card);
}

static void snd_ctl_led_release(struct device *dev)
{
}

static void snd_ctl_led_dev_release(struct device *dev)
{
}

/*
 * sysfs
 */

static ssize_t mode_show(struct device *dev,
			 struct device_attribute *attr, char *buf)
{
	struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
	const char *str = NULL;

	switch (led->mode) {
	case MODE_FOLLOW_MUTE:	str = "follow-mute"; break;
	case MODE_FOLLOW_ROUTE:	str = "follow-route"; break;
	case MODE_ON:		str = "on"; break;
	case MODE_OFF:		str = "off"; break;
	}
	return sysfs_emit(buf, "%s\n", str);
}

static ssize_t mode_store(struct device *dev,
			  struct device_attribute *attr,
			  const char *buf, size_t count)
{
	struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
	char _buf[16];
	size_t l = min(count, sizeof(_buf) - 1);
	enum snd_ctl_led_mode mode;

	memcpy(_buf, buf, l);
	_buf[l] = '\0';
	if (strstr(_buf, "mute"))
		mode = MODE_FOLLOW_MUTE;
	else if (strstr(_buf, "route"))
		mode = MODE_FOLLOW_ROUTE;
	else if (strncmp(_buf, "off", 3) == 0 || strncmp(_buf, "0", 1) == 0)
		mode = MODE_OFF;
	else if (strncmp(_buf, "on", 2) == 0 || strncmp(_buf, "1", 1) == 0)
		mode = MODE_ON;
	else
		return count;

	scoped_guard(mutex, &snd_ctl_led_mutex)
		led->mode = mode;

	snd_ctl_led_set_state(NULL, group_to_access(led->group), NULL, 0);
	return count;
}

static ssize_t brightness_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
	struct led_trigger *trig = snd_ctl_ledtrig_audio[led->trigger_type];

	return sysfs_emit(buf, "%u\n", led_trigger_get_brightness(trig));
}

static DEVICE_ATTR_RW(mode);
static DEVICE_ATTR_RO(brightness);

static struct attribute *snd_ctl_led_dev_attrs[] = {
	&dev_attr_mode.attr,
	&dev_attr_brightness.attr,
	NULL,
};

static const struct attribute_group snd_ctl_led_dev_attr_group = {
	.attrs = snd_ctl_led_dev_attrs,
};

static const struct attribute_group *snd_ctl_led_dev_attr_groups[] = {
	&snd_ctl_led_dev_attr_group,
	NULL,
};

static char *find_eos(char *s)
{
	while (*s && *s != ',')
		s++;
	if (*s)
		s++;
	return s;
}

static char *parse_uint(char *s, unsigned int *val)
{
	unsigned long long res;
	if (kstrtoull(s, 10, &res))
		res = 0;
	*val = res;
	return find_eos(s);
}

static char *parse_string(char *s, char *val, size_t val_size)
{
	if (*s == '"' || *s == '\'') {
		char c = *s;
		s++;
		while (*s && *s != c) {
			if (val_size > 1) {
				*val++ = *s;
				val_size--;
			}
			s++;
		}
	} else {
		while (*s && *s != ',') {
			if (val_size > 1) {
				*val++ = *s;
				val_size--;
			}
			s++;
		}
	}
	*val = '\0';
	if (*s)
		s++;
	return s;
}

static char *parse_iface(char *s, snd_ctl_elem_iface_t *val)
{
	if (!strncasecmp(s, "card", 4))
		*val = SNDRV_CTL_ELEM_IFACE_CARD;
	else if (!strncasecmp(s, "mixer", 5))
		*val = SNDRV_CTL_ELEM_IFACE_MIXER;
	return find_eos(s);
}

/*
 * These types of input strings are accepted:
 *
 *   unsigned integer - numid (equivaled to numid=UINT)
 *   string - basic mixer name (equivalent to iface=MIXER,name=STR)
 *   numid=UINT
 *   [iface=MIXER,][device=UINT,][subdevice=UINT,]name=STR[,index=UINT]
 */
static ssize_t set_led_id(struct snd_ctl_led_card *led_card, const char *buf, size_t count,
			  bool attach)
{
	char buf2[256], *s, *os;
	struct snd_ctl_elem_id id;
	int err;

	if (strscpy(buf2, buf, sizeof(buf2)) < 0)
		return -E2BIG;
	memset(&id, 0, sizeof(id));
	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
	s = buf2;
	while (*s) {
		os = s;
		if (!strncasecmp(s, "numid=", 6)) {
			s = parse_uint(s + 6, &id.numid);
		} else if (!strncasecmp(s, "iface=", 6)) {
			s = parse_iface(s + 6, &id.iface);
		} else if (!strncasecmp(s, "device=", 7)) {
			s = parse_uint(s + 7, &id.device);
		} else if (!strncasecmp(s, "subdevice=", 10)) {
			s = parse_uint(s + 10, &id.subdevice);
		} else if (!strncasecmp(s, "name=", 5)) {
			s = parse_string(s + 5, id.name, sizeof(id.name));
		} else if (!strncasecmp(s, "index=", 6)) {
			s = parse_uint(s + 6, &id.index);
		} else if (s == buf2) {
			while (*s) {
				if (*s < '0' || *s > '9')
					break;
				s++;
			}
			if (*s == '\0')
				parse_uint(buf2, &id.numid);
			else {
				for (; *s >= ' '; s++);
				*s = '\0';
				strscpy(id.name, buf2, sizeof(id.name));
			}
			break;
		}
		if (*s == ',')
			s++;
		if (s == os)
			break;
	}

	err = snd_ctl_led_set_id(led_card->number, &id, led_card->led->group, attach);
	if (err < 0)
		return err;

	return count;
}

static ssize_t attach_store(struct device *dev,
			    struct device_attribute *attr,
			    const char *buf, size_t count)
{
	struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
	return set_led_id(led_card, buf, count, true);
}

static ssize_t detach_store(struct device *dev,
			    struct device_attribute *attr,
			    const char *buf, size_t count)
{
	struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
	return set_led_id(led_card, buf, count, false);
}

static ssize_t reset_store(struct device *dev,
			   struct device_attribute *attr,
			   const char *buf, size_t count)
{
	struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
	int err;

	if (count > 0 && buf[0] == '1') {
		err = snd_ctl_led_reset(led_card->number, led_card->led->group);
		if (err < 0)
			return err;
	}
	return count;
}

static ssize_t list_show(struct device *dev,
			 struct device_attribute *attr, char *buf)
{
	struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
	struct snd_card *card __free(snd_card_unref) = NULL;
	struct snd_ctl_led_ctl *lctl;
	size_t l = 0;

	card = snd_card_ref(led_card->number);
	if (!card)
		return -ENXIO;
	guard(rwsem_read)(&card->controls_rwsem);
	guard(mutex)(&snd_ctl_led_mutex);
	if (snd_ctl_led_card_valid[led_card->number]) {
		list_for_each_entry(lctl, &led_card->led->controls, list) {
			if (lctl->card != card)
				continue;
			if (l)
				l += sysfs_emit_at(buf, l, " ");
			l += sysfs_emit_at(buf, l, "%u",
					   lctl->kctl->id.numid + lctl->index_offset);
		}
	}
	return l;
}

static DEVICE_ATTR_WO(attach);
static DEVICE_ATTR_WO(detach);
static DEVICE_ATTR_WO(reset);
static DEVICE_ATTR_RO(list);

static struct attribute *snd_ctl_led_card_attrs[] = {
	&dev_attr_attach.attr,
	&dev_attr_detach.attr,
	&dev_attr_reset.attr,
	&dev_attr_list.attr,
	NULL,
};

static const struct attribute_group snd_ctl_led_card_attr_group = {
	.attrs = snd_ctl_led_card_attrs,
};

static const struct attribute_group *snd_ctl_led_card_attr_groups[] = {
	&snd_ctl_led_card_attr_group,
	NULL,
};

static struct device snd_ctl_led_dev;

static void snd_ctl_led_sysfs_add(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 = kzalloc(sizeof(*led_card), GFP_KERNEL);
		if (!led_card)
			goto cerr2;
		led_card->number = card->number;
		led_card->led = led;
		device_initialize(&led_card->dev);
		led_card->dev.release = snd_ctl_led_card_release;
		if (dev_set_name(&led_card->dev, "card%d", card->number) < 0)
			goto cerr;
		led_card->dev.parent = &led->dev;
		led_card->dev.groups = snd_ctl_led_card_attr_groups;
		if (device_add(&led_card->dev))
			goto cerr;
		led->cards[card->number] = led_card;
		snprintf(link_name, sizeof(link_name), "led-%s", led->name);
		WARN(sysfs_create_link(&card->ctl_dev->kobj, &led_card->dev.kobj, link_name),
			"can't create symlink to controlC%i device\n", card->number);
		WARN(sysfs_create_link(&led_card->dev.kobj, &card->card_dev.kobj, "card"),
			"can't create symlink to card%i\n", card->number);

		continue;
cerr:
		put_device(&led_card->dev);
cerr2:
		printk(KERN_ERR "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;
}

static void __exit snd_ctl_led_exit(void)
{
	struct snd_ctl_led *led;
	struct snd_card *card;
	unsigned int group, card_number;

	snd_ctl_disconnect_layer(&snd_ctl_led_lops);
	for (card_number = 0; card_number < SNDRV_CARDS; card_number++) {
		if (!snd_ctl_led_card_valid[card_number])
			continue;
		card = snd_card_ref(card_number);
		if (card) {
			snd_ctl_led_sysfs_remove(card);
			snd_card_unref(card);
		}
	}
	for (group = 0; group < MAX_LED; group++) {
		led = &snd_ctl_leds[group];
		device_unregister(&led->dev);
	}
	device_unregister(&snd_ctl_led_dev);
	snd_ctl_led_clean(NULL);

	led_trigger_unregister_simple(snd_ctl_ledtrig_audio[LED_AUDIO_MUTE]);
	led_trigger_unregister_simple(snd_ctl_ledtrig_audio[LED_AUDIO_MICMUTE]);
}

module_init(snd_ctl_led_init)
module_exit(snd_ctl_led_exit)

MODULE_ALIAS("ledtrig:audio-mute");
MODULE_ALIAS("ledtrig:audio-micmute");
