···11+What: /sys/class/hidraw/hidraw*/device/speed22+Date: April 201033+Kernel Version: 2.6.3544+Contact: linux-bluetooth@vger.kernel.org55+Description:66+ The /sys/class/hidraw/hidraw*/device/speed file controls77+ reporting speed of wacom bluetooth tablet. Reading from88+ this file returns 1 if tablet reports in high speed mode99+ or 0 otherwise. Writing to this file one of these values1010+ switches reporting speed.
+17-2
drivers/hid/Kconfig
···273273 depends on USB_HID274274 default !EMBEDDED275275 ---help---276276- Support for Samsung InfraRed remote control.276276+ Support for Samsung InfraRed remote control or keyboards.277277278278config HID_SONY279279 tristate "Sony" if EMBEDDED···332332 depends on USB_HID333333 default !EMBEDDED334334 ---help---335335- Say Y if you have a TopSeed Cyberlink remote control.335335+ Say Y if you have a TopSeed Cyberlink or BTC Emprex remote control.336336337337config HID_THRUSTMASTER338338 tristate "ThrustMaster devices support" if EMBEDDED···357357 ---help---358358 Support for Wacom Graphire Bluetooth tablet.359359360360+config HID_WACOM_POWER_SUPPLY361361+ bool "Wacom Bluetooth devices power supply status support"362362+ depends on HID_WACOM363363+ select POWER_SUPPLY364364+ ---help---365365+ Say Y here if you want to enable power supply status monitoring for366366+ Wacom Bluetooth devices.367367+360368config HID_ZEROPLUS361369 tristate "Zeroplus based game controller support" if EMBEDDED362370 depends on USB_HID···379371 ---help---380372 Say Y here if you have a Zeroplus based game controller and want381373 to have force feedback support for it.374374+375375+config HID_ZYDACRON376376+ tristate "Zydacron remote control support" if EMBEDDED377377+ depends on USB_HID378378+ default !EMBEDDED379379+ ---help---380380+ Support for Zydacron remote control.382381383382endmenu384383
···126126 case 0x1004: lg_map_key_clear(KEY_VIDEO); break;127127 case 0x1005: lg_map_key_clear(KEY_AUDIO); break;128128 case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break;129129+ /* The following two entries are Playlist 1 and 2 on the MX3200 */130130+ case 0x100f: lg_map_key_clear(KEY_FN_1); break;131131+ case 0x1010: lg_map_key_clear(KEY_FN_2); break;129132 case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break;130133 case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break;131134 case 0x1013: lg_map_key_clear(KEY_CAMERA); break;···140137 case 0x1019: lg_map_key_clear(KEY_PROG1); break;141138 case 0x101a: lg_map_key_clear(KEY_PROG2); break;142139 case 0x101b: lg_map_key_clear(KEY_PROG3); break;140140+ case 0x101c: lg_map_key_clear(KEY_CYCLEWINDOWS); break;143141 case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break;144142 case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break;145143 case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break;···151147 case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break;152148 case 0x102a: lg_map_key_clear(KEY_BACK); break;153149 case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break;150150+ case 0x102d: lg_map_key_clear(KEY_WWW); break;151151+ /* The following two are 'Start/answer call' and 'End/reject call'152152+ on the MX3200 */153153+ case 0x1031: lg_map_key_clear(KEY_OK); break;154154+ case 0x1032: lg_map_key_clear(KEY_CANCEL); break;154155 case 0x1041: lg_map_key_clear(KEY_BATTERY); break;155156 case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break;156157 case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break;
+83-12
drivers/hid/hid-samsung.c
···77 * Copyright (c) 2006-2007 Jiri Kosina88 * Copyright (c) 2007 Paul Walmsley99 * Copyright (c) 2008 Jiri Slaby1010+ * Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>1111+ *1212+ *1313+ * This driver supports several HID devices:1414+ *1515+ * [0419:0001] Samsung IrDA remote controller (reports as Cypress USB Mouse).1616+ * various hid report fixups for different variants.1717+ *1818+ * [0419:0600] Creative Desktop Wireless 6000 keyboard/mouse combo1919+ * several key mappings used from the consumer usage page2020+ * deviate from the USB HUT 1.12 standard.2121+ *1022 */11231224/*···2917 */30183119#include <linux/device.h>2020+#include <linux/usb.h>3221#include <linux/hid.h>3322#include <linux/module.h>34233524#include "hid-ids.h"36253726/*3838- * Samsung IrDA remote controller (reports as Cypress USB Mouse).3939- *4027 * There are several variants for 0419:0001:4128 *4229 * 1. 184 byte report descriptor···5443 * 4. 171 byte report descriptor5544 * Report #3 has an array field with logical range 0..1 instead of 1..3.5645 */5757-static inline void samsung_dev_trace(struct hid_device *hdev,4646+static inline void samsung_irda_dev_trace(struct hid_device *hdev,5847 unsigned int rsize)5948{6049 dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "6150 "descriptor\n", rsize);6251}63526464-static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,5353+static void samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,6554 unsigned int rsize)6655{6756 if (rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&6857 rdesc[177] == 0x75 && rdesc[178] == 0x30 &&6958 rdesc[179] == 0x95 && rdesc[180] == 0x01 &&7059 rdesc[182] == 0x40) {7171- samsung_dev_trace(hdev, 184);6060+ samsung_irda_dev_trace(hdev, 184);7261 rdesc[176] = 0xff;7362 rdesc[178] = 0x08;7463 rdesc[180] = 0x06;···7665 } else7766 if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&7867 rdesc[194] == 0x25 && rdesc[195] == 0x12) {7979- samsung_dev_trace(hdev, 203);6868+ samsung_irda_dev_trace(hdev, 203);8069 rdesc[193] = 0x1;8170 rdesc[195] = 0xf;8271 } else8372 if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&8473 rdesc[126] == 0x25 && rdesc[127] == 0x11) {8585- samsung_dev_trace(hdev, 135);7474+ samsung_irda_dev_trace(hdev, 135);8675 rdesc[125] = 0x1;8776 rdesc[127] = 0xe;8877 } else8978 if (rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&9079 rdesc[162] == 0x25 && rdesc[163] == 0x01) {9191- samsung_dev_trace(hdev, 171);8080+ samsung_irda_dev_trace(hdev, 171);9281 rdesc[161] = 0x1;9382 rdesc[163] = 0x3;9483 }8484+}8585+8686+#define samsung_kbd_mouse_map_key_clear(c) \8787+ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))8888+8989+static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,9090+ struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,9191+ unsigned long **bit, int *max)9292+{9393+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);9494+ unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber;9595+9696+ if (1 != ifnum || HID_UP_CONSUMER != (usage->hid & HID_USAGE_PAGE))9797+ return 0;9898+9999+ dbg_hid("samsung wireless keyboard/mouse input mapping event [0x%x]\n",100100+ usage->hid & HID_USAGE);101101+102102+ switch (usage->hid & HID_USAGE) {103103+ /* report 2 */104104+ case 0x183: samsung_kbd_mouse_map_key_clear(KEY_MEDIA); break;105105+ case 0x195: samsung_kbd_mouse_map_key_clear(KEY_EMAIL); break;106106+ case 0x196: samsung_kbd_mouse_map_key_clear(KEY_CALC); break;107107+ case 0x197: samsung_kbd_mouse_map_key_clear(KEY_COMPUTER); break;108108+ case 0x22b: samsung_kbd_mouse_map_key_clear(KEY_SEARCH); break;109109+ case 0x22c: samsung_kbd_mouse_map_key_clear(KEY_WWW); break;110110+ case 0x22d: samsung_kbd_mouse_map_key_clear(KEY_BACK); break;111111+ case 0x22e: samsung_kbd_mouse_map_key_clear(KEY_FORWARD); break;112112+ case 0x22f: samsung_kbd_mouse_map_key_clear(KEY_FAVORITES); break;113113+ case 0x230: samsung_kbd_mouse_map_key_clear(KEY_REFRESH); break;114114+ case 0x231: samsung_kbd_mouse_map_key_clear(KEY_STOP); break;115115+ default:116116+ return 0;117117+ }118118+119119+ return 1;120120+}121121+122122+static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,123123+ unsigned int rsize)124124+{125125+ if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)126126+ samsung_irda_report_fixup(hdev, rdesc, rsize);127127+}128128+129129+static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,130130+ struct hid_field *field, struct hid_usage *usage,131131+ unsigned long **bit, int *max)132132+{133133+ int ret = 0;134134+135135+ if (USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE == hdev->product)136136+ ret = samsung_kbd_mouse_input_mapping(hdev,137137+ hi, field, usage, bit, max);138138+139139+ return ret;95140}9614197142static int samsung_probe(struct hid_device *hdev,···16295 goto err_free;16396 }16497165165- if (hdev->rsize == 184) {166166- /* disable hidinput, force hiddev */167167- cmask = (cmask & ~HID_CONNECT_HIDINPUT) |168168- HID_CONNECT_HIDDEV_FORCE;9898+ if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) {9999+ if (hdev->rsize == 184) {100100+ /* disable hidinput, force hiddev */101101+ cmask = (cmask & ~HID_CONNECT_HIDINPUT) |102102+ HID_CONNECT_HIDDEV_FORCE;103103+ }169104 }170105171106 ret = hid_hw_start(hdev, cmask);···183114184115static const struct hid_device_id samsung_devices[] = {185116 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },117117+ { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },186118 { }187119};188120MODULE_DEVICE_TABLE(hid, samsung_devices);···192122 .name = "samsung",193123 .id_table = samsung_devices,194124 .report_fixup = samsung_report_fixup,125125+ .input_mapping = samsung_input_mapping,195126 .probe = samsung_probe,196127};197128
+24-14
drivers/hid/hid-topseed.c
···33 *44 * Copyright (c) 2008 Lev Babiev55 * based on hid-cherry driver66+ *77+ * Modified to also support BTC "Emprex 3009URF III Vista MCE Remote" by88+ * Wayne Thomas 2010.69 */710811/*···2724 struct hid_field *field, struct hid_usage *usage,2825 unsigned long **bit, int *max)2926{3030- if ((usage->hid & HID_USAGE_PAGE) != 0x0ffbc0000)2727+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)3128 return 0;32293330 switch (usage->hid & HID_USAGE) {3434- case 0x00d: ts_map_key_clear(KEY_HOME); break;3535- case 0x024: ts_map_key_clear(KEY_MENU); break;3636- case 0x025: ts_map_key_clear(KEY_TV); break;3737- case 0x048: ts_map_key_clear(KEY_RED); break;3838- case 0x047: ts_map_key_clear(KEY_GREEN); break;3939- case 0x049: ts_map_key_clear(KEY_YELLOW); break;4040- case 0x04a: ts_map_key_clear(KEY_BLUE); break;4141- case 0x04b: ts_map_key_clear(KEY_ANGLE); break;4242- case 0x04c: ts_map_key_clear(KEY_LANGUAGE); break;4343- case 0x04d: ts_map_key_clear(KEY_SUBTITLE); break;4444- case 0x031: ts_map_key_clear(KEY_AUDIO); break;4545- case 0x032: ts_map_key_clear(KEY_TEXT); break;4646- case 0x033: ts_map_key_clear(KEY_CHANNEL); break;3131+ case 0x00d: ts_map_key_clear(KEY_MEDIA); break;3232+ case 0x024: ts_map_key_clear(KEY_MENU); break;3333+ case 0x025: ts_map_key_clear(KEY_TV); break;3434+ case 0x031: ts_map_key_clear(KEY_AUDIO); break;3535+ case 0x032: ts_map_key_clear(KEY_TEXT); break;3636+ case 0x033: ts_map_key_clear(KEY_CHANNEL); break;3737+ case 0x047: ts_map_key_clear(KEY_MP3); break;3838+ case 0x048: ts_map_key_clear(KEY_TV2); break;3939+ case 0x049: ts_map_key_clear(KEY_CAMERA); break;4040+ case 0x04a: ts_map_key_clear(KEY_VIDEO); break;4141+ case 0x04b: ts_map_key_clear(KEY_ANGLE); break;4242+ case 0x04c: ts_map_key_clear(KEY_LANGUAGE); break;4343+ case 0x04d: ts_map_key_clear(KEY_SUBTITLE); break;4444+ case 0x050: ts_map_key_clear(KEY_RADIO); break;4545+ case 0x05a: ts_map_key_clear(KEY_TEXT); break;4646+ case 0x05b: ts_map_key_clear(KEY_RED); break;4747+ case 0x05c: ts_map_key_clear(KEY_GREEN); break;4848+ case 0x05d: ts_map_key_clear(KEY_YELLOW); break;4949+ case 0x05e: ts_map_key_clear(KEY_BLUE); break;4750 default:4851 return 0;4952 }···59506051static const struct hid_device_id ts_devices[] = {6152 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },5353+ { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },6254 { }6355};6456MODULE_DEVICE_TABLE(hid, ts_devices);
+204-25
drivers/hid/hid-wacom.c
···2222#include <linux/hid.h>2323#include <linux/module.h>2424#include <linux/slab.h>2525+#ifdef CONFIG_HID_WACOM_POWER_SUPPLY2626+#include <linux/power_supply.h>2727+#endif25282629#include "hid-ids.h"27302831struct wacom_data {2932 __u16 tool;3033 unsigned char butstate;3434+ unsigned char high_speed;3535+#ifdef CONFIG_HID_WACOM_POWER_SUPPLY3636+ int battery_capacity;3737+ struct power_supply battery;3838+ struct power_supply ac;3939+#endif3140};4141+4242+#ifdef CONFIG_HID_WACOM_POWER_SUPPLY4343+/*percent of battery capacity, 0 means AC online*/4444+static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 };4545+4646+static enum power_supply_property wacom_battery_props[] = {4747+ POWER_SUPPLY_PROP_PRESENT,4848+ POWER_SUPPLY_PROP_CAPACITY4949+};5050+5151+static enum power_supply_property wacom_ac_props[] = {5252+ POWER_SUPPLY_PROP_PRESENT,5353+ POWER_SUPPLY_PROP_ONLINE5454+};5555+5656+static int wacom_battery_get_property(struct power_supply *psy,5757+ enum power_supply_property psp,5858+ union power_supply_propval *val)5959+{6060+ struct wacom_data *wdata = container_of(psy,6161+ struct wacom_data, battery);6262+ int power_state = batcap[wdata->battery_capacity];6363+ int ret = 0;6464+6565+ switch (psp) {6666+ case POWER_SUPPLY_PROP_PRESENT:6767+ val->intval = 1;6868+ break;6969+ case POWER_SUPPLY_PROP_CAPACITY:7070+ /* show 100% battery capacity when charging */7171+ if (power_state == 0)7272+ val->intval = 100;7373+ else7474+ val->intval = power_state;7575+ break;7676+ default:7777+ ret = -EINVAL;7878+ break;7979+ }8080+ return ret;8181+}8282+8383+static int wacom_ac_get_property(struct power_supply *psy,8484+ enum power_supply_property psp,8585+ union power_supply_propval *val)8686+{8787+ struct wacom_data *wdata = container_of(psy, struct wacom_data, ac);8888+ int power_state = batcap[wdata->battery_capacity];8989+ int ret = 0;9090+9191+ switch (psp) {9292+ case POWER_SUPPLY_PROP_PRESENT:9393+ /* fall through */9494+ case POWER_SUPPLY_PROP_ONLINE:9595+ if (power_state == 0)9696+ val->intval = 1;9797+ else9898+ val->intval = 0;9999+ break;100100+ default:101101+ ret = -EINVAL;102102+ break;103103+ }104104+ return ret;105105+}106106+#endif107107+108108+static void wacom_poke(struct hid_device *hdev, u8 speed)109109+{110110+ struct wacom_data *wdata = hid_get_drvdata(hdev);111111+ int limit, ret;112112+ char rep_data[2];113113+114114+ rep_data[0] = 0x03 ; rep_data[1] = 0x00;115115+ limit = 3;116116+ do {117117+ ret = hdev->hid_output_raw_report(hdev, rep_data, 2,118118+ HID_FEATURE_REPORT);119119+ } while (ret < 0 && limit-- > 0);120120+121121+ if (ret >= 0) {122122+ if (speed == 0)123123+ rep_data[0] = 0x05;124124+ else125125+ rep_data[0] = 0x06;126126+127127+ rep_data[1] = 0x00;128128+ limit = 3;129129+ do {130130+ ret = hdev->hid_output_raw_report(hdev, rep_data, 2,131131+ HID_FEATURE_REPORT);132132+ } while (ret < 0 && limit-- > 0);133133+134134+ if (ret >= 0) {135135+ wdata->high_speed = speed;136136+ return;137137+ }138138+ }139139+140140+ /*141141+ * Note that if the raw queries fail, it's not a hard failure and it142142+ * is safe to continue143143+ */144144+ dev_warn(&hdev->dev, "failed to poke device, command %d, err %d\n",145145+ rep_data[0], ret);146146+ return;147147+}148148+149149+static ssize_t wacom_show_speed(struct device *dev,150150+ struct device_attribute151151+ *attr, char *buf)152152+{153153+ struct wacom_data *wdata = dev_get_drvdata(dev);154154+155155+ return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed);156156+}157157+158158+static ssize_t wacom_store_speed(struct device *dev,159159+ struct device_attribute *attr,160160+ const char *buf, size_t count)161161+{162162+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);163163+ int new_speed;164164+165165+ if (sscanf(buf, "%1d", &new_speed ) != 1)166166+ return -EINVAL;167167+168168+ if (new_speed == 0 || new_speed == 1) {169169+ wacom_poke(hdev, new_speed);170170+ return strnlen(buf, PAGE_SIZE);171171+ } else172172+ return -EINVAL;173173+}174174+175175+static DEVICE_ATTR(speed, S_IRUGO | S_IWUGO,176176+ wacom_show_speed, wacom_store_speed);3217733178static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,34179 u8 *raw_data, int size)···293148 input_sync(input);294149 }295150151151+#ifdef CONFIG_HID_WACOM_POWER_SUPPLY152152+ /* Store current battery capacity */153153+ rw = (data[7] >> 2 & 0x07);154154+ if (rw != wdata->battery_capacity)155155+ wdata->battery_capacity = rw;156156+#endif296157 return 1;297158}298159···308157 struct hid_input *hidinput;309158 struct input_dev *input;310159 struct wacom_data *wdata;311311- char rep_data[2];312160 int ret;313313- int limit;314161315162 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);316163 if (wdata == NULL) {···331182 goto err_free;332183 }333184334334- /*335335- * Note that if the raw queries fail, it's not a hard failure and it336336- * is safe to continue337337- */185185+ ret = device_create_file(&hdev->dev, &dev_attr_speed);186186+ if (ret)187187+ dev_warn(&hdev->dev,188188+ "can't create sysfs speed attribute err: %d\n", ret);338189339339- /* Set Wacom mode2 */340340- rep_data[0] = 0x03; rep_data[1] = 0x00;341341- limit = 3;342342- do {343343- ret = hdev->hid_output_raw_report(hdev, rep_data, 2,344344- HID_FEATURE_REPORT);345345- } while (ret < 0 && limit-- > 0);346346- if (ret < 0)347347- dev_warn(&hdev->dev, "failed to poke device #1, %d\n", ret);190190+ /* Set Wacom mode 2 with high reporting speed */191191+ wacom_poke(hdev, 1);348192349349- /* 0x06 - high reporting speed, 0x05 - low speed */350350- rep_data[0] = 0x06; rep_data[1] = 0x00;351351- limit = 3;352352- do {353353- ret = hdev->hid_output_raw_report(hdev, rep_data, 2,354354- HID_FEATURE_REPORT);355355- } while (ret < 0 && limit-- > 0);356356- if (ret < 0)357357- dev_warn(&hdev->dev, "failed to poke device #2, %d\n", ret);193193+#ifdef CONFIG_HID_WACOM_POWER_SUPPLY194194+ wdata->battery.properties = wacom_battery_props;195195+ wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props);196196+ wdata->battery.get_property = wacom_battery_get_property;197197+ wdata->battery.name = "wacom_battery";198198+ wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;199199+ wdata->battery.use_for_apm = 0;358200201201+ ret = power_supply_register(&hdev->dev, &wdata->battery);202202+ if (ret) {203203+ dev_warn(&hdev->dev,204204+ "can't create sysfs battery attribute, err: %d\n", ret);205205+ /*206206+ * battery attribute is not critical for the tablet, but if it207207+ * failed then there is no need to create ac attribute208208+ */209209+ goto move_on;210210+ }211211+212212+ wdata->ac.properties = wacom_ac_props;213213+ wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);214214+ wdata->ac.get_property = wacom_ac_get_property;215215+ wdata->ac.name = "wacom_ac";216216+ wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;217217+ wdata->ac.use_for_apm = 0;218218+219219+ ret = power_supply_register(&hdev->dev, &wdata->ac);220220+ if (ret) {221221+ dev_warn(&hdev->dev,222222+ "can't create ac battery attribute, err: %d\n", ret);223223+ /*224224+ * ac attribute is not critical for the tablet, but if it225225+ * failed then we don't want to battery attribute to exist226226+ */227227+ power_supply_unregister(&wdata->battery);228228+ }229229+230230+move_on:231231+#endif359232 hidinput = list_entry(hdev->inputs.next, struct hid_input, list);360233 input = hidinput->input;361234···422251423252static void wacom_remove(struct hid_device *hdev)424253{254254+#ifdef CONFIG_HID_WACOM_POWER_SUPPLY255255+ struct wacom_data *wdata = hid_get_drvdata(hdev);256256+#endif425257 hid_hw_stop(hdev);258258+259259+#ifdef CONFIG_HID_WACOM_POWER_SUPPLY260260+ power_supply_unregister(&wdata->battery);261261+ power_supply_unregister(&wdata->ac);262262+#endif426263 kfree(hid_get_drvdata(hdev));427264}428265429266static const struct hid_device_id wacom_devices[] = {430267 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },431431-268268+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },432269 { }433270};434271MODULE_DEVICE_TABLE(hid, wacom_devices);
+237
drivers/hid/hid-zydacron.c
···11+/*22+* HID driver for zydacron remote control33+*44+* Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>55+*/66+77+/*88+* This program is free software; you can redistribute it and/or modify it99+* under the terms of the GNU General Public License as published by the Free1010+* Software Foundation; either version 2 of the License, or (at your option)1111+* any later version.1212+*/1313+1414+#include <linux/device.h>1515+#include <linux/hid.h>1616+#include <linux/module.h>1717+1818+#include "hid-ids.h"1919+2020+struct zc_device {2121+ struct input_dev *input_ep81;2222+ unsigned short last_key[4];2323+};2424+2525+2626+/*2727+* Zydacron remote control has an invalid HID report descriptor,2828+* that needs fixing before we can parse it.2929+*/3030+static void zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,3131+ unsigned int rsize)3232+{3333+ if (rsize >= 253 &&3434+ rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff &&3535+ rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff &&3636+ rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) {3737+ dev_info(&hdev->dev,3838+ "fixing up zydacron remote control report "3939+ "descriptor\n");4040+ rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c;4141+ rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00;4242+ }4343+}4444+4545+#define zc_map_key_clear(c) \4646+ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))4747+4848+static int zc_input_mapping(struct hid_device *hdev, struct hid_input *hi,4949+ struct hid_field *field, struct hid_usage *usage,5050+ unsigned long **bit, int *max)5151+{5252+ int i;5353+ struct zc_device *zc = hid_get_drvdata(hdev);5454+ zc->input_ep81 = hi->input;5555+5656+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)5757+ return 0;5858+5959+ dbg_hid("zynacron input mapping event [0x%x]\n",6060+ usage->hid & HID_USAGE);6161+6262+ switch (usage->hid & HID_USAGE) {6363+ /* report 2 */6464+ case 0x10:6565+ zc_map_key_clear(KEY_MODE);6666+ break;6767+ case 0x30:6868+ zc_map_key_clear(KEY_SCREEN);6969+ break;7070+ case 0x70:7171+ zc_map_key_clear(KEY_INFO);7272+ break;7373+ /* report 3 */7474+ case 0x04:7575+ zc_map_key_clear(KEY_RADIO);7676+ break;7777+ /* report 4 */7878+ case 0x0d:7979+ zc_map_key_clear(KEY_PVR);8080+ break;8181+ case 0x25:8282+ zc_map_key_clear(KEY_TV);8383+ break;8484+ case 0x47:8585+ zc_map_key_clear(KEY_AUDIO);8686+ break;8787+ case 0x49:8888+ zc_map_key_clear(KEY_AUX);8989+ break;9090+ case 0x4a:9191+ zc_map_key_clear(KEY_VIDEO);9292+ break;9393+ case 0x48:9494+ zc_map_key_clear(KEY_DVD);9595+ break;9696+ case 0x24:9797+ zc_map_key_clear(KEY_MENU);9898+ break;9999+ case 0x32:100100+ zc_map_key_clear(KEY_TEXT);101101+ break;102102+ default:103103+ return 0;104104+ }105105+106106+ for (i = 0; i < 4; i++)107107+ zc->last_key[i] = 0;108108+109109+ return 1;110110+}111111+112112+static int zc_raw_event(struct hid_device *hdev, struct hid_report *report,113113+ u8 *data, int size)114114+{115115+ struct zc_device *zc = hid_get_drvdata(hdev);116116+ int ret = 0;117117+ unsigned key;118118+ unsigned short index;119119+120120+ if (report->id == data[0]) {121121+122122+ /* break keys */123123+ for (index = 0; index < 4; index++) {124124+ key = zc->last_key[index];125125+ if (key) {126126+ input_event(zc->input_ep81, EV_KEY, key, 0);127127+ zc->last_key[index] = 0;128128+ }129129+ }130130+131131+ key = 0;132132+ switch (report->id) {133133+ case 0x02:134134+ case 0x03:135135+ switch (data[1]) {136136+ case 0x10:137137+ key = KEY_MODE;138138+ index = 0;139139+ break;140140+ case 0x30:141141+ key = KEY_SCREEN;142142+ index = 1;143143+ break;144144+ case 0x70:145145+ key = KEY_INFO;146146+ index = 2;147147+ break;148148+ case 0x04:149149+ key = KEY_RADIO;150150+ index = 3;151151+ break;152152+ }153153+154154+ if (key) {155155+ input_event(zc->input_ep81, EV_KEY, key, 1);156156+ zc->last_key[index] = key;157157+ }158158+159159+ ret = 1;160160+ break;161161+ }162162+ }163163+164164+ return ret;165165+}166166+167167+static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id)168168+{169169+ int ret;170170+ struct zc_device *zc;171171+172172+ zc = kzalloc(sizeof(*zc), GFP_KERNEL);173173+ if (zc == NULL) {174174+ dev_err(&hdev->dev, "zydacron: can't alloc descriptor\n");175175+ return -ENOMEM;176176+ }177177+178178+ hid_set_drvdata(hdev, zc);179179+180180+ ret = hid_parse(hdev);181181+ if (ret) {182182+ dev_err(&hdev->dev, "zydacron: parse failed\n");183183+ goto err_free;184184+ }185185+186186+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);187187+ if (ret) {188188+ dev_err(&hdev->dev, "zydacron: hw start failed\n");189189+ goto err_free;190190+ }191191+192192+ return 0;193193+err_free:194194+ kfree(zc);195195+196196+ return ret;197197+}198198+199199+static void zc_remove(struct hid_device *hdev)200200+{201201+ struct zc_device *zc = hid_get_drvdata(hdev);202202+203203+ hid_hw_stop(hdev);204204+205205+ if (NULL != zc)206206+ kfree(zc);207207+}208208+209209+static const struct hid_device_id zc_devices[] = {210210+ { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },211211+ { }212212+};213213+MODULE_DEVICE_TABLE(hid, zc_devices);214214+215215+static struct hid_driver zc_driver = {216216+ .name = "zydacron",217217+ .id_table = zc_devices,218218+ .report_fixup = zc_report_fixup,219219+ .input_mapping = zc_input_mapping,220220+ .raw_event = zc_raw_event,221221+ .probe = zc_probe,222222+ .remove = zc_remove,223223+};224224+225225+static int __init zc_init(void)226226+{227227+ return hid_register_driver(&zc_driver);228228+}229229+230230+static void __exit zc_exit(void)231231+{232232+ hid_unregister_driver(&zc_driver);233233+}234234+235235+module_init(zc_init);236236+module_exit(zc_exit);237237+MODULE_LICENSE("GPL");
···807807 struct usb_host_interface *interface = intf->cur_altsetting;808808 int ret;809809810810- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),811811- HID_REQ_SET_REPORT,812812- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,813813- ((report_type + 1) << 8) | *buf,814814- interface->desc.bInterfaceNumber, buf + 1, count - 1,815815- USB_CTRL_SET_TIMEOUT);816816-817817- /* count also the report id */818818- if (ret > 0)819819- ret++;810810+ if (usbhid->urbout) {811811+ int actual_length;812812+ int skipped_report_id = 0;813813+ if (buf[0] == 0x0) {814814+ /* Don't send the Report ID */815815+ buf++;816816+ count--;817817+ skipped_report_id = 1;818818+ }819819+ ret = usb_interrupt_msg(dev, usbhid->urbout->pipe,820820+ buf, count, &actual_length,821821+ USB_CTRL_SET_TIMEOUT);822822+ /* return the number of bytes transferred */823823+ if (ret == 0) {824824+ ret = actual_length;825825+ /* count also the report id */826826+ if (skipped_report_id)827827+ ret++;828828+ }829829+ } else {830830+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),831831+ HID_REQ_SET_REPORT,832832+ USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,833833+ ((report_type + 1) << 8) | *buf,834834+ interface->desc.bInterfaceNumber, buf + 1, count - 1,835835+ USB_CTRL_SET_TIMEOUT);836836+ /* count also the report id */837837+ if (ret > 0)838838+ ret++;839839+ }820840821841 return ret;822842}···10391019 /* Some keyboards don't work until their LEDs have been set.10401020 * Since BIOSes do set the LEDs, it must be safe for any device10411021 * that supports the keyboard boot protocol.10221022+ * In addition, enable remote wakeup by default for all keyboard10231023+ * devices supporting the boot protocol.10421024 */10431025 if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT &&10441026 interface->desc.bInterfaceProtocol ==10451045- USB_INTERFACE_PROTOCOL_KEYBOARD)10271027+ USB_INTERFACE_PROTOCOL_KEYBOARD) {10461028 usbhid_set_leds(hid);10471047-10291029+ device_set_wakeup_enable(&dev->dev, 1);10301030+ }10481031 return 0;1049103210501033fail:···11561133 hid->vendor = le16_to_cpu(dev->descriptor.idVendor);11571134 hid->product = le16_to_cpu(dev->descriptor.idProduct);11581135 hid->name[0] = 0;11361136+ hid->quirks = usbhid_lookup_quirk(hid->vendor, hid->product);11591137 if (intf->cur_altsetting->desc.bInterfaceProtocol ==11601138 USB_INTERFACE_PROTOCOL_MOUSE)11611139 hid->type = HID_TYPE_USBMOUSE;
···308308#define HID_QUIRK_NOTOUCH 0x00000002309309#define HID_QUIRK_IGNORE 0x00000004310310#define HID_QUIRK_NOGET 0x00000008311311+#define HID_QUIRK_HIDDEV_FORCE 0x00000010311312#define HID_QUIRK_BADPAD 0x00000020312313#define HID_QUIRK_MULTI_INPUT 0x00000040313314#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000314315#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000315316#define HID_QUIRK_NO_INIT_REPORTS 0x20000000317317+#define HID_QUIRK_NO_IGNORE 0x40000000316318317319/*318320 * This is the global environment of the parser. This information is