@@ -1201,12 +1201,10 @@ static void wacom_intuos_bt_process_data(struct wacom_wac *wacom,
12011201
12021202static int wacom_intuos_bt_irq (struct wacom_wac * wacom , size_t len )
12031203{
1204- unsigned char data [ WACOM_PKGLEN_MAX ] ;
1204+ u8 * data = kmemdup ( wacom -> data , len , GFP_KERNEL ) ;
12051205 int i = 1 ;
12061206 unsigned power_raw , battery_capacity , bat_charging , ps_connected ;
12071207
1208- memcpy (data , wacom -> data , len );
1209-
12101208 switch (data [0 ]) {
12111209 case 0x04 :
12121210 wacom_intuos_bt_process_data (wacom , data + i );
@@ -1230,8 +1228,10 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
12301228 dev_dbg (wacom -> pen_input -> dev .parent ,
12311229 "Unknown report: %d,%d size:%zu\n" ,
12321230 data [0 ], data [1 ], len );
1233- return 0 ;
1231+ break ;
12341232 }
1233+
1234+ kfree (data );
12351235 return 0 ;
12361236}
12371237
@@ -1353,9 +1353,9 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
13531353 rotation -= 1800 ;
13541354
13551355 input_report_abs (pen_input , ABS_TILT_X ,
1356- (char )frame [7 ]);
1356+ (signed char )frame [7 ]);
13571357 input_report_abs (pen_input , ABS_TILT_Y ,
1358- (char )frame [8 ]);
1358+ (signed char )frame [8 ]);
13591359 input_report_abs (pen_input , ABS_Z , rotation );
13601360 input_report_abs (pen_input , ABS_WHEEL ,
13611361 get_unaligned_le16 (& frame [11 ]));
@@ -1906,11 +1906,12 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
19061906 if ((code == ABS_X || code == ABS_Y ) && !resolution ) {
19071907 resolution = WACOM_INTUOS_RES ;
19081908 hid_warn (input ,
1909- "Wacom usage (%d) missing resolution \n" ,
1910- code );
1909+ "Using default resolution for axis type 0x%x code 0x%x \n" ,
1910+ type , code );
19111911 }
19121912 input_abs_set_res (input , code , resolution );
19131913 break ;
1914+ case EV_REL :
19141915 case EV_KEY :
19151916 case EV_MSC :
19161917 case EV_SW :
@@ -2047,7 +2048,23 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
20472048 features -> device_type |= WACOM_DEVICETYPE_PAD ;
20482049 break ;
20492050 case WACOM_HID_WD_TOUCHRING :
2050- wacom_map_usage (input , usage , field , EV_ABS , ABS_WHEEL , 0 );
2051+ if (field -> flags & HID_MAIN_ITEM_RELATIVE ) {
2052+ wacom_wac -> relring_count ++ ;
2053+ if (wacom_wac -> relring_count == 1 ) {
2054+ wacom_map_usage (input , usage , field , EV_REL , REL_WHEEL_HI_RES , 0 );
2055+ set_bit (REL_WHEEL , input -> relbit );
2056+ }
2057+ else if (wacom_wac -> relring_count == 2 ) {
2058+ wacom_map_usage (input , usage , field , EV_REL , REL_HWHEEL_HI_RES , 0 );
2059+ set_bit (REL_HWHEEL , input -> relbit );
2060+ }
2061+ } else {
2062+ wacom_wac -> absring_count ++ ;
2063+ if (wacom_wac -> absring_count == 1 )
2064+ wacom_map_usage (input , usage , field , EV_ABS , ABS_WHEEL , 0 );
2065+ else if (wacom_wac -> absring_count == 2 )
2066+ wacom_map_usage (input , usage , field , EV_ABS , ABS_THROTTLE , 0 );
2067+ }
20512068 features -> device_type |= WACOM_DEVICETYPE_PAD ;
20522069 break ;
20532070 case WACOM_HID_WD_TOUCHRINGSTATUS :
@@ -2112,7 +2129,10 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
21122129 return ;
21132130
21142131 if (wacom_equivalent_usage (field -> physical ) == HID_DG_TABLETFUNCTIONKEY ) {
2115- if (usage -> hid != WACOM_HID_WD_TOUCHRING )
2132+ bool is_abs_touchring = usage -> hid == WACOM_HID_WD_TOUCHRING &&
2133+ !(field -> flags & HID_MAIN_ITEM_RELATIVE );
2134+
2135+ if (!is_abs_touchring )
21162136 wacom_wac -> hid_data .inrange_state |= value ;
21172137 }
21182138
@@ -2165,6 +2185,52 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
21652185 hdev -> product == 0x3AA )
21662186 value = wacom_offset_rotation (input , usage , value , 1 , 2 );
21672187 }
2188+ else if (field -> flags & HID_MAIN_ITEM_RELATIVE ) {
2189+ int hires_value = value * 120 / usage -> resolution_multiplier ;
2190+ int * ring_value ;
2191+ int lowres_code ;
2192+
2193+ if (usage -> code == REL_WHEEL_HI_RES ) {
2194+ /* We must invert the sign for vertical
2195+ * relative scrolling. Clockwise
2196+ * rotation produces positive values
2197+ * from HW, but userspace treats
2198+ * positive REL_WHEEL as a scroll *up*!
2199+ */
2200+ hires_value = - hires_value ;
2201+ ring_value = & wacom_wac -> hid_data .ring_value ;
2202+ lowres_code = REL_WHEEL ;
2203+ }
2204+ else if (usage -> code == REL_HWHEEL_HI_RES ) {
2205+ /* No need to invert the sign for
2206+ * horizontal relative scrolling.
2207+ * Clockwise rotation produces positive
2208+ * values from HW and userspace treats
2209+ * positive REL_HWHEEL as a scroll
2210+ * right.
2211+ */
2212+ ring_value = & wacom_wac -> hid_data .ring2_value ;
2213+ lowres_code = REL_HWHEEL ;
2214+ }
2215+ else {
2216+ hid_err (wacom -> hdev , "unrecognized relative wheel with code %d\n" ,
2217+ usage -> code );
2218+ break ;
2219+ }
2220+
2221+ value = hires_value ;
2222+ * ring_value += hires_value ;
2223+
2224+ /* Emulate a legacy wheel click for every 120
2225+ * units of hi-res travel.
2226+ */
2227+ if (* ring_value >= 120 || * ring_value <= -120 ) {
2228+ int clicks = * ring_value / 120 ;
2229+
2230+ input_event (input , usage -> type , lowres_code , clicks );
2231+ * ring_value -= clicks * 120 ;
2232+ }
2233+ }
21682234 else {
21692235 value = wacom_offset_rotation (input , usage , value , 1 , 4 );
21702236 }
@@ -2356,9 +2422,11 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
23562422 wacom_wac -> hid_data .sense_state = value ;
23572423 return ;
23582424 case HID_DG_INVERT :
2359- wacom_wac -> hid_data .invert_state = value ;
2425+ wacom_wac -> hid_data .eraser | = value ;
23602426 return ;
23612427 case HID_DG_ERASER :
2428+ wacom_wac -> hid_data .eraser |= value ;
2429+ fallthrough ;
23622430 case HID_DG_TIPSWITCH :
23632431 wacom_wac -> hid_data .tipswitch |= value ;
23642432 return ;
@@ -2499,7 +2567,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
24992567
25002568 if (entering_range ) { /* first in range */
25012569 /* Going into range select tool */
2502- if (wacom_wac -> hid_data .invert_state )
2570+ if (wacom_wac -> hid_data .eraser )
25032571 wacom_wac -> tool [0 ] = BTN_TOOL_RUBBER ;
25042572 else if (wacom_wac -> features .quirks & WACOM_QUIRK_AESPEN )
25052573 wacom_wac -> tool [0 ] = BTN_TOOL_PEN ;
@@ -2553,6 +2621,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
25532621 }
25542622
25552623 wacom_wac -> hid_data .tipswitch = false;
2624+ wacom_wac -> hid_data .eraser = false;
25562625
25572626 input_sync (input );
25582627 }
@@ -4877,6 +4946,10 @@ static const struct wacom_features wacom_features_0x94 =
48774946 HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
48784947 .driver_data = (kernel_ulong_t)&wacom_features_##prod
48794948
4949+ #define PCI_DEVICE_WACOM (prod ) \
4950+ HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
4951+ .driver_data = (kernel_ulong_t)&wacom_features_##prod
4952+
48804953#define USB_DEVICE_LENOVO (prod ) \
48814954 HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \
48824955 .driver_data = (kernel_ulong_t)&wacom_features_##prod
@@ -5046,6 +5119,7 @@ const struct hid_device_id wacom_ids[] = {
50465119
50475120 { USB_DEVICE_WACOM (HID_ANY_ID ) },
50485121 { I2C_DEVICE_WACOM (HID_ANY_ID ) },
5122+ { PCI_DEVICE_WACOM (HID_ANY_ID ) },
50495123 { BT_DEVICE_WACOM (HID_ANY_ID ) },
50505124 { }
50515125};
0 commit comments