diff options
Diffstat (limited to 'drivers/leds/trigger')
-rw-r--r-- | drivers/leds/trigger/Kconfig | 7 | ||||
-rw-r--r-- | drivers/leds/trigger/Makefile | 1 | ||||
-rw-r--r-- | drivers/leds/trigger/ledtrig-audio.c | 44 | ||||
-rw-r--r-- | drivers/leds/trigger/ledtrig-pattern.c | 27 |
4 files changed, 60 insertions, 19 deletions
diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig index b76fc3cdc8f8..23cc85e2e0e5 100644 --- a/drivers/leds/trigger/Kconfig +++ b/drivers/leds/trigger/Kconfig @@ -136,4 +136,11 @@ config LEDS_TRIGGER_PATTERN which is a series of tuples, of brightness and duration (ms). If unsure, say N +config LEDS_TRIGGER_AUDIO + tristate "Audio Mute LED Trigger" + help + This allows LEDs to be controlled by audio drivers for following + the audio mute and mic-mute changes. + If unsure, say N + endif # LEDS_TRIGGERS diff --git a/drivers/leds/trigger/Makefile b/drivers/leds/trigger/Makefile index 9bcb64ee8123..733a83e2a718 100644 --- a/drivers/leds/trigger/Makefile +++ b/drivers/leds/trigger/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledtrig-panic.o obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o obj-$(CONFIG_LEDS_TRIGGER_PATTERN) += ledtrig-pattern.o +obj-$(CONFIG_LEDS_TRIGGER_AUDIO) += ledtrig-audio.o diff --git a/drivers/leds/trigger/ledtrig-audio.c b/drivers/leds/trigger/ledtrig-audio.c new file mode 100644 index 000000000000..f76621e88482 --- /dev/null +++ b/drivers/leds/trigger/ledtrig-audio.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Audio Mute LED trigger +// + +#include <linux/kernel.h> +#include <linux/leds.h> +#include <linux/module.h> + +static struct led_trigger *ledtrig_audio[NUM_AUDIO_LEDS]; +static enum led_brightness audio_state[NUM_AUDIO_LEDS]; + +enum led_brightness ledtrig_audio_get(enum led_audio type) +{ + return audio_state[type]; +} +EXPORT_SYMBOL_GPL(ledtrig_audio_get); + +void ledtrig_audio_set(enum led_audio type, enum led_brightness state) +{ + audio_state[type] = state; + led_trigger_event(ledtrig_audio[type], state); +} +EXPORT_SYMBOL_GPL(ledtrig_audio_set); + +static int __init ledtrig_audio_init(void) +{ + led_trigger_register_simple("audio-mute", + &ledtrig_audio[LED_AUDIO_MUTE]); + led_trigger_register_simple("audio-micmute", + &ledtrig_audio[LED_AUDIO_MICMUTE]); + return 0; +} +module_init(ledtrig_audio_init); + +static void __exit ledtrig_audio_exit(void) +{ + led_trigger_unregister_simple(ledtrig_audio[LED_AUDIO_MUTE]); + led_trigger_unregister_simple(ledtrig_audio[LED_AUDIO_MICMUTE]); +} +module_exit(ledtrig_audio_exit); + +MODULE_DESCRIPTION("LED trigger for audio mute control"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/leds/trigger/ledtrig-pattern.c b/drivers/leds/trigger/ledtrig-pattern.c index ce7acd115dd8..1870cf87afe1 100644 --- a/drivers/leds/trigger/ledtrig-pattern.c +++ b/drivers/leds/trigger/ledtrig-pattern.c @@ -75,8 +75,6 @@ static void pattern_trig_timer_function(struct timer_list *t) { struct pattern_trig_data *data = from_timer(data, t, timer); - mutex_lock(&data->lock); - for (;;) { if (!data->is_indefinite && !data->repeat) break; @@ -87,9 +85,10 @@ static void pattern_trig_timer_function(struct timer_list *t) data->curr->brightness); mod_timer(&data->timer, jiffies + msecs_to_jiffies(data->curr->delta_t)); - - /* Skip the tuple with zero duration */ - pattern_trig_update_patterns(data); + if (!data->next->delta_t) { + /* Skip the tuple with zero duration */ + pattern_trig_update_patterns(data); + } /* Select next tuple */ pattern_trig_update_patterns(data); } else { @@ -116,8 +115,6 @@ static void pattern_trig_timer_function(struct timer_list *t) break; } - - mutex_unlock(&data->lock); } static int pattern_trig_start_pattern(struct led_classdev *led_cdev) @@ -176,14 +173,10 @@ static ssize_t repeat_store(struct device *dev, struct device_attribute *attr, if (res < -1 || res == 0) return -EINVAL; - /* - * Clear previous patterns' performence firstly, and remove the timer - * without mutex lock to avoid dead lock. - */ - del_timer_sync(&data->timer); - mutex_lock(&data->lock); + del_timer_sync(&data->timer); + if (data->is_hw_pattern) led_cdev->pattern_clear(led_cdev); @@ -234,14 +227,10 @@ static ssize_t pattern_trig_store_patterns(struct led_classdev *led_cdev, struct pattern_trig_data *data = led_cdev->trigger_data; int ccount, cr, offset = 0, err = 0; - /* - * Clear previous patterns' performence firstly, and remove the timer - * without mutex lock to avoid dead lock. - */ - del_timer_sync(&data->timer); - mutex_lock(&data->lock); + del_timer_sync(&data->timer); + if (data->is_hw_pattern) led_cdev->pattern_clear(led_cdev); |