From: Thomas Tuttle <thinkinginbinary@gmail.com>
To: linux-kernel@vger.kernel.org
Subject: PATCH: Integrate asus_acpi LED's with new LED subsystem
Date: Wed, 5 Jul 2006 22:58:15 -0400 [thread overview]
Message-ID: <20060706025815.GB25835@phoenix> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 139 bytes --]
Again... I'm sorry, Gmail sucks, here's a plain text version against
2.6.17-git25.
Comments are happily accepted.
Thanks,
Thomas Tuttle
[-- Attachment #1.2: asus-acpi-led-subsystem.patch --]
[-- Type: text/plain, Size: 7583 bytes --]
diff -udrN linux-2.6.17-git25/drivers/acpi/asus_acpi.c linux-2.6.17-git25-mine/drivers/acpi/asus_acpi.c
--- linux-2.6.17-git25/drivers/acpi/asus_acpi.c 2006-07-05 22:11:37.000000000 -0400
+++ linux-2.6.17-git25-mine/drivers/acpi/asus_acpi.c 2006-07-05 22:26:51.000000000 -0400
@@ -27,14 +27,19 @@
* Johann Wiesner - Small compile fixes
* John Belmonte - ACPI code for Toshiba laptop was a good starting point.
* �ric Burghard - LED display support for W1N
+ * Thomas Tuttle - LED subsystem integration
*
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
+#ifdef CONFIG_ACPI_ASUS_NEW_LED
+#include <linux/leds.h>
+#endif
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>
@@ -916,6 +921,145 @@
return 0;
}
+#ifdef CONFIG_ACPI_ASUS_NEW_LED
+
+/* These functions are called by the LED subsystem to update the desired
+ * state of the LED's. */
+static void led_set_mled(struct led_classdev *led_cdev,
+ enum led_brightness value);
+static void led_set_wled(struct led_classdev *led_cdev,
+ enum led_brightness value);
+static void led_set_tled(struct led_classdev *led_cdev,
+ enum led_brightness value);
+
+/* LED class devices. */
+static struct led_classdev led_cdev_mled =
+ { .name = "asus:mail", .brightness_set = led_set_mled };
+static struct led_classdev led_cdev_wled =
+ { .name = "asus:wireless", .brightness_set = led_set_wled };
+static struct led_classdev led_cdev_tled =
+ { .name = "asus:touchpad", .brightness_set = led_set_tled };
+
+/* These functions actually update the LED's, and are called from a
+ * workqueue. By doing this as separate work rather than when the LED
+ * subsystem asks, I avoid messing with the Asus ACPI stuff during a
+ * potentially bad time, such as a timer interrupt. */
+static void led_update_mled(void *private);
+static void led_update_wled(void *private);
+static void led_update_tled(void *private);
+
+/* Desired values of LED's. */
+static int led_mled_value = 0;
+static int led_wled_value = 0;
+static int led_tled_value = 0;
+
+/* LED workqueue. */
+static struct workqueue_struct *led_workqueue;
+
+/* LED update work structs. */
+DECLARE_WORK(led_mled_work, led_update_mled, NULL);
+DECLARE_WORK(led_wled_work, led_update_wled, NULL);
+DECLARE_WORK(led_tled_work, led_update_tled, NULL);
+
+/* LED subsystem callbacks. */
+static void led_set_mled(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ led_mled_value = value;
+ queue_work(led_workqueue, &led_mled_work);
+}
+
+static void led_set_wled(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ led_wled_value = value;
+ queue_work(led_workqueue, &led_wled_work);
+}
+
+static void led_set_tled(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ led_tled_value = value;
+ queue_work(led_workqueue, &led_tled_work);
+}
+
+/* LED work functions. */
+static void led_update_mled(void *private) {
+ char *ledname = hotk->methods->mt_mled;
+ int led_out = led_mled_value ? 1 : 0;
+ hotk->status = (led_out) ? (hotk->status | MLED_ON) : (hotk->status & ~MLED_ON);
+ led_out = 1 - led_out;
+ if (!write_acpi_int(hotk->handle, ledname, led_out, NULL))
+ printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
+ ledname);
+}
+
+static void led_update_wled(void *private) {
+ char *ledname = hotk->methods->mt_wled;
+ int led_out = led_wled_value ? 1 : 0;
+ hotk->status = (led_out) ? (hotk->status | WLED_ON) : (hotk->status & ~WLED_ON);
+ if (!write_acpi_int(hotk->handle, ledname, led_out, NULL))
+ printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
+ ledname);
+}
+
+static void led_update_tled(void *private) {
+ char *ledname = hotk->methods->mt_tled;
+ int led_out = led_tled_value ? 1 : 0;
+ hotk->status = (led_out) ? (hotk->status | TLED_ON) : (hotk->status & ~TLED_ON);
+ if (!write_acpi_int(hotk->handle, ledname, led_out, NULL))
+ printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
+ ledname);
+}
+
+/* Registers LED class devices and sets up workqueue. */
+static int led_initialize(struct device *parent)
+{
+ int result;
+
+ if (hotk->methods->mt_mled) {
+ result = led_classdev_register(parent, &led_cdev_mled);
+ if (result)
+ return result;
+ }
+
+ if (hotk->methods->mt_wled) {
+ result = led_classdev_register(parent, &led_cdev_wled);
+ if (result)
+ return result;
+ }
+
+ if (hotk->methods->mt_tled) {
+ result = led_classdev_register(parent, &led_cdev_tled);
+ if (result)
+ return result;
+ }
+
+ led_workqueue = create_singlethread_workqueue("led_workqueue");
+
+ return 0;
+}
+
+/* Destroys the workqueue and unregisters the LED class devices. */
+static void led_terminate(void)
+{
+ destroy_workqueue(led_workqueue);
+
+ if (hotk->methods->mt_tled) {
+ led_classdev_unregister(&led_cdev_tled);
+ }
+
+ if (hotk->methods->mt_wled) {
+ led_classdev_unregister(&led_cdev_wled);
+ }
+
+ if (hotk->methods->mt_mled) {
+ led_classdev_unregister(&led_cdev_mled);
+ }
+}
+
+#endif
+
static int asus_hotk_add_fs(struct acpi_device *device)
{
struct proc_dir_entry *proc;
@@ -1299,6 +1443,10 @@
/* LED display is off by default */
hotk->ledd_status = 0xFFF;
+#ifdef CONFIG_ACPI_ASUS_NEW_LED
+ result = led_initialize(acpi_get_physical_device(device->handle));
+#endif
+
end:
if (result) {
kfree(hotk);
@@ -1314,6 +1462,10 @@
if (!device || !acpi_driver_data(device))
return -EINVAL;
+#ifdef CONFIG_ACPI_ASUS_NEW_LED
+ led_terminate();
+#endif
+
status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
asus_hotk_notify);
if (ACPI_FAILURE(status))
diff -udrN linux-2.6.17-git25/drivers/acpi/Kconfig linux-2.6.17-git25-mine/drivers/acpi/Kconfig
--- linux-2.6.17-git25/drivers/acpi/Kconfig 2006-07-05 22:44:33.000000000 -0400
+++ linux-2.6.17-git25-mine/drivers/acpi/Kconfig 2006-07-05 22:44:43.000000000 -0400
@@ -199,6 +199,15 @@
something works not quite as expected, please use the mailing list
available on the above page (acpi4asus-user@lists.sourceforge.net)
+config ACPI_ASUS_NEW_LED
+ bool "ASUS/Medion LED subsystem integration"
+ depends on ACPI_ASUS
+ depends on LEDS_CLASS
+ help
+ This adds support for the new LED subsystem to the asus_acpi
+ driver. The LED's will show up as asus:mail, asus:wireless,
+ and asus:touchpad, as applicable to your laptop.
+
config ACPI_IBM
tristate "IBM ThinkPad Laptop Extras"
depends on X86
[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]
next reply other threads:[~2006-07-06 2:58 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-06 2:58 Thomas Tuttle [this message]
-- strict thread matches above, loose matches on Subject: below --
2006-07-06 1:19 PATCH: Integrate asus_acpi LED's with new LED subsystem Thomas Tuttle
2006-07-06 2:50 ` Thomas Tuttle
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=20060706025815.GB25835@phoenix \
--to=thinkinginbinary@gmail.com \
--cc=linux-kernel@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.