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

Commit 4637f40f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (40 commits)
  Input: ADP5589 - new driver for I2C Keypad Decoder and I/O Expander
  Input: tsc2007 - add X, Y and Z fuzz factors to platform data
  Input: tsc2007 - add poll_period parameter to platform data
  Input: tsc2007 - add poll_delay parameter to platform data
  Input: tsc2007 - add max_rt parameter to platform data
  Input: tsc2007 - debounce pressure measurement
  Input: ad714x - fix captouch wheel option algorithm
  Input: ad714x - allow platform code to specify irqflags
  Input: ad714x - fix threshold and completion interrupt masks
  Input: ad714x - fix up input configuration
  Input: elantech - remove support for proprietary X driver
  Input: elantech - report multitouch with proper ABS_MT messages
  Input: elantech - export pressure and width when supported
  Input: elantech - describe further the protocol
  Input: atmel_tsadcc - correct call to input_free_device
  Input: add driver FSL MPR121 capacitive touch sensor
  Input: remove useless synchronize_rcu() calls
  Input: ads7846 - fix gpio_pendown configuration
  Input: ads7846 - add possibility to use external vref on ads7846
  Input: rotary-encoder - add support for half-period encoders
  ...
parents 5129df03 b73077eb
Loading
Loading
Loading
Loading
+100 −23
Original line number Diff line number Diff line
@@ -34,7 +34,8 @@ Contents
Currently the Linux Elantech touchpad driver is aware of two different
hardware versions unimaginatively called version 1 and version 2. Version 1
is found in "older" laptops and uses 4 bytes per packet. Version 2 seems to
be introduced with the EeePC and uses 6 bytes per packet.
be introduced with the EeePC and uses 6 bytes per packet, and provides
additional features such as position of two fingers, and width of the touch.

The driver tries to support both hardware versions and should be compatible
with the Xorg Synaptics touchpad driver and its graphical configuration
@@ -94,18 +95,44 @@ Currently the Linux Elantech touchpad driver provides two extra knobs under
   can check these bits and reject any packet that appears corrupted. Using
   this knob you can bypass that check.

   It is not known yet whether hardware version 2 provides the same parity
   bits. Hence checking is disabled by default. Currently even turning it on
   will do nothing.

   Hardware version 2 does not provide the same parity bits. Only some basic
   data consistency checking can be done. For now checking is disabled by
   default. Currently even turning it on will do nothing.

/////////////////////////////////////////////////////////////////////////////

3. Differentiating hardware versions
   =================================

3. Hardware version 1
To detect the hardware version, read the version number as param[0].param[1].param[2]

 4 bytes version: (after the arrow is the name given in the Dell-provided driver)
 02.00.22 => EF013
 02.06.00 => EF019
In the wild, there appear to be more versions, such as 00.01.64, 01.00.21,
02.00.00, 02.00.04, 02.00.06.

 6 bytes:
 02.00.30 => EF113
 02.08.00 => EF023
 02.08.XX => EF123
 02.0B.00 => EF215
 04.01.XX => Scroll_EF051
 04.02.XX => EF051
In the wild, there appear to be more versions, such as 04.03.01, 04.04.11. There
appears to be almost no difference, except for EF113, which does not report
pressure/width and has different data consistency checks.

Probably all the versions with param[0] <= 01 can be considered as
4 bytes/firmware 1. The versions < 02.08.00, with the exception of 02.00.30, as
4 bytes/firmware 2. Everything >= 02.08.00 can be considered as 6 bytes.

/////////////////////////////////////////////////////////////////////////////

4. Hardware version 1
   ==================

3.1 Registers
4.1 Registers
    ~~~~~~~~~

By echoing a hexadecimal value to a register it contents can be altered.
@@ -168,7 +195,7 @@ For example:
         smart edge activation area width?


3.2 Native relative mode 4 byte packet format
4.2 Native relative mode 4 byte packet format
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

byte 0:
@@ -226,9 +253,13 @@ byte 3:
                       positive = down


3.3 Native absolute mode 4 byte packet format
4.3 Native absolute mode 4 byte packet format
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

EF013 and EF019 have a special behaviour (due to a bug in the firmware?), and
when 1 finger is touching, the first 2 position reports must be discarded.
This counting is reset whenever a different number of fingers is reported.

byte 0:
   firmware version 1.x:

@@ -279,11 +310,11 @@ byte 3:
/////////////////////////////////////////////////////////////////////////////


4. Hardware version 2
5. Hardware version 2
   ==================


4.1 Registers
5.1 Registers
    ~~~~~~~~~

By echoing a hexadecimal value to a register it contents can be altered.
@@ -316,16 +347,41 @@ For example:
                                   0x7f = never i.e. tap again to release)


4.2 Native absolute mode 6 byte packet format
5.2 Native absolute mode 6 byte packet format
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

4.2.1 One finger touch
5.2.1 Parity checking and packet re-synchronization
There is no parity checking, however some consistency checks can be performed.

For instance for EF113:
        SA1= packet[0];
        A1 = packet[1];
        B1 = packet[2];
        SB1= packet[3];
        C1 = packet[4];
        D1 = packet[5];
        if( (((SA1 & 0x3C) != 0x3C) && ((SA1 & 0xC0) != 0x80)) || // check Byte 1
            (((SA1 & 0x0C) != 0x0C) && ((SA1 & 0xC0) == 0x80)) || // check Byte 1 (one finger pressed)
            (((SA1 & 0xC0) != 0x80) && (( A1 & 0xF0) != 0x00)) || // check Byte 2
            (((SB1 & 0x3E) != 0x38) && ((SA1 & 0xC0) != 0x80)) || // check Byte 4
            (((SB1 & 0x0E) != 0x08) && ((SA1 & 0xC0) == 0x80)) || // check Byte 4 (one finger pressed)
            (((SA1 & 0xC0) != 0x80) && (( C1 & 0xF0) != 0x00))  ) // check Byte 5
		// error detected

For all the other ones, there are just a few constant bits:
        if( ((packet[0] & 0x0C) != 0x04) ||
            ((packet[3] & 0x0f) != 0x02) )
		// error detected


In case an error is detected, all the packets are shifted by one (and packet[0] is discarded).

5.2.1 One/Three finger touch
      ~~~~~~~~~~~~~~~~

byte 0:

   bit   7   6   5   4   3   2   1   0
        n1  n0   .   .   .   .   R   L
	 n1  n0  w3  w2   .   .   R   L

         L, R = 1 when Left, Right mouse button pressed
         n1..n0 = numbers of fingers on touchpad
@@ -333,24 +389,40 @@ byte 0:
byte 1:

   bit   7   6   5   4   3   2   1   0
         .   .   .   .   .  x10 x9  x8
	 p7  p6  p5  p4  .  x10 x9  x8

byte 2:

   bit   7   6   5   4   3   2   1   0
        x7  x6  x5  x4  x4  x2  x1  x0
	 x7  x6  x5  x4  x3  x2  x1  x0

         x10..x0 = absolute x value (horizontal)

byte 3:

   bit   7   6   5   4   3   2   1   0
         .   .   .   .   .   .   .   .
	 n4  vf  w1  w0   .   .   .  b2

	 n4 = set if more than 3 fingers (only in 3 fingers mode)
	 vf = a kind of flag ? (only on EF123, 0 when finger is over one
	      of the buttons, 1 otherwise)
	 w3..w0 = width of the finger touch (not EF113)
	 b2 (on EF113 only, 0 otherwise), b2.R.L indicates one button pressed:
		0 = none
		1 = Left
		2 = Right
		3 = Middle (Left and Right)
		4 = Forward
		5 = Back
		6 = Another one
		7 = Another one

byte 4:

   bit   7   6   5   4   3   2   1   0
         .   .   .   .   .   .  y9  y8
        p3  p1  p2  p0   .   .  y9  y8

	 p7..p0 = pressure (not EF113)

byte 5:

@@ -363,6 +435,11 @@ byte 5:
4.2.2 Two finger touch
      ~~~~~~~~~~~~~~~~

Note that the two pairs of coordinates are not exactly the coordinates of the
two fingers, but only the pair of the lower-left and upper-right coordinates.
So the actual fingers might be situated on the other diagonal of the square
defined by these two points.

byte 0:

   bit   7   6   5   4   3   2   1   0
@@ -376,14 +453,14 @@ byte 1:
   bit   7   6   5   4   3   2   1   0
        ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0

         ax8..ax0 = first finger absolute x value
	 ax8..ax0 = lower-left finger absolute x value

byte 2:

   bit   7   6   5   4   3   2   1   0
        ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0

         ay8..ay0 = first finger absolute y value
	 ay8..ay0 = lower-left finger absolute y value

byte 3:

@@ -395,11 +472,11 @@ byte 4:
   bit   7   6   5   4   3   2   1   0
        bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0

         bx8..bx0 = second finger absolute x value
         bx8..bx0 = upper-right finger absolute x value

byte 5:

   bit   7   6   5   4   3   2   1   0
        by7 by8 by5 by4 by3 by2 by1 by0

         by8..by0 = second finger absolute y value
         by8..by0 = upper-right finger absolute y value
+13 −0
Original line number Diff line number Diff line
@@ -9,6 +9,9 @@ peripherals with two wires. The outputs are phase-shifted by 90 degrees
and by triggering on falling and rising edges, the turn direction can
be determined.

Some encoders have both outputs low in stable states, whereas others also have
a stable state with both outputs high (half-period mode).

The phase diagram of these two outputs look like this:

                  _____       _____       _____
@@ -26,6 +29,8 @@ The phase diagram of these two outputs look like this:
                |<-------->|
	          one step

                |<-->|
	          one step (half-period mode)

For more information, please see
	http://en.wikipedia.org/wiki/Rotary_encoder
@@ -34,6 +39,13 @@ For more information, please see
1. Events / state machine
-------------------------

In half-period mode, state a) and c) above are used to determine the
rotational direction based on the last stable state. Events are reported in
states b) and d) given that the new stable state is different from the last
(i.e. the rotation was not reversed half-way).

Otherwise, the following apply:

a) Rising edge on channel A, channel B in low state
	This state is used to recognize a clockwise turn

@@ -96,6 +108,7 @@ static struct rotary_encoder_platform_data my_rotary_encoder_info = {
	.gpio_b		= GPIO_ROTARY_B,
	.inverted_a	= 0,
	.inverted_b	= 0,
	.half_period	= false,
};

static struct platform_device rotary_encoder_device = {
+1 −3
Original line number Diff line number Diff line
@@ -50,13 +50,11 @@ struct tegra_kbc_platform_data {
	unsigned int debounce_cnt;
	unsigned int repeat_cnt;

	unsigned int wake_cnt; /* 0:wake on any key >1:wake on wake_cfg */
	const struct tegra_kbc_wake_key *wake_cfg;

	struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO];
	const struct matrix_keymap_data *keymap_data;

	bool wakeup;
	bool use_fn_map;
	bool use_ghost_filter;
};
#endif
+11 −8
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ struct evdev {
struct evdev_client {
	unsigned int head;
	unsigned int tail;
	unsigned int packet_head; /* [future] position of the first element of next packet */
	spinlock_t buffer_lock; /* protects access to buffer, head and tail */
	struct fasync_struct *fasync;
	struct evdev *evdev;
@@ -72,14 +73,18 @@ static void evdev_pass_event(struct evdev_client *client,
		client->buffer[client->tail].type = EV_SYN;
		client->buffer[client->tail].code = SYN_DROPPED;
		client->buffer[client->tail].value = 0;
	}

	spin_unlock(&client->buffer_lock);
		client->packet_head = client->tail;
	}

	if (event->type == EV_SYN)
	if (event->type == EV_SYN && event->code == SYN_REPORT) {
		client->packet_head = client->head;
		kill_fasync(&client->fasync, SIGIO, POLL_IN);
	}

	spin_unlock(&client->buffer_lock);
}

/*
 * Pass incoming event to all connected clients.
 */
@@ -159,7 +164,6 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client)
		return error;

	rcu_assign_pointer(evdev->grab, client);
	synchronize_rcu();

	return 0;
}
@@ -182,7 +186,6 @@ static void evdev_attach_client(struct evdev *evdev,
	spin_lock(&evdev->client_lock);
	list_add_tail_rcu(&client->node, &evdev->client_list);
	spin_unlock(&evdev->client_lock);
	synchronize_rcu();
}

static void evdev_detach_client(struct evdev *evdev,
@@ -387,12 +390,12 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
	if (count < input_event_size())
		return -EINVAL;

	if (client->head == client->tail && evdev->exist &&
	if (client->packet_head == client->tail && evdev->exist &&
	    (file->f_flags & O_NONBLOCK))
		return -EAGAIN;

	retval = wait_event_interruptible(evdev->wait,
		client->head != client->tail || !evdev->exist);
		client->packet_head != client->tail || !evdev->exist);
	if (retval)
		return retval;

@@ -421,7 +424,7 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait)
	poll_wait(file, &evdev->wait, wait);

	mask = evdev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR;
	if (client->head != client->tail)
	if (client->packet_head != client->tail)
		mask |= POLLIN | POLLRDNORM;

	return mask;
+3 −53
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/input-polldev.h>

MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
@@ -20,44 +21,6 @@ MODULE_DESCRIPTION("Generic implementation of a polled input device");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.1");

static DEFINE_MUTEX(polldev_mutex);
static int polldev_users;
static struct workqueue_struct *polldev_wq;

static int input_polldev_start_workqueue(void)
{
	int retval;

	retval = mutex_lock_interruptible(&polldev_mutex);
	if (retval)
		return retval;

	if (!polldev_users) {
		polldev_wq = create_singlethread_workqueue("ipolldevd");
		if (!polldev_wq) {
			pr_err("failed to create ipolldevd workqueue\n");
			retval = -ENOMEM;
			goto out;
		}
	}

	polldev_users++;

 out:
	mutex_unlock(&polldev_mutex);
	return retval;
}

static void input_polldev_stop_workqueue(void)
{
	mutex_lock(&polldev_mutex);

	if (!--polldev_users)
		destroy_workqueue(polldev_wq);

	mutex_unlock(&polldev_mutex);
}

static void input_polldev_queue_work(struct input_polled_dev *dev)
{
	unsigned long delay;
@@ -66,7 +29,7 @@ static void input_polldev_queue_work(struct input_polled_dev *dev)
	if (delay >= HZ)
		delay = round_jiffies_relative(delay);

	queue_delayed_work(polldev_wq, &dev->work, delay);
	queue_delayed_work(system_freezable_wq, &dev->work, delay);
}

static void input_polled_device_work(struct work_struct *work)
@@ -81,18 +44,13 @@ static void input_polled_device_work(struct work_struct *work)
static int input_open_polled_device(struct input_dev *input)
{
	struct input_polled_dev *dev = input_get_drvdata(input);
	int error;

	error = input_polldev_start_workqueue();
	if (error)
		return error;

	if (dev->open)
		dev->open(dev);

	/* Only start polling if polling is enabled */
	if (dev->poll_interval > 0)
		queue_delayed_work(polldev_wq, &dev->work, 0);
		queue_delayed_work(system_freezable_wq, &dev->work, 0);

	return 0;
}
@@ -102,13 +60,6 @@ static void input_close_polled_device(struct input_dev *input)
	struct input_polled_dev *dev = input_get_drvdata(input);

	cancel_delayed_work_sync(&dev->work);
	/*
	 * Clean up work struct to remove references to the workqueue.
	 * It may be destroyed by the next call. This causes problems
	 * at next device open-close in case of poll_interval == 0.
	 */
	INIT_DELAYED_WORK(&dev->work, dev->work.work.func);
	input_polldev_stop_workqueue();

	if (dev->close)
		dev->close(dev);
@@ -295,4 +246,3 @@ void input_unregister_polled_device(struct input_polled_dev *dev)
	input_unregister_device(dev->input);
}
EXPORT_SYMBOL(input_unregister_polled_device);
Loading