~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to drivers/input/tablet/wacom_sys.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
/* defines to get/set USB message */
49
49
#define USB_REQ_GET_REPORT      0x01
50
50
#define USB_REQ_SET_REPORT      0x09
 
51
 
51
52
#define WAC_HID_FEATURE_REPORT  0x03
52
 
 
53
 
static int usb_get_report(struct usb_interface *intf, unsigned char type,
54
 
                                unsigned char id, void *buf, int size)
 
53
#define WAC_MSG_RETRIES         5
 
54
 
 
55
#define WAC_CMD_LED_CONTROL     0x20
 
56
#define WAC_CMD_ICON_START      0x21
 
57
#define WAC_CMD_ICON_XFER       0x23
 
58
#define WAC_CMD_RETRIES         10
 
59
 
 
60
static int wacom_get_report(struct usb_interface *intf, u8 type, u8 id,
 
61
                            void *buf, size_t size, unsigned int retries)
55
62
{
56
 
        return usb_control_msg(interface_to_usbdev(intf),
57
 
                usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
58
 
                USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
59
 
                (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
60
 
                buf, size, 100);
 
63
        struct usb_device *dev = interface_to_usbdev(intf);
 
64
        int retval;
 
65
 
 
66
        do {
 
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;
61
76
}
62
77
 
63
 
static int usb_set_report(struct usb_interface *intf, unsigned char type,
64
 
                                unsigned char id, void *buf, int size)
 
78
static int wacom_set_report(struct usb_interface *intf, u8 type, u8 id,
 
79
                            void *buf, size_t size, unsigned int retries)
65
80
{
66
 
        return usb_control_msg(interface_to_usbdev(intf),
67
 
                usb_sndctrlpipe(interface_to_usbdev(intf), 0),
68
 
                USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
69
 
                (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
70
 
                buf, size, 1000);
 
81
        struct usb_device *dev = interface_to_usbdev(intf);
 
82
        int retval;
 
83
 
 
84
        do {
 
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;
71
94
}
72
95
 
73
96
static void wacom_sys_irq(struct urb *urb)
165
188
                        report,
166
189
                        hid_desc->wDescriptorLength,
167
190
                        5000); /* 5 secs */
168
 
        } while (result < 0 && limit++ < 5);
 
191
        } while (result < 0 && limit++ < WAC_MSG_RETRIES);
169
192
 
170
193
        /* No need to parse the Descriptor. It isn't an error though */
171
194
        if (result < 0)
228
251
                                                        get_unaligned_le16(&report[i + 3]);
229
252
                                                i += 4;
230
253
                                        }
231
 
                                } else if (usage == WCM_DIGITIZER) {
232
 
                                        /* max pressure isn't reported
233
 
                                        features->pressure_max = (unsigned short)
234
 
                                                        (report[i+4] << 8  | report[i + 3]);
235
 
                                        */
236
 
                                        features->pressure_max = 255;
237
 
                                        i += 4;
238
254
                                }
239
255
                                break;
240
256
 
290
306
                                pen = 1;
291
307
                                i++;
292
308
                                break;
293
 
 
294
 
                        case HID_USAGE_UNDEFINED:
295
 
                                if (usage == WCM_DESKTOP && finger) /* capacity */
296
 
                                        features->pressure_max =
297
 
                                                get_unaligned_le16(&report[i + 3]);
298
 
                                i += 4;
299
 
                                break;
300
309
                        }
301
310
                        break;
302
311
 
319
328
        int limit = 0, report_id = 2;
320
329
        int error = -ENOMEM;
321
330
 
322
 
        rep_data = kmalloc(2, GFP_KERNEL);
 
331
        rep_data = kmalloc(4, GFP_KERNEL);
323
332
        if (!rep_data)
324
333
                return error;
325
334
 
326
 
        /* ask to report tablet data if it is 2FGT Tablet PC or
 
335
        /* ask to report tablet data if it is MT Tablet PC or
327
336
         * not a Tablet PC */
328
337
        if (features->type == TABLETPC2FG) {
329
338
                do {
330
339
                        rep_data[0] = 3;
331
340
                        rep_data[1] = 4;
 
341
                        rep_data[2] = 0;
 
342
                        rep_data[3] = 0;
332
343
                        report_id = 3;
333
 
                        error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
334
 
                                report_id, rep_data, 2);
 
344
                        error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
 
345
                                                 report_id, rep_data, 4, 1);
335
346
                        if (error >= 0)
336
 
                                error = usb_get_report(intf,
337
 
                                        WAC_HID_FEATURE_REPORT, report_id,
338
 
                                        rep_data, 3);
339
 
                } while ((error < 0 || rep_data[1] != 4) && limit++ < 5);
 
347
                                error = wacom_get_report(intf,
 
348
                                                WAC_HID_FEATURE_REPORT,
 
349
                                                report_id, rep_data, 4, 1);
 
350
                } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES);
340
351
        } else if (features->type != TABLETPC) {
341
352
                do {
342
353
                        rep_data[0] = 2;
343
354
                        rep_data[1] = 2;
344
 
                        error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
345
 
                                report_id, rep_data, 2);
 
355
                        error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
 
356
                                                 report_id, rep_data, 2, 1);
346
357
                        if (error >= 0)
347
 
                                error = usb_get_report(intf,
348
 
                                        WAC_HID_FEATURE_REPORT, report_id,
349
 
                                        rep_data, 2);
350
 
                } while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
 
358
                                error = wacom_get_report(intf,
 
359
                                                WAC_HID_FEATURE_REPORT,
 
360
                                                report_id, rep_data, 2, 1);
 
361
                } while ((error < 0 || rep_data[1] != 2) && limit++ < WAC_MSG_RETRIES);
351
362
        }
352
363
 
353
364
        kfree(rep_data);
465
476
        }
466
477
}
467
478
 
 
479
static 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
 
 
506
static 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
 
 
541
out:
 
542
        kfree(buf);
 
543
        return retval;
 
544
}
 
545
 
 
546
static 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)                                  \
 
568
static 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
}                                                                       \
 
573
static 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
}                                                                       \
 
579
static 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
 
 
583
DEVICE_LED_SELECT_ATTR(0);
 
584
DEVICE_LED_SELECT_ATTR(1);
 
585
 
 
586
static 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)                              \
 
607
static 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
}                                                                       \
 
615
static DEVICE_ATTR(name##_luminance, S_IWUSR,                           \
 
616
                   NULL, wacom_##name##_luminance_store)
 
617
 
 
618
DEVICE_LUMINANCE_ATTR(status0, llv);
 
619
DEVICE_LUMINANCE_ATTR(status1, hlv);
 
620
DEVICE_LUMINANCE_ATTR(buttons, img_lum);
 
621
 
 
622
static 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)                                   \
 
641
static 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
}                                                                       \
 
646
static DEVICE_ATTR(button##BUTTON_ID##_rawimg, S_IWUSR,                 \
 
647
                   NULL, wacom_btnimg##BUTTON_ID##_store)
 
648
 
 
649
DEVICE_BTNIMG_ATTR(0);
 
650
DEVICE_BTNIMG_ATTR(1);
 
651
DEVICE_BTNIMG_ATTR(2);
 
652
DEVICE_BTNIMG_ATTR(3);
 
653
DEVICE_BTNIMG_ATTR(4);
 
654
DEVICE_BTNIMG_ATTR(5);
 
655
DEVICE_BTNIMG_ATTR(6);
 
656
DEVICE_BTNIMG_ATTR(7);
 
657
 
 
658
static struct attribute *cintiq_led_attrs[] = {
 
659
        &dev_attr_status_led0_select.attr,
 
660
        &dev_attr_status_led1_select.attr,
 
661
        NULL
 
662
};
 
663
 
 
664
static struct attribute_group cintiq_led_attr_group = {
 
665
        .name = "wacom_led",
 
666
        .attrs = cintiq_led_attrs,
 
667
};
 
668
 
 
669
static 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
 
 
685
static struct attribute_group intuos4_led_attr_group = {
 
686
        .name = "wacom_led",
 
687
        .attrs = intuos4_led_attrs,
 
688
};
 
689
 
 
690
static 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
 
 
732
static 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
 
468
748
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
469
749
{
470
750
        struct usb_device *dev = interface_to_usbdev(intf);
553
833
        wacom->irq->transfer_dma = wacom->data_dma;
554
834
        wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
555
835
 
 
836
        error = wacom_initialize_leds(wacom);
 
837
        if (error)
 
838
                goto fail4;
 
839
 
556
840
        error = input_register_device(input_dev);
557
841
        if (error)
558
 
                goto fail4;
 
842
                goto fail5;
559
843
 
560
844
        /* Note that if query fails it is not a hard failure */
561
845
        wacom_query_tablet_data(intf, features);
563
847
        usb_set_intfdata(intf, wacom);
564
848
        return 0;
565
849
 
 
850
 fail5: wacom_destroy_leds(wacom);
566
851
 fail4: wacom_remove_shared_data(wacom_wac);
567
852
 fail3: usb_free_urb(wacom->irq);
568
853
 fail2: usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
579
864
 
580
865
        usb_kill_urb(wacom->irq);
581
866
        input_unregister_device(wacom->wacom_wac.input);
 
867
        wacom_destroy_leds(wacom);
582
868
        usb_free_urb(wacom->irq);
583
869
        usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
584
870
                        wacom->wacom_wac.data, wacom->data_dma);
601
887
{
602
888
        struct wacom *wacom = usb_get_intfdata(intf);
603
889
        struct wacom_features *features = &wacom->wacom_wac.features;
604
 
        int rv;
 
890
        int rv = 0;
605
891
 
606
892
        mutex_lock(&wacom->lock);
607
893
 
608
894
        /* switch to wacom mode first */
609
895
        wacom_query_tablet_data(intf, features);
 
896
        wacom_led_control(wacom);
610
897
 
611
 
        if (wacom->open)
612
 
                rv = usb_submit_urb(wacom->irq, GFP_NOIO);
613
 
        else
614
 
                rv = 0;
 
898
        if (wacom->open && usb_submit_urb(wacom->irq, GFP_NOIO) < 0)
 
899
                rv = -EIO;
615
900
 
616
901
        mutex_unlock(&wacom->lock);
617
902