Skip to content

Commit e0361b7

Browse files
whotdtor
authored andcommitted
Input: wacom_w8001 - split the touch and pen devices into two devices
These devices have a pen device and a touch device through the same serial protocol, split it up into two separate devices like we do for USB Wacom tablets too. Userspace already matches on the device name so we can't drop it completely. Compose the same basename based on capabilities and append the tool type, leading to a name like "Wacom Serial Penabled 2FG Touchscreen Pen". Note that this drops BTN_TOOL_FINGER, it is not needed once the tools are split out (and a touch device with BTN_TOOL_FINGER is interpreted as touchpad by most of userspace). Signed-off-by: Peter Hutterer <[email protected]> Acked-by: Benjamin Tissoires <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 5d0a4fe commit e0361b7

File tree

1 file changed

+116
-51
lines changed

1 file changed

+116
-51
lines changed

drivers/input/touchscreen/wacom_w8001.c

Lines changed: 116 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ struct w8001_touch_query {
8080
*/
8181

8282
struct w8001 {
83-
struct input_dev *dev;
83+
struct input_dev *pen_dev;
84+
struct input_dev *touch_dev;
8485
struct serio *serio;
8586
struct completion cmd_done;
8687
int id;
@@ -95,7 +96,10 @@ struct w8001 {
9596
u16 max_touch_y;
9697
u16 max_pen_x;
9798
u16 max_pen_y;
98-
char name[64];
99+
char pen_name[64];
100+
char touch_name[64];
101+
int open_count;
102+
struct mutex mutex;
99103
};
100104

101105
static void parse_pen_data(u8 *data, struct w8001_coord *coord)
@@ -141,7 +145,7 @@ static void scale_touch_coordinates(struct w8001 *w8001,
141145

142146
static void parse_multi_touch(struct w8001 *w8001)
143147
{
144-
struct input_dev *dev = w8001->dev;
148+
struct input_dev *dev = w8001->touch_dev;
145149
unsigned char *data = w8001->data;
146150
unsigned int x, y;
147151
int i;
@@ -207,7 +211,7 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query)
207211

208212
static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
209213
{
210-
struct input_dev *dev = w8001->dev;
214+
struct input_dev *dev = w8001->pen_dev;
211215

212216
/*
213217
* We have 1 bit for proximity (rdy) and 3 bits for tip, side,
@@ -233,11 +237,6 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
233237
break;
234238

235239
case BTN_TOOL_FINGER:
236-
input_report_key(dev, BTN_TOUCH, 0);
237-
input_report_key(dev, BTN_TOOL_FINGER, 0);
238-
input_sync(dev);
239-
/* fall through */
240-
241240
case KEY_RESERVED:
242241
w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
243242
break;
@@ -261,7 +260,7 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
261260

262261
static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord)
263262
{
264-
struct input_dev *dev = w8001->dev;
263+
struct input_dev *dev = w8001->touch_dev;
265264
unsigned int x = coord->x;
266265
unsigned int y = coord->y;
267266

@@ -271,7 +270,6 @@ static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord)
271270
input_report_abs(dev, ABS_X, x);
272271
input_report_abs(dev, ABS_Y, y);
273272
input_report_key(dev, BTN_TOUCH, coord->tsw);
274-
input_report_key(dev, BTN_TOOL_FINGER, coord->tsw);
275273

276274
input_sync(dev);
277275

@@ -369,20 +367,36 @@ static int w8001_command(struct w8001 *w8001, unsigned char command,
369367
static int w8001_open(struct input_dev *dev)
370368
{
371369
struct w8001 *w8001 = input_get_drvdata(dev);
370+
int err;
371+
372+
err = mutex_lock_interruptible(&w8001->mutex);
373+
if (err)
374+
return err;
375+
376+
if (w8001->open_count++ == 0) {
377+
err = w8001_command(w8001, W8001_CMD_START, false);
378+
if (err)
379+
w8001->open_count--;
380+
}
372381

373-
return w8001_command(w8001, W8001_CMD_START, false);
382+
mutex_unlock(&w8001->mutex);
383+
return err;
374384
}
375385

376386
static void w8001_close(struct input_dev *dev)
377387
{
378388
struct w8001 *w8001 = input_get_drvdata(dev);
379389

380-
w8001_command(w8001, W8001_CMD_STOP, false);
390+
mutex_lock(&w8001->mutex);
391+
392+
if (--w8001->open_count == 0)
393+
w8001_command(w8001, W8001_CMD_STOP, false);
394+
395+
mutex_unlock(&w8001->mutex);
381396
}
382397

383398
static int w8001_detect(struct w8001 *w8001)
384399
{
385-
struct input_dev *dev = w8001->dev;
386400
int error;
387401

388402
error = w8001_command(w8001, W8001_CMD_STOP, false);
@@ -391,18 +405,13 @@ static int w8001_detect(struct w8001 *w8001)
391405

392406
msleep(250); /* wait 250ms before querying the device */
393407

394-
__set_bit(EV_KEY, dev->evbit);
395-
__set_bit(EV_ABS, dev->evbit);
396-
strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name));
397-
398-
__set_bit(INPUT_PROP_DIRECT, dev->propbit);
399-
400408
return 0;
401409
}
402410

403-
static int w8001_setup_pen(struct w8001 *w8001)
411+
static int w8001_setup_pen(struct w8001 *w8001, char *basename,
412+
size_t basename_sz)
404413
{
405-
struct input_dev *dev = w8001->dev;
414+
struct input_dev *dev = w8001->pen_dev;
406415
struct w8001_coord coord;
407416
int error;
408417

@@ -411,11 +420,14 @@ static int w8001_setup_pen(struct w8001 *w8001)
411420
if (error)
412421
return error;
413422

423+
__set_bit(EV_KEY, dev->evbit);
424+
__set_bit(EV_ABS, dev->evbit);
414425
__set_bit(BTN_TOUCH, dev->keybit);
415426
__set_bit(BTN_TOOL_PEN, dev->keybit);
416427
__set_bit(BTN_TOOL_RUBBER, dev->keybit);
417428
__set_bit(BTN_STYLUS, dev->keybit);
418429
__set_bit(BTN_STYLUS2, dev->keybit);
430+
__set_bit(INPUT_PROP_DIRECT, dev->propbit);
419431

420432
parse_pen_data(w8001->response, &coord);
421433
w8001->max_pen_x = coord.x;
@@ -432,17 +444,19 @@ static int w8001_setup_pen(struct w8001 *w8001)
432444
}
433445

434446
w8001->id = 0x90;
435-
strlcat(w8001->name, " Penabled", sizeof(w8001->name));
447+
strlcat(basename, " Penabled", basename_sz);
436448

437449
return 0;
438450
}
439451

440-
static int w8001_setup_touch(struct w8001 *w8001)
452+
static int w8001_setup_touch(struct w8001 *w8001, char *basename,
453+
size_t basename_sz)
441454
{
442-
struct input_dev *dev = w8001->dev;
455+
struct input_dev *dev = w8001->touch_dev;
443456
struct w8001_touch_query touch;
444457
int error;
445458

459+
446460
/* Touch enabled? */
447461
error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true);
448462
if (error)
@@ -454,8 +468,10 @@ static int w8001_setup_touch(struct w8001 *w8001)
454468
if (!w8001->response[1])
455469
return -ENXIO;
456470

471+
__set_bit(EV_KEY, dev->evbit);
472+
__set_bit(EV_ABS, dev->evbit);
457473
__set_bit(BTN_TOUCH, dev->keybit);
458-
__set_bit(BTN_TOOL_FINGER, dev->keybit);
474+
__set_bit(INPUT_PROP_DIRECT, dev->propbit);
459475

460476
parse_touchquery(w8001->response, &touch);
461477
w8001->max_touch_x = touch.x;
@@ -478,14 +494,14 @@ static int w8001_setup_touch(struct w8001 *w8001)
478494
case 2:
479495
w8001->pktlen = W8001_PKTLEN_TOUCH93;
480496
w8001->id = 0x93;
481-
strlcat(w8001->name, " 1FG", sizeof(w8001->name));
497+
strlcat(basename, " 1FG", basename_sz);
482498
break;
483499

484500
case 1:
485501
case 3:
486502
case 4:
487503
w8001->pktlen = W8001_PKTLEN_TOUCH9A;
488-
strlcat(w8001->name, " 1FG", sizeof(w8001->name));
504+
strlcat(basename, " 1FG", basename_sz);
489505
w8001->id = 0x9a;
490506
break;
491507

@@ -501,19 +517,35 @@ static int w8001_setup_touch(struct w8001 *w8001)
501517
input_set_abs_params(dev, ABS_MT_TOOL_TYPE,
502518
0, MT_TOOL_MAX, 0, 0);
503519

504-
strlcat(w8001->name, " 2FG", sizeof(w8001->name));
520+
strlcat(basename, " 2FG", basename_sz);
505521
if (w8001->max_pen_x && w8001->max_pen_y)
506522
w8001->id = 0xE3;
507523
else
508524
w8001->id = 0xE2;
509525
break;
510526
}
511527

512-
strlcat(w8001->name, " Touchscreen", sizeof(w8001->name));
528+
strlcat(basename, " Touchscreen", basename_sz);
513529

514530
return 0;
515531
}
516532

533+
static void w8001_set_devdata(struct input_dev *dev, struct w8001 *w8001,
534+
struct serio *serio)
535+
{
536+
dev->phys = w8001->phys;
537+
dev->id.bustype = BUS_RS232;
538+
dev->id.product = w8001->id;
539+
dev->id.vendor = 0x056a;
540+
dev->id.version = 0x0100;
541+
dev->open = w8001_open;
542+
dev->close = w8001_close;
543+
544+
dev->dev.parent = &serio->dev;
545+
546+
input_set_drvdata(dev, w8001);
547+
}
548+
517549
/*
518550
* w8001_disconnect() is the opposite of w8001_connect()
519551
*/
@@ -524,7 +556,10 @@ static void w8001_disconnect(struct serio *serio)
524556

525557
serio_close(serio);
526558

527-
input_unregister_device(w8001->dev);
559+
if (w8001->pen_dev)
560+
input_unregister_device(w8001->pen_dev);
561+
if (w8001->touch_dev)
562+
input_unregister_device(w8001->touch_dev);
528563
kfree(w8001);
529564

530565
serio_set_drvdata(serio, NULL);
@@ -539,18 +574,23 @@ static void w8001_disconnect(struct serio *serio)
539574
static int w8001_connect(struct serio *serio, struct serio_driver *drv)
540575
{
541576
struct w8001 *w8001;
542-
struct input_dev *input_dev;
577+
struct input_dev *input_dev_pen;
578+
struct input_dev *input_dev_touch;
579+
char basename[64];
543580
int err, err_pen, err_touch;
544581

545582
w8001 = kzalloc(sizeof(struct w8001), GFP_KERNEL);
546-
input_dev = input_allocate_device();
547-
if (!w8001 || !input_dev) {
583+
input_dev_pen = input_allocate_device();
584+
input_dev_touch = input_allocate_device();
585+
if (!w8001 || !input_dev_pen || !input_dev_touch) {
548586
err = -ENOMEM;
549587
goto fail1;
550588
}
551589

552590
w8001->serio = serio;
553-
w8001->dev = input_dev;
591+
w8001->pen_dev = input_dev_pen;
592+
w8001->touch_dev = input_dev_touch;
593+
mutex_init(&w8001->mutex);
554594
init_completion(&w8001->cmd_done);
555595
snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
556596

@@ -563,38 +603,63 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
563603
if (err)
564604
goto fail3;
565605

566-
err_pen = w8001_setup_pen(w8001);
567-
err_touch = w8001_setup_touch(w8001);
606+
/* For backwards-compatibility we compose the basename based on
607+
* capabilities and then just append the tool type
608+
*/
609+
strlcpy(basename, "Wacom Serial", sizeof(basename));
610+
611+
err_pen = w8001_setup_pen(w8001, basename, sizeof(basename));
612+
err_touch = w8001_setup_touch(w8001, basename, sizeof(basename));
568613
if (err_pen && err_touch) {
569614
err = -ENXIO;
570615
goto fail3;
571616
}
572617

573-
input_dev->name = w8001->name;
574-
input_dev->phys = w8001->phys;
575-
input_dev->id.product = w8001->id;
576-
input_dev->id.bustype = BUS_RS232;
577-
input_dev->id.vendor = 0x056a;
578-
input_dev->id.version = 0x0100;
579-
input_dev->dev.parent = &serio->dev;
618+
if (!err_pen) {
619+
strlcpy(w8001->pen_name, basename, sizeof(w8001->pen_name));
620+
strlcat(w8001->pen_name, " Pen", sizeof(w8001->pen_name));
621+
input_dev_pen->name = w8001->pen_name;
580622

581-
input_dev->open = w8001_open;
582-
input_dev->close = w8001_close;
623+
w8001_set_devdata(input_dev_pen, w8001, serio);
583624

584-
input_set_drvdata(input_dev, w8001);
625+
err = input_register_device(w8001->pen_dev);
626+
if (err)
627+
goto fail3;
628+
} else {
629+
input_free_device(input_dev_pen);
630+
input_dev_pen = NULL;
631+
w8001->pen_dev = NULL;
632+
}
585633

586-
err = input_register_device(w8001->dev);
587-
if (err)
588-
goto fail3;
634+
if (!err_touch) {
635+
strlcpy(w8001->touch_name, basename, sizeof(w8001->touch_name));
636+
strlcat(w8001->touch_name, " Finger",
637+
sizeof(w8001->touch_name));
638+
input_dev_touch->name = w8001->touch_name;
639+
640+
w8001_set_devdata(input_dev_touch, w8001, serio);
641+
642+
err = input_register_device(w8001->touch_dev);
643+
if (err)
644+
goto fail4;
645+
} else {
646+
input_free_device(input_dev_touch);
647+
input_dev_touch = NULL;
648+
w8001->touch_dev = NULL;
649+
}
589650

590651
return 0;
591652

653+
fail4:
654+
if (w8001->pen_dev)
655+
input_unregister_device(w8001->pen_dev);
592656
fail3:
593657
serio_close(serio);
594658
fail2:
595659
serio_set_drvdata(serio, NULL);
596660
fail1:
597-
input_free_device(input_dev);
661+
input_free_device(input_dev_pen);
662+
input_free_device(input_dev_touch);
598663
kfree(w8001);
599664
return err;
600665
}

0 commit comments

Comments
 (0)