elantech: Report multitouch with proper ABS_MT messages
Subsystems (2)
PATCH 5/6 elantech: Report multitouch with proper ABS_MT messages
Multitouch info was reported only via a old protocol used by the proprietary X driver from elantech. Let's report the multitouch info also following the official MT protocol. It's semi-mt because the device only reports the lowest/highest coordinates.
This was done following the multi-touch-protocol.txt documentation, and inspired by the bcm5974 and elantech implementations. Testing was light as there is not many applications using this protocol yet, but the X synaptics driver didn't complain and the X multitouch driver behaved correctly.
Signed-off-by Éric Piel <[email protected]>
--- drivers/input/mouse/elantech.c | 36 +++++++++++++++++++++++++++++++----- 1 files changed, 31 insertions(+), 5 deletions(-)
drivers/input/mouse/elantech.c +31 -5
@@ -16,6 +16,7 @@#include <linux/slab.h> #include <linux/module.h> #include <linux/input.h> +#include <linux/input/mt.h> #include <linux/serio.h> #include <linux/libps2.h> #include "psmouse.h"
@@ -242,6 +243,24 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)input_sync (dev); } +static void set_slot (struct input_dev *dev,int slot,bool active,unsigned int x,unsigned int y) +{ +input_mt_slot (dev, slot); +input_mt_report_slot_state (dev,MT_TOOL_FINGER , active); +if (active) { +input_report_abs (dev,ABS_MT_POSITION_X , x); +input_report_abs (dev,ABS_MT_POSITION_Y , y); + } +} + +/* x1 < x2 and y1 < y2 when two fingers, x = y = 0 when not pressed */ +static void elantech_report_semi_mt_data (struct input_dev *dev,int num_fingers, +unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2) +{ +set_slot (dev,0 , (num_fingers >0 ), x1, y1); +set_slot (dev,1 , (num_fingers ==2 ), x2, y2); +} +/* * Interpret complete data packets and report absolute mode input events for * hardware version 2. (6 byte packets)
@@ -251,7 +270,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)struct elantech_data *etd = psmouse->private;struct input_dev *dev = psmouse->dev;unsigned char *packet = psmouse->packet; -int fingers, x1, y1, x2, y2, width =0 , pres =0 ; +unsigned int fingers, x1 =0 , y1 =0 , x2 =0 , y2 =0 , width =0 , pres =0 ;/* byte 0: n1 n0 . . . . R L */ fingers = (packet[0 ] &0xc0 ) >>6 ;
@@ -271,14 +290,16 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)* byte 1: . . . . . x10 x9 x8 * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 */ -input_report_abs (dev,ABS_X , - ((packet[1 ] &0x07 ) <<8 ) | packet[2 ]); + x1 = ((packet[1 ] &0x07 ) <<8 ) | packet[2 ];/* * byte 4: . . . . . . y9 y8 * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 */ -input_report_abs (dev,ABS_Y , -ETP_YMAX_V2 - (((packet[4 ] &0x03 ) <<8 ) | packet[5 ])); + y1 =ETP_YMAX_V2 - (((packet[4 ] &0x03 ) <<8 ) | packet[5 ]); + +input_report_abs (dev,ABS_X , x1); +input_report_abs (dev,ABS_Y , y1); + pres = (packet[1 ] &0xf0 ) | ((packet[4 ] &0xf0 ) >>4 ); width = ((packet[0 ] &0x30 ) >>2 ) | ((packet[3 ] &0x30 ) >>4 );break ;
@@ -321,6 +342,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)break ; } +elantech_report_semi_mt_data (dev, fingers, x1, y1, x2, y2);input_report_key (dev,BTN_TOOL_FINGER , fingers ==1 );input_report_key (dev,BTN_TOOL_DOUBLETAP , fingers ==2 );input_report_key (dev,BTN_TOOL_TRIPLETAP , fingers ==3 );
@@ -548,6 +570,10 @@ static void elantech_set_input_params(struct psmouse *psmouse)input_set_abs_params (dev,ABS_TOOL_WIDTH ,ETP_WMIN_V2 ,ETP_WMAX_V2 ,0 ,0 ); } +__set_bit (INPUT_PROP_SEMI_MT , dev->propbit); +input_mt_init_slots (dev,2 ); +input_set_abs_params (dev,ABS_MT_POSITION_X ,ETP_XMIN_V2 ,ETP_XMAX_V2 ,0 ,0 ); +input_set_abs_params (dev,ABS_MT_POSITION_Y ,ETP_YMIN_V2 ,ETP_YMAX_V2 ,0 ,0 );input_set_abs_params (dev,ABS_HAT0X ,ETP_2FT_XMIN ,ETP_2FT_XMAX ,0 ,0 );input_set_abs_params (dev,ABS_HAT0Y ,ETP_2FT_YMIN ,ETP_2FT_YMAX ,0 ,0 );input_set_abs_params (dev,ABS_HAT1X ,ETP_2FT_XMIN ,ETP_2FT_XMAX ,0 ,0 );
Signature · 6 lines
1.7.5.1 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html