[PATCH 20/30] staging: nvec: Create nvec_event module for power button/lid switch
Julian Andres Klode
jak at jak-linux.org
Fri Sep 23 09:38:12 PDT 2011
This is the initial version of the nvec_event module with power
button and lid switch support for the Toshiba AC100.
Signed-off-by: Julian Andres Klode <jak at jak-linux.org>
---
drivers/staging/nvec/Kconfig | 7 ++
drivers/staging/nvec/Makefile | 1 +
drivers/staging/nvec/nvec_event.c | 139 +++++++++++++++++++++++++++++++++++++
3 files changed, 147 insertions(+), 0 deletions(-)
create mode 100644 drivers/staging/nvec/nvec_event.c
diff --git a/drivers/staging/nvec/Kconfig b/drivers/staging/nvec/Kconfig
index 4c2dc58..4c6ffd4 100644
--- a/drivers/staging/nvec/Kconfig
+++ b/drivers/staging/nvec/Kconfig
@@ -31,3 +31,10 @@ config NVEC_LEDS
depends on MFD_NVEC && LEDS_CLASS
help
Say Y to enable yellow side leds on AC100 or other nVidia tegra nvec leds
+
+config NVEC_EVENT
+ bool "NVEC event handler"
+ depends on MFD_NVEC
+ help
+ Say Y to enable the power button and lid switch on the AC100. It
+ is unknown whether that driver is compatible with other devices.
diff --git a/drivers/staging/nvec/Makefile b/drivers/staging/nvec/Makefile
index b844d60..4a3a13a 100644
--- a/drivers/staging/nvec/Makefile
+++ b/drivers/staging/nvec/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_MFD_NVEC) += nvec.o
obj-$(CONFIG_NVEC_POWER) += nvec_power.o
obj-$(CONFIG_KEYBOARD_NVEC) += nvec_kbd.o
obj-$(CONFIG_NVEC_LEDS) += nvec_leds.o
+obj-$(CONFIG_NVEC_EVENT) += nvec_event.o
diff --git a/drivers/staging/nvec/nvec_event.c b/drivers/staging/nvec/nvec_event.c
new file mode 100644
index 0000000..cb36287
--- /dev/null
+++ b/drivers/staging/nvec/nvec_event.c
@@ -0,0 +1,139 @@
+/*
+ * various events driver for a NVIDIA compliant embedded controller
+ *
+ * Copyright (C) 2011 Julian Andres Klode <jak at jak-linux.org>
+ *
+ * Authors: Julian Andres Klode <jak at jak-linux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include "nvec.h"
+
+static struct nvec_event_device {
+ struct input_dev *sleep;
+ struct input_dev *power;
+ struct input_dev *lid;
+ struct notifier_block notifier;
+ struct nvec_chip *nvec;
+} event_handler;
+
+struct nvec_sys_event {
+ unsigned char command;
+ unsigned char length;
+ unsigned char payload[32];
+};
+
+static int nvec_event_notifier(struct notifier_block *nb,
+ unsigned long event_type, void *data)
+{
+ struct nvec_sys_event *event = data;
+
+ if (event_type != 0x85 || (event->command & (NVEC_VAR_SIZE << 5)) == 0
+ || event->length != 4 || event->payload[0] != 1
+ || event->payload[1] != 0)
+ return NOTIFY_DONE;
+
+ switch (event->payload[2]) {
+#if 0
+ case -1: /* invalid */
+ input_report_key(event_handler.sleep, KEY_SLEEP, 1);
+ input_sync(event_handler.sleep);
+ input_report_key(event_handler.sleep, KEY_SLEEP, 1);
+ input_sync(event_handler.sleep);
+ break;
+#endif
+ case 0x80: /* short power button press */
+ input_report_key(event_handler.power, KEY_POWER, 1);
+ input_sync(event_handler.power);
+ input_report_key(event_handler.power, KEY_POWER, 0);
+ input_sync(event_handler.power);
+ break;
+ case 0x02: /* lid close */
+ input_report_switch(event_handler.lid, SW_LID, 1);
+ input_sync(event_handler.lid);
+ break;
+ case 0x00: /* lid open */
+ input_report_switch(event_handler.lid, SW_LID, 0);
+ input_sync(event_handler.lid);
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+
+ return NOTIFY_STOP;
+}
+
+static int __devinit nvec_event_probe(struct platform_device *pdev)
+{
+ struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+ int err;
+
+ event_handler.nvec = nvec;
+ event_handler.sleep = input_allocate_device();
+ event_handler.sleep->name = "NVEC sleep button";
+ event_handler.sleep->phys = "NVEC";
+ event_handler.sleep->evbit[0] = BIT_MASK(EV_KEY);
+ set_bit(KEY_SLEEP, event_handler.sleep->keybit);
+
+ event_handler.power = input_allocate_device();
+ event_handler.power->name = "NVEC power button";
+ event_handler.power->phys = "NVEC";
+ event_handler.power->evbit[0] = BIT_MASK(EV_KEY);
+ set_bit(KEY_POWER, event_handler.power->keybit);
+
+ event_handler.lid = input_allocate_device();
+ event_handler.lid->name = "NVEC lid switch button";
+ event_handler.lid->phys = "NVEC";
+ event_handler.lid->evbit[0] = BIT_MASK(EV_SW);
+ set_bit(SW_LID, event_handler.lid->swbit);
+
+ err = input_register_device(event_handler.sleep);
+ if (err)
+ goto fail;
+
+ err = input_register_device(event_handler.power);
+ if (err)
+ goto fail;
+
+ err = input_register_device(event_handler.lid);
+ if (err)
+ goto fail;
+
+ event_handler.notifier.notifier_call = nvec_event_notifier;
+ nvec_register_notifier(nvec, &event_handler.notifier, 0);
+
+ return 0;
+
+fail:
+ input_free_device(event_handler.sleep);
+ input_free_device(event_handler.power);
+ input_free_device(event_handler.lid);
+ return err;
+}
+
+static struct platform_driver nvec_event_driver = {
+ .probe = nvec_event_probe,
+ .driver = {
+ .name = "nvec-event",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init nvec_event_init(void)
+{
+ return platform_driver_register(&nvec_event_driver);
+}
+
+module_init(nvec_event_init);
+
+MODULE_AUTHOR("Julian Andres Klode <jak at jak-linux.org>");
+MODULE_DESCRIPTION("NVEC power/sleep/lid switch driver");
+MODULE_LICENSE("GPL");
--
1.7.5.4
More information about the devel
mailing list