aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet/wacom_sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/tablet/wacom_sys.c')
-rw-r--r--drivers/input/tablet/wacom_sys.c356
1 files changed, 326 insertions, 30 deletions
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 958b4eb6369..1c1b7b43cf9 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -48,27 +48,49 @@ struct hid_descriptor {
48/* defines to get/set USB message */ 48/* defines to get/set USB message */
49#define USB_REQ_GET_REPORT 0x01 49#define USB_REQ_GET_REPORT 0x01
50#define USB_REQ_SET_REPORT 0x09 50#define USB_REQ_SET_REPORT 0x09
51
51#define WAC_HID_FEATURE_REPORT 0x03 52#define WAC_HID_FEATURE_REPORT 0x03
52#define WAC_MSG_RETRIES 5 53#define WAC_MSG_RETRIES 5
53 54
54static int usb_get_report(struct usb_interface *intf, unsigned char type, 55#define WAC_CMD_LED_CONTROL 0x20
55 unsigned char id, void *buf, int size) 56#define WAC_CMD_ICON_START 0x21
57#define WAC_CMD_ICON_XFER 0x23
58#define WAC_CMD_RETRIES 10
59
60static int wacom_get_report(struct usb_interface *intf, u8 type, u8 id,
61 void *buf, size_t size, unsigned int retries)
56{ 62{
57 return usb_control_msg(interface_to_usbdev(intf), 63 struct usb_device *dev = interface_to_usbdev(intf);
58 usb_rcvctrlpipe(interface_to_usbdev(intf), 0), 64 int retval;
59 USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 65
60 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, 66 do {
61 buf, size, 100); 67 retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
68 USB_REQ_GET_REPORT,
69 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
70 (type << 8) + id,
71 intf->altsetting[0].desc.bInterfaceNumber,
72 buf, size, 100);
73 } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries);
74
75 return retval;
62} 76}
63 77
64static int usb_set_report(struct usb_interface *intf, unsigned char type, 78static int wacom_set_report(struct usb_interface *intf, u8 type, u8 id,
65 unsigned char id, void *buf, int size) 79 void *buf, size_t size, unsigned int retries)
66{ 80{
67 return usb_control_msg(interface_to_usbdev(intf), 81 struct usb_device *dev = interface_to_usbdev(intf);
68 usb_sndctrlpipe(interface_to_usbdev(intf), 0), 82 int retval;
69 USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 83
70 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, 84 do {
71 buf, size, 1000); 85 retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
86 USB_REQ_SET_REPORT,
87 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
88 (type << 8) + id,
89 intf->altsetting[0].desc.bInterfaceNumber,
90 buf, size, 1000);
91 } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries);
92
93 return retval;
72} 94}
73 95
74static void wacom_sys_irq(struct urb *urb) 96static void wacom_sys_irq(struct urb *urb)
@@ -319,23 +341,23 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
319 rep_data[2] = 0; 341 rep_data[2] = 0;
320 rep_data[3] = 0; 342 rep_data[3] = 0;
321 report_id = 3; 343 report_id = 3;
322 error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, 344 error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
323 report_id, rep_data, 4); 345 report_id, rep_data, 4, 1);
324 if (error >= 0) 346 if (error >= 0)
325 error = usb_get_report(intf, 347 error = wacom_get_report(intf,
326 WAC_HID_FEATURE_REPORT, report_id, 348 WAC_HID_FEATURE_REPORT,
327 rep_data, 4); 349 report_id, rep_data, 4, 1);
328 } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES); 350 } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES);
329 } else if (features->type != TABLETPC) { 351 } else if (features->type != TABLETPC) {
330 do { 352 do {
331 rep_data[0] = 2; 353 rep_data[0] = 2;
332 rep_data[1] = 2; 354 rep_data[1] = 2;
333 error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, 355 error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
334 report_id, rep_data, 2); 356 report_id, rep_data, 2, 1);
335 if (error >= 0) 357 if (error >= 0)
336 error = usb_get_report(intf, 358 error = wacom_get_report(intf,
337 WAC_HID_FEATURE_REPORT, report_id, 359 WAC_HID_FEATURE_REPORT,
338 rep_data, 2); 360 report_id, rep_data, 2, 1);
339 } while ((error < 0 || rep_data[1] != 2) && limit++ < WAC_MSG_RETRIES); 361 } while ((error < 0 || rep_data[1] != 2) && limit++ < WAC_MSG_RETRIES);
340 } 362 }
341 363
@@ -454,6 +476,275 @@ static void wacom_remove_shared_data(struct wacom_wac *wacom)
454 } 476 }
455} 477}
456 478
479static int wacom_led_control(struct wacom *wacom)
480{
481 unsigned char *buf;
482 int retval, led = 0;
483
484 buf = kzalloc(9, GFP_KERNEL);
485 if (!buf)
486 return -ENOMEM;
487
488 if (wacom->wacom_wac.features.type == WACOM_21UX2)
489 led = (wacom->led.select[1] << 4) | 0x40;
490
491 led |= wacom->led.select[0] | 0x4;
492
493 buf[0] = WAC_CMD_LED_CONTROL;
494 buf[1] = led;
495 buf[2] = wacom->led.llv;
496 buf[3] = wacom->led.hlv;
497 buf[4] = wacom->led.img_lum;
498
499 retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL,
500 buf, 9, WAC_CMD_RETRIES);
501 kfree(buf);
502
503 return retval;
504}
505
506static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *img)
507{
508 unsigned char *buf;
509 int i, retval;
510
511 buf = kzalloc(259, GFP_KERNEL);
512 if (!buf)
513 return -ENOMEM;
514
515 /* Send 'start' command */
516 buf[0] = WAC_CMD_ICON_START;
517 buf[1] = 1;
518 retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START,
519 buf, 2, WAC_CMD_RETRIES);
520 if (retval < 0)
521 goto out;
522
523 buf[0] = WAC_CMD_ICON_XFER;
524 buf[1] = button_id & 0x07;
525 for (i = 0; i < 4; i++) {
526 buf[2] = i;
527 memcpy(buf + 3, img + i * 256, 256);
528
529 retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_XFER,
530 buf, 259, WAC_CMD_RETRIES);
531 if (retval < 0)
532 break;
533 }
534
535 /* Send 'stop' */
536 buf[0] = WAC_CMD_ICON_START;
537 buf[1] = 0;
538 wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START,
539 buf, 2, WAC_CMD_RETRIES);
540
541out:
542 kfree(buf);
543 return retval;
544}
545
546static ssize_t wacom_led_select_store(struct device *dev, int set_id,
547 const char *buf, size_t count)
548{
549 struct wacom *wacom = dev_get_drvdata(dev);
550 unsigned int id;
551 int err;
552
553 err = kstrtouint(buf, 10, &id);
554 if (err)
555 return err;
556
557 mutex_lock(&wacom->lock);
558
559 wacom->led.select[set_id] = id & 0x3;
560 err = wacom_led_control(wacom);
561
562 mutex_unlock(&wacom->lock);
563
564 return err < 0 ? err : count;
565}
566
567#define DEVICE_LED_SELECT_ATTR(SET_ID) \
568static ssize_t wacom_led##SET_ID##_select_store(struct device *dev, \
569 struct device_attribute *attr, const char *buf, size_t count) \
570{ \
571 return wacom_led_select_store(dev, SET_ID, buf, count); \
572} \
573static ssize_t wacom_led##SET_ID##_select_show(struct device *dev, \
574 struct device_attribute *attr, char *buf) \
575{ \
576 struct wacom *wacom = dev_get_drvdata(dev); \
577 return snprintf(buf, 2, "%d\n", wacom->led.select[SET_ID]); \
578} \
579static DEVICE_ATTR(status_led##SET_ID##_select, S_IWUSR | S_IRUSR, \
580 wacom_led##SET_ID##_select_show, \
581 wacom_led##SET_ID##_select_store)
582
583DEVICE_LED_SELECT_ATTR(0);
584DEVICE_LED_SELECT_ATTR(1);
585
586static ssize_t wacom_luminance_store(struct wacom *wacom, u8 *dest,
587 const char *buf, size_t count)
588{
589 unsigned int value;
590 int err;
591
592 err = kstrtouint(buf, 10, &value);
593 if (err)
594 return err;
595
596 mutex_lock(&wacom->lock);
597
598 *dest = value & 0x7f;
599 err = wacom_led_control(wacom);
600
601 mutex_unlock(&wacom->lock);
602
603 return err < 0 ? err : count;
604}
605
606#define DEVICE_LUMINANCE_ATTR(name, field) \
607static ssize_t wacom_##name##_luminance_store(struct device *dev, \
608 struct device_attribute *attr, const char *buf, size_t count) \
609{ \
610 struct wacom *wacom = dev_get_drvdata(dev); \
611 \
612 return wacom_luminance_store(wacom, &wacom->led.field, \
613 buf, count); \
614} \
615static DEVICE_ATTR(name##_luminance, S_IWUSR, \
616 NULL, wacom_##name##_luminance_store)
617
618DEVICE_LUMINANCE_ATTR(status0, llv);
619DEVICE_LUMINANCE_ATTR(status1, hlv);
620DEVICE_LUMINANCE_ATTR(buttons, img_lum);
621
622static ssize_t wacom_button_image_store(struct device *dev, int button_id,
623 const char *buf, size_t count)
624{
625 struct wacom *wacom = dev_get_drvdata(dev);
626 int err;
627
628 if (count != 1024)
629 return -EINVAL;
630
631 mutex_lock(&wacom->lock);
632
633 err = wacom_led_putimage(wacom, button_id, buf);
634
635 mutex_unlock(&wacom->lock);
636
637 return err < 0 ? err : count;
638}
639
640#define DEVICE_BTNIMG_ATTR(BUTTON_ID) \
641static ssize_t wacom_btnimg##BUTTON_ID##_store(struct device *dev, \
642 struct device_attribute *attr, const char *buf, size_t count) \
643{ \
644 return wacom_button_image_store(dev, BUTTON_ID, buf, count); \
645} \
646static DEVICE_ATTR(button##BUTTON_ID##_rawimg, S_IWUSR, \
647 NULL, wacom_btnimg##BUTTON_ID##_store)
648
649DEVICE_BTNIMG_ATTR(0);
650DEVICE_BTNIMG_ATTR(1);
651DEVICE_BTNIMG_ATTR(2);
652DEVICE_BTNIMG_ATTR(3);
653DEVICE_BTNIMG_ATTR(4);
654DEVICE_BTNIMG_ATTR(5);
655DEVICE_BTNIMG_ATTR(6);
656DEVICE_BTNIMG_ATTR(7);
657
658static struct attribute *cintiq_led_attrs[] = {
659 &dev_attr_status_led0_select.attr,
660 &dev_attr_status_led1_select.attr,
661 NULL
662};
663
664static struct attribute_group cintiq_led_attr_group = {
665 .name = "wacom_led",
666 .attrs = cintiq_led_attrs,
667};
668
669static struct attribute *intuos4_led_attrs[] = {
670 &dev_attr_status0_luminance.attr,
671 &dev_attr_status1_luminance.attr,
672 &dev_attr_status_led0_select.attr,
673 &dev_attr_buttons_luminance.attr,
674 &dev_attr_button0_rawimg.attr,
675 &dev_attr_button1_rawimg.attr,
676 &dev_attr_button2_rawimg.attr,
677 &dev_attr_button3_rawimg.attr,
678 &dev_attr_button4_rawimg.attr,
679 &dev_attr_button5_rawimg.attr,
680 &dev_attr_button6_rawimg.attr,
681 &dev_attr_button7_rawimg.attr,
682 NULL
683};
684
685static struct attribute_group intuos4_led_attr_group = {
686 .name = "wacom_led",
687 .attrs = intuos4_led_attrs,
688};
689
690static int wacom_initialize_leds(struct wacom *wacom)
691{
692 int error;
693
694 /* Initialize default values */
695 switch (wacom->wacom_wac.features.type) {
696 case INTUOS4:
697 case INTUOS4L:
698 wacom->led.select[0] = 0;
699 wacom->led.select[1] = 0;
700 wacom->led.llv = 10;
701 wacom->led.hlv = 20;
702 wacom->led.img_lum = 10;
703 error = sysfs_create_group(&wacom->intf->dev.kobj,
704 &intuos4_led_attr_group);
705 break;
706
707 case WACOM_21UX2:
708 wacom->led.select[0] = 0;
709 wacom->led.select[1] = 0;
710 wacom->led.llv = 0;
711 wacom->led.hlv = 0;
712 wacom->led.img_lum = 0;
713
714 error = sysfs_create_group(&wacom->intf->dev.kobj,
715 &cintiq_led_attr_group);
716 break;
717
718 default:
719 return 0;
720 }
721
722 if (error) {
723 dev_err(&wacom->intf->dev,
724 "cannot create sysfs group err: %d\n", error);
725 return error;
726 }
727 wacom_led_control(wacom);
728
729 return 0;
730}
731
732static void wacom_destroy_leds(struct wacom *wacom)
733{
734 switch (wacom->wacom_wac.features.type) {
735 case INTUOS4:
736 case INTUOS4L:
737 sysfs_remove_group(&wacom->intf->dev.kobj,
738 &intuos4_led_attr_group);
739 break;
740
741 case WACOM_21UX2:
742 sysfs_remove_group(&wacom->intf->dev.kobj,
743 &cintiq_led_attr_group);
744 break;
745 }
746}
747
457static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) 748static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
458{ 749{
459 struct usb_device *dev = interface_to_usbdev(intf); 750 struct usb_device *dev = interface_to_usbdev(intf);
@@ -542,16 +833,21 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
542 wacom->irq->transfer_dma = wacom->data_dma; 833 wacom->irq->transfer_dma = wacom->data_dma;
543 wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 834 wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
544 835
545 error = input_register_device(input_dev); 836 error = wacom_initialize_leds(wacom);
546 if (error) 837 if (error)
547 goto fail4; 838 goto fail4;
548 839
840 error = input_register_device(input_dev);
841 if (error)
842 goto fail5;
843
549 /* Note that if query fails it is not a hard failure */ 844 /* Note that if query fails it is not a hard failure */
550 wacom_query_tablet_data(intf, features); 845 wacom_query_tablet_data(intf, features);
551 846
552 usb_set_intfdata(intf, wacom); 847 usb_set_intfdata(intf, wacom);
553 return 0; 848 return 0;
554 849
850 fail5: wacom_destroy_leds(wacom);
555 fail4: wacom_remove_shared_data(wacom_wac); 851 fail4: wacom_remove_shared_data(wacom_wac);
556 fail3: usb_free_urb(wacom->irq); 852 fail3: usb_free_urb(wacom->irq);
557 fail2: usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma); 853 fail2: usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
@@ -568,6 +864,7 @@ static void wacom_disconnect(struct usb_interface *intf)
568 864
569 usb_kill_urb(wacom->irq); 865 usb_kill_urb(wacom->irq);
570 input_unregister_device(wacom->wacom_wac.input); 866 input_unregister_device(wacom->wacom_wac.input);
867 wacom_destroy_leds(wacom);
571 usb_free_urb(wacom->irq); 868 usb_free_urb(wacom->irq);
572 usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX, 869 usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
573 wacom->wacom_wac.data, wacom->data_dma); 870 wacom->wacom_wac.data, wacom->data_dma);
@@ -590,17 +887,16 @@ static int wacom_resume(struct usb_interface *intf)
590{ 887{
591 struct wacom *wacom = usb_get_intfdata(intf); 888 struct wacom *wacom = usb_get_intfdata(intf);
592 struct wacom_features *features = &wacom->wacom_wac.features; 889 struct wacom_features *features = &wacom->wacom_wac.features;
593 int rv; 890 int rv = 0;
594 891
595 mutex_lock(&wacom->lock); 892 mutex_lock(&wacom->lock);
596 893
597 /* switch to wacom mode first */ 894 /* switch to wacom mode first */
598 wacom_query_tablet_data(intf, features); 895 wacom_query_tablet_data(intf, features);
896 wacom_led_control(wacom);
599 897
600 if (wacom->open) 898 if (wacom->open && usb_submit_urb(wacom->irq, GFP_NOIO) < 0)
601 rv = usb_submit_urb(wacom->irq, GFP_NOIO); 899 rv = -EIO;
602 else
603 rv = 0;
604 900
605 mutex_unlock(&wacom->lock); 901 mutex_unlock(&wacom->lock);
606 902