From: Phil Sutter <phil@nwl.cc>
To: Pavel Machek <pavel@ucw.cz>
Cc: linux-leds@vger.kernel.org
Subject: [PATCH] leds: trigger: Add invert attribute to ledtrig-audio
Date: Mon, 9 Aug 2021 14:29:10 +0200 [thread overview]
Message-ID: <20210809122910.11580-1-phil@nwl.cc> (raw)
Inverting micmute LED used to be possible via a mixer setting, but
conversion to LEDs class (probably) killed it. Re-establish the old
functionality via sysfs attribute in audio LED triggers.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
drivers/leds/trigger/ledtrig-audio.c | 106 ++++++++++++++++++++++++++-
1 file changed, 102 insertions(+), 4 deletions(-)
diff --git a/drivers/leds/trigger/ledtrig-audio.c b/drivers/leds/trigger/ledtrig-audio.c
index f76621e88482d..319ac4f514dfd 100644
--- a/drivers/leds/trigger/ledtrig-audio.c
+++ b/drivers/leds/trigger/ledtrig-audio.c
@@ -6,9 +6,12 @@
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
static struct led_trigger *ledtrig_audio[NUM_AUDIO_LEDS];
static enum led_brightness audio_state[NUM_AUDIO_LEDS];
+static bool led_invert[NUM_AUDIO_LEDS];
enum led_brightness ledtrig_audio_get(enum led_audio type)
{
@@ -18,17 +21,112 @@ EXPORT_SYMBOL_GPL(ledtrig_audio_get);
void ledtrig_audio_set(enum led_audio type, enum led_brightness state)
{
+ if (led_invert[type])
+ state = !state;
+
audio_state[type] = state;
led_trigger_event(ledtrig_audio[type], state);
}
EXPORT_SYMBOL_GPL(ledtrig_audio_set);
+static ssize_t do_invert_show(enum led_audio type, char *buf)
+{
+ return sprintf(buf, "%u\n", led_invert[type]);
+}
+
+static ssize_t mute_invert_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return do_invert_show(LED_AUDIO_MUTE, buf);
+}
+
+static ssize_t micmute_invert_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return do_invert_show(LED_AUDIO_MICMUTE, buf);
+}
+
+static ssize_t do_invert_store(enum led_audio type,
+ const char *buf, size_t size)
+{
+ unsigned long state;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &state);
+ if (ret)
+ return ret;
+
+ led_invert[type] = !!state;
+ ledtrig_audio_set(type, audio_state[type]);
+
+ return size;
+}
+
+static ssize_t mute_invert_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ return do_invert_store(LED_AUDIO_MUTE, buf, size);
+}
+
+static ssize_t micmute_invert_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ return do_invert_store(LED_AUDIO_MICMUTE, buf, size);
+}
+
+static struct device_attribute dev_attr_mute_invert =
+ __ATTR(invert, 0644, mute_invert_show, mute_invert_store);
+
+static struct attribute *audio_mute_trig_attrs[] = {
+ &dev_attr_mute_invert.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(audio_mute_trig);
+
+static struct device_attribute dev_attr_micmute_invert =
+ __ATTR(invert, 0644, micmute_invert_show, micmute_invert_store);
+
+static struct attribute *audio_micmute_trig_attrs[] = {
+ &dev_attr_micmute_invert.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(audio_micmute_trig);
+
+static void __init do_ledtrig_audio_init(const char *name,
+ enum led_audio type,
+ const struct attribute_group **groups)
+{
+ struct led_trigger *trigger;
+ int err;
+
+ trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
+ if (!trigger) {
+ pr_warn("LED trigger %s failed to register (no memory)\n",
+ name);
+ goto out;
+ }
+
+ trigger->name = name;
+ trigger->groups = groups;
+
+ err = led_trigger_register(trigger);
+ if (err < 0) {
+ kfree(trigger);
+ trigger = NULL;
+ pr_warn("LED trigger %s failed to register (%d)\n", name, err);
+ }
+out:
+ ledtrig_audio[type] = trigger;
+}
+
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]);
+ do_ledtrig_audio_init("audio-mute", LED_AUDIO_MUTE,
+ audio_mute_trig_groups);
+ do_ledtrig_audio_init("audio-micmute", LED_AUDIO_MICMUTE,
+ audio_micmute_trig_groups);
return 0;
}
module_init(ledtrig_audio_init);
--
2.32.0
next reply other threads:[~2021-08-09 12:29 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-09 12:29 Phil Sutter [this message]
2021-08-09 18:11 ` [PATCH] leds: trigger: Add invert attribute to ledtrig-audio Pavel Machek
2021-08-10 9:22 ` Phil Sutter
2021-08-10 13:52 ` Pavel Machek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210809122910.11580-1-phil@nwl.cc \
--to=phil@nwl.cc \
--cc=linux-leds@vger.kernel.org \
--cc=pavel@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).