Loading Documentation/devicetree/bindings/input/gpio-keys.txt +7 −3 Original line number Diff line number Diff line Loading @@ -10,12 +10,13 @@ Optional properties: Each button (key) is represented as a sub-node of "gpio-keys": Subnode properties: - gpios: OF device-tree gpio specification. - interrupts: the interrupt line for that input. - label: Descriptive name of the key. - linux,code: Keycode to emit. Required mutual exclusive subnode-properties: - gpios: OF device-tree gpio specification. - interrupts: the interrupt line for that input Note that either "interrupts" or "gpios" properties can be omitted, but not both at the same time. Specifying both properties is allowed. Optional subnode-properties: - linux,input-type: Specify event type this button/key generates. Loading @@ -23,6 +24,9 @@ Optional subnode-properties: - debounce-interval: Debouncing interval time in milliseconds. If not specified defaults to 5. - gpio-key,wakeup: Boolean, button can wake-up the system. - linux,can-disable: Boolean, indicates that button is connected to dedicated (not shared) interrupt which can be disabled to suppress events from the button. Example nodes: Loading Documentation/devicetree/bindings/input/stmpe-keypad.txt +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,8 @@ Optional properties: - debounce-interval : Debouncing interval time in milliseconds - st,scan-count : Scanning cycles elapsed before key data is updated - st,no-autorepeat : If specified device will not autorepeat - keypad,num-rows : See ./matrix-keymap.txt - keypad,num-columns : See ./matrix-keymap.txt Example: Loading drivers/input/evdev.c +44 −16 Original line number Diff line number Diff line Loading @@ -28,6 +28,13 @@ #include <linux/cdev.h> #include "input-compat.h" enum evdev_clock_type { EV_CLK_REAL = 0, EV_CLK_MONO, EV_CLK_BOOT, EV_CLK_MAX }; struct evdev { int open; struct input_handle handle; Loading @@ -49,12 +56,32 @@ struct evdev_client { struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; int clkid; int clk_type; bool revoked; unsigned int bufsize; struct input_event buffer[]; }; static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) { switch (clkid) { case CLOCK_REALTIME: client->clk_type = EV_CLK_REAL; break; case CLOCK_MONOTONIC: client->clk_type = EV_CLK_MONO; break; case CLOCK_BOOTTIME: client->clk_type = EV_CLK_BOOT; break; default: return -EINVAL; } return 0; } /* flush queued events of type @type, caller must hold client->buffer_lock */ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) { Loading Loading @@ -108,8 +135,11 @@ static void evdev_queue_syn_dropped(struct evdev_client *client) struct input_event ev; ktime_t time; time = (client->clkid == CLOCK_MONOTONIC) ? ktime_get() : ktime_get_real(); time = client->clk_type == EV_CLK_REAL ? ktime_get_real() : client->clk_type == EV_CLK_MONO ? ktime_get() : ktime_get_boottime(); ev.time = ktime_to_timeval(time); ev.type = EV_SYN; Loading Loading @@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client, static void evdev_pass_values(struct evdev_client *client, const struct input_value *vals, unsigned int count, ktime_t mono, ktime_t real) ktime_t *ev_time) { struct evdev *evdev = client->evdev; const struct input_value *v; Loading @@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client, if (client->revoked) return; event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? mono : real); event.time = ktime_to_timeval(ev_time[client->clk_type]); /* Interrupts are disabled, just acquire the lock. */ spin_lock(&client->buffer_lock); Loading Loading @@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle, { struct evdev *evdev = handle->private; struct evdev_client *client; ktime_t time_mono, time_real; ktime_t ev_time[EV_CLK_MAX]; time_mono = ktime_get(); time_real = ktime_mono_to_real(time_mono); ev_time[EV_CLK_MONO] = ktime_get(); ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]); ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO], TK_OFFS_BOOT); rcu_read_lock(); client = rcu_dereference(evdev->grab); if (client) evdev_pass_values(client, vals, count, time_mono, time_real); evdev_pass_values(client, vals, count, ev_time); else list_for_each_entry_rcu(client, &evdev->client_list, node) evdev_pass_values(client, vals, count, time_mono, time_real); evdev_pass_values(client, vals, count, ev_time); rcu_read_unlock(); } Loading Loading @@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, case EVIOCSCLOCKID: if (copy_from_user(&i, p, sizeof(unsigned int))) return -EFAULT; if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME) return -EINVAL; client->clkid = i; return 0; return evdev_set_clk_type(client, i); case EVIOCGKEYCODE: return evdev_handle_get_keycode(dev, p); Loading drivers/input/input.c +13 −9 Original line number Diff line number Diff line Loading @@ -1974,6 +1974,7 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */ if (test_bit(EV_ABS, dev->evbit)) { for (i = 0; i < ABS_CNT; i++) { if (test_bit(i, dev->absbit)) { if (input_is_mt_axis(i)) Loading @@ -1982,10 +1983,13 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) events++; } } } if (test_bit(EV_REL, dev->evbit)) { for (i = 0; i < REL_CNT; i++) if (test_bit(i, dev->relbit)) events++; } /* Make room for KEY and MSC events */ events += 7; Loading drivers/input/keyboard/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC config KEYBOARD_STMPE tristate "STMPE keypad support" depends on MFD_STMPE depends on OF select INPUT_MATRIXKMAP help Say Y here if you want to use the keypad controller on STMPE I/O Loading Loading
Documentation/devicetree/bindings/input/gpio-keys.txt +7 −3 Original line number Diff line number Diff line Loading @@ -10,12 +10,13 @@ Optional properties: Each button (key) is represented as a sub-node of "gpio-keys": Subnode properties: - gpios: OF device-tree gpio specification. - interrupts: the interrupt line for that input. - label: Descriptive name of the key. - linux,code: Keycode to emit. Required mutual exclusive subnode-properties: - gpios: OF device-tree gpio specification. - interrupts: the interrupt line for that input Note that either "interrupts" or "gpios" properties can be omitted, but not both at the same time. Specifying both properties is allowed. Optional subnode-properties: - linux,input-type: Specify event type this button/key generates. Loading @@ -23,6 +24,9 @@ Optional subnode-properties: - debounce-interval: Debouncing interval time in milliseconds. If not specified defaults to 5. - gpio-key,wakeup: Boolean, button can wake-up the system. - linux,can-disable: Boolean, indicates that button is connected to dedicated (not shared) interrupt which can be disabled to suppress events from the button. Example nodes: Loading
Documentation/devicetree/bindings/input/stmpe-keypad.txt +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,8 @@ Optional properties: - debounce-interval : Debouncing interval time in milliseconds - st,scan-count : Scanning cycles elapsed before key data is updated - st,no-autorepeat : If specified device will not autorepeat - keypad,num-rows : See ./matrix-keymap.txt - keypad,num-columns : See ./matrix-keymap.txt Example: Loading
drivers/input/evdev.c +44 −16 Original line number Diff line number Diff line Loading @@ -28,6 +28,13 @@ #include <linux/cdev.h> #include "input-compat.h" enum evdev_clock_type { EV_CLK_REAL = 0, EV_CLK_MONO, EV_CLK_BOOT, EV_CLK_MAX }; struct evdev { int open; struct input_handle handle; Loading @@ -49,12 +56,32 @@ struct evdev_client { struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; int clkid; int clk_type; bool revoked; unsigned int bufsize; struct input_event buffer[]; }; static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) { switch (clkid) { case CLOCK_REALTIME: client->clk_type = EV_CLK_REAL; break; case CLOCK_MONOTONIC: client->clk_type = EV_CLK_MONO; break; case CLOCK_BOOTTIME: client->clk_type = EV_CLK_BOOT; break; default: return -EINVAL; } return 0; } /* flush queued events of type @type, caller must hold client->buffer_lock */ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) { Loading Loading @@ -108,8 +135,11 @@ static void evdev_queue_syn_dropped(struct evdev_client *client) struct input_event ev; ktime_t time; time = (client->clkid == CLOCK_MONOTONIC) ? ktime_get() : ktime_get_real(); time = client->clk_type == EV_CLK_REAL ? ktime_get_real() : client->clk_type == EV_CLK_MONO ? ktime_get() : ktime_get_boottime(); ev.time = ktime_to_timeval(time); ev.type = EV_SYN; Loading Loading @@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client, static void evdev_pass_values(struct evdev_client *client, const struct input_value *vals, unsigned int count, ktime_t mono, ktime_t real) ktime_t *ev_time) { struct evdev *evdev = client->evdev; const struct input_value *v; Loading @@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client, if (client->revoked) return; event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? mono : real); event.time = ktime_to_timeval(ev_time[client->clk_type]); /* Interrupts are disabled, just acquire the lock. */ spin_lock(&client->buffer_lock); Loading Loading @@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle, { struct evdev *evdev = handle->private; struct evdev_client *client; ktime_t time_mono, time_real; ktime_t ev_time[EV_CLK_MAX]; time_mono = ktime_get(); time_real = ktime_mono_to_real(time_mono); ev_time[EV_CLK_MONO] = ktime_get(); ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]); ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO], TK_OFFS_BOOT); rcu_read_lock(); client = rcu_dereference(evdev->grab); if (client) evdev_pass_values(client, vals, count, time_mono, time_real); evdev_pass_values(client, vals, count, ev_time); else list_for_each_entry_rcu(client, &evdev->client_list, node) evdev_pass_values(client, vals, count, time_mono, time_real); evdev_pass_values(client, vals, count, ev_time); rcu_read_unlock(); } Loading Loading @@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, case EVIOCSCLOCKID: if (copy_from_user(&i, p, sizeof(unsigned int))) return -EFAULT; if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME) return -EINVAL; client->clkid = i; return 0; return evdev_set_clk_type(client, i); case EVIOCGKEYCODE: return evdev_handle_get_keycode(dev, p); Loading
drivers/input/input.c +13 −9 Original line number Diff line number Diff line Loading @@ -1974,6 +1974,7 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */ if (test_bit(EV_ABS, dev->evbit)) { for (i = 0; i < ABS_CNT; i++) { if (test_bit(i, dev->absbit)) { if (input_is_mt_axis(i)) Loading @@ -1982,10 +1983,13 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) events++; } } } if (test_bit(EV_REL, dev->evbit)) { for (i = 0; i < REL_CNT; i++) if (test_bit(i, dev->relbit)) events++; } /* Make room for KEY and MSC events */ events += 7; Loading
drivers/input/keyboard/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC config KEYBOARD_STMPE tristate "STMPE keypad support" depends on MFD_STMPE depends on OF select INPUT_MATRIXKMAP help Say Y here if you want to use the keypad controller on STMPE I/O Loading