[PATCH 20/30] staging: nvec: Create nvec_event module for power button/lid switch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxx>
---
 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@xxxxxxxxxxxxx>
+ *
+ * Authors:  Julian Andres Klode <jak@xxxxxxxxxxxxx>
+ *
+ * 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@xxxxxxxxxxxxx>");
+MODULE_DESCRIPTION("NVEC power/sleep/lid switch driver");
+MODULE_LICENSE("GPL");
-- 
1.7.5.4

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel


[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux