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