Commit 56c381f9 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input subsystem updates from Dmitry Torokhov:
 "Mostly small fixups to PS/2 tochpad drivers (ALPS, Elantech,
  Synaptics) to better deal with specific hardware"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: elantech - update the documentation
  Input: elantech - provide a sysfs knob for crc_enabled
  Input: elantech - report the middle button of the touchpad
  Input: alps - ignore bad data on Dell Latitudes E6440 and E7440
  Input: alps - allow up to 2 invalid packets without resetting device
  Input: alps - ignore potential bare packets when device is out of sync
  Input: elantech - fix crc_enabled for Fujitsu H730
  Input: elantech - use elantech_report_trackpoint for hardware v4 too
  Input: twl4030-pwrbutton - ensure a wakeup event is recorded.
  Input: synaptics - add min/max quirk for Lenovo T440s
parents 0861fd1c c6c748ef
...@@ -38,22 +38,38 @@ Contents ...@@ -38,22 +38,38 @@ Contents
7.2.1 Status packet 7.2.1 Status packet
7.2.2 Head packet 7.2.2 Head packet
7.2.3 Motion packet 7.2.3 Motion packet
8. Trackpoint (for Hardware version 3 and 4)
8.1 Registers
8.2 Native relative mode 6 byte packet format
8.2.1 Status Packet
1. Introduction 1. Introduction
~~~~~~~~~~~~ ~~~~~~~~~~~~
Currently the Linux Elantech touchpad driver is aware of two different Currently the Linux Elantech touchpad driver is aware of four different
hardware versions unimaginatively called version 1 and version 2. Version 1 hardware versions unimaginatively called version 1,version 2, version 3
is found in "older" laptops and uses 4 bytes per packet. Version 2 seems to and version 4. Version 1 is found in "older" laptops and uses 4 bytes per
be introduced with the EeePC and uses 6 bytes per packet, and provides packet. Version 2 seems to be introduced with the EeePC and uses 6 bytes
additional features such as position of two fingers, and width of the touch. per packet, and provides additional features such as position of two fingers,
and width of the touch. Hardware version 3 uses 6 bytes per packet (and
for 2 fingers the concatenation of two 6 bytes packets) and allows tracking
of up to 3 fingers. Hardware version 4 uses 6 bytes per packet, and can
combine a status packet with multiple head or motion packets. Hardware version
4 allows tracking up to 5 fingers.
Some Hardware version 3 and version 4 also have a trackpoint which uses a
separate packet format. It is also 6 bytes per packet.
The driver tries to support both hardware versions and should be compatible The driver tries to support both hardware versions and should be compatible
with the Xorg Synaptics touchpad driver and its graphical configuration with the Xorg Synaptics touchpad driver and its graphical configuration
utilities. utilities.
Note that a mouse button is also associated with either the touchpad or the
trackpoint when a trackpoint is available. Disabling the Touchpad in xorg
(TouchPadOff=0) will also disable the buttons associated with the touchpad.
Additionally the operation of the touchpad can be altered by adjusting the Additionally the operation of the touchpad can be altered by adjusting the
contents of some of its internal registers. These registers are represented contents of some of its internal registers. These registers are represented
by the driver as sysfs entries under /sys/bus/serio/drivers/psmouse/serio? by the driver as sysfs entries under /sys/bus/serio/drivers/psmouse/serio?
...@@ -78,7 +94,7 @@ completeness sake. ...@@ -78,7 +94,7 @@ completeness sake.
2. Extra knobs 2. Extra knobs
~~~~~~~~~~~ ~~~~~~~~~~~
Currently the Linux Elantech touchpad driver provides two extra knobs under Currently the Linux Elantech touchpad driver provides three extra knobs under
/sys/bus/serio/drivers/psmouse/serio? for the user. /sys/bus/serio/drivers/psmouse/serio? for the user.
* debug * debug
...@@ -112,6 +128,20 @@ Currently the Linux Elantech touchpad driver provides two extra knobs under ...@@ -112,6 +128,20 @@ Currently the Linux Elantech touchpad driver provides two extra knobs under
data consistency checking can be done. For now checking is disabled by data consistency checking can be done. For now checking is disabled by
default. Currently even turning it on will do nothing. default. Currently even turning it on will do nothing.
* crc_enabled
Sets crc_enabled to 0/1. The name "crc_enabled" is the official name of
this integrity check, even though it is not an actual cyclic redundancy
check.
Depending on the state of crc_enabled, certain basic data integrity
verification is done by the driver on hardware version 3 and 4. The
driver will reject any packet that appears corrupted. Using this knob,
The state of crc_enabled can be altered with this knob.
Reading the crc_enabled value will show the active value. Echoing
"0" or "1" to this file will set the state to "0" or "1".
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
3. Differentiating hardware versions 3. Differentiating hardware versions
...@@ -746,3 +776,42 @@ byte 5: ...@@ -746,3 +776,42 @@ byte 5:
byte 0 ~ 2 for one finger byte 0 ~ 2 for one finger
byte 3 ~ 5 for another byte 3 ~ 5 for another
8. Trackpoint (for Hardware version 3 and 4)
=========================================
8.1 Registers
~~~~~~~~~
No special registers have been identified.
8.2 Native relative mode 6 byte packet format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8.2.1 Status Packet
~~~~~~~~~~~~~
byte 0:
bit 7 6 5 4 3 2 1 0
0 0 sx sy 0 M R L
byte 1:
bit 7 6 5 4 3 2 1 0
~sx 0 0 0 0 0 0 0
byte 2:
bit 7 6 5 4 3 2 1 0
~sy 0 0 0 0 0 0 0
byte 3:
bit 7 6 5 4 3 2 1 0
0 0 ~sy ~sx 0 1 1 0
byte 4:
bit 7 6 5 4 3 2 1 0
x7 x6 x5 x4 x3 x2 x1 x0
byte 5:
bit 7 6 5 4 3 2 1 0
y7 y6 y5 y4 y3 y2 y1 y0
x and y are written in two's complement spread
over 9 bits with sx/sy the relative top bit and
x7..x0 and y7..y0 the lower bits.
~sx is the inverse of sx, ~sy is the inverse of sy.
The sign of y is opposite to what the input driver
expects for a relative movement
...@@ -85,6 +85,7 @@ static int twl4030_pwrbutton_probe(struct platform_device *pdev) ...@@ -85,6 +85,7 @@ static int twl4030_pwrbutton_probe(struct platform_device *pdev)
} }
platform_set_drvdata(pdev, pwr); platform_set_drvdata(pdev, pwr);
device_init_wakeup(&pdev->dev, true);
return 0; return 0;
} }
......
...@@ -1156,7 +1156,13 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) ...@@ -1156,7 +1156,13 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
{ {
struct alps_data *priv = psmouse->private; struct alps_data *priv = psmouse->private;
if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ /*
* Check if we are dealing with a bare PS/2 packet, presumably from
* a device connected to the external PS/2 port. Because bare PS/2
* protocol does not have enough constant bits to self-synchronize
* properly we only do this if the device is fully synchronized.
*/
if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) {
if (psmouse->pktcnt == 3) { if (psmouse->pktcnt == 3) {
alps_report_bare_ps2_packet(psmouse, psmouse->packet, alps_report_bare_ps2_packet(psmouse, psmouse->packet,
true); true);
...@@ -1180,12 +1186,27 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) ...@@ -1180,12 +1186,27 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
} }
/* Bytes 2 - pktsize should have 0 in the highest bit */ /* Bytes 2 - pktsize should have 0 in the highest bit */
if ((priv->proto_version < ALPS_PROTO_V5) && if (priv->proto_version < ALPS_PROTO_V5 &&
psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
(psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
psmouse->pktcnt - 1, psmouse->pktcnt - 1,
psmouse->packet[psmouse->pktcnt - 1]); psmouse->packet[psmouse->pktcnt - 1]);
if (priv->proto_version == ALPS_PROTO_V3 &&
psmouse->pktcnt == psmouse->pktsize) {
/*
* Some Dell boxes, such as Latitude E6440 or E7440
* with closed lid, quite often smash last byte of
* otherwise valid packet with 0xff. Given that the
* next packet is very likely to be valid let's
* report PSMOUSE_FULL_PACKET but not process data,
* rather than reporting PSMOUSE_BAD_DATA and
* filling the logs.
*/
return PSMOUSE_FULL_PACKET;
}
return PSMOUSE_BAD_DATA; return PSMOUSE_BAD_DATA;
} }
...@@ -2389,6 +2410,9 @@ int alps_init(struct psmouse *psmouse) ...@@ -2389,6 +2410,9 @@ int alps_init(struct psmouse *psmouse)
/* We are having trouble resyncing ALPS touchpads so disable it for now */ /* We are having trouble resyncing ALPS touchpads so disable it for now */
psmouse->resync_time = 0; psmouse->resync_time = 0;
/* Allow 2 invalid packets without resetting device */
psmouse->resetafter = psmouse->pktsize * 2;
return 0; return 0;
init_fail: init_fail:
......
...@@ -563,6 +563,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse) ...@@ -563,6 +563,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
} else { } else {
input_report_key(dev, BTN_LEFT, packet[0] & 0x01); input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
} }
input_mt_report_pointer_emulation(dev, true); input_mt_report_pointer_emulation(dev, true);
...@@ -792,6 +793,9 @@ static int elantech_packet_check_v4(struct psmouse *psmouse) ...@@ -792,6 +793,9 @@ static int elantech_packet_check_v4(struct psmouse *psmouse)
unsigned char packet_type = packet[3] & 0x03; unsigned char packet_type = packet[3] & 0x03;
bool sanity_check; bool sanity_check;
if ((packet[3] & 0x0f) == 0x06)
return PACKET_TRACKPOINT;
/* /*
* Sanity check based on the constant bits of a packet. * Sanity check based on the constant bits of a packet.
* The constant bits change depending on the value of * The constant bits change depending on the value of
...@@ -877,13 +881,22 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) ...@@ -877,13 +881,22 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
case 4: case 4:
packet_type = elantech_packet_check_v4(psmouse); packet_type = elantech_packet_check_v4(psmouse);
if (packet_type == PACKET_UNKNOWN) switch (packet_type) {
case PACKET_UNKNOWN:
return PSMOUSE_BAD_DATA; return PSMOUSE_BAD_DATA;
case PACKET_TRACKPOINT:
elantech_report_trackpoint(psmouse, packet_type);
break;
default:
elantech_report_absolute_v4(psmouse, packet_type); elantech_report_absolute_v4(psmouse, packet_type);
break; break;
} }
break;
}
return PSMOUSE_FULL_PACKET; return PSMOUSE_FULL_PACKET;
} }
...@@ -1119,6 +1132,22 @@ static void elantech_set_buttonpad_prop(struct psmouse *psmouse) ...@@ -1119,6 +1132,22 @@ static void elantech_set_buttonpad_prop(struct psmouse *psmouse)
} }
} }
/*
* Some hw_version 4 models do have a middle button
*/
static const struct dmi_system_id elantech_dmi_has_middle_button[] = {
#if defined(CONFIG_DMI) && defined(CONFIG_X86)
{
/* Fujitsu H730 has a middle button */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"),
},
},
#endif
{ }
};
/* /*
* Set the appropriate event bits for the input subsystem * Set the appropriate event bits for the input subsystem
*/ */
...@@ -1138,6 +1167,8 @@ static int elantech_set_input_params(struct psmouse *psmouse) ...@@ -1138,6 +1167,8 @@ static int elantech_set_input_params(struct psmouse *psmouse)
__clear_bit(EV_REL, dev->evbit); __clear_bit(EV_REL, dev->evbit);
__set_bit(BTN_LEFT, dev->keybit); __set_bit(BTN_LEFT, dev->keybit);
if (dmi_check_system(elantech_dmi_has_middle_button))
__set_bit(BTN_MIDDLE, dev->keybit);
__set_bit(BTN_RIGHT, dev->keybit); __set_bit(BTN_RIGHT, dev->keybit);
__set_bit(BTN_TOUCH, dev->keybit); __set_bit(BTN_TOUCH, dev->keybit);
...@@ -1299,6 +1330,7 @@ ELANTECH_INT_ATTR(reg_25, 0x25); ...@@ -1299,6 +1330,7 @@ ELANTECH_INT_ATTR(reg_25, 0x25);
ELANTECH_INT_ATTR(reg_26, 0x26); ELANTECH_INT_ATTR(reg_26, 0x26);
ELANTECH_INT_ATTR(debug, 0); ELANTECH_INT_ATTR(debug, 0);
ELANTECH_INT_ATTR(paritycheck, 0); ELANTECH_INT_ATTR(paritycheck, 0);
ELANTECH_INT_ATTR(crc_enabled, 0);
static struct attribute *elantech_attrs[] = { static struct attribute *elantech_attrs[] = {
&psmouse_attr_reg_07.dattr.attr, &psmouse_attr_reg_07.dattr.attr,
...@@ -1313,6 +1345,7 @@ static struct attribute *elantech_attrs[] = { ...@@ -1313,6 +1345,7 @@ static struct attribute *elantech_attrs[] = {
&psmouse_attr_reg_26.dattr.attr, &psmouse_attr_reg_26.dattr.attr,
&psmouse_attr_debug.dattr.attr, &psmouse_attr_debug.dattr.attr,
&psmouse_attr_paritycheck.dattr.attr, &psmouse_attr_paritycheck.dattr.attr,
&psmouse_attr_crc_enabled.dattr.attr,
NULL NULL
}; };
...@@ -1438,6 +1471,22 @@ static int elantech_reconnect(struct psmouse *psmouse) ...@@ -1438,6 +1471,22 @@ static int elantech_reconnect(struct psmouse *psmouse)
return 0; return 0;
} }
/*
* Some hw_version 4 models do not work with crc_disabled
*/
static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
#if defined(CONFIG_DMI) && defined(CONFIG_X86)
{
/* Fujitsu H730 does not work with crc_enabled == 0 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"),
},
},
#endif
{ }
};
/* /*
* Some hw_version 3 models go into error state when we try to set * Some hw_version 3 models go into error state when we try to set
* bit 3 and/or bit 1 of r10. * bit 3 and/or bit 1 of r10.
...@@ -1513,7 +1562,8 @@ static int elantech_set_properties(struct elantech_data *etd) ...@@ -1513,7 +1562,8 @@ static int elantech_set_properties(struct elantech_data *etd)
* The signatures of v3 and v4 packets change depending on the * The signatures of v3 and v4 packets change depending on the
* value of this hardware flag. * value of this hardware flag.
*/ */
etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000); etd->crc_enabled = (etd->fw_version & 0x4000) == 0x4000 ||
dmi_check_system(elantech_dmi_force_crc_enabled);
/* Enable real hardware resolution on hw_version 3 ? */ /* Enable real hardware resolution on hw_version 3 ? */
etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table); etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table);
......
...@@ -135,8 +135,8 @@ static const struct min_max_quirk min_max_pnpid_table[] = { ...@@ -135,8 +135,8 @@ static const struct min_max_quirk min_max_pnpid_table[] = {
1232, 5710, 1156, 4696 1232, 5710, 1156, 4696
}, },
{ {
(const char * const []){"LEN0034", "LEN0036", "LEN2002", (const char * const []){"LEN0034", "LEN0036", "LEN0039",
"LEN2004", NULL}, "LEN2002", "LEN2004", NULL},
1024, 5112, 2024, 4832 1024, 5112, 2024, 4832
}, },
{ {
...@@ -163,6 +163,7 @@ static const char * const topbuttonpad_pnp_ids[] = { ...@@ -163,6 +163,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
"LEN0036", /* T440 */ "LEN0036", /* T440 */
"LEN0037", "LEN0037",
"LEN0038", "LEN0038",
"LEN0039", /* T440s */
"LEN0041", "LEN0041",
"LEN0042", /* Yoga */ "LEN0042", /* Yoga */
"LEN0045", "LEN0045",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment