From d7d714d49d0efedc0aa9d52e60106af024370e33 Mon Sep 17 00:00:00 2001 From: Dongjin Kim Date: Mon, 17 Nov 2014 12:27:07 +0900 Subject: [PATCH] ODROID: Add ODROID sysfs feature enhancement driver Change-Id: I91dedbf5c99de60f50d1f46c0f3aa973d76e24af Signed-off-by: Dongjin Kim --- drivers/Makefile | 4 +- drivers/hardkernel/Makefile | 1 + drivers/hardkernel/odroid-sysfs.c | 216 ++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 drivers/hardkernel/Makefile create mode 100644 drivers/hardkernel/odroid-sysfs.c diff --git a/drivers/Makefile b/drivers/Makefile index 236b679c66b1..c0429378e792 100755 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -154,4 +154,6 @@ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_IPACK_BUS) += ipack/ obj-$(CONFIG_NTB) += ntb/ -obj-$(CONFIG_PLAT_MESON) += amlogic/ \ No newline at end of file +obj-$(CONFIG_PLAT_MESON) += amlogic/ + +obj-y += hardkernel/ diff --git a/drivers/hardkernel/Makefile b/drivers/hardkernel/Makefile new file mode 100644 index 000000000000..5d8f658febfd --- /dev/null +++ b/drivers/hardkernel/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_MACH_MESON8B_ODROIDC) += odroid-sysfs.o diff --git a/drivers/hardkernel/odroid-sysfs.c b/drivers/hardkernel/odroid-sysfs.c new file mode 100644 index 000000000000..c1be2794990a --- /dev/null +++ b/drivers/hardkernel/odroid-sysfs.c @@ -0,0 +1,216 @@ +/* + * ODROID sysfs support for extra feature enhancement + * + * Copyright (C) 2014, Hardkernel Co,.Ltd + * Author: Charles Park + * Author: Dongjin Kim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Hardkernel Co,.Ltd"); +MODULE_DESCRIPTION("SYSFS driver for ODROID hardware"); +MODULE_LICENSE("GPL"); + +static struct hrtimer input_timer; +static struct input_dev *input_dev; +static int keycode[] = { KEY_POWER, }; +static int key_release_seconds = 0; + +static ssize_t set_poweroff_trigger(struct device *dev, struct + device_attribute *attr, const char *buf, size_t count) +{ + unsigned int val; + + if (!(sscanf(buf, "%d\n", &val))) + return -EINVAL; + + // Emulate power button by software + if ((val != 0) && (val < 5)) { + if (!key_release_seconds) { + key_release_seconds = val; + input_report_key(input_dev, KEY_POWER, 1); + + hrtimer_start(&input_timer, + ktime_set(key_release_seconds, 0), + HRTIMER_MODE_REL); + + input_sync(input_dev); + } + } + + return count; +} + + +static DEVICE_ATTR(poweroff_trigger, S_IRWXUGO, NULL, set_poweroff_trigger); + +static struct attribute *odroid_sysfs_entries[] = { + &dev_attr_poweroff_trigger.attr, + NULL +}; + +static struct attribute_group odroid_sysfs_attr_group = { + .name = NULL, + .attrs = odroid_sysfs_entries, +}; + +static enum hrtimer_restart input_timer_function(struct hrtimer *timer) +{ + key_release_seconds = 0; + input_report_key(input_dev, KEY_POWER, 0); + input_sync(input_dev); + + return HRTIMER_NORESTART; +} + +static int odroid_sysfs_probe(struct platform_device *pdev) +{ + int error = -ENOMEM; + +#if defined(SLEEP_DISABLE_FLAG) +#if defined(CONFIG_HAS_WAKELOCK) + wake_lock(&sleep_wake_lock); +#endif +#endif + //------------------------------------------------------------------------ + // virtual key init (Power Off Key) + //------------------------------------------------------------------------ + input_dev = input_allocate_device(); + if (!input_dev) + goto err_out; + + input_dev->name = "vt-input"; + input_dev->phys = "vt-input/input0"; + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0x16B4; + input_dev->id.product = 0x0701; + input_dev->id.version = 0x0001; + input_dev->keycode = keycode; + input_dev->keycodesize = sizeof(keycode[0]); + input_dev->keycodemax = ARRAY_SIZE(keycode); + + set_bit(EV_KEY, input_dev->evbit); + set_bit(KEY_POWER & KEY_MAX, input_dev->keybit); + + error = input_register_device(input_dev); + if (error) + goto err_out; + + printk("%s input driver registered!!\n", "Virtual-Key"); + + hrtimer_init(&input_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + input_timer.function = input_timer_function; + + return sysfs_create_group(&pdev->dev.kobj, &odroid_sysfs_attr_group); + +err_out: + input_free_device(input_dev); + return error; +} + +static int odroid_sysfs_remove(struct platform_device *pdev) +{ +#if defined(SLEEP_DISABLE_FLAG) +#if defined(CONFIG_HAS_WAKELOCK) + wake_unlock(&sleep_wake_lock); +#endif +#endif + + sysfs_remove_group(&pdev->dev.kobj, &odroid_sysfs_attr_group); + + return 0; +} + +static int odroid_sysfs_suspend(struct platform_device *dev, pm_message_t state) +{ +#if defined(DEBUG_PM_MSG) + printk("%s\n", __FUNCTION__); +#endif + + return 0; +} + +static int odroid_sysfs_resume(struct platform_device *dev) +{ +#if defined(DEBUG_PM_MSG) + printk("%s\n", __FUNCTION__); +#endif + + return 0; +} + +#if defined(CONFIG_OF) +static const struct of_device_id odroid_sysfs_dt[] = { + { .compatible = "odroid-sysfs" }, + { }, +}; +MODULE_DEVICE_TABLE(of, odroid_sysfs_dt); +#endif + +static struct platform_driver odroid_sysfs_driver = { + .driver = { + .name = "odroid-sysfs", + .owner = THIS_MODULE, +#if defined(CONFIG_OF) + .of_match_table = of_match_ptr(odroid_sysfs_dt), +#endif + }, + .probe = odroid_sysfs_probe, + .remove = odroid_sysfs_remove, + .suspend = odroid_sysfs_suspend, + .resume = odroid_sysfs_resume, +}; + +static int __init odroid_sysfs_init(void) +{ + printk("--------------------------------------------------------\n"); +#if defined(SLEEP_DISABLE_FLAG) +#if defined(CONFIG_HAS_WAKELOCK) + printk("%s(%d) : Sleep Disable Flag SET!!(Wake_lock_init)\n", + __FUNCTION__, __LINE__); + + wake_lock_init(&sleep_wake_lock, WAKE_LOCK_SUSPEND, "sleep_wake_lock"); +#endif +#else + printk("%s(%d) : Sleep Enable !! \n", __FUNCTION__, __LINE__); +#endif + printk("--------------------------------------------------------\n"); + + return platform_driver_register(&odroid_sysfs_driver); +} + +static void __exit odroid_sysfs_exit(void) +{ +#if defined(SLEEP_DISABLE_FLAG) +#if defined(CONFIG_HAS_WAKELOCK) + wake_lock_destroy(&sleep_wake_lock); +#endif +#endif + platform_driver_unregister(&odroid_sysfs_driver); +} + +module_init(odroid_sysfs_init); +module_exit(odroid_sysfs_exit);