@@ -567,8 +567,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
567
567
keys = data [9 ] & 0x07 ;
568
568
}
569
569
} else {
570
- buttons = ((data [6 ] & 0x10 ) << 10 ) |
571
- ((data [5 ] & 0x10 ) << 9 ) |
570
+ buttons = ((data [6 ] & 0x10 ) << 5 ) |
571
+ ((data [5 ] & 0x10 ) << 4 ) |
572
572
((data [6 ] & 0x0F ) << 4 ) |
573
573
(data [5 ] & 0x0F );
574
574
}
@@ -1227,11 +1227,17 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
1227
1227
continue ;
1228
1228
1229
1229
if (range ) {
1230
+ /* Fix rotation alignment: userspace expects zero at left */
1231
+ int16_t rotation = (int16_t )get_unaligned_le16 (& frame [9 ]);
1232
+ rotation += 1800 /4 ;
1233
+ if (rotation > 899 )
1234
+ rotation -= 1800 ;
1235
+
1230
1236
input_report_abs (pen_input , ABS_X , get_unaligned_le16 (& frame [1 ]));
1231
1237
input_report_abs (pen_input , ABS_Y , get_unaligned_le16 (& frame [3 ]));
1232
- input_report_abs (pen_input , ABS_TILT_X , frame [7 ]);
1233
- input_report_abs (pen_input , ABS_TILT_Y , frame [8 ]);
1234
- input_report_abs (pen_input , ABS_Z , get_unaligned_le16 ( & frame [ 9 ]) );
1238
+ input_report_abs (pen_input , ABS_TILT_X , ( char ) frame [7 ]);
1239
+ input_report_abs (pen_input , ABS_TILT_Y , ( char ) frame [8 ]);
1240
+ input_report_abs (pen_input , ABS_Z , rotation );
1235
1241
input_report_abs (pen_input , ABS_WHEEL , get_unaligned_le16 (& frame [11 ]));
1236
1242
}
1237
1243
input_report_abs (pen_input , ABS_PRESSURE , get_unaligned_le16 (& frame [5 ]));
@@ -1319,12 +1325,19 @@ static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom)
1319
1325
unsigned char * data = wacom -> data ;
1320
1326
1321
1327
int buttons = (data [282 ] << 1 ) | ((data [281 ] >> 6 ) & 0x01 );
1322
- int ring = data [285 ];
1323
- int prox = buttons | (ring & 0x80 );
1328
+ int ring = data [285 ] & 0x7F ;
1329
+ bool ringstatus = data [285 ] & 0x80 ;
1330
+ bool prox = buttons || ringstatus ;
1331
+
1332
+ /* Fix touchring data: userspace expects 0 at left and increasing clockwise */
1333
+ ring = 71 - ring ;
1334
+ ring += 3 * 72 /16 ;
1335
+ if (ring > 71 )
1336
+ ring -= 72 ;
1324
1337
1325
1338
wacom_report_numbered_buttons (pad_input , 9 , buttons );
1326
1339
1327
- input_report_abs (pad_input , ABS_WHEEL , ( ring & 0x80 ) ? ( ring & 0x7f ) : 0 );
1340
+ input_report_abs (pad_input , ABS_WHEEL , ringstatus ? ring : 0 );
1328
1341
1329
1342
input_report_key (pad_input , wacom -> tool [1 ], prox ? 1 : 0 );
1330
1343
input_report_abs (pad_input , ABS_MISC , prox ? PAD_DEVICE_ID : 0 );
@@ -1616,6 +1629,20 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
1616
1629
return 0 ;
1617
1630
}
1618
1631
1632
+ static int wacom_offset_rotation (struct input_dev * input , struct hid_usage * usage ,
1633
+ int value , int num , int denom )
1634
+ {
1635
+ struct input_absinfo * abs = & input -> absinfo [usage -> code ];
1636
+ int range = (abs -> maximum - abs -> minimum + 1 );
1637
+
1638
+ value += num * range /denom ;
1639
+ if (value > abs -> maximum )
1640
+ value -= range ;
1641
+ else if (value < abs -> minimum )
1642
+ value += range ;
1643
+ return value ;
1644
+ }
1645
+
1619
1646
int wacom_equivalent_usage (int usage )
1620
1647
{
1621
1648
if ((usage & HID_USAGE_PAGE ) == WACOM_HID_UP_WACOMDIGITIZER ) {
@@ -1898,6 +1925,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
1898
1925
unsigned equivalent_usage = wacom_equivalent_usage (usage -> hid );
1899
1926
int i ;
1900
1927
bool is_touch_on = value ;
1928
+ bool do_report = false;
1901
1929
1902
1930
/*
1903
1931
* Avoid reporting this event and setting inrange_state if this usage
@@ -1912,6 +1940,29 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
1912
1940
}
1913
1941
1914
1942
switch (equivalent_usage ) {
1943
+ case WACOM_HID_WD_TOUCHRING :
1944
+ /*
1945
+ * Userspace expects touchrings to increase in value with
1946
+ * clockwise gestures and have their zero point at the
1947
+ * tablet's left. HID events "should" be clockwise-
1948
+ * increasing and zero at top, though the MobileStudio
1949
+ * Pro and 2nd-gen Intuos Pro don't do this...
1950
+ */
1951
+ if (hdev -> vendor == 0x56a &&
1952
+ (hdev -> product == 0x34d || hdev -> product == 0x34e || /* MobileStudio Pro */
1953
+ hdev -> product == 0x357 || hdev -> product == 0x358 )) { /* Intuos Pro 2 */
1954
+ value = (field -> logical_maximum - value );
1955
+
1956
+ if (hdev -> product == 0x357 || hdev -> product == 0x358 )
1957
+ value = wacom_offset_rotation (input , usage , value , 3 , 16 );
1958
+ else if (hdev -> product == 0x34d || hdev -> product == 0x34e )
1959
+ value = wacom_offset_rotation (input , usage , value , 1 , 2 );
1960
+ }
1961
+ else {
1962
+ value = wacom_offset_rotation (input , usage , value , 1 , 4 );
1963
+ }
1964
+ do_report = true;
1965
+ break ;
1915
1966
case WACOM_HID_WD_TOUCHRINGSTATUS :
1916
1967
if (!value )
1917
1968
input_event (input , usage -> type , usage -> code , 0 );
@@ -1945,10 +1996,14 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
1945
1996
value , i );
1946
1997
/* fall through*/
1947
1998
default :
1999
+ do_report = true;
2000
+ break ;
2001
+ }
2002
+
2003
+ if (do_report ) {
1948
2004
input_event (input , usage -> type , usage -> code , value );
1949
2005
if (value )
1950
2006
wacom_wac -> hid_data .pad_input_event_flag = true;
1951
- break ;
1952
2007
}
1953
2008
}
1954
2009
@@ -2086,22 +2141,34 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
2086
2141
wacom_wac -> hid_data .tipswitch |= value ;
2087
2142
return ;
2088
2143
case HID_DG_TOOLSERIALNUMBER :
2089
- wacom_wac -> serial [0 ] = (wacom_wac -> serial [0 ] & ~0xFFFFFFFFULL );
2090
- wacom_wac -> serial [0 ] |= (__u32 )value ;
2144
+ if (value ) {
2145
+ wacom_wac -> serial [0 ] = (wacom_wac -> serial [0 ] & ~0xFFFFFFFFULL );
2146
+ wacom_wac -> serial [0 ] |= (__u32 )value ;
2147
+ }
2091
2148
return ;
2149
+ case HID_DG_TWIST :
2150
+ /*
2151
+ * Userspace expects pen twist to have its zero point when
2152
+ * the buttons/finger is on the tablet's left. HID values
2153
+ * are zero when buttons are toward the top.
2154
+ */
2155
+ value = wacom_offset_rotation (input , usage , value , 1 , 4 );
2156
+ break ;
2092
2157
case WACOM_HID_WD_SENSE :
2093
2158
wacom_wac -> hid_data .sense_state = value ;
2094
2159
return ;
2095
2160
case WACOM_HID_WD_SERIALHI :
2096
- wacom_wac -> serial [0 ] = (wacom_wac -> serial [0 ] & 0xFFFFFFFF );
2097
- wacom_wac -> serial [0 ] |= ((__u64 )value ) << 32 ;
2098
- /*
2099
- * Non-USI EMR devices may contain additional tool type
2100
- * information here. See WACOM_HID_WD_TOOLTYPE case for
2101
- * more details.
2102
- */
2103
- if (value >> 20 == 1 ) {
2104
- wacom_wac -> id [0 ] |= value & 0xFFFFF ;
2161
+ if (value ) {
2162
+ wacom_wac -> serial [0 ] = (wacom_wac -> serial [0 ] & 0xFFFFFFFF );
2163
+ wacom_wac -> serial [0 ] |= ((__u64 )value ) << 32 ;
2164
+ /*
2165
+ * Non-USI EMR devices may contain additional tool type
2166
+ * information here. See WACOM_HID_WD_TOOLTYPE case for
2167
+ * more details.
2168
+ */
2169
+ if (value >> 20 == 1 ) {
2170
+ wacom_wac -> id [0 ] |= value & 0xFFFFF ;
2171
+ }
2105
2172
}
2106
2173
return ;
2107
2174
case WACOM_HID_WD_TOOLTYPE :
@@ -2205,7 +2272,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
2205
2272
input_report_key (input , wacom_wac -> tool [0 ], prox );
2206
2273
if (wacom_wac -> serial [0 ]) {
2207
2274
input_event (input , EV_MSC , MSC_SERIAL , wacom_wac -> serial [0 ]);
2208
- input_report_abs (input , ABS_MISC , id );
2275
+ input_report_abs (input , ABS_MISC , prox ? id : 0 );
2209
2276
}
2210
2277
2211
2278
wacom_wac -> hid_data .tipswitch = false;
@@ -2216,6 +2283,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
2216
2283
if (!prox ) {
2217
2284
wacom_wac -> tool [0 ] = 0 ;
2218
2285
wacom_wac -> id [0 ] = 0 ;
2286
+ wacom_wac -> serial [0 ] = 0 ;
2219
2287
}
2220
2288
}
2221
2289
0 commit comments