diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-27 21:30:41 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-27 21:30:41 (GMT) |
commit | d85486d47123961bd8b08e94f6d4886c59a1fd76 (patch) | |
tree | 8bfcebed0fd1753fa8f0fa85286551b80e8ed7d1 /drivers/input/misc/hisi_powerkey.c | |
parent | 66304207cd341045df34195b4a8d422075bff513 (diff) | |
parent | 0808882863774ab69066d83f49f511606be024e0 (diff) | |
download | linux-d85486d47123961bd8b08e94f6d4886c59a1fd76.tar.xz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
"Updates for the input subsystem. This contains the following new
drivers promised in the last merge window:
- driver for touchscreen controller found in Surface 3
- driver for Pegasus Notetaker tablet
- driver for Atmel Captouch Buttons
- driver for Raydium I2C touchscreen controllers
- powerkey driver for HISI 65xx SoC
plus a few fixes"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (40 commits)
Input: tty/vt/keyboard - use memdup_user()
Input: pegasus_notetaker - set device mode in reset_resume() if in use
Input: pegasus_notetaker - cancel workqueue's work in suspend()
Input: pegasus_notetaker - fix usb_autopm calls to be balanced
Input: pegasus_notetaker - handle usb control msg errors
Input: wacom_w8001 - handle errors from input_mt_init_slots()
Input: wacom_w8001 - resolution wasn't set for ABS_MT_POSITION_X/Y
Input: pixcir_ts - add support for axis inversion / swapping
Input: icn8318 - use of_touchscreen helpers for inverting / swapping axes
Input: edt-ft5x06 - add support for inverting / swapping axes
Input: of_touchscreen - add support for inverted / swapped axes
Input: synaptics-rmi4 - use the RMI_F11_REL_BYTES define in rmi_f11_rel_pos_report
Input: synaptics-rmi4 - remove unneeded variable
Input: synaptics-rmi4 - remove pointer to rmi_function in f12_data
Input: synaptics-rmi4 - support regulator supplies
Input: raydium_i2c_ts - check CRC of incoming packets
Input: xen-kbdfront - prefer xenbus_write() over xenbus_printf() where possible
Input: fix a double word "is is" in include/linux/input.h
Input: add powerkey driver for HISI 65xx SoC
Input: apanel - spelling mistake - "skiping" -> "skipping"
...
Diffstat (limited to 'drivers/input/misc/hisi_powerkey.c')
-rw-r--r-- | drivers/input/misc/hisi_powerkey.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/drivers/input/misc/hisi_powerkey.c b/drivers/input/misc/hisi_powerkey.c new file mode 100644 index 0000000..675539c --- /dev/null +++ b/drivers/input/misc/hisi_powerkey.c @@ -0,0 +1,142 @@ +/* + * Hisilicon PMIC powerkey driver + * + * Copyright (C) 2013 Hisilicon Ltd. + * Copyright (C) 2015, 2016 Linaro Ltd. + * + * 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. + * + * 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. + */ + +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/reboot.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_irq.h> +#include <linux/input.h> +#include <linux/slab.h> + +/* the held interrupt will trigger after 4 seconds */ +#define MAX_HELD_TIME (4 * MSEC_PER_SEC) + +static irqreturn_t hi65xx_power_press_isr(int irq, void *q) +{ + struct input_dev *input = q; + + pm_wakeup_event(input->dev.parent, MAX_HELD_TIME); + input_report_key(input, KEY_POWER, 1); + input_sync(input); + + return IRQ_HANDLED; +} + +static irqreturn_t hi65xx_power_release_isr(int irq, void *q) +{ + struct input_dev *input = q; + + pm_wakeup_event(input->dev.parent, MAX_HELD_TIME); + input_report_key(input, KEY_POWER, 0); + input_sync(input); + + return IRQ_HANDLED; +} + +static irqreturn_t hi65xx_restart_toggle_isr(int irq, void *q) +{ + struct input_dev *input = q; + int value = test_bit(KEY_RESTART, input->key); + + pm_wakeup_event(input->dev.parent, MAX_HELD_TIME); + input_report_key(input, KEY_RESTART, !value); + input_sync(input); + + return IRQ_HANDLED; +} + +static const struct { + const char *name; + irqreturn_t (*handler)(int irq, void *q); +} hi65xx_irq_info[] = { + { "down", hi65xx_power_press_isr }, + { "up", hi65xx_power_release_isr }, + { "hold 4s", hi65xx_restart_toggle_isr }, +}; + +static int hi65xx_powerkey_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct input_dev *input; + int irq, i, error; + + input = devm_input_allocate_device(&pdev->dev); + if (!input) { + dev_err(&pdev->dev, "failed to allocate input device\n"); + return -ENOMEM; + } + + input->phys = "hisi_on/input0"; + input->name = "HISI 65xx PowerOn Key"; + + input_set_capability(input, EV_KEY, KEY_POWER); + input_set_capability(input, EV_KEY, KEY_RESTART); + + for (i = 0; i < ARRAY_SIZE(hi65xx_irq_info); i++) { + + irq = platform_get_irq_byname(pdev, hi65xx_irq_info[i].name); + if (irq < 0) { + error = irq; + dev_err(dev, "couldn't get irq %s: %d\n", + hi65xx_irq_info[i].name, error); + return error; + } + + error = devm_request_any_context_irq(dev, irq, + hi65xx_irq_info[i].handler, + IRQF_ONESHOT, + hi65xx_irq_info[i].name, + input); + if (error < 0) { + dev_err(dev, "couldn't request irq %s: %d\n", + hi65xx_irq_info[i].name, error); + return error; + } + } + + error = input_register_device(input); + if (error) { + dev_err(&pdev->dev, "failed to register input device: %d\n", + error); + return error; + } + + device_init_wakeup(&pdev->dev, 1); + + return 0; +} + +static int hi65xx_powerkey_remove(struct platform_device *pdev) +{ + device_init_wakeup(&pdev->dev, 0); + + return 0; +} + +static struct platform_driver hi65xx_powerkey_driver = { + .driver = { + .name = "hi65xx-powerkey", + }, + .probe = hi65xx_powerkey_probe, + .remove = hi65xx_powerkey_remove, +}; +module_platform_driver(hi65xx_powerkey_driver); + +MODULE_AUTHOR("Zhiliang Xue <xuezhiliang@huawei.com"); +MODULE_DESCRIPTION("Hisi PMIC Power key driver"); +MODULE_LICENSE("GPL v2"); |