Merge branch 'hid-battery' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy...
authorJiri Kosina <jkosina@suse.cz>
Mon, 9 Jan 2012 10:24:59 +0000 (11:24 +0100)
committerJiri Kosina <jkosina@suse.cz>
Mon, 9 Jan 2012 10:24:59 +0000 (11:24 +0100)
1  2 
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
include/linux/hid.h

diff --combined drivers/hid/hid-core.c
@@@ -90,7 -90,7 +90,7 @@@ static struct hid_field *hid_register_f
        struct hid_field *field;
  
        if (report->maxfield == HID_MAX_FIELDS) {
 -              dbg_hid("too many fields in report\n");
 +              hid_err(report->device, "too many fields in report\n");
                return NULL;
        }
  
@@@ -121,7 -121,7 +121,7 @@@ static int open_collection(struct hid_p
        usage = parser->local.usage[0];
  
        if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
 -              dbg_hid("collection stack overflow\n");
 +              hid_err(parser->device, "collection stack overflow\n");
                return -1;
        }
  
                collection = kmalloc(sizeof(struct hid_collection) *
                                parser->device->collection_size * 2, GFP_KERNEL);
                if (collection == NULL) {
 -                      dbg_hid("failed to reallocate collection array\n");
 +                      hid_err(parser->device, "failed to reallocate collection array\n");
                        return -1;
                }
                memcpy(collection, parser->device->collection,
  static int close_collection(struct hid_parser *parser)
  {
        if (!parser->collection_stack_ptr) {
 -              dbg_hid("collection stack underflow\n");
 +              hid_err(parser->device, "collection stack underflow\n");
                return -1;
        }
        parser->collection_stack_ptr--;
@@@ -197,7 -197,7 +197,7 @@@ static unsigned hid_lookup_collection(s
  static int hid_add_usage(struct hid_parser *parser, unsigned usage)
  {
        if (parser->local.usage_index >= HID_MAX_USAGES) {
 -              dbg_hid("usage index exceeded\n");
 +              hid_err(parser->device, "usage index exceeded\n");
                return -1;
        }
        parser->local.usage[parser->local.usage_index] = usage;
@@@ -222,13 -222,12 +222,13 @@@ static int hid_add_field(struct hid_par
  
        report = hid_register_report(parser->device, report_type, parser->global.report_id);
        if (!report) {
 -              dbg_hid("hid_register_report failed\n");
 +              hid_err(parser->device, "hid_register_report failed\n");
                return -1;
        }
  
        if (parser->global.logical_maximum < parser->global.logical_minimum) {
 -              dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum);
 +              hid_err(parser->device, "logical range invalid %d %d\n",
 +                              parser->global.logical_minimum, parser->global.logical_maximum);
                return -1;
        }
  
@@@ -308,7 -307,7 +308,7 @@@ static int hid_parser_global(struct hid
        case HID_GLOBAL_ITEM_TAG_PUSH:
  
                if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
 -                      dbg_hid("global environment stack overflow\n");
 +                      hid_err(parser->device, "global environment stack overflow\n");
                        return -1;
                }
  
        case HID_GLOBAL_ITEM_TAG_POP:
  
                if (!parser->global_stack_ptr) {
 -                      dbg_hid("global environment stack underflow\n");
 +                      hid_err(parser->device, "global environment stack underflow\n");
                        return -1;
                }
  
        case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
                parser->global.report_size = item_udata(item);
                if (parser->global.report_size > 96) {
 -                      dbg_hid("invalid report_size %d\n",
 +                      hid_err(parser->device, "invalid report_size %d\n",
                                        parser->global.report_size);
                        return -1;
                }
        case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
                parser->global.report_count = item_udata(item);
                if (parser->global.report_count > HID_MAX_USAGES) {
 -                      dbg_hid("invalid report_count %d\n",
 +                      hid_err(parser->device, "invalid report_count %d\n",
                                        parser->global.report_count);
                        return -1;
                }
        case HID_GLOBAL_ITEM_TAG_REPORT_ID:
                parser->global.report_id = item_udata(item);
                if (parser->global.report_id == 0) {
 -                      dbg_hid("report_id 0 is invalid\n");
 +                      hid_err(parser->device, "report_id 0 is invalid\n");
                        return -1;
                }
                return 0;
  
        default:
 -              dbg_hid("unknown global tag 0x%x\n", item->tag);
 +              hid_err(parser->device, "unknown global tag 0x%x\n", item->tag);
                return -1;
        }
  }
@@@ -415,14 -414,14 +415,14 @@@ static int hid_parser_local(struct hid_
                         * items and the first delimiter set.
                         */
                        if (parser->local.delimiter_depth != 0) {
 -                              dbg_hid("nested delimiters\n");
 +                              hid_err(parser->device, "nested delimiters\n");
                                return -1;
                        }
                        parser->local.delimiter_depth++;
                        parser->local.delimiter_branch++;
                } else {
                        if (parser->local.delimiter_depth < 1) {
 -                              dbg_hid("bogus close delimiter\n");
 +                              hid_err(parser->device, "bogus close delimiter\n");
                                return -1;
                        }
                        parser->local.delimiter_depth--;
@@@ -507,7 -506,7 +507,7 @@@ static int hid_parser_main(struct hid_p
                ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
                break;
        default:
 -              dbg_hid("unknown main item tag 0x%x\n", item->tag);
 +              hid_err(parser->device, "unknown main item tag 0x%x\n", item->tag);
                ret = 0;
        }
  
@@@ -679,12 -678,12 +679,12 @@@ int hid_parse_report(struct hid_device 
        while ((start = fetch_item(start, end, &item)) != NULL) {
  
                if (item.format != HID_ITEM_FORMAT_SHORT) {
 -                      dbg_hid("unexpected long global item\n");
 +                      hid_err(device, "unexpected long global item\n");
                        goto err;
                }
  
                if (dispatch_type[item.type](parser, &item)) {
 -                      dbg_hid("item %u %u %u %u parsing failed\n",
 +                      hid_err(device, "item %u %u %u %u parsing failed\n",
                                item.format, (unsigned)item.size,
                                (unsigned)item.type, (unsigned)item.tag);
                        goto err;
  
                if (start == end) {
                        if (parser->collection_stack_ptr) {
 -                              dbg_hid("unbalanced collection at end of report description\n");
 +                              hid_err(device, "unbalanced collection at end of report description\n");
                                goto err;
                        }
                        if (parser->local.delimiter_depth) {
 -                              dbg_hid("unbalanced delimiter at end of report description\n");
 +                              hid_err(device, "unbalanced delimiter at end of report description\n");
                                goto err;
                        }
                        vfree(parser);
                }
        }
  
 -      dbg_hid("item fetching failed at offset %d\n", (int)(end - start));
 +      hid_err(device, "item fetching failed at offset %d\n", (int)(end - start));
  err:
        vfree(parser);
        return ret;
@@@ -874,7 -873,7 +874,7 @@@ static void hid_process_event(struct hi
                ret = hdrv->event(hid, field, usage, value);
                if (ret != 0) {
                        if (ret < 0)
 -                              dbg_hid("%s's event failed with %d\n",
 +                              hid_err(hid, "%s's event failed with %d\n",
                                                hdrv->name, ret);
                        return;
                }
@@@ -996,13 -995,12 +996,13 @@@ int hid_set_field(struct hid_field *fie
        hid_dump_input(field->report->device, field->usage + offset, value);
  
        if (offset >= field->report_count) {
 -              dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
 +              hid_err(field->report->device, "offset (%d) exceeds report_count (%d)\n",
 +                              offset, field->report_count);
                return -1;
        }
        if (field->logical_minimum < 0) {
                if (value != snto32(s32ton(value, size), size)) {
 -                      dbg_hid("value %d is out of range\n", value);
 +                      hid_err(field->report->device, "value %d is out of range\n", value);
                        return -1;
                }
        }
@@@ -1159,7 -1157,7 +1159,7 @@@ static bool hid_match_one_id(struct hid
                (id->product == HID_ANY_ID || id->product == hdev->product);
  }
  
static const struct hid_device_id *hid_match_id(struct hid_device *hdev,
+ const struct hid_device_id *hid_match_id(struct hid_device *hdev,
                const struct hid_device_id *id)
  {
        for (; id->bus; id++)
@@@ -1406,13 -1404,11 +1406,13 @@@ static const struct hid_device_id hid_h
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
 -      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
 -      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
 -      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
 -      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
 -      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) },
        { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6650) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
        { 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_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
        { 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_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX1) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX1) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR1) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX2) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX2) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
@@@ -1791,8 -1772,8 +1791,8 @@@ static const struct hid_device_id hid_i
        { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
 -      { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) },
diff --combined drivers/hid/hid-ids.h
@@@ -21,7 -21,6 +21,7 @@@
  #define USB_VENDOR_ID_3M              0x0596
  #define USB_DEVICE_ID_3M1968          0x0500
  #define USB_DEVICE_ID_3M2256          0x0502
 +#define USB_DEVICE_ID_3M3266          0x0506
  
  #define USB_VENDOR_ID_A4TECH          0x09da
  #define USB_DEVICE_ID_A4TECH_WCP32PU  0x0006
  #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI  0x0239
  #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO   0x023a
  #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS   0x023b
+ #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI  0x0255
  #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO   0x0256
  #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY  0x030a
  #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY   0x030b
  #define USB_DEVICE_ID_ATEN_4PORTKVM   0x2205
  #define USB_DEVICE_ID_ATEN_4PORTKVMC  0x2208
  
 +#define USB_VENDOR_ID_ATMEL           0x03eb
 +#define USB_DEVICE_ID_ATMEL_MULTITOUCH        0x211c
 +
  #define USB_VENDOR_ID_AVERMEDIA               0x07ca
  #define USB_DEVICE_ID_AVER_FM_MR800   0xb800
  
  
  #define USB_VENDOR_ID_DWAV            0x0eef
  #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER  0x0001
 -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH  0x480d
 -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c
 -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2 0x72a1
 -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3 0x480e
 -#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4 0x726b
 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D     0x480d
 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E     0x480e
 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C     0x720c
 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B     0x726b
 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1     0x72a1
 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA     0x72fa
 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302     0x7302
 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001     0xa001
  
  #define USB_VENDOR_ID_ELECOM          0x056e
  #define USB_DEVICE_ID_ELECOM_BM084    0x0061
  #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR        0x0002
  
  #define USB_VENDOR_ID_GENERAL_TOUCH   0x0dfc
 -#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0001
 +#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
  
  #define USB_VENDOR_ID_GLAB            0x06c2
  #define USB_DEVICE_ID_4_PHIDGETSERVO_30       0x0038
  #define USB_VENDOR_ID_HANVON          0x20b3
  #define USB_DEVICE_ID_HANVON_MULTITOUCH       0x0a18
  
 +#define USB_VENDOR_ID_HANVON_ALT      0x22ed
 +#define USB_DEVICE_ID_HANVON_ALT_MULTITOUCH   0x1010
 +
  #define USB_VENDOR_ID_HAPP            0x078b
  #define USB_DEVICE_ID_UGCI_DRIVING    0x0010
  #define USB_DEVICE_ID_UGCI_FLYING     0x0020
  #define USB_VENDOR_ID_PI_ENGINEERING  0x05f3
  #define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL        0xff
  
 +#define USB_VENDOR_ID_PIXART                          0x093a
 +#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN     0x8001
 +#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1    0x8002
 +#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2    0x8003
 +
  #define USB_VENDOR_ID_PLAYDOTCOM      0x0b43
  #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII    0x0003
  
  #define USB_DEVICE_ID_PRODIGE_CORDLESS        0x3062
  
  #define USB_VENDOR_ID_QUANTA          0x0408
 -#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH    0x3000
 +#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH            0x3000
 +#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001               0x3001
 +#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008               0x3008
  #define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
  
  #define USB_VENDOR_ID_ROCCAT          0x1e7d
  #define USB_DEVICE_ID_ROCCAT_ARVO     0x30d4
 +#define USB_DEVICE_ID_ROCCAT_ISKU     0x319c
  #define USB_DEVICE_ID_ROCCAT_KONE     0x2ced
  #define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51
  #define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50
  
  #define USB_VENDOR_ID_WACOM           0x056a
  #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH        0x81
 +#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH   0x00BD
  
  #define USB_VENDOR_ID_WALTOP                          0x172f
  #define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH     0x0032
  #define USB_VENDOR_ID_XAT     0x2505
  #define USB_DEVICE_ID_XAT_CSR 0x0220
  
 +#define USB_VENDOR_ID_XIROKU          0x1477
 +#define USB_DEVICE_ID_XIROKU_SPX      0x1006
 +#define USB_DEVICE_ID_XIROKU_MPX      0x1007
 +#define USB_DEVICE_ID_XIROKU_CSR      0x100e
 +#define USB_DEVICE_ID_XIROKU_SPX1     0x1021
 +#define USB_DEVICE_ID_XIROKU_CSR1     0x1022
 +#define USB_DEVICE_ID_XIROKU_MPX1     0x1023
 +#define USB_DEVICE_ID_XIROKU_SPX2     0x1024
 +#define USB_DEVICE_ID_XIROKU_CSR2     0x1025
 +#define USB_DEVICE_ID_XIROKU_MPX2     0x1026
 +
  #define USB_VENDOR_ID_YEALINK         0x6993
  #define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K     0xb001
  
diff --combined drivers/hid/hid-input.c
@@@ -32,6 -32,8 +32,8 @@@
  #include <linux/hid.h>
  #include <linux/hid-debug.h>
  
+ #include "hid-ids.h"
  #define unk   KEY_UNKNOWN
  
  static const unsigned char hid_keyboard[256] = {
@@@ -277,14 -279,38 +279,38 @@@ static enum power_supply_property hidin
        POWER_SUPPLY_PROP_ONLINE,
        POWER_SUPPLY_PROP_CAPACITY,
        POWER_SUPPLY_PROP_MODEL_NAME,
+       POWER_SUPPLY_PROP_STATUS
  };
  
+ #define HID_BATTERY_QUIRK_PERCENT     (1 << 0) /* always reports percent */
+ #define HID_BATTERY_QUIRK_FEATURE     (1 << 1) /* ask for feature report */
+ static const struct hid_device_id hid_battery_quirks[] = {
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+                              USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
+         HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+       {}
+ };
+ static unsigned find_battery_quirk(struct hid_device *hdev)
+ {
+       unsigned quirks = 0;
+       const struct hid_device_id *match;
+       match = hid_match_id(hdev, hid_battery_quirks);
+       if (match != NULL)
+               quirks = match->driver_data;
+       return quirks;
+ }
  static int hidinput_get_battery_property(struct power_supply *psy,
                                         enum power_supply_property prop,
                                         union power_supply_propval *val)
  {
        struct hid_device *dev = container_of(psy, struct hid_device, battery);
        int ret = 0;
+       __u8 buf[2] = {};
  
        switch (prop) {
        case POWER_SUPPLY_PROP_PRESENT:
                break;
  
        case POWER_SUPPLY_PROP_CAPACITY:
+               ret = dev->hid_get_raw_report(dev, dev->battery_report_id,
+                                             buf, sizeof(buf),
+                                             dev->battery_report_type);
+               if (ret != 2) {
+                       if (ret >= 0)
+                               ret = -EINVAL;
+                       break;
+               }
                if (dev->battery_min < dev->battery_max &&
-                   dev->battery_val >= dev->battery_min &&
-                   dev->battery_val <= dev->battery_max)
-                       val->intval = (100 * (dev->battery_val - dev->battery_min)) /
+                   buf[1] >= dev->battery_min &&
+                   buf[1] <= dev->battery_max)
+                       val->intval = (100 * (buf[1] - dev->battery_min)) /
                                (dev->battery_max - dev->battery_min);
-               else
-                       ret = -EINVAL;
                break;
  
        case POWER_SUPPLY_PROP_MODEL_NAME:
                val->strval = dev->name;
                break;
  
+       case POWER_SUPPLY_PROP_STATUS:
+               val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+               break;
        default:
                ret = -EINVAL;
                break;
        return ret;
  }
  
- static void hidinput_setup_battery(struct hid_device *dev, s32 min, s32 max)
+ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field)
  {
        struct power_supply *battery = &dev->battery;
        int ret;
+       unsigned quirks;
+       s32 min, max;
+       if (field->usage->hid != HID_DC_BATTERYSTRENGTH)
+               return false;   /* no match */
  
        if (battery->name != NULL)
-               return;         /* already initialized? */
+               goto out;       /* already initialized? */
  
        battery->name = kasprintf(GFP_KERNEL, "hid-%s-battery", dev->uniq);
        if (battery->name == NULL)
-               return;
+               goto out;
  
        battery->type = POWER_SUPPLY_TYPE_BATTERY;
        battery->properties = hidinput_battery_props;
        battery->use_for_apm = 0;
        battery->get_property = hidinput_get_battery_property;
  
+       quirks = find_battery_quirk(dev);
+       hid_dbg(dev, "device %x:%x:%x %d quirks %d\n",
+               dev->bus, dev->vendor, dev->product, dev->version, quirks);
+       min = field->logical_minimum;
+       max = field->logical_maximum;
+       if (quirks & HID_BATTERY_QUIRK_PERCENT) {
+               min = 0;
+               max = 100;
+       }
+       if (quirks & HID_BATTERY_QUIRK_FEATURE)
+               report_type = HID_FEATURE_REPORT;
        dev->battery_min = min;
        dev->battery_max = max;
+       dev->battery_report_type = report_type;
+       dev->battery_report_id = field->report->id;
  
        ret = power_supply_register(&dev->dev, battery);
        if (ret != 0) {
                kfree(battery->name);
                battery->name = NULL;
        }
+ out:
+       return true;
  }
  
  static void hidinput_cleanup_battery(struct hid_device *dev)
        dev->battery.name = NULL;
  }
  #else  /* !CONFIG_HID_BATTERY_STRENGTH */
- static void hidinput_setup_battery(struct hid_device *dev, s32 min, s32 max)
+ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+                                  struct hid_field *field)
  {
+       return false;
  }
  
  static void hidinput_cleanup_battery(struct hid_device *dev)
@@@ -721,12 -787,9 +787,9 @@@ static void hidinput_configure_usage(st
                break;
  
        case HID_UP_GENDEVCTRLS:
-               if ((usage->hid & HID_USAGE) == 0x20) { /* Battery Strength */
-                       hidinput_setup_battery(device,
-                                              field->logical_minimum,
-                                              field->logical_maximum);
+               if (hidinput_setup_battery(device, HID_INPUT_REPORT, field))
                        goto ignore;
-               else
+               else
                        goto unknown;
                break;
  
@@@ -861,14 -924,6 +924,6 @@@ void hidinput_hid_event(struct hid_devi
  
        input = field->hidinput->input;
  
- #ifdef CONFIG_HID_BATTERY_STRENGTH
-       if (usage->hid == HID_DC_BATTERYSTRENGTH) {
-               hid->battery_val = value;
-               hid_dbg(hid, "battery value is %d (range %d-%d)\n",
-                       value, hid->battery_min, hid->battery_max);
-               return;
-       }
- #endif
        if (!usage->type)
                return;
  
@@@ -976,48 -1031,6 +1031,48 @@@ int hidinput_find_field(struct hid_devi
  }
  EXPORT_SYMBOL_GPL(hidinput_find_field);
  
 +struct hid_field *hidinput_get_led_field(struct hid_device *hid)
 +{
 +      struct hid_report *report;
 +      struct hid_field *field;
 +      int i, j;
 +
 +      list_for_each_entry(report,
 +                          &hid->report_enum[HID_OUTPUT_REPORT].report_list,
 +                          list) {
 +              for (i = 0; i < report->maxfield; i++) {
 +                      field = report->field[i];
 +                      for (j = 0; j < field->maxusage; j++)
 +                              if (field->usage[j].type == EV_LED)
 +                                      return field;
 +              }
 +      }
 +      return NULL;
 +}
 +EXPORT_SYMBOL_GPL(hidinput_get_led_field);
 +
 +unsigned int hidinput_count_leds(struct hid_device *hid)
 +{
 +      struct hid_report *report;
 +      struct hid_field *field;
 +      int i, j;
 +      unsigned int count = 0;
 +
 +      list_for_each_entry(report,
 +                          &hid->report_enum[HID_OUTPUT_REPORT].report_list,
 +                          list) {
 +              for (i = 0; i < report->maxfield; i++) {
 +                      field = report->field[i];
 +                      for (j = 0; j < field->maxusage; j++)
 +                              if (field->usage[j].type == EV_LED &&
 +                                  field->value[j])
 +                                      count += 1;
 +              }
 +      }
 +      return count;
 +}
 +EXPORT_SYMBOL_GPL(hidinput_count_leds);
 +
  static int hidinput_open(struct input_dev *dev)
  {
        struct hid_device *hid = input_get_drvdata(dev);
@@@ -1039,15 -1052,17 +1094,17 @@@ static void report_features(struct hid_
        struct hid_report *rep;
        int i, j;
  
-       if (!drv->feature_mapping)
-               return;
        rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
        list_for_each_entry(rep, &rep_enum->report_list, list)
                for (i = 0; i < rep->maxfield; i++)
-                       for (j = 0; j < rep->field[i]->maxusage; j++)
-                               drv->feature_mapping(hid, rep->field[i],
-                                                    rep->field[i]->usage + j);
+                       for (j = 0; j < rep->field[i]->maxusage; j++) {
+                               /* Verify if Battery Strength feature is available */
+                               hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]);
+                               if (drv->feature_mapping)
+                                       drv->feature_mapping(hid, rep->field[i],
+                                                            rep->field[i]->usage + j);
+                       }
  }
  
  /*
diff --combined include/linux/hid.h
@@@ -495,7 -495,8 +495,8 @@@ struct hid_device {                                                        /* device rep
        struct power_supply battery;
        __s32 battery_min;
        __s32 battery_max;
-       __s32 battery_val;
+       __s32 battery_report_type;
+       __s32 battery_report_id;
  #endif
  
        unsigned int status;                                            /* see STAT flags above */
@@@ -713,11 -714,10 +714,11 @@@ extern void hid_destroy_device(struct h
  
  extern int __must_check __hid_register_driver(struct hid_driver *,
                struct module *, const char *mod_name);
 -static inline int __must_check hid_register_driver(struct hid_driver *driver)
 -{
 -      return __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
 -}
 +
 +/* use a define to avoid include chaining to get THIS_MODULE & friends */
 +#define hid_register_driver(driver) \
 +      __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
 +
  extern void hid_unregister_driver(struct hid_driver *);
  
  extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
@@@ -728,8 -728,6 +729,8 @@@ extern void hidinput_disconnect(struct 
  int hid_set_field(struct hid_field *, unsigned, __s32);
  int hid_input_report(struct hid_device *, int type, u8 *, int, int);
  int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
 +struct hid_field *hidinput_get_led_field(struct hid_device *hid);
 +unsigned int hidinput_count_leds(struct hid_device *hid);
  void hid_output_report(struct hid_report *report, __u8 *data);
  struct hid_device *hid_allocate_device(void);
  struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
@@@ -737,6 -735,8 +738,8 @@@ int hid_parse_report(struct hid_device 
  int hid_check_keys_pressed(struct hid_device *hid);
  int hid_connect(struct hid_device *hid, unsigned int connect_mask);
  void hid_disconnect(struct hid_device *hid);
+ const struct hid_device_id *hid_match_id(struct hid_device *hdev,
+                                        const struct hid_device_id *id);
  
  /**
   * hid_map_usage - map usage input bits