@@ -81,24 +81,6 @@ static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
81
81
return rdesc ;
82
82
}
83
83
84
- static int uclogic_input_mapping (struct hid_device * hdev ,
85
- struct hid_input * hi ,
86
- struct hid_field * field ,
87
- struct hid_usage * usage ,
88
- unsigned long * * bit ,
89
- int * max )
90
- {
91
- struct uclogic_drvdata * drvdata = hid_get_drvdata (hdev );
92
- struct uclogic_params * params = & drvdata -> params ;
93
-
94
- /* discard the unused pen interface */
95
- if (params -> pen_unused && (field -> application == HID_DG_PEN ))
96
- return -1 ;
97
-
98
- /* let hid-core decide what to do */
99
- return 0 ;
100
- }
101
-
102
84
static int uclogic_input_configured (struct hid_device * hdev ,
103
85
struct hid_input * hi )
104
86
{
@@ -246,100 +228,171 @@ static int uclogic_resume(struct hid_device *hdev)
246
228
}
247
229
#endif
248
230
231
+ /**
232
+ * uclogic_raw_event_pen - handle raw pen events (pen HID reports).
233
+ *
234
+ * @drvdata: Driver data.
235
+ * @data: Report data buffer, can be modified.
236
+ * @size: Report data size, bytes.
237
+ *
238
+ * Returns:
239
+ * Negative value on error (stops event delivery), zero for success.
240
+ */
241
+ static int uclogic_raw_event_pen (struct uclogic_drvdata * drvdata ,
242
+ u8 * data , int size )
243
+ {
244
+ struct uclogic_params_pen * pen = & drvdata -> params .pen ;
245
+
246
+ WARN_ON (drvdata == NULL );
247
+ WARN_ON (data == NULL && size != 0 );
248
+
249
+ /* If in-range reports are inverted */
250
+ if (pen -> inrange ==
251
+ UCLOGIC_PARAMS_PEN_INRANGE_INVERTED ) {
252
+ /* Invert the in-range bit */
253
+ data [1 ] ^= 0x40 ;
254
+ }
255
+ /*
256
+ * If report contains fragmented high-resolution pen
257
+ * coordinates
258
+ */
259
+ if (size >= 10 && pen -> fragmented_hires ) {
260
+ u8 pressure_low_byte ;
261
+ u8 pressure_high_byte ;
262
+
263
+ /* Lift pressure bytes */
264
+ pressure_low_byte = data [6 ];
265
+ pressure_high_byte = data [7 ];
266
+ /*
267
+ * Move Y coord to make space for high-order X
268
+ * coord byte
269
+ */
270
+ data [6 ] = data [5 ];
271
+ data [5 ] = data [4 ];
272
+ /* Move high-order X coord byte */
273
+ data [4 ] = data [8 ];
274
+ /* Move high-order Y coord byte */
275
+ data [7 ] = data [9 ];
276
+ /* Place pressure bytes */
277
+ data [8 ] = pressure_low_byte ;
278
+ data [9 ] = pressure_high_byte ;
279
+ }
280
+ /* If we need to emulate in-range detection */
281
+ if (pen -> inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE ) {
282
+ /* Set in-range bit */
283
+ data [1 ] |= 0x40 ;
284
+ /* (Re-)start in-range timeout */
285
+ mod_timer (& drvdata -> inrange_timer ,
286
+ jiffies + msecs_to_jiffies (100 ));
287
+ }
288
+ /* If we report tilt and Y direction is flipped */
289
+ if (size >= 12 && pen -> tilt_y_flipped )
290
+ data [11 ] = - data [11 ];
291
+
292
+ return 0 ;
293
+ }
294
+
295
+ /**
296
+ * uclogic_raw_event_frame - handle raw frame events (frame HID reports).
297
+ *
298
+ * @drvdata: Driver data.
299
+ * @frame: The parameters of the frame controls to handle.
300
+ * @data: Report data buffer, can be modified.
301
+ * @size: Report data size, bytes.
302
+ *
303
+ * Returns:
304
+ * Negative value on error (stops event delivery), zero for success.
305
+ */
306
+ static int uclogic_raw_event_frame (
307
+ struct uclogic_drvdata * drvdata ,
308
+ const struct uclogic_params_frame * frame ,
309
+ u8 * data , int size )
310
+ {
311
+ WARN_ON (drvdata == NULL );
312
+ WARN_ON (data == NULL && size != 0 );
313
+
314
+ /* If need to, and can, set pad device ID for Wacom drivers */
315
+ if (frame -> dev_id_byte > 0 && frame -> dev_id_byte < size ) {
316
+ data [frame -> dev_id_byte ] = 0xf ;
317
+ }
318
+ /* If need to, and can, read rotary encoder state change */
319
+ if (frame -> re_lsb > 0 && frame -> re_lsb / 8 < size ) {
320
+ unsigned int byte = frame -> re_lsb / 8 ;
321
+ unsigned int bit = frame -> re_lsb % 8 ;
322
+
323
+ u8 change ;
324
+ u8 prev_state = drvdata -> re_state ;
325
+ /* Read Gray-coded state */
326
+ u8 state = (data [byte ] >> bit ) & 0x3 ;
327
+ /* Encode state change into 2-bit signed integer */
328
+ if ((prev_state == 1 && state == 0 ) ||
329
+ (prev_state == 2 && state == 3 )) {
330
+ change = 1 ;
331
+ } else if ((prev_state == 2 && state == 0 ) ||
332
+ (prev_state == 1 && state == 3 )) {
333
+ change = 3 ;
334
+ } else {
335
+ change = 0 ;
336
+ }
337
+ /* Write change */
338
+ data [byte ] = (data [byte ] & ~((u8 )3 << bit )) |
339
+ (change << bit );
340
+ /* Remember state */
341
+ drvdata -> re_state = state ;
342
+ }
343
+
344
+ return 0 ;
345
+ }
346
+
249
347
static int uclogic_raw_event (struct hid_device * hdev ,
250
348
struct hid_report * report ,
251
349
u8 * data , int size )
252
350
{
351
+ unsigned int report_id = report -> id ;
253
352
struct uclogic_drvdata * drvdata = hid_get_drvdata (hdev );
254
353
struct uclogic_params * params = & drvdata -> params ;
354
+ struct uclogic_params_pen_subreport * subreport ;
355
+ struct uclogic_params_pen_subreport * subreport_list_end ;
356
+ size_t i ;
255
357
256
- /* Tweak pen reports, if necessary */
257
- if (!params -> pen_unused &&
258
- (report -> type == HID_INPUT_REPORT ) &&
259
- (report -> id == params -> pen .id ) &&
260
- (size >= 2 )) {
261
- /* If it's the "virtual" frame controls report */
262
- if (params -> frame .id != 0 &&
263
- data [1 ] & params -> pen_frame_flag ) {
264
- /* Change to virtual frame controls report ID */
265
- data [0 ] = params -> frame .id ;
266
- return 0 ;
267
- }
268
- /* If in-range reports are inverted */
269
- if (params -> pen .inrange ==
270
- UCLOGIC_PARAMS_PEN_INRANGE_INVERTED ) {
271
- /* Invert the in-range bit */
272
- data [1 ] ^= 0x40 ;
273
- }
274
- /*
275
- * If report contains fragmented high-resolution pen
276
- * coordinates
277
- */
278
- if (size >= 10 && params -> pen .fragmented_hires ) {
279
- u8 pressure_low_byte ;
280
- u8 pressure_high_byte ;
281
-
282
- /* Lift pressure bytes */
283
- pressure_low_byte = data [6 ];
284
- pressure_high_byte = data [7 ];
285
- /*
286
- * Move Y coord to make space for high-order X
287
- * coord byte
288
- */
289
- data [6 ] = data [5 ];
290
- data [5 ] = data [4 ];
291
- /* Move high-order X coord byte */
292
- data [4 ] = data [8 ];
293
- /* Move high-order Y coord byte */
294
- data [7 ] = data [9 ];
295
- /* Place pressure bytes */
296
- data [8 ] = pressure_low_byte ;
297
- data [9 ] = pressure_high_byte ;
298
- }
299
- /* If we need to emulate in-range detection */
300
- if (params -> pen .inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE ) {
301
- /* Set in-range bit */
302
- data [1 ] |= 0x40 ;
303
- /* (Re-)start in-range timeout */
304
- mod_timer (& drvdata -> inrange_timer ,
305
- jiffies + msecs_to_jiffies (100 ));
306
- }
307
- }
358
+ /* Do not handle anything but input reports */
359
+ if (report -> type != HID_INPUT_REPORT )
360
+ return 0 ;
308
361
309
- /* Tweak frame control reports, if necessary */
310
- if ((report -> type == HID_INPUT_REPORT ) &&
311
- (report -> id == params -> frame .id )) {
312
- /* If need to, and can, set pad device ID for Wacom drivers */
313
- if (params -> frame .dev_id_byte > 0 &&
314
- params -> frame .dev_id_byte < size ) {
315
- data [params -> frame .dev_id_byte ] = 0xf ;
316
- }
317
- /* If need to, and can, read rotary encoder state change */
318
- if (params -> frame .re_lsb > 0 &&
319
- params -> frame .re_lsb / 8 < size ) {
320
- unsigned int byte = params -> frame .re_lsb / 8 ;
321
- unsigned int bit = params -> frame .re_lsb % 8 ;
322
-
323
- u8 change ;
324
- u8 prev_state = drvdata -> re_state ;
325
- /* Read Gray-coded state */
326
- u8 state = (data [byte ] >> bit ) & 0x3 ;
327
- /* Encode state change into 2-bit signed integer */
328
- if ((prev_state == 1 && state == 0 ) ||
329
- (prev_state == 2 && state == 3 )) {
330
- change = 1 ;
331
- } else if ((prev_state == 2 && state == 0 ) ||
332
- (prev_state == 1 && state == 3 )) {
333
- change = 3 ;
362
+ while (true) {
363
+ /* Tweak pen reports, if necessary */
364
+ if ((report_id == params -> pen .id ) && (size >= 2 )) {
365
+ subreport_list_end =
366
+ params -> pen .subreport_list +
367
+ ARRAY_SIZE (params -> pen .subreport_list );
368
+ /* Try to match a subreport */
369
+ for (subreport = params -> pen .subreport_list ;
370
+ subreport < subreport_list_end ; subreport ++ ) {
371
+ if (subreport -> value != 0 &&
372
+ subreport -> value == data [1 ]) {
373
+ break ;
374
+ }
375
+ }
376
+ /* If a subreport matched */
377
+ if (subreport < subreport_list_end ) {
378
+ /* Change to subreport ID, and restart */
379
+ report_id = data [0 ] = subreport -> id ;
380
+ continue ;
334
381
} else {
335
- change = 0 ;
382
+ return uclogic_raw_event_pen (drvdata , data , size );
383
+ }
384
+ }
385
+
386
+ /* Tweak frame control reports, if necessary */
387
+ for (i = 0 ; i < ARRAY_SIZE (params -> frame_list ); i ++ ) {
388
+ if (report_id == params -> frame_list [i ].id ) {
389
+ return uclogic_raw_event_frame (
390
+ drvdata , & params -> frame_list [i ],
391
+ data , size );
336
392
}
337
- /* Write change */
338
- data [byte ] = (data [byte ] & ~((u8 )3 << bit )) |
339
- (change << bit );
340
- /* Remember state */
341
- drvdata -> re_state = state ;
342
393
}
394
+
395
+ break ;
343
396
}
344
397
345
398
return 0 ;
@@ -373,7 +426,7 @@ static const struct hid_device_id uclogic_devices[] = {
373
426
{ HID_USB_DEVICE (USB_VENDOR_ID_HUION ,
374
427
USB_DEVICE_ID_HUION_TABLET ) },
375
428
{ HID_USB_DEVICE (USB_VENDOR_ID_HUION ,
376
- USB_DEVICE_ID_HUION_HS64 ) },
429
+ USB_DEVICE_ID_HUION_TABLET2 ) },
377
430
{ HID_USB_DEVICE (USB_VENDOR_ID_TRUST ,
378
431
USB_DEVICE_ID_TRUST_PANORA_TABLET ) },
379
432
{ HID_USB_DEVICE (USB_VENDOR_ID_UCLOGIC ,
@@ -415,7 +468,6 @@ static struct hid_driver uclogic_driver = {
415
468
.remove = uclogic_remove ,
416
469
.report_fixup = uclogic_report_fixup ,
417
470
.raw_event = uclogic_raw_event ,
418
- .input_mapping = uclogic_input_mapping ,
419
471
.input_configured = uclogic_input_configured ,
420
472
#ifdef CONFIG_PM
421
473
.resume = uclogic_resume ,
0 commit comments