]> Git Repo - linux.git/commitdiff
Merge branch 'upstream' into for-linus
authorJiri Kosina <[email protected]>
Wed, 19 May 2010 12:04:49 +0000 (14:04 +0200)
committerJiri Kosina <[email protected]>
Wed, 19 May 2010 12:04:49 +0000 (14:04 +0200)
Conflicts:
drivers/hid/hid-wacom.c

1  2 
drivers/hid/hid-3m-pct.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-wacom.c
drivers/hid/hidraw.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-quirks.c

diff --combined drivers/hid/hid-3m-pct.c
index c31e0be8ccea34eea7d6c0956f5a759debf324dc,883fd1af3c4c036bdfe6589749ac42be571c9a72..2a0d56b7a02be34fe0b5d09eff67148730424a9f
@@@ -1,7 -1,7 +1,7 @@@
  /*
   *  HID driver for 3M PCT multitouch panels
   *
-  *  Copyright (c) 2009 Stephane Chatty <[email protected]>
+  *  Copyright (c) 2009-2010 Stephane Chatty <[email protected]>
   *
   */
  
@@@ -15,7 -15,6 +15,7 @@@
  #include <linux/device.h>
  #include <linux/hid.h>
  #include <linux/module.h>
 +#include <linux/slab.h>
  #include <linux/usb.h>
  
  MODULE_AUTHOR("Stephane Chatty <[email protected]>");
@@@ -25,7 -24,7 +25,7 @@@ MODULE_LICENSE("GPL")
  #include "hid-ids.h"
  
  struct mmm_finger {
-       __s32 x, y;
+       __s32 x, y, w, h;
        __u8 rank;
        bool touch, valid;
  };
@@@ -82,7 -81,18 +82,18 @@@ static int mmm_input_mapping(struct hid
                        /* touchscreen emulation */
                        hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
                        return 1;
+               case HID_DG_WIDTH:
+                       hid_map_usage(hi, usage, bit, max,
+                                       EV_ABS, ABS_MT_TOUCH_MAJOR);
+                       return 1;
+               case HID_DG_HEIGHT:
+                       hid_map_usage(hi, usage, bit, max,
+                                       EV_ABS, ABS_MT_TOUCH_MINOR);
+                       input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
+                                       1, 1, 0, 0);
+                       return 1;
                case HID_DG_CONTACTID:
+                       field->logical_maximum = 59;
                        hid_map_usage(hi, usage, bit, max,
                                        EV_ABS, ABS_MT_TRACKING_ID);
                        return 1;
@@@ -128,9 -138,15 +139,15 @@@ static void mmm_filter_event(struct mmm
                        /* this finger is just placeholder data, ignore */
                } else if (f->touch) {
                        /* this finger is on the screen */
+                       int wide = (f->w > f->h);
                        input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i);
                        input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
                        input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
+                       input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
+                       input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR,
+                                               wide ? f->w : f->h);
+                       input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR,
+                                               wide ? f->h : f->w);
                        input_mt_sync(input);
                        /*
                         * touchscreen emulation: maintain the age rank
@@@ -197,6 -213,14 +214,14 @@@ static int mmm_event(struct hid_device 
                case HID_DG_CONFIDENCE:
                        md->valid = value;
                        break;
+               case HID_DG_WIDTH:
+                       if (md->valid)
+                               md->f[md->curid].w = value;
+                       break;
+               case HID_DG_HEIGHT:
+                       if (md->valid)
+                               md->f[md->curid].h = value;
+                       break;
                case HID_DG_CONTACTID:
                        if (md->valid) {
                                md->curid = value;
@@@ -255,6 -279,7 +280,7 @@@ static void mmm_remove(struct hid_devic
  
  static const struct hid_device_id mmm_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
        { }
  };
  MODULE_DEVICE_TABLE(hid, mmm_devices);
@@@ -287,5 -312,4 +313,4 @@@ static void __exit mmm_exit(void
  
  module_init(mmm_init);
  module_exit(mmm_exit);
- MODULE_LICENSE("GPL");
  
diff --combined drivers/hid/hid-core.c
index 143e788b729b1bdaadb4888e3568dac3a6714b0c,c625c3419a8c7723589d197b8fd603362513359d..69fdf1e2347b3e4f6bc5070cc6859ea10cdc567f
@@@ -653,10 -653,9 +653,9 @@@ int hid_parse_report(struct hid_device 
        if (device->driver->report_fixup)
                device->driver->report_fixup(device, start, size);
  
-       device->rdesc = kmalloc(size, GFP_KERNEL);
+       device->rdesc = kmemdup(start, size, GFP_KERNEL);
        if (device->rdesc == NULL)
                return -ENOMEM;
-       memcpy(device->rdesc, start, size);
        device->rsize = size;
  
        parser = vmalloc(sizeof(struct hid_parser));
@@@ -940,13 -939,8 +939,8 @@@ static void hid_output_field(struct hid
        unsigned count = field->report_count;
        unsigned offset = field->report_offset;
        unsigned size = field->report_size;
-       unsigned bitsused = offset + count * size;
        unsigned n;
  
-       /* make sure the unused bits in the last byte are zeros */
-       if (count > 0 && size > 0 && (bitsused % 8) != 0)
-               data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1;
        for (n = 0; n < count; n++) {
                if (field->logical_minimum < 0) /* signed values */
                        implement(data, offset + n * size, size, s32ton(field->value[n], size));
@@@ -966,6 -960,7 +960,7 @@@ void hid_output_report(struct hid_repor
        if (report->id > 0)
                *data++ = report->id;
  
+       memset(data, 0, ((report->size - 1) >> 3) + 1);
        for (n = 0; n < report->maxfield; n++)
                hid_output_field(report->field[n], data);
  }
@@@ -1043,8 -1038,13 +1038,8 @@@ void hid_report_raw_event(struct hid_de
  
        if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
                hid->hiddev_report_event(hid, report);
 -      if (hid->claimed & HID_CLAIMED_HIDRAW) {
 -              /* numbered reports need to be passed with the report num */
 -              if (report_enum->numbered)
 -                      hidraw_report_event(hid, data - 1, size + 1);
 -              else
 -                      hidraw_report_event(hid, data, size);
 -      }
 +      if (hid->claimed & HID_CLAIMED_HIDRAW)
 +              hidraw_report_event(hid, data, size);
  
        for (a = 0; a < report->maxfield; a++)
                hid_input_field(hid, report->field[a], cdata, interrupt);
@@@ -1167,6 -1167,8 +1162,8 @@@ int hid_connect(struct hid_device *hdev
        unsigned int i;
        int len;
  
+       if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
+               connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
        if (hdev->bus != BUS_USB)
                connect_mask &= ~HID_CONNECT_HIDDEV;
        if (hid_hiddev(hdev))
@@@ -1246,6 -1248,7 +1243,7 @@@ EXPORT_SYMBOL_GPL(hid_disconnect)
  /* a list of devices for which there is a specialized driver on HID bus */
  static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
  
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
        { }
@@@ -1757,7 -1762,7 +1759,7 @@@ int hid_add_device(struct hid_device *h
  
        /* we need to kill them here, otherwise they will stay allocated to
         * wait for coming driver */
-       if (hid_ignore(hdev))
+       if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) && hid_ignore(hdev))
                return -ENODEV;
  
        /* XXX hack, any other cleaner solution after the driver core
        dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
                     hdev->vendor, hdev->product, atomic_inc_return(&id));
  
+       hid_debug_register(hdev, dev_name(&hdev->dev));
        ret = device_add(&hdev->dev);
        if (!ret)
                hdev->status |= HID_STAT_ADDED;
-       hid_debug_register(hdev, dev_name(&hdev->dev));
+       else
+               hid_debug_unregister(hdev);
  
        return ret;
  }
diff --combined drivers/hid/hid-ids.h
index 09d27649a0f7212e7948b0a2c6afdcad199001a1,ba071b1aba3ea37cb69719f5ab9077729f511b21..d55b81d2d16ef61a9819f4fddfe556bcf2ee9b83
@@@ -20,6 -20,7 +20,7 @@@
  
  #define USB_VENDOR_ID_3M              0x0596
  #define USB_DEVICE_ID_3M1968          0x0500
+ #define USB_DEVICE_ID_3M2256          0x0502
  
  #define USB_VENDOR_ID_A4TECH          0x09da
  #define USB_DEVICE_ID_A4TECH_WCP32PU  0x0006
  #define USB_VENDOR_ID_BERKSHIRE               0x0c98
  #define USB_DEVICE_ID_BERKSHIRE_PCWD  0x1140
  
+ #define USB_VENDOR_ID_BTC             0x046e
+ #define USB_DEVICE_ID_BTC_EMPREX_REMOTE       0x5578
  #define USB_VENDOR_ID_CH              0x068e
  #define USB_DEVICE_ID_CH_PRO_PEDALS   0x00f2
  #define USB_DEVICE_ID_CH_COMBATSTICK  0x00f4
  
  #define USB_VENDOR_ID_CHERRY          0x046a
  #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
 +#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR   0x0027
  
  #define USB_VENDOR_ID_CHIC            0x05fe
  #define USB_DEVICE_ID_CHIC_GAMEPAD    0x0014
  
  #define USB_VENDOR_ID_DRAGONRISE      0x0079
  
+ #define USB_VENDOR_ID_EGALAX          0x0EEF
+ #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER  0x0001
  #define USB_VENDOR_ID_ELO             0x04E7
  #define USB_DEVICE_ID_ELO_TS2700      0x0020
  
  
  #define USB_VENDOR_ID_SAMSUNG         0x0419
  #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE       0x0001
+ #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE      0x0600
  
  #define USB_VENDOR_ID_SONY                    0x054c
  #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE     0x024b
  
  #define USB_VENDOR_ID_UCLOGIC         0x5543
  #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209   0x0042
 +#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U  0x0003
  
  #define USB_VENDOR_ID_VERNIER         0x08f7
  #define USB_DEVICE_ID_VERNIER_LABPRO  0x0001
  
  #define USB_VENDOR_ID_WACOM           0x056a
  #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH        0x81
+ #define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0xbd
  
  #define USB_VENDOR_ID_WISEGROUP               0x0925
  #define USB_DEVICE_ID_SMARTJOY_PLUS   0x0005
  
  #define USB_VENDOR_ID_ZEROPLUS                0x0c12
  
+ #define USB_VENDOR_ID_ZYDACRON        0x13EC
+ #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
  #define USB_VENDOR_ID_KYE             0x0458
  #define USB_DEVICE_ID_KYE_ERGO_525V   0x0087
  #define USB_DEVICE_ID_KYE_GPEN_560    0x5003
diff --combined drivers/hid/hid-wacom.c
index f947d8337e212ce8bff976996496e974912b59d1,51d7d77eb43bafa2edcd941e04b334326eafc2a7..1e051f1171e4a6e12f9afcb559a62dc2c1b757d0
  #include <linux/device.h>
  #include <linux/hid.h>
  #include <linux/module.h>
 +#include <linux/slab.h>
+ #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
+ #include <linux/power_supply.h>
+ #endif
  
  #include "hid-ids.h"
  
  struct wacom_data {
        __u16 tool;
        unsigned char butstate;
+       unsigned char high_speed;
+ #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
+       int battery_capacity;
+       struct power_supply battery;
+       struct power_supply ac;
+ #endif
  };
  
+ #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
+ /*percent of battery capacity, 0 means AC online*/
+ static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 };
+ static enum power_supply_property wacom_battery_props[] = {
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_CAPACITY
+ };
+ static enum power_supply_property wacom_ac_props[] = {
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_ONLINE
+ };
+ static int wacom_battery_get_property(struct power_supply *psy,
+                               enum power_supply_property psp,
+                               union power_supply_propval *val)
+ {
+       struct wacom_data *wdata = container_of(psy,
+                                       struct wacom_data, battery);
+       int power_state = batcap[wdata->battery_capacity];
+       int ret = 0;
+       switch (psp) {
+       case POWER_SUPPLY_PROP_PRESENT:
+               val->intval = 1;
+               break;
+       case POWER_SUPPLY_PROP_CAPACITY:
+               /* show 100% battery capacity when charging */
+               if (power_state == 0)
+                       val->intval = 100;
+               else
+                       val->intval = power_state;
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+ }
+ static int wacom_ac_get_property(struct power_supply *psy,
+                               enum power_supply_property psp,
+                               union power_supply_propval *val)
+ {
+       struct wacom_data *wdata = container_of(psy, struct wacom_data, ac);
+       int power_state = batcap[wdata->battery_capacity];
+       int ret = 0;
+       switch (psp) {
+       case POWER_SUPPLY_PROP_PRESENT:
+               /* fall through */
+       case POWER_SUPPLY_PROP_ONLINE:
+               if (power_state == 0)
+                       val->intval = 1;
+               else
+                       val->intval = 0;
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+ }
+ #endif
+ static void wacom_poke(struct hid_device *hdev, u8 speed)
+ {
+       struct wacom_data *wdata = hid_get_drvdata(hdev);
+       int limit, ret;
+       char rep_data[2];
+       rep_data[0] = 0x03 ; rep_data[1] = 0x00;
+       limit = 3;
+       do {
+               ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
+                               HID_FEATURE_REPORT);
+       } while (ret < 0 && limit-- > 0);
+       if (ret >= 0) {
+               if (speed == 0)
+                       rep_data[0] = 0x05;
+               else
+                       rep_data[0] = 0x06;
+               rep_data[1] = 0x00;
+               limit = 3;
+               do {
+                       ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
+                                       HID_FEATURE_REPORT);
+               } while (ret < 0 && limit-- > 0);
+               if (ret >= 0) {
+                       wdata->high_speed = speed;
+                       return;
+               }
+       }
+       /*
+        * Note that if the raw queries fail, it's not a hard failure and it
+        * is safe to continue
+        */
+       dev_warn(&hdev->dev, "failed to poke device, command %d, err %d\n",
+                               rep_data[0], ret);
+       return;
+ }
+ static ssize_t wacom_show_speed(struct device *dev,
+                               struct device_attribute
+                               *attr, char *buf)
+ {
+       struct wacom_data *wdata = dev_get_drvdata(dev);
+       return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed);
+ }
+ static ssize_t wacom_store_speed(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+ {
+       struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+       int new_speed;
+       if (sscanf(buf, "%1d", &new_speed ) != 1)
+               return -EINVAL;
+       if (new_speed == 0 || new_speed == 1) {
+               wacom_poke(hdev, new_speed);
+               return strnlen(buf, PAGE_SIZE);
+       } else
+               return -EINVAL;
+ }
+ static DEVICE_ATTR(speed, S_IRUGO | S_IWUGO,
+               wacom_show_speed, wacom_store_speed);
  static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
                u8 *raw_data, int size)
  {
                input_sync(input);
        }
  
+ #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
+       /* Store current battery capacity */
+       rw = (data[7] >> 2 & 0x07);
+       if (rw != wdata->battery_capacity)
+               wdata->battery_capacity = rw;
+ #endif
        return 1;
  }
  
@@@ -157,9 -307,7 +308,7 @@@ static int wacom_probe(struct hid_devic
        struct hid_input *hidinput;
        struct input_dev *input;
        struct wacom_data *wdata;
-       char rep_data[2];
        int ret;
-       int limit;
  
        wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
        if (wdata == NULL) {
                goto err_free;
        }
  
-       /*
-        * Note that if the raw queries fail, it's not a hard failure and it
-        * is safe to continue
-        */
+       ret = device_create_file(&hdev->dev, &dev_attr_speed);
+       if (ret)
+               dev_warn(&hdev->dev,
+                       "can't create sysfs speed attribute err: %d\n", ret);
  
-       /* Set Wacom mode2 */
-       rep_data[0] = 0x03; rep_data[1] = 0x00;
-       limit = 3;
-       do {
-               ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
-                               HID_FEATURE_REPORT);
-       } while (ret < 0 && limit-- > 0);
-       if (ret < 0)
-               dev_warn(&hdev->dev, "failed to poke device #1, %d\n", ret);
+       /* Set Wacom mode 2 with high reporting speed */
+       wacom_poke(hdev, 1);
  
-       /* 0x06 - high reporting speed, 0x05 - low speed */
-       rep_data[0] = 0x06; rep_data[1] = 0x00;
-       limit = 3;
-       do {
-               ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
-                               HID_FEATURE_REPORT);
-       } while (ret < 0 && limit-- > 0);
-       if (ret < 0)
-               dev_warn(&hdev->dev, "failed to poke device #2, %d\n", ret);
+ #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
+       wdata->battery.properties = wacom_battery_props;
+       wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
+       wdata->battery.get_property = wacom_battery_get_property;
+       wdata->battery.name = "wacom_battery";
+       wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+       wdata->battery.use_for_apm = 0;
  
+       ret = power_supply_register(&hdev->dev, &wdata->battery);
+       if (ret) {
+               dev_warn(&hdev->dev,
+                       "can't create sysfs battery attribute, err: %d\n", ret);
+               /*
+                * battery attribute is not critical for the tablet, but if it
+                * failed then there is no need to create ac attribute
+                */
+               goto move_on;
+       }
+       wdata->ac.properties = wacom_ac_props;
+       wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
+       wdata->ac.get_property = wacom_ac_get_property;
+       wdata->ac.name = "wacom_ac";
+       wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
+       wdata->ac.use_for_apm = 0;
+       ret = power_supply_register(&hdev->dev, &wdata->ac);
+       if (ret) {
+               dev_warn(&hdev->dev,
+                       "can't create ac battery attribute, err: %d\n", ret);
+               /*
+                * ac attribute is not critical for the tablet, but if it
+                * failed then we don't want to battery attribute to exist
+                */
+               power_supply_unregister(&wdata->battery);
+       }
+ move_on:
+ #endif
        hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
        input = hidinput->input;
  
@@@ -251,13 -421,21 +422,21 @@@ err_free
  
  static void wacom_remove(struct hid_device *hdev)
  {
+ #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
+       struct wacom_data *wdata = hid_get_drvdata(hdev);
+ #endif
        hid_hw_stop(hdev);
+ #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
+       power_supply_unregister(&wdata->battery);
+       power_supply_unregister(&wdata->ac);
+ #endif
        kfree(hid_get_drvdata(hdev));
  }
  
  static const struct hid_device_id wacom_devices[] = {
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
        { }
  };
  MODULE_DEVICE_TABLE(hid, wacom_devices);
@@@ -277,6 -455,7 +456,6 @@@ static int __init wacom_init(void
        ret = hid_register_driver(&wacom_driver);
        if (ret)
                printk(KERN_ERR "can't register wacom driver\n");
 -      printk(KERN_ERR "wacom driver registered\n");
        return ret;
  }
  
diff --combined drivers/hid/hidraw.c
index 6eadf1a9b3cca9b31e80fb231a85a56ec0393c45,a758ead3df61a633aa4e68bcba3e1997a2d314e4..a9becf9cd0f6194f0a90ee545f51cf9be4664a8e
@@@ -28,7 -28,6 +28,7 @@@
  #include <linux/poll.h>
  #include <linux/device.h>
  #include <linux/major.h>
 +#include <linux/slab.h>
  #include <linux/hid.h>
  #include <linux/mutex.h>
  #include <linux/sched.h>
@@@ -311,7 -310,7 +311,7 @@@ static long hidraw_ioctl(struct file *f
                                                -EFAULT : len;
                                        break;
                                }
-                 }
+               }
  
                ret = -ENOTTY;
        }
index 7b85b696fdabc372295d49234a14245ca14ba41f,f9640a362caa956e61ffd16ad105ebd83c96883d..a2ebe19967403c43dd7ee1b8b2026f55e0204300
@@@ -807,16 -807,36 +807,36 @@@ static int usbhid_output_raw_report(str
        struct usb_host_interface *interface = intf->cur_altsetting;
        int ret;
  
-       ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-               HID_REQ_SET_REPORT,
-               USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-               ((report_type + 1) << 8) | *buf,
-               interface->desc.bInterfaceNumber, buf + 1, count - 1,
-               USB_CTRL_SET_TIMEOUT);
-       /* count also the report id */
-       if (ret > 0)
-               ret++;
+       if (usbhid->urbout) {
+               int actual_length;
+               int skipped_report_id = 0;
+               if (buf[0] == 0x0) {
+                       /* Don't send the Report ID */
+                       buf++;
+                       count--;
+                       skipped_report_id = 1;
+               }
+               ret = usb_interrupt_msg(dev, usbhid->urbout->pipe,
+                       buf, count, &actual_length,
+                       USB_CTRL_SET_TIMEOUT);
+               /* return the number of bytes transferred */
+               if (ret == 0) {
+                       ret = actual_length;
+                       /* count also the report id */
+                       if (skipped_report_id)
+                               ret++;
+               }
+       } else {
+               ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+                       HID_REQ_SET_REPORT,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       ((report_type + 1) << 8) | *buf,
+                       interface->desc.bInterfaceNumber, buf + 1, count - 1,
+                       USB_CTRL_SET_TIMEOUT);
+               /* count also the report id */
+               if (ret > 0)
+                       ret++;
+       }
  
        return ret;
  }
@@@ -999,6 -1019,13 +1019,6 @@@ static int usbhid_start(struct hid_devi
                }
        }
  
 -      init_waitqueue_head(&usbhid->wait);
 -      INIT_WORK(&usbhid->reset_work, hid_reset);
 -      INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
 -      setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
 -
 -      spin_lock_init(&usbhid->lock);
 -
        usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
        if (!usbhid->urbctrl) {
                ret = -ENOMEM;
        /* Some keyboards don't work until their LEDs have been set.
         * Since BIOSes do set the LEDs, it must be safe for any device
         * that supports the keyboard boot protocol.
+        * In addition, enable remote wakeup by default for all keyboard
+        * devices supporting the boot protocol.
         */
        if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT &&
                        interface->desc.bInterfaceProtocol ==
-                               USB_INTERFACE_PROTOCOL_KEYBOARD)
+                               USB_INTERFACE_PROTOCOL_KEYBOARD) {
                usbhid_set_leds(hid);
+               device_set_wakeup_enable(&dev->dev, 1);
+       }
        return 0;
  
  fail:
@@@ -1133,6 -1163,7 +1156,7 @@@ static int usbhid_probe(struct usb_inte
        hid->vendor = le16_to_cpu(dev->descriptor.idVendor);
        hid->product = le16_to_cpu(dev->descriptor.idProduct);
        hid->name[0] = 0;
+       hid->quirks = usbhid_lookup_quirk(hid->vendor, hid->product);
        if (intf->cur_altsetting->desc.bInterfaceProtocol ==
                        USB_INTERFACE_PROTOCOL_MOUSE)
                hid->type = HID_TYPE_USBMOUSE;
        usbhid->intf = intf;
        usbhid->ifnum = interface->desc.bInterfaceNumber;
  
 +      init_waitqueue_head(&usbhid->wait);
 +      INIT_WORK(&usbhid->reset_work, hid_reset);
 +      INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
 +      setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
 +      spin_lock_init(&usbhid->lock);
 +
        ret = hid_add_device(hid);
        if (ret) {
                if (ret != -ENODEV)
index 1152f9b5fd444c13492de3ae976ef644fb36c9f7,8ea185246a7864a8206dca71f0b97cc43d3836ca..7a6bda23283ee9fca633de3ce9fcbed82571376b
@@@ -16,7 -16,6 +16,7 @@@
   */
  
  #include <linux/hid.h>
 +#include <linux/slab.h>
  
  #include "../hid-ids.h"
  
@@@ -33,6 -32,7 +33,7 @@@ static const struct hid_blacklist 
        { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
        { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
        { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
+       { USB_VENDOR_ID_EGALAX, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
 +      { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
 +      { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
  
This page took 0.087349 seconds and 4 git commands to generate.