Input: wacom: Use full 32-bit HID Usage value in switch statement
Subsystems (2)
PATCH 1/4 Input: wacom: Use full 32-bit HID Usage value in switch statement
A HID Usage is a 32-bit value: an upper 16-bit "page" and a lower 16-bit ID. While the two halves are normally reported seperately, only the combination uniquely idenfifes a particular HID Usage.
The existing code performs the comparison in two steps, first performing a switch on the ID and then verifying the page within each case. While this works fine, it is very akward to handle two Usages that share a single ID, such as HID_USAGE_PRESSURE and HID_USAGE_X because the case statement can only have a single identifier.
To work around this, we now check the full 32-bit HID Usage directly rather than first checking the ID and then the page. This allows the switch statement to have distinct cases for e.g. HID_USAGE_PRESSURE and HID_USAGE_X.
--- drivers/input/tablet/wacom_sys.c | 237 ++++++++++++++++++--------------------- 1 file changed, 109 insertions(+), 128 deletions(-)
drivers/input/tablet/wacom_sys.c +109 -128
@@ -22,23 +22,17 @@#define HID_USAGE_PAGE_DIGITIZER 0x0d#define HID_USAGE_PAGE_DESKTOP 0x01#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_USAGE_CONTACTMAX 0x55 +#define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30) +#define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31) +#define HID_USAGE_X_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d) +#define HID_USAGE_Y_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e) +#define HID_USAGE_FINGER ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22) +#define HID_USAGE_STYLUS ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x20) +#define HID_USAGE_CONTACTMAX ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x55)#define HID_COLLECTION 0xa1#define HID_COLLECTION_LOGICAL 0x02#define HID_COLLECTION_END 0xc0 -enum { -WCM_UNDEFINED =0 , -WCM_DESKTOP , -WCM_DIGITIZER , -}; -struct hid_descriptor {struct usb_descriptor_header header;__le16 bcdHID;
@@ -305,7 +299,7 @@ static int wacom_parse_hid(struct usb_interface *intf,char limit =0 ;/* result has to be defined as int for some devices */ int result =0 , touch_max =0 ; -int i =0 , usage =WCM_UNDEFINED , finger =0 , pen =0 ; +int i =0 , page =0 , finger =0 , pen =0 ;unsigned char *report; report =kzalloc (hid_desc->wDescriptorLength,GFP_KERNEL );
@@ -332,134 +326,121 @@ static int wacom_parse_hid(struct usb_interface *intf,switch (report[i]) {case HID_USAGE_PAGE : -switch (report[i +1 ]) { -case HID_USAGE_PAGE_DIGITIZER : - usage =WCM_DIGITIZER ; - i++; -break ; - -case HID_USAGE_PAGE_DESKTOP : - usage =WCM_DESKTOP ; - i++; -break ; - } + page = report[i +1 ]; + i++;break ;case HID_USAGE : -switch (report[i +1 ]) { +switch (page <<16 | report[i +1 ]) {case HID_USAGE_X : -if (usage ==WCM_DESKTOP ) { -if (finger) { - features->device_type =BTN_TOOL_FINGER ; -/* touch device at least supports one touch point */ - touch_max =1 ; -switch (features->type) { -case TABLETPC2FG : - features->pktlen =WACOM_PKGLEN_TPC2FG ; -break ; - -case MTSCREEN : -case WACOM_24HDT : - features->pktlen =WACOM_PKGLEN_MTOUCH ; -break ; - -case MTTPC : - features->pktlen =WACOM_PKGLEN_MTTPC ; -break ; - -case BAMBOO_PT : - features->pktlen =WACOM_PKGLEN_BBTOUCH ; -break ; - -default : - features->pktlen =WACOM_PKGLEN_GRAPHIRE ; -break ; - } - -switch (features->type) { -case BAMBOO_PT : - features->x_phy = -get_unaligned_le16 (&report[i +5 ]); - features->x_max = -get_unaligned_le16 (&report[i +8 ]); - i +=15 ; -break ; - -case WACOM_24HDT : - features->x_max = -get_unaligned_le16 (&report[i +3 ]); - features->x_phy = -get_unaligned_le16 (&report[i +8 ]); - features->unit = report[i -1 ]; - features->unitExpo = report[i -3 ]; - i +=12 ; -break ; - -default : - features->x_max = -get_unaligned_le16 (&report[i +3 ]); - features->x_phy = -get_unaligned_le16 (&report[i +6 ]); - features->unit = report[i +9 ]; - features->unitExpo = report[i +11 ]; - i +=12 ; -break ; - } - }else if (pen) { -/* penabled only accepts exact bytes of data */ -if (features->type >=TABLETPC ) - features->pktlen =WACOM_PKGLEN_GRAPHIRE ; - features->device_type =BTN_TOOL_PEN ; +if (finger) { + features->device_type =BTN_TOOL_FINGER ; +/* touch device at least supports one touch point */ + touch_max =1 ; +switch (features->type) { +case TABLETPC2FG : + features->pktlen =WACOM_PKGLEN_TPC2FG ; +break ; + +case MTSCREEN : +case WACOM_24HDT : + features->pktlen =WACOM_PKGLEN_MTOUCH ; +break ; + +case MTTPC : + features->pktlen =WACOM_PKGLEN_MTTPC ; +break ; + +case BAMBOO_PT : + features->pktlen =WACOM_PKGLEN_BBTOUCH ; +break ; + +default : + features->pktlen =WACOM_PKGLEN_GRAPHIRE ; +break ; + } + +switch (features->type) { +case BAMBOO_PT : + features->x_phy = +get_unaligned_le16 (&report[i +5 ]); + features->x_max = +get_unaligned_le16 (&report[i +8 ]); + i +=15 ; +break ; + +case WACOM_24HDT : features->x_max =get_unaligned_le16 (&report[i +3 ]); - i +=4 ; + features->x_phy = +get_unaligned_le16 (&report[i +8 ]); + features->unit = report[i -1 ]; + features->unitExpo = report[i -3 ]; + i +=12 ; +break ; + +default : + features->x_max = +get_unaligned_le16 (&report[i +3 ]); + features->x_phy = +get_unaligned_le16 (&report[i +6 ]); + features->unit = report[i +9 ]; + features->unitExpo = report[i +11 ]; + i +=12 ; +break ; } + }else if (pen) { +/* penabled only accepts exact bytes of data */ +if (features->type >=TABLETPC ) + features->pktlen =WACOM_PKGLEN_GRAPHIRE ; + features->device_type =BTN_TOOL_PEN ; + features->x_max = +get_unaligned_le16 (&report[i +3 ]); + i +=4 ; }break ;case HID_USAGE_Y : -if (usage ==WCM_DESKTOP ) { -if (finger) { -switch (features->type) { -case TABLETPC2FG : -case MTSCREEN : -case MTTPC : - features->y_max = -get_unaligned_le16 (&report[i +3 ]); - features->y_phy = -get_unaligned_le16 (&report[i +6 ]); - i +=7 ; -break ; - -case WACOM_24HDT : - features->y_max = -get_unaligned_le16 (&report[i +3 ]); - features->y_phy = -get_unaligned_le16 (&report[i -2 ]); - i +=7 ; -break ; - -case BAMBOO_PT : - features->y_phy = -get_unaligned_le16 (&report[i +3 ]); - features->y_max = -get_unaligned_le16 (&report[i +6 ]); - i +=12 ; -break ; - -default : - features->y_max = - features->x_max; - features->y_phy = -get_unaligned_le16 (&report[i +3 ]); - i +=4 ; -break ; - } - }else if (pen) { +if (finger) { +switch (features->type) { +case TABLETPC2FG : +case MTSCREEN : +case MTTPC : + features->y_max = +get_unaligned_le16 (&report[i +3 ]); + features->y_phy = +get_unaligned_le16 (&report[i +6 ]); + i +=7 ; +break ; + +case WACOM_24HDT : + features->y_max = +get_unaligned_le16 (&report[i +3 ]); + features->y_phy = +get_unaligned_le16 (&report[i -2 ]); + i +=7 ; +break ; + +case BAMBOO_PT : + features->y_phy = +get_unaligned_le16 (&report[i +3 ]); + features->y_max = +get_unaligned_le16 (&report[i +6 ]); + i +=12 ; +break ; + +default : features->y_max = + features->x_max; + features->y_phy =get_unaligned_le16 (&report[i +3 ]); i +=4 ; +break ; } + }else if (pen) { + features->y_max = +get_unaligned_le16 (&report[i +3 ]); + i +=4 ; }break ;
@@ -489,7 +470,7 @@ static int wacom_parse_hid(struct usb_interface *intf,case HID_COLLECTION_END :/* reset UsagePage and Finger */ - finger = usage =0 ; + finger = page =0 ;break ;case HID_COLLECTION :
Signature · 1 line
1.8.5.3
PATCH 2/4 Input: wacom: Override 'pressure_max' with value from HID_USAGE_PRESSURE
The 0xEC sensor is used in multiple tablet PCs and curiously has versions that report 256 levels of pressure (Samsung Slate 7) as well as versions that report 1024 levels (Lenovo Thinkpad Yoga). To allow both versions to work properly, we allow the value of HID_USAGE_PRESSURE reported to override pressure_max.
--- drivers/input/tablet/wacom_sys.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/input/tablet/wacom_sys.c +9 -0
@@ -24,6 +24,7 @@#define HID_USAGE 0x09#define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30)#define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31) +#define HID_USAGE_PRESSURE ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x30)#define HID_USAGE_X_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d)#define HID_USAGE_Y_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e)#define HID_USAGE_FINGER ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22)
@@ -465,6 +466,14 @@ static int wacom_parse_hid(struct usb_interface *intf,wacom_retrieve_report_data (intf, features); i++;break ; + +case HID_USAGE_PRESSURE : +if (pen) { + features->pressure_max = +get_unaligned_le16 (&report[i +3 ]); + i +=4 ; + } +break ; }break ;
Signature · 1 line
1.8.5.3
A message that is not in the archive (sent off-list or not yet received): 1391107728-1306-2-git-send-email-killertofu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Aaron Armstrong Skomra
Tested-by Aaron SkomraRe: [PATCH 2/4] Input: wacom: Override 'pressure_max' with value from HID_USAGE_PRESSURE
Quoted 51 lines · Jason Gerecke
The
0xECsensor is used in multiple tablet PCs and curiously has versions that report 256 levels of pressure (Samsung Slate 7) as well as versions that report 1024 levels (Lenovo Thinkpad Yoga). To allow both versions to work properly, we allow the value ofHID_USAGE_PRESSUREreported to overridepressure_max.Signed-off-by Jason Gerecke <[email protected]>--- drivers/input/tablet/wacom_sys.c | 9 +++++++++ 1 file changed, 9 insertions(+)drivers/input/tablet/wacom_sys.c +1
-0@@ -24,6 +24,7 @@#define HID_USAGE 0x09#define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30)#define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31) +#define HID_USAGE_PRESSURE ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x30)#define
HID_USAGE_X_TILT((HID_USAGE_PAGE_DIGITIZER<< 16)
|0x3d)
#defineHID_USAGE_Y_TILT((HID_USAGE_PAGE_DIGITIZER<< 16)
|0x3e)
#defineHID_USAGE_FINGER((HID_USAGE_PAGE_DIGITIZER<< 16)
|0x22)drivers/input/tablet/wacom_sys.c +8
-0@@ -465,6 +466,14 @@ static int wacom_parse_hid(struct usb_interface *intf,wacom_retrieve_report_data (intf, features); i++;break ; + +case HID_USAGE_PRESSURE : +if (pen) { + features->pressure_max = +get_unaligned_le16 (&report[i +3 ]); + i +=4 ; + } +break ; }break;--
1.8.5.3
Signature · 3 lines
Aaron Skomra [email protected] 503-208-5430
------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool. Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer Customize your own dashboards, set traffic alerts and generate reports. Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
Re: [PATCH 2/4] Input: wacom: Override 'pressure_max' with value from HID_USAGE_PRESSURE
In reply to Jason GereckeQuoted 39 lines · Jason Gerecke
The
0xECsensor is used in multiple tablet PCs and curiously has versions that report 256 levels of pressure (Samsung Slate 7) as well as versions that report 1024 levels (Lenovo Thinkpad Yoga). To allow both versions to work properly, we allow the value ofHID_USAGE_PRESSUREreported to overridepressure_max.Signed-off-by Jason Gerecke <[email protected]>--- drivers/input/tablet/wacom_sys.c | 9 +++++++++ 1 file changed, 9 insertions(+)drivers/input/tablet/wacom_sys.c +9
-1@@ -24,6 +24,7 @@#define HID_USAGE 0x09#define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30)#define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31) +#define HID_USAGE_PRESSURE ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x30)#define HID_USAGE_X_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d)#define HID_USAGE_Y_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e)#define HID_USAGE_FINGER ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22)@@ -465,6 +466,14 @@ static int wacom_parse_hid(struct usb_interface *intf,wacom_retrieve_report_data (intf, features); i++;break ; + +case HID_USAGE_PRESSURE : +if (pen) { + features->pressure_max = +get_unaligned_le16 (&report[i +3 ]); + i +=4 ; + } +break ; }break ; --
Quoted 2 lines
1.8.5.3
PATCH 3/4 Input: wacom: References to 'wacom->data' should use 'unsigned char*'
In reply to Jason Gerecke'wacom->data' contains raw binary data and can lead to unexpected behavior if a byte under examination happens to have its MSB set.
--- drivers/input/tablet/wacom_wac.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)
drivers/input/tablet/wacom_wac.c +9 -18
@@ -178,10 +178,9 @@ static int wacom_ptu_irq(struct wacom_wac *wacom)static int wacom_dtu_irq (struct wacom_wac *wacom) { -struct wacom_features *features = &wacom->features; -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->input; -int prox = data[1 ] &0x20 , pressure; +int prox = data[1 ] &0x20 ;dev_dbg (input->dev.parent,"%s: received report #%d" , __func__, data[0 ]);
@@ -198,10 +197,7 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)input_report_key (input,BTN_STYLUS2 , data[1 ] &0x10 );input_report_abs (input,ABS_X ,le16_to_cpup ((__le16 *)&data[2 ]));input_report_abs (input,ABS_Y ,le16_to_cpup ((__le16 *)&data[4 ])); - pressure = ((data[7 ] &0x01 ) <<8 ) | data[6 ]; -if (pressure <0 ) - pressure = features->pressure_max + pressure +1 ; -input_report_abs (input,ABS_PRESSURE , pressure); +input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x01 ) <<8 ) | data[6 ]);input_report_key (input,BTN_TOUCH , data[1 ] &0x05 );if (!prox)/* out-prox */ wacom->id[0 ] =0 ;
@@ -906,7 +902,7 @@ static int int_dist(int x1, int y1, int x2, int y2)static int wacom_24hdt_irq (struct wacom_wac *wacom) {struct input_dev *input = wacom->input; -char *data = wacom->data; +unsigned char *data = wacom->data;int i;int current_num_contacts = data[61 ];int contacts_to_send =0 ;
@@ -959,7 +955,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)static int wacom_mt_touch (struct wacom_wac *wacom) {struct input_dev *input = wacom->input; -char *data = wacom->data; +unsigned char *data = wacom->data;int i;int current_num_contacts = data[2 ];int contacts_to_send =0 ;
@@ -1038,7 +1034,7 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom)static int wacom_tpc_single_touch (struct wacom_wac *wacom,size_t len) { -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->input;bool prox;int x =0 , y =0 ;
@@ -1074,10 +1070,8 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)static int wacom_tpc_pen (struct wacom_wac *wacom) { -struct wacom_features *features = &wacom->features; -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->input; -int pressure;bool prox = data[1 ] &0x20 ;if (!wacom->shared->stylus_in_proximity)/* first in prox */
@@ -1093,10 +1087,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)input_report_key (input,BTN_STYLUS2 , data[1 ] &0x10 );input_report_abs (input,ABS_X ,le16_to_cpup ((__le16 *)&data[2 ]));input_report_abs (input,ABS_Y ,le16_to_cpup ((__le16 *)&data[4 ])); - pressure = ((data[7 ] &0x01 ) <<8 ) | data[6 ]; -if (pressure <0 ) - pressure = features->pressure_max + pressure +1 ; -input_report_abs (input,ABS_PRESSURE , pressure); +input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x01 ) <<8 ) | data[6 ]);input_report_key (input,BTN_TOUCH , data[1 ] &0x05 );input_report_key (input, wacom->tool[0 ], prox);return 1 ;
@@ -1107,7 +1098,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)static int wacom_tpc_irq (struct wacom_wac *wacom,size_t len) { -char *data = wacom->data; +unsigned char *data = wacom->data;dev_dbg (wacom->input->dev.parent,"%s: received report #%d\n" , __func__, data[0 ]);
Signature · 1 line
1.8.5.3
A message that is not in the archive (sent off-list or not yet received): 1391107728-1306-3-git-send-email-killertofu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Aaron Armstrong Skomra
Tested-by Aaron SkomraRe: [PATCH 3/4] Input: wacom: References to 'wacom->data' should use 'unsigned char*'
Quoted 108 lines · Jason Gerecke
'
wacom->data' contains raw binary data and can lead to unexpected behavior if a byte under examination happens to have its MSB set.Signed-off-by Jason Gerecke <[email protected]>--- drivers/input/tablet/wacom_wac.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)drivers/input/tablet/wacom_wac.c +3
-7@@ -178,10 +178,9 @@ static int wacom_ptu_irq(struct wacom_wac *wacom)static int wacom_dtu_irq (struct wacom_wac *wacom) { -struct wacom_features *features = &wacom->features; -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->input; -int prox = data[1 ] &0x20 , pressure; +int prox = data[1 ] &0x20 ;dev_dbg (input->dev.parent,"%s: received report #%d" , __func__, data[0 ]);@@ -198,10 +197,7 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)input_report_key (input,BTN_STYLUS2 , data[1 ] &0x10 );input_report_abs (input,ABS_X ,le16_to_cpup ((__le16 *)&data[2 ]));input_report_abs (input,ABS_Y ,le16_to_cpup ((__le16 *)&data[4 ])); - pressure = ((data[7 ] &0x01 ) <<8 ) | data[6 ]; -if (pressure <0 ) - pressure = features->pressure_max + pressure +1 ; -input_report_abs (input,ABS_PRESSURE , pressure); +input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x01 ) <<8 ) | data[6 ]);input_report_key (input,BTN_TOUCH , data[1 ] &0x05 );if (!prox)/* out-prox */ wacom->id[0] = 0;drivers/input/tablet/wacom_wac.c +3
-3@@ -906,7 +902,7 @@ static int int_dist(int x1, int y1, int x2, int y2)static int wacom_24hdt_irq (struct wacom_wac *wacom) {struct input_dev *input = wacom->input; -char *data = wacom->data; +unsigned char *data = wacom->data;int i;int current_num_contacts = data[61 ];int contacts_to_send =0 ;@@ -959,7 +955,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)static int wacom_mt_touch (struct wacom_wac *wacom) {struct input_dev *input = wacom->input; -char *data = wacom->data; +unsigned char *data = wacom->data;int i;int current_num_contacts = data[2 ];int contacts_to_send =0 ;@@ -1038,7 +1034,7 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom)static int wacom_tpc_single_touch (struct wacom_wac *wacom,size_t len) { -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->input;bool prox;int x = 0, y = 0;drivers/input/tablet/wacom_wac.c +1
-3@@ -1074,10 +1070,8 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)static int wacom_tpc_pen (struct wacom_wac *wacom) { -struct wacom_features *features = &wacom->features; -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->input; -int pressure;bool prox = data[1 ] &0x20 ;if (!wacom->shared->stylus_in_proximity) /* first in prox */drivers/input/tablet/wacom_wac.c +1
-4@@ -1093,10 +1087,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)input_report_key (input,BTN_STYLUS2 , data[1 ] &0x10 );input_report_abs (input,ABS_X ,le16_to_cpup ((__le16 *)&data[2 ]));input_report_abs (input,ABS_Y ,le16_to_cpup ((__le16 *)&data[4 ])); - pressure = ((data[7 ] &0x01 ) <<8 ) | data[6 ]; -if (pressure <0 ) - pressure = features->pressure_max + pressure +1 ; -input_report_abs (input,ABS_PRESSURE , pressure); +input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x01 ) <<8 ) | data[6 ]);input_report_key(input, BTN_TOUCH, data[1] & 0x05); input_report_key(input, wacom->tool[0], prox); return 1;drivers/input/tablet/wacom_wac.c +1
-2@@ -1107,7 +1098,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)static int wacom_tpc_irq (struct wacom_wac *wacom,size_t len) { -char *data = wacom->data; +unsigned char *data = wacom->data;dev_dbg (wacom->input->dev.parent,"%s: received report #%d\n" , __func__, data[0 ]); --1.8.5.3
Signature · 3 lines
Aaron Skomra [email protected] 503-208-5430
------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool. Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer Customize your own dashboards, set traffic alerts and generate reports. Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
Re: [PATCH 3/4] Input: wacom: References to 'wacom->data' should use 'unsigned char*'
In reply to Jason GereckeQuoted 98 lines · Jason Gerecke
'
wacom->data' contains raw binary data and can lead to unexpected behavior if a byte under examination happens to have its MSB set.Signed-off-by Jason Gerecke <[email protected]>--- drivers/input/tablet/wacom_wac.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)drivers/input/tablet/wacom_wac.c +9
-19@@ -178,10 +178,9 @@ static int wacom_ptu_irq(struct wacom_wac *wacom)static int wacom_dtu_irq (struct wacom_wac *wacom) { -struct wacom_features *features = &wacom->features; -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->input; -int prox = data[1 ] &0x20 , pressure; +int prox = data[1 ] &0x20 ;dev_dbg (input->dev.parent,"%s: received report #%d" , __func__, data[0 ]);@@ -198,10 +197,7 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)input_report_key (input,BTN_STYLUS2 , data[1 ] &0x10 );input_report_abs (input,ABS_X ,le16_to_cpup ((__le16 *)&data[2 ]));input_report_abs (input,ABS_Y ,le16_to_cpup ((__le16 *)&data[4 ])); - pressure = ((data[7 ] &0x01 ) <<8 ) | data[6 ]; -if (pressure <0 ) - pressure = features->pressure_max + pressure +1 ; -input_report_abs (input,ABS_PRESSURE , pressure); +input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x01 ) <<8 ) | data[6 ]);input_report_key (input,BTN_TOUCH , data[1 ] &0x05 );if (!prox)/* out-prox */ wacom->id[0 ] =0 ;@@ -906,7 +902,7 @@ static int int_dist(int x1, int y1, int x2, int y2)static int wacom_24hdt_irq (struct wacom_wac *wacom) {struct input_dev *input = wacom->input; -char *data = wacom->data; +unsigned char *data = wacom->data;int i;int current_num_contacts = data[61 ];int contacts_to_send =0 ;@@ -959,7 +955,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)static int wacom_mt_touch (struct wacom_wac *wacom) {struct input_dev *input = wacom->input; -char *data = wacom->data; +unsigned char *data = wacom->data;int i;int current_num_contacts = data[2 ];int contacts_to_send =0 ;@@ -1038,7 +1034,7 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom)static int wacom_tpc_single_touch (struct wacom_wac *wacom,size_t len) { -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->input;bool prox;int x =0 , y =0 ;@@ -1074,10 +1070,8 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)static int wacom_tpc_pen (struct wacom_wac *wacom) { -struct wacom_features *features = &wacom->features; -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->input; -int pressure;bool prox = data[1 ] &0x20 ;if (!wacom->shared->stylus_in_proximity)/* first in prox */ @@ -1093,10 +1087,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)input_report_key (input,BTN_STYLUS2 , data[1 ] &0x10 );input_report_abs (input,ABS_X ,le16_to_cpup ((__le16 *)&data[2 ]));input_report_abs (input,ABS_Y ,le16_to_cpup ((__le16 *)&data[4 ])); - pressure = ((data[7 ] &0x01 ) <<8 ) | data[6 ]; -if (pressure <0 ) - pressure = features->pressure_max + pressure +1 ; -input_report_abs (input,ABS_PRESSURE , pressure); +input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x01 ) <<8 ) | data[6 ]);input_report_key (input,BTN_TOUCH , data[1 ] &0x05 );input_report_key (input, wacom->tool[0 ], prox);return 1 ;@@ -1107,7 +1098,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)static int wacom_tpc_irq (struct wacom_wac *wacom,size_t len) { -char *data = wacom->data; +unsigned char *data = wacom->data;dev_dbg (wacom->input->dev.parent,"%s: received report #%d\n" , __func__, data[0 ]); --
Quoted 2 lines
1.8.5.3
PATCH 4/4 Input: wacom: Handle 1024 pressure levels in wacom_tpc_pen
In reply to Jason GereckeSome tablet PC sensors (e.g. the 0xEC found in the Thinkpad Yoga) report more than 256 pressure levels and will experience wraparound unless the full range is read.
--- drivers/input/tablet/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/tablet/wacom_wac.c +1 -1
@@ -1087,7 +1087,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)input_report_key (input,BTN_STYLUS2 , data[1 ] &0x10 );input_report_abs (input,ABS_X ,le16_to_cpup ((__le16 *)&data[2 ]));input_report_abs (input,ABS_Y ,le16_to_cpup ((__le16 *)&data[4 ])); -input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x01 ) <<8 ) | data[6 ]); +input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x03 ) <<8 ) | data[6 ]);input_report_key (input,BTN_TOUCH , data[1 ] &0x05 );input_report_key (input, wacom->tool[0 ], prox);return 1 ;
Signature · 1 line
1.8.5.3
A message that is not in the archive (sent off-list or not yet received): 1391107728-1306-4-git-send-email-killertofu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Aaron Armstrong Skomra
Tested-by Aaron SkomraRe: [PATCH 4/4] Input: wacom: Handle 1024 pressure levels in wacom_tpc_pen
Quoted 31 lines · Jason Gerecke
Some tablet PC sensors (e.g. the
0xECfound in the Thinkpad Yoga) report more than 256 pressure levels and will experience wraparound unless the full range is read.Signed-off-by Jason Gerecke <[email protected]>--- drivers/input/tablet/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/input/tablet/wacom_wac.c +1
-1@@ -1087,7 +1087,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)input_report_key (input,BTN_STYLUS2 , data[1 ] &0x10 );input_report_abs (input,ABS_X ,le16_to_cpup ((__le16 *)&data[2 ]));input_report_abs (input,ABS_Y ,le16_to_cpup ((__le16 *)&data[4 ])); -input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x01 ) << 8) | data[6]); + input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x03) <<8) | data[6]); input_report_key(input, BTN_TOUCH, data[1] & 0x05); input_report_key(input, wacom->tool[0], prox); return 1;--
1.8.5.3
Signature · 3 lines
Aaron Skomra [email protected] 503-208-5430
------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool. Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer Customize your own dashboards, set traffic alerts and generate reports. Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
Re: [PATCH 4/4] Input: wacom: Handle 1024 pressure levels in wacom_tpc_pen
In reply to Jason GereckeQuoted 23 lines · Jason Gerecke
Some tablet PC sensors (e.g. the
0xECfound in the Thinkpad Yoga) report more than 256 pressure levels and will experience wraparound unless the full range is read.Signed-off-by Jason Gerecke <[email protected]>--- drivers/input/tablet/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/input/tablet/wacom_wac.c +1
-2@@ -1087,7 +1087,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)input_report_key (input,BTN_STYLUS2 , data[1 ] &0x10 );input_report_abs (input,ABS_X ,le16_to_cpup ((__le16 *)&data[2 ]));input_report_abs (input,ABS_Y ,le16_to_cpup ((__le16 *)&data[4 ])); -input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x01 ) <<8 ) | data[6 ]); +input_report_abs (input,ABS_PRESSURE , ((data[7 ] &0x03 ) <<8 ) | data[6 ]);input_report_key (input,BTN_TOUCH , data[1 ] &0x05 );input_report_key (input, wacom->tool[0 ], prox);return 1 ; --
Quoted 2 lines
1.8.5.3
Quoted 311 lines · Jason Gerecke
A HID Usage is a 32-bit value: an upper 16-bit "page" and a lower 16-bit ID. While the two halves are normally reported seperately, only the combination uniquely idenfifes a particular HID Usage.
The existing code performs the comparison in two steps, first performing a switch on the ID and then verifying the page within each case. While this works fine, it is very akward to handle two Usages that share a single ID, such as
HID_USAGE_PRESSUREandHID_USAGE_Xbecause the case statement can only have a single identifier.To work around this, we now check the full 32-bit HID Usage directly rather than first checking the ID and then the page. This allows the switch statement to have distinct cases for e.g.
HID_USAGE_PRESSUREandHID_USAGE_X.Signed-off-by Jason Gerecke <[email protected]>--- drivers/input/tablet/wacom_sys.c | 237 ++++++++++++++++++--------------------- 1 file changed, 109 insertions(+), 128 deletions(-)drivers/input/tablet/wacom_sys.c +109
-129@@ -22,23 +22,17 @@#define HID_USAGE_PAGE_DIGITIZER 0x0d#define HID_USAGE_PAGE_DESKTOP 0x01#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_USAGE_CONTACTMAX 0x55 +#define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30) +#define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31) +#define HID_USAGE_X_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d) +#define HID_USAGE_Y_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e) +#define HID_USAGE_FINGER ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22) +#define HID_USAGE_STYLUS ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x20) +#define HID_USAGE_CONTACTMAX ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x55)#define HID_COLLECTION 0xa1#define HID_COLLECTION_LOGICAL 0x02#define HID_COLLECTION_END 0xc0 -enum { -WCM_UNDEFINED =0 , -WCM_DESKTOP , -WCM_DIGITIZER , -}; -struct hid_descriptor {struct usb_descriptor_header header;__le16 bcdHID;@@ -305,7 +299,7 @@ static int wacom_parse_hid(struct usb_interface *intf,char limit =0 ;/* result has to be defined as int for some devices */ int result =0 , touch_max =0 ; -int i =0 , usage =WCM_UNDEFINED , finger =0 , pen =0 ; +int i =0 , page =0 , finger =0 , pen =0 ;unsigned char *report; report =kzalloc (hid_desc->wDescriptorLength,GFP_KERNEL );@@ -332,134 +326,121 @@ static int wacom_parse_hid(struct usb_interface *intf,switch (report[i]) {case HID_USAGE_PAGE : -switch (report[i +1 ]) { -case HID_USAGE_PAGE_DIGITIZER : - usage =WCM_DIGITIZER ; - i++; -break ; - -case HID_USAGE_PAGE_DESKTOP : - usage =WCM_DESKTOP ; - i++; -break ; - } + page = report[i +1 ]; + i++;break ;case HID_USAGE : -switch (report[i +1 ]) { +switch (page <<16 | report[i +1 ]) {case HID_USAGE_X : -if (usage ==WCM_DESKTOP ) { -if (finger) { - features->device_type =BTN_TOOL_FINGER ; -/* touch device at least supports one touch point */ - touch_max =1 ; -switch (features->type) { -case TABLETPC2FG : - features->pktlen =WACOM_PKGLEN_TPC2FG ; -break ; - -case MTSCREEN : -case WACOM_24HDT : - features->pktlen =WACOM_PKGLEN_MTOUCH ; -break ; - -case MTTPC : - features->pktlen =WACOM_PKGLEN_MTTPC ; -break ; - -case BAMBOO_PT : - features->pktlen =WACOM_PKGLEN_BBTOUCH ; -break ; - -default : - features->pktlen =WACOM_PKGLEN_GRAPHIRE ; -break ; - } - -switch (features->type) { -case BAMBOO_PT : - features->x_phy = -get_unaligned_le16 (&report[i +5 ]); - features->x_max = -get_unaligned_le16 (&report[i +8 ]); - i +=15 ; -break ; - -case WACOM_24HDT : - features->x_max = -get_unaligned_le16 (&report[i +3 ]); - features->x_phy = -get_unaligned_le16 (&report[i +8 ]); - features->unit = report[i -1 ]; - features->unitExpo = report[i -3 ]; - i +=12 ; -break ; - -default : - features->x_max = -get_unaligned_le16 (&report[i +3 ]); - features->x_phy = -get_unaligned_le16 (&report[i +6 ]); - features->unit = report[i +9 ]; - features->unitExpo = report[i +11 ]; - i +=12 ; -break ; - } - }else if (pen) { -/* penabled only accepts exact bytes of data */ -if (features->type >=TABLETPC ) - features->pktlen =WACOM_PKGLEN_GRAPHIRE ; - features->device_type =BTN_TOOL_PEN ; +if (finger) { + features->device_type =BTN_TOOL_FINGER ; +/* touch device at least supports one touch point */ + touch_max =1 ; +switch (features->type) { +case TABLETPC2FG : + features->pktlen =WACOM_PKGLEN_TPC2FG ; +break ; + +case MTSCREEN : +case WACOM_24HDT : + features->pktlen =WACOM_PKGLEN_MTOUCH ; +break ; + +case MTTPC : + features->pktlen =WACOM_PKGLEN_MTTPC ; +break ; + +case BAMBOO_PT : + features->pktlen =WACOM_PKGLEN_BBTOUCH ; +break ; + +default : + features->pktlen =WACOM_PKGLEN_GRAPHIRE ; +break ; + } + +switch (features->type) { +case BAMBOO_PT : + features->x_phy = +get_unaligned_le16 (&report[i +5 ]); + features->x_max = +get_unaligned_le16 (&report[i +8 ]); + i +=15 ; +break ; + +case WACOM_24HDT : features->x_max =get_unaligned_le16 (&report[i +3 ]); - i +=4 ; + features->x_phy = +get_unaligned_le16 (&report[i +8 ]); + features->unit = report[i -1 ]; + features->unitExpo = report[i -3 ]; + i +=12 ; +break ; + +default : + features->x_max = +get_unaligned_le16 (&report[i +3 ]); + features->x_phy = +get_unaligned_le16 (&report[i +6 ]); + features->unit = report[i +9 ]; + features->unitExpo = report[i +11 ]; + i +=12 ; +break ; } + }else if (pen) { +/* penabled only accepts exact bytes of data */ +if (features->type >=TABLETPC ) + features->pktlen =WACOM_PKGLEN_GRAPHIRE ; + features->device_type =BTN_TOOL_PEN ; + features->x_max = +get_unaligned_le16 (&report[i +3 ]); + i +=4 ; }break ;case HID_USAGE_Y : -if (usage ==WCM_DESKTOP ) { -if (finger) { -switch (features->type) { -case TABLETPC2FG : -case MTSCREEN : -case MTTPC : - features->y_max = -get_unaligned_le16 (&report[i +3 ]); - features->y_phy = -get_unaligned_le16 (&report[i +6 ]); - i +=7 ; -break ; - -case WACOM_24HDT : - features->y_max = -get_unaligned_le16 (&report[i +3 ]); - features->y_phy = -get_unaligned_le16 (&report[i -2 ]); - i +=7 ; -break ; - -case BAMBOO_PT : - features->y_phy = -get_unaligned_le16 (&report[i +3 ]); - features->y_max = -get_unaligned_le16 (&report[i +6 ]); - i +=12 ; -break ; - -default : - features->y_max = - features->x_max; - features->y_phy = -get_unaligned_le16 (&report[i +3 ]); - i +=4 ; -break ; - } - }else if (pen) { +if (finger) { +switch (features->type) { +case TABLETPC2FG : +case MTSCREEN : +case MTTPC : + features->y_max = +get_unaligned_le16 (&report[i +3 ]); + features->y_phy = +get_unaligned_le16 (&report[i +6 ]); + i +=7 ; +break ; + +case WACOM_24HDT : + features->y_max = +get_unaligned_le16 (&report[i +3 ]); + features->y_phy = +get_unaligned_le16 (&report[i -2 ]); + i +=7 ; +break ; + +case BAMBOO_PT : + features->y_phy = +get_unaligned_le16 (&report[i +3 ]); + features->y_max = +get_unaligned_le16 (&report[i +6 ]); + i +=12 ; +break ; + +default : features->y_max = + features->x_max; + features->y_phy =get_unaligned_le16 (&report[i +3 ]); i +=4 ; +break ; } + }else if (pen) { + features->y_max = +get_unaligned_le16 (&report[i +3 ]); + i +=4 ; }break ;@@ -489,7 +470,7 @@ static int wacom_parse_hid(struct usb_interface *intf,case HID_COLLECTION_END :/* reset UsagePage and Finger */ - finger = usage =0 ; + finger = page =0 ;break ;case HID_COLLECTION : --
Quoted 2 lines
1.8.5.3