Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bac22980 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull input layer fixes from Dmitry Torokhov:
 "Fixes for v7 protocol for ALPS devices and few other driver fixes.

  Also users can request input events to be stamped with boot time
  timestamps, in addition to real and monotonic timestamps"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: hil_kbd - fix incorrect use of init_completion
  Input: alps - v7: document the v7 touchpad packet protocol
  Input: alps - v7: fix finger counting for > 2 fingers on clickpads
  Input: alps - v7: sometimes a single touch is reported in mt[1]
  Input: alps - v7: ignore new packets
  Input: evdev - add CLOCK_BOOTTIME support
  Input: psmouse - expose drift duration for IBM trackpoints
  Input: stmpe - bias keypad columns properly
  Input: stmpe - enforce device tree only mode
  mfd: stmpe: add pull up/down register offsets for STMPE
  Input: optimize events_per_packet count calculation
  Input: edt-ft5x06 - fixed a macro coding style issue
  Input: gpio_keys - replace timer and workqueue with delayed workqueue
  Input: gpio_keys - allow separating gpio and irq in device tree
parents 831a39c2 cceeb872
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -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.
@@ -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:

+2 −0
Original line number Diff line number Diff line
@@ -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:

+44 −16
Original line number Diff line number Diff line
@@ -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;
@@ -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)
{
@@ -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;
@@ -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;
@@ -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);
@@ -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();
}
@@ -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);
+13 −9
Original line number Diff line number Diff line
@@ -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))
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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