aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig9
-rw-r--r--drivers/hid/Makefile5
-rw-r--r--drivers/hid/hid-apple.c3
-rw-r--r--drivers/hid/hid-core.c61
-rw-r--r--drivers/hid/hid-icade.c259
-rw-r--r--drivers/hid/hid-ids.h19
-rw-r--r--drivers/hid/hid-input.c97
-rw-r--r--drivers/hid/hid-multitouch.c109
-rw-r--r--drivers/hid/hid-roccat-isku.c44
-rw-r--r--drivers/hid/hid-roccat-isku.h78
-rw-r--r--drivers/hid/hid-roccat-koneplus.c348
-rw-r--r--drivers/hid/hid-roccat-koneplus.h101
-rw-r--r--drivers/hid/hid-roccat-kovaplus.c237
-rw-r--r--drivers/hid/hid-roccat-kovaplus.h16
-rw-r--r--drivers/hid/hid-roccat-lua.c227
-rw-r--r--drivers/hid/hid-roccat-lua.h29
-rw-r--r--drivers/hid/hid-roccat-pyra.c342
-rw-r--r--drivers/hid/hid-roccat-pyra.h24
-rw-r--r--drivers/hid/hid-roccat-savu.c4
-rw-r--r--drivers/hid/hid-sensor-hub.c36
-rw-r--r--drivers/hid/hidraw.c16
-rw-r--r--drivers/hid/usbhid/hid-quirks.c3
-rw-r--r--drivers/hid/usbhid/hiddev.c10
23 files changed, 1195 insertions, 882 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 95cfe9181bf2..e7d6a13ec6a6 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -265,6 +265,15 @@ config HID_GYRATION
265 ---help--- 265 ---help---
266 Support for Gyration remote control. 266 Support for Gyration remote control.
267 267
268config HID_ICADE
269 tristate "ION iCade arcade controller"
270 depends on BT_HIDP
271 ---help---
272 Support for the ION iCade arcade controller to work as a joystick.
273
274 To compile this driver as a module, choose M here: the
275 module will be called hid-icade.
276
268config HID_TWINHAN 277config HID_TWINHAN
269 tristate "Twinhan IR remote control" 278 tristate "Twinhan IR remote control"
270 depends on USB_HID 279 depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index a1a28befac72..b62215716b2f 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
52obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o 52obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o
53obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o 53obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
54obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o 54obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o
55obj-$(CONFIG_HID_ICADE) += hid-icade.o
55obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o 56obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
56obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o 57obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
57obj-$(CONFIG_HID_KYE) += hid-kye.o 58obj-$(CONFIG_HID_KYE) += hid-kye.o
@@ -93,8 +94,8 @@ obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
93obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o 94obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o
94obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ 95obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
95 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ 96 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
96 hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o \ 97 hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-lua.o \
97 hid-roccat-savu.o 98 hid-roccat-pyra.o hid-roccat-savu.o
98obj-$(CONFIG_HID_SAITEK) += hid-saitek.o 99obj-$(CONFIG_HID_SAITEK) += hid-saitek.o
99obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 100obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
100obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 101obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index fd7722aecf77..d0f7662aacca 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -439,7 +439,8 @@ static const struct hid_device_id apple_devices[] = {
439 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI), 439 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
440 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, 440 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
441 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO), 441 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
442 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, 442 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
443 APPLE_ISO_KEYBOARD },
443 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), 444 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
444 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | 445 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
445 APPLE_RDESC_JIS }, 446 APPLE_RDESC_JIS },
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index f4109fd657ff..eb2ee11b6412 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -92,6 +92,7 @@ EXPORT_SYMBOL_GPL(hid_register_report);
92static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) 92static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values)
93{ 93{
94 struct hid_field *field; 94 struct hid_field *field;
95 int i;
95 96
96 if (report->maxfield == HID_MAX_FIELDS) { 97 if (report->maxfield == HID_MAX_FIELDS) {
97 hid_err(report->device, "too many fields in report\n"); 98 hid_err(report->device, "too many fields in report\n");
@@ -110,6 +111,9 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
110 field->value = (s32 *)(field->usage + usages); 111 field->value = (s32 *)(field->usage + usages);
111 field->report = report; 112 field->report = report;
112 113
114 for (i = 0; i < usages; i++)
115 field->usage[i].usage_index = i;
116
113 return field; 117 return field;
114} 118}
115 119
@@ -315,6 +319,7 @@ static s32 item_sdata(struct hid_item *item)
315 319
316static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) 320static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
317{ 321{
322 __u32 raw_value;
318 switch (item->tag) { 323 switch (item->tag) {
319 case HID_GLOBAL_ITEM_TAG_PUSH: 324 case HID_GLOBAL_ITEM_TAG_PUSH:
320 325
@@ -365,7 +370,14 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
365 return 0; 370 return 0;
366 371
367 case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: 372 case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
368 parser->global.unit_exponent = item_sdata(item); 373 /* Units exponent negative numbers are given through a
374 * two's complement.
375 * See "6.2.2.7 Global Items" for more information. */
376 raw_value = item_udata(item);
377 if (!(raw_value & 0xfffffff0))
378 parser->global.unit_exponent = hid_snto32(raw_value, 4);
379 else
380 parser->global.unit_exponent = raw_value;
369 return 0; 381 return 0;
370 382
371 case HID_GLOBAL_ITEM_TAG_UNIT: 383 case HID_GLOBAL_ITEM_TAG_UNIT:
@@ -713,7 +725,12 @@ static int hid_scan_report(struct hid_device *hid)
713 hid_scan_usage(hid, u); 725 hid_scan_usage(hid, u);
714 break; 726 break;
715 } 727 }
716 } 728 } else if (page == HID_UP_SENSOR &&
729 item.type == HID_ITEM_TYPE_MAIN &&
730 item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION &&
731 (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL &&
732 hid->bus == BUS_USB)
733 hid->group = HID_GROUP_SENSOR_HUB;
717 } 734 }
718 735
719 return 0; 736 return 0;
@@ -865,6 +882,12 @@ static s32 snto32(__u32 value, unsigned n)
865 return value & (1 << (n - 1)) ? value | (-1 << n) : value; 882 return value & (1 << (n - 1)) ? value | (-1 << n) : value;
866} 883}
867 884
885s32 hid_snto32(__u32 value, unsigned n)
886{
887 return snto32(value, n);
888}
889EXPORT_SYMBOL_GPL(hid_snto32);
890
868/* 891/*
869 * Convert a signed 32-bit integer to a signed n-bit integer. 892 * Convert a signed 32-bit integer to a signed n-bit integer.
870 */ 893 */
@@ -1465,6 +1488,10 @@ EXPORT_SYMBOL_GPL(hid_disconnect);
1465 * there is a proper autodetection and autoloading in place (based on presence 1488 * there is a proper autodetection and autoloading in place (based on presence
1466 * of HID_DG_CONTACTID), so those devices don't need to be added to this list, 1489 * of HID_DG_CONTACTID), so those devices don't need to be added to this list,
1467 * as we are doing the right thing in hid_scan_usage(). 1490 * as we are doing the right thing in hid_scan_usage().
1491 *
1492 * Autodetection for (USB) HID sensor hubs exists too. If a collection of type
1493 * physical is found inside a usage page of type sensor, hid-sensor-hub will be
1494 * used as a driver. See hid_scan_report().
1468 */ 1495 */
1469static const struct hid_device_id hid_have_special_driver[] = { 1496static const struct hid_device_id hid_have_special_driver[] = {
1470 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, 1497 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
@@ -1538,6 +1565,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1538 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, 1565 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
1539 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, 1566 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
1540 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, 1567 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
1568 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) },
1541 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, 1569 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) },
1542 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1570 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1543 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1571 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
@@ -1571,10 +1599,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1571 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, 1599 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
1572 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, 1600 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
1573 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, 1601 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
1574 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_1020) }, 1602 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
1575 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_09FA) },
1576 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_1020) },
1577 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_09FA) },
1578 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, 1603 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
1579 { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, 1604 { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
1580 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, 1605 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
@@ -1658,6 +1683,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1658 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, 1683 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
1659 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, 1684 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
1660 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, 1685 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
1686 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
1661 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, 1687 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
1662 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, 1688 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
1663 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) }, 1689 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
@@ -1672,7 +1698,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
1672 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1698 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1673 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, 1699 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
1674 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, 1700 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
1675 { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_SENSOR_HUB_7014) },
1676 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, 1701 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
1677 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, 1702 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
1678 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, 1703 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
@@ -2150,8 +2175,13 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
2150 { } 2175 { }
2151}; 2176};
2152 2177
2153static bool hid_ignore(struct hid_device *hdev) 2178bool hid_ignore(struct hid_device *hdev)
2154{ 2179{
2180 if (hdev->quirks & HID_QUIRK_NO_IGNORE)
2181 return false;
2182 if (hdev->quirks & HID_QUIRK_IGNORE)
2183 return true;
2184
2155 switch (hdev->vendor) { 2185 switch (hdev->vendor) {
2156 case USB_VENDOR_ID_CODEMERCS: 2186 case USB_VENDOR_ID_CODEMERCS:
2157 /* ignore all Code Mercenaries IOWarrior devices */ 2187 /* ignore all Code Mercenaries IOWarrior devices */
@@ -2188,7 +2218,16 @@ static bool hid_ignore(struct hid_device *hdev)
2188 if (hdev->product == USB_DEVICE_ID_JESS_YUREX && 2218 if (hdev->product == USB_DEVICE_ID_JESS_YUREX &&
2189 hdev->type == HID_TYPE_USBNONE) 2219 hdev->type == HID_TYPE_USBNONE)
2190 return true; 2220 return true;
2191 break; 2221 break;
2222 case USB_VENDOR_ID_DWAV:
2223 /* These are handled by usbtouchscreen. hdev->type is probably
2224 * HID_TYPE_USBNONE, but we say !HID_TYPE_USBMOUSE to match
2225 * usbtouchscreen. */
2226 if ((hdev->product == USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER ||
2227 hdev->product == USB_DEVICE_ID_DWAV_TOUCHCONTROLLER) &&
2228 hdev->type != HID_TYPE_USBMOUSE)
2229 return true;
2230 break;
2192 } 2231 }
2193 2232
2194 if (hdev->type == HID_TYPE_USBMOUSE && 2233 if (hdev->type == HID_TYPE_USBMOUSE &&
@@ -2197,6 +2236,7 @@ static bool hid_ignore(struct hid_device *hdev)
2197 2236
2198 return !!hid_match_id(hdev, hid_ignore_list); 2237 return !!hid_match_id(hdev, hid_ignore_list);
2199} 2238}
2239EXPORT_SYMBOL_GPL(hid_ignore);
2200 2240
2201int hid_add_device(struct hid_device *hdev) 2241int hid_add_device(struct hid_device *hdev)
2202{ 2242{
@@ -2208,8 +2248,7 @@ int hid_add_device(struct hid_device *hdev)
2208 2248
2209 /* we need to kill them here, otherwise they will stay allocated to 2249 /* we need to kill them here, otherwise they will stay allocated to
2210 * wait for coming driver */ 2250 * wait for coming driver */
2211 if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) 2251 if (hid_ignore(hdev))
2212 && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE)))
2213 return -ENODEV; 2252 return -ENODEV;
2214 2253
2215 /* 2254 /*
diff --git a/drivers/hid/hid-icade.c b/drivers/hid/hid-icade.c
new file mode 100644
index 000000000000..1d6565e37ba3
--- /dev/null
+++ b/drivers/hid/hid-icade.c
@@ -0,0 +1,259 @@
1/*
2 * ION iCade input driver
3 *
4 * Copyright (c) 2012 Bastien Nocera <hadess@hadess.net>
5 * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/device.h>
16#include <linux/hid.h>
17#include <linux/module.h>
18
19#include "hid-ids.h"
20
21/*
22 * ↑ A C Y L
23 * ← →
24 * ↓ B X Z R
25 *
26 *
27 * UP ON,OFF = w,e
28 * RT ON,OFF = d,c
29 * DN ON,OFF = x,z
30 * LT ON,OFF = a,q
31 * A ON,OFF = y,t
32 * B ON,OFF = h,r
33 * C ON,OFF = u,f
34 * X ON,OFF = j,n
35 * Y ON,OFF = i,m
36 * Z ON,OFF = k,p
37 * L ON,OFF = o,g
38 * R ON,OFF = l,v
39 */
40
41/* The translation code uses HID usage instead of input layer
42 * keys. This code generates a lookup table that makes
43 * translation quick.
44 *
45 * #include <linux/input.h>
46 * #include <stdio.h>
47 * #include <assert.h>
48 *
49 * #define unk KEY_UNKNOWN
50 *
51 * < copy of hid_keyboard[] from hid-input.c >
52 *
53 * struct icade_key_translation {
54 * int from;
55 * const char *to;
56 * int press;
57 * };
58 *
59 * static const struct icade_key_translation icade_keys[] = {
60 * { KEY_W, "KEY_UP", 1 },
61 * { KEY_E, "KEY_UP", 0 },
62 * { KEY_D, "KEY_RIGHT", 1 },
63 * { KEY_C, "KEY_RIGHT", 0 },
64 * { KEY_X, "KEY_DOWN", 1 },
65 * { KEY_Z, "KEY_DOWN", 0 },
66 * { KEY_A, "KEY_LEFT", 1 },
67 * { KEY_Q, "KEY_LEFT", 0 },
68 * { KEY_Y, "BTN_A", 1 },
69 * { KEY_T, "BTN_A", 0 },
70 * { KEY_H, "BTN_B", 1 },
71 * { KEY_R, "BTN_B", 0 },
72 * { KEY_U, "BTN_C", 1 },
73 * { KEY_F, "BTN_C", 0 },
74 * { KEY_J, "BTN_X", 1 },
75 * { KEY_N, "BTN_X", 0 },
76 * { KEY_I, "BTN_Y", 1 },
77 * { KEY_M, "BTN_Y", 0 },
78 * { KEY_K, "BTN_Z", 1 },
79 * { KEY_P, "BTN_Z", 0 },
80 * { KEY_O, "BTN_THUMBL", 1 },
81 * { KEY_G, "BTN_THUMBL", 0 },
82 * { KEY_L, "BTN_THUMBR", 1 },
83 * { KEY_V, "BTN_THUMBR", 0 },
84 *
85 * { }
86 * };
87 *
88 * static int
89 * usage_for_key (int key)
90 * {
91 * int i;
92 * for (i = 0; i < 256; i++) {
93 * if (hid_keyboard[i] == key)
94 * return i;
95 * }
96 * assert(0);
97 * }
98 *
99 * int main (int argc, char **argv)
100 * {
101 * const struct icade_key_translation *trans;
102 * int max_usage = 0;
103 *
104 * for (trans = icade_keys; trans->from; trans++) {
105 * int usage = usage_for_key (trans->from);
106 * max_usage = usage > max_usage ? usage : max_usage;
107 * }
108 *
109 * printf ("#define ICADE_MAX_USAGE %d\n\n", max_usage);
110 * printf ("struct icade_key {\n");
111 * printf ("\tu16 to;\n");
112 * printf ("\tu8 press:1;\n");
113 * printf ("};\n\n");
114 * printf ("static const struct icade_key "
115 * "icade_usage_table[%d] = {\n", max_usage + 1);
116 * for (trans = icade_keys; trans->from; trans++) {
117 * printf ("\t[%d] = { %s, %d },\n",
118 * usage_for_key (trans->from), trans->to, trans->press);
119 * }
120 * printf ("};\n");
121 *
122 * return 0;
123 * }
124 */
125
126#define ICADE_MAX_USAGE 29
127
128struct icade_key {
129 u16 to;
130 u8 press:1;
131};
132
133static const struct icade_key icade_usage_table[30] = {
134 [26] = { KEY_UP, 1 },
135 [8] = { KEY_UP, 0 },
136 [7] = { KEY_RIGHT, 1 },
137 [6] = { KEY_RIGHT, 0 },
138 [27] = { KEY_DOWN, 1 },
139 [29] = { KEY_DOWN, 0 },
140 [4] = { KEY_LEFT, 1 },
141 [20] = { KEY_LEFT, 0 },
142 [28] = { BTN_A, 1 },
143 [23] = { BTN_A, 0 },
144 [11] = { BTN_B, 1 },
145 [21] = { BTN_B, 0 },
146 [24] = { BTN_C, 1 },
147 [9] = { BTN_C, 0 },
148 [13] = { BTN_X, 1 },
149 [17] = { BTN_X, 0 },
150 [12] = { BTN_Y, 1 },
151 [16] = { BTN_Y, 0 },
152 [14] = { BTN_Z, 1 },
153 [19] = { BTN_Z, 0 },
154 [18] = { BTN_THUMBL, 1 },
155 [10] = { BTN_THUMBL, 0 },
156 [15] = { BTN_THUMBR, 1 },
157 [25] = { BTN_THUMBR, 0 },
158};
159
160static const struct icade_key *icade_find_translation(u16 from)
161{
162 if (from < 0 || from > ICADE_MAX_USAGE)
163 return NULL;
164 return &icade_usage_table[from];
165}
166
167static int icade_event(struct hid_device *hdev, struct hid_field *field,
168 struct hid_usage *usage, __s32 value)
169{
170 const struct icade_key *trans;
171
172 if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
173 !usage->type)
174 return 0;
175
176 /* We ignore the fake key up, and act only on key down */
177 if (!value)
178 return 1;
179
180 trans = icade_find_translation(usage->hid & HID_USAGE);
181
182 if (!trans)
183 return 1;
184
185 input_event(field->hidinput->input, usage->type,
186 trans->to, trans->press);
187
188 return 1;
189}
190
191static int icade_input_mapping(struct hid_device *hdev, struct hid_input *hi,
192 struct hid_field *field, struct hid_usage *usage,
193 unsigned long **bit, int *max)
194{
195 const struct icade_key *trans;
196
197 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_KEYBOARD) {
198 trans = icade_find_translation(usage->hid & HID_USAGE);
199
200 if (!trans)
201 return -1;
202
203 hid_map_usage(hi, usage, bit, max, EV_KEY, trans->to);
204 set_bit(trans->to, hi->input->keybit);
205
206 return 1;
207 }
208
209 /* ignore others */
210 return -1;
211
212}
213
214static int icade_input_mapped(struct hid_device *hdev, struct hid_input *hi,
215 struct hid_field *field, struct hid_usage *usage,
216 unsigned long **bit, int *max)
217{
218 if (usage->type == EV_KEY)
219 set_bit(usage->type, hi->input->evbit);
220
221 return -1;
222}
223
224static const struct hid_device_id icade_devices[] = {
225 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
226
227 { }
228};
229MODULE_DEVICE_TABLE(hid, icade_devices);
230
231static struct hid_driver icade_driver = {
232 .name = "icade",
233 .id_table = icade_devices,
234 .event = icade_event,
235 .input_mapped = icade_input_mapped,
236 .input_mapping = icade_input_mapping,
237};
238
239static int __init icade_init(void)
240{
241 int ret;
242
243 ret = hid_register_driver(&icade_driver);
244 if (ret)
245 pr_err("can't register icade driver\n");
246
247 return ret;
248}
249
250static void __exit icade_exit(void)
251{
252 hid_unregister_driver(&icade_driver);
253}
254
255module_init(icade_init);
256module_exit(icade_exit);
257MODULE_LICENSE("GPL");
258MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
259MODULE_DESCRIPTION("ION iCade input driver");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 9d7a42857ea1..4dfa605e2d14 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -257,6 +257,7 @@
257 257
258#define USB_VENDOR_ID_DWAV 0x0eef 258#define USB_VENDOR_ID_DWAV 0x0eef
259#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 259#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
260#define USB_DEVICE_ID_DWAV_TOUCHCONTROLLER 0x0002
260#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d 261#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d
261#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e 262#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e
262#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207 263#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207
@@ -423,6 +424,9 @@
423#define USB_VENDOR_ID_ILITEK 0x222a 424#define USB_VENDOR_ID_ILITEK 0x222a
424#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 425#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001
425 426
427#define USB_VENDOR_ID_ION 0x15e4
428#define USB_DEVICE_ID_ICADE 0x0132
429
426#define USB_VENDOR_ID_HOLTEK 0x1241 430#define USB_VENDOR_ID_HOLTEK 0x1241
427#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015 431#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015
428 432
@@ -432,11 +436,6 @@
432#define USB_VENDOR_ID_IMATION 0x0718 436#define USB_VENDOR_ID_IMATION 0x0718
433#define USB_DEVICE_ID_DISC_STAKKA 0xd000 437#define USB_DEVICE_ID_DISC_STAKKA 0xd000
434 438
435#define USB_VENDOR_ID_INTEL_8086 0x8086
436#define USB_VENDOR_ID_INTEL_8087 0x8087
437#define USB_DEVICE_ID_SENSOR_HUB_1020 0x1020
438#define USB_DEVICE_ID_SENSOR_HUB_09FA 0x09FA
439
440#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 439#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615
441#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 440#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070
442 441
@@ -603,6 +602,7 @@
603 602
604#define USB_VENDOR_ID_NOVATEK 0x0603 603#define USB_VENDOR_ID_NOVATEK 0x0603
605#define USB_DEVICE_ID_NOVATEK_PCT 0x0600 604#define USB_DEVICE_ID_NOVATEK_PCT 0x0600
605#define USB_DEVICE_ID_NOVATEK_MOUSE 0x1602
606 606
607#define USB_VENDOR_ID_NTRIG 0x1b96 607#define USB_VENDOR_ID_NTRIG 0x1b96
608#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 608#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
@@ -677,7 +677,9 @@
677#define USB_DEVICE_ID_ROCCAT_ISKU 0x319c 677#define USB_DEVICE_ID_ROCCAT_ISKU 0x319c
678#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced 678#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
679#define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 679#define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51
680#define USB_DEVICE_ID_ROCCAT_KONEXTD 0x2e22
680#define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 681#define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50
682#define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e
681#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 683#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
682#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 684#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
683#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a 685#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a
@@ -696,6 +698,9 @@
696#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f 698#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f
697#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 699#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002
698 700
701#define USB_VENDOR_ID_SIGMATEL 0x066F
702#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780
703
699#define USB_VENDOR_ID_SKYCABLE 0x1223 704#define USB_VENDOR_ID_SKYCABLE 0x1223
700#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 705#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
701 706
@@ -714,7 +719,6 @@
714 719
715#define USB_VENDOR_ID_STANTUM_STM 0x0483 720#define USB_VENDOR_ID_STANTUM_STM 0x0483
716#define USB_DEVICE_ID_MTP_STM 0x3261 721#define USB_DEVICE_ID_MTP_STM 0x3261
717#define USB_DEVICE_ID_SENSOR_HUB_7014 0x7014
718 722
719#define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 723#define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403
720#define USB_DEVICE_ID_MTP_SITRONIX 0x5001 724#define USB_DEVICE_ID_MTP_SITRONIX 0x5001
@@ -762,6 +766,9 @@
762#define USB_VENDOR_ID_TOUCHPACK 0x1bfd 766#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
763#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 767#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
764 768
769#define USB_VENDOR_ID_TPV 0x25aa
770#define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN 0x8883
771
765#define USB_VENDOR_ID_TURBOX 0x062a 772#define USB_VENDOR_ID_TURBOX 0x062a
766#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 773#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
767#define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100 774#define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index d917c0d53685..21b196c394b1 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -192,7 +192,6 @@ static int hidinput_setkeycode(struct input_dev *dev,
192 return -EINVAL; 192 return -EINVAL;
193} 193}
194 194
195
196/** 195/**
197 * hidinput_calc_abs_res - calculate an absolute axis resolution 196 * hidinput_calc_abs_res - calculate an absolute axis resolution
198 * @field: the HID report field to calculate resolution for 197 * @field: the HID report field to calculate resolution for
@@ -208,7 +207,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
208 * Only exponent 1 length units are processed. Centimeters and inches are 207 * Only exponent 1 length units are processed. Centimeters and inches are
209 * converted to millimeters. Degrees are converted to radians. 208 * converted to millimeters. Degrees are converted to radians.
210 */ 209 */
211static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) 210__s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
212{ 211{
213 __s32 unit_exponent = field->unit_exponent; 212 __s32 unit_exponent = field->unit_exponent;
214 __s32 logical_extents = field->logical_maximum - 213 __s32 logical_extents = field->logical_maximum -
@@ -229,17 +228,29 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
229 case ABS_X: 228 case ABS_X:
230 case ABS_Y: 229 case ABS_Y:
231 case ABS_Z: 230 case ABS_Z:
232 if (field->unit == 0x11) { /* If centimeters */ 231 case ABS_MT_POSITION_X:
232 case ABS_MT_POSITION_Y:
233 case ABS_MT_TOOL_X:
234 case ABS_MT_TOOL_Y:
235 case ABS_MT_TOUCH_MAJOR:
236 case ABS_MT_TOUCH_MINOR:
237 if (field->unit & 0xffffff00) /* Not a length */
238 return 0;
239 unit_exponent += hid_snto32(field->unit >> 4, 4) - 1;
240 switch (field->unit & 0xf) {
241 case 0x1: /* If centimeters */
233 /* Convert to millimeters */ 242 /* Convert to millimeters */
234 unit_exponent += 1; 243 unit_exponent += 1;
235 } else if (field->unit == 0x13) { /* If inches */ 244 break;
245 case 0x3: /* If inches */
236 /* Convert to millimeters */ 246 /* Convert to millimeters */
237 prev = physical_extents; 247 prev = physical_extents;
238 physical_extents *= 254; 248 physical_extents *= 254;
239 if (physical_extents < prev) 249 if (physical_extents < prev)
240 return 0; 250 return 0;
241 unit_exponent -= 1; 251 unit_exponent -= 1;
242 } else { 252 break;
253 default:
243 return 0; 254 return 0;
244 } 255 }
245 break; 256 break;
@@ -281,8 +292,9 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
281 } 292 }
282 293
283 /* Calculate resolution */ 294 /* Calculate resolution */
284 return logical_extents / physical_extents; 295 return DIV_ROUND_CLOSEST(logical_extents, physical_extents);
285} 296}
297EXPORT_SYMBOL_GPL(hidinput_calc_abs_res);
286 298
287#ifdef CONFIG_HID_BATTERY_STRENGTH 299#ifdef CONFIG_HID_BATTERY_STRENGTH
288static enum power_supply_property hidinput_battery_props[] = { 300static enum power_supply_property hidinput_battery_props[] = {
@@ -299,6 +311,9 @@ static enum power_supply_property hidinput_battery_props[] = {
299 311
300static const struct hid_device_id hid_battery_quirks[] = { 312static const struct hid_device_id hid_battery_quirks[] = {
301 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 313 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
314 USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
315 HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
316 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
302 USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), 317 USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
303 HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, 318 HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
304 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 319 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
@@ -502,9 +517,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
502 if (code <= 0xf) 517 if (code <= 0xf)
503 code += BTN_JOYSTICK; 518 code += BTN_JOYSTICK;
504 else 519 else
505 code += BTN_TRIGGER_HAPPY; 520 code += BTN_TRIGGER_HAPPY - 0x10;
521 break;
522 case HID_GD_GAMEPAD:
523 if (code <= 0xf)
524 code += BTN_GAMEPAD;
525 else
526 code += BTN_TRIGGER_HAPPY - 0x10;
506 break; 527 break;
507 case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break;
508 default: 528 default:
509 switch (field->physical) { 529 switch (field->physical) {
510 case HID_GD_MOUSE: 530 case HID_GD_MOUSE:
@@ -1146,6 +1166,38 @@ static void report_features(struct hid_device *hid)
1146 } 1166 }
1147} 1167}
1148 1168
1169static struct hid_input *hidinput_allocate(struct hid_device *hid)
1170{
1171 struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
1172 struct input_dev *input_dev = input_allocate_device();
1173 if (!hidinput || !input_dev) {
1174 kfree(hidinput);
1175 input_free_device(input_dev);
1176 hid_err(hid, "Out of memory during hid input probe\n");
1177 return NULL;
1178 }
1179
1180 input_set_drvdata(input_dev, hid);
1181 input_dev->event = hid->ll_driver->hidinput_input_event;
1182 input_dev->open = hidinput_open;
1183 input_dev->close = hidinput_close;
1184 input_dev->setkeycode = hidinput_setkeycode;
1185 input_dev->getkeycode = hidinput_getkeycode;
1186
1187 input_dev->name = hid->name;
1188 input_dev->phys = hid->phys;
1189 input_dev->uniq = hid->uniq;
1190 input_dev->id.bustype = hid->bus;
1191 input_dev->id.vendor = hid->vendor;
1192 input_dev->id.product = hid->product;
1193 input_dev->id.version = hid->version;
1194 input_dev->dev.parent = hid->dev.parent;
1195 hidinput->input = input_dev;
1196 list_add_tail(&hidinput->list, &hid->inputs);
1197
1198 return hidinput;
1199}
1200
1149/* 1201/*
1150 * Register the input device; print a message. 1202 * Register the input device; print a message.
1151 * Configure the input layer interface 1203 * Configure the input layer interface
@@ -1157,7 +1209,6 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
1157 struct hid_driver *drv = hid->driver; 1209 struct hid_driver *drv = hid->driver;
1158 struct hid_report *report; 1210 struct hid_report *report;
1159 struct hid_input *hidinput = NULL; 1211 struct hid_input *hidinput = NULL;
1160 struct input_dev *input_dev;
1161 int i, j, k; 1212 int i, j, k;
1162 1213
1163 INIT_LIST_HEAD(&hid->inputs); 1214 INIT_LIST_HEAD(&hid->inputs);
@@ -1188,33 +1239,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
1188 continue; 1239 continue;
1189 1240
1190 if (!hidinput) { 1241 if (!hidinput) {
1191 hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); 1242 hidinput = hidinput_allocate(hid);
1192 input_dev = input_allocate_device(); 1243 if (!hidinput)
1193 if (!hidinput || !input_dev) {
1194 kfree(hidinput);
1195 input_free_device(input_dev);
1196 hid_err(hid, "Out of memory during hid input probe\n");
1197 goto out_unwind; 1244 goto out_unwind;
1198 }
1199
1200 input_set_drvdata(input_dev, hid);
1201 input_dev->event =
1202 hid->ll_driver->hidinput_input_event;
1203 input_dev->open = hidinput_open;
1204 input_dev->close = hidinput_close;
1205 input_dev->setkeycode = hidinput_setkeycode;
1206 input_dev->getkeycode = hidinput_getkeycode;
1207
1208 input_dev->name = hid->name;
1209 input_dev->phys = hid->phys;
1210 input_dev->uniq = hid->uniq;
1211 input_dev->id.bustype = hid->bus;
1212 input_dev->id.vendor = hid->vendor;
1213 input_dev->id.product = hid->product;
1214 input_dev->id.version = hid->version;
1215 input_dev->dev.parent = hid->dev.parent;
1216 hidinput->input = input_dev;
1217 list_add_tail(&hidinput->list, &hid->inputs);
1218 } 1245 }
1219 1246
1220 for (i = 0; i < report->maxfield; i++) 1247 for (i = 0; i < report->maxfield; i++)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 7867d69f0efe..61543c02ea0b 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -52,11 +52,14 @@ MODULE_LICENSE("GPL");
52#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6) 52#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6)
53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8) 53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8)
54#define MT_QUIRK_NO_AREA (1 << 9) 54#define MT_QUIRK_NO_AREA (1 << 9)
55#define MT_QUIRK_IGNORE_DUPLICATES (1 << 10)
56#define MT_QUIRK_HOVERING (1 << 11)
55 57
56struct mt_slot { 58struct mt_slot {
57 __s32 x, y, p, w, h; 59 __s32 x, y, cx, cy, p, w, h;
58 __s32 contactid; /* the device ContactID assigned to this slot */ 60 __s32 contactid; /* the device ContactID assigned to this slot */
59 bool touch_state; /* is the touch valid? */ 61 bool touch_state; /* is the touch valid? */
62 bool inrange_state; /* is the finger in proximity of the sensor? */
60}; 63};
61 64
62struct mt_class { 65struct mt_class {
@@ -121,6 +124,7 @@ struct mt_device {
121#define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109 124#define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109
122 125
123#define MT_DEFAULT_MAXCONTACT 10 126#define MT_DEFAULT_MAXCONTACT 10
127#define MT_MAX_MAXCONTACT 250
124 128
125#define MT_USB_DEVICE(v, p) HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH, v, p) 129#define MT_USB_DEVICE(v, p) HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH, v, p)
126#define MT_BT_DEVICE(v, p) HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH, v, p) 130#define MT_BT_DEVICE(v, p) HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH, v, p)
@@ -282,11 +286,26 @@ static void mt_feature_mapping(struct hid_device *hdev,
282 case HID_DG_CONTACTMAX: 286 case HID_DG_CONTACTMAX:
283 td->maxcontact_report_id = field->report->id; 287 td->maxcontact_report_id = field->report->id;
284 td->maxcontacts = field->value[0]; 288 td->maxcontacts = field->value[0];
289 if (!td->maxcontacts &&
290 field->logical_maximum <= MT_MAX_MAXCONTACT)
291 td->maxcontacts = field->logical_maximum;
285 if (td->mtclass.maxcontacts) 292 if (td->mtclass.maxcontacts)
286 /* check if the maxcontacts is given by the class */ 293 /* check if the maxcontacts is given by the class */
287 td->maxcontacts = td->mtclass.maxcontacts; 294 td->maxcontacts = td->mtclass.maxcontacts;
288 295
289 break; 296 break;
297 case 0xff0000c5:
298 if (field->report_count == 256 && field->report_size == 8) {
299 /* Win 8 devices need special quirks */
300 __s32 *quirks = &td->mtclass.quirks;
301 *quirks |= MT_QUIRK_ALWAYS_VALID;
302 *quirks |= MT_QUIRK_IGNORE_DUPLICATES;
303 *quirks |= MT_QUIRK_HOVERING;
304 *quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP;
305 *quirks &= ~MT_QUIRK_VALID_IS_INRANGE;
306 *quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE;
307 }
308 break;
290 } 309 }
291} 310}
292 311
@@ -297,6 +316,7 @@ static void set_abs(struct input_dev *input, unsigned int code,
297 int fmax = field->logical_maximum; 316 int fmax = field->logical_maximum;
298 int fuzz = snratio ? (fmax - fmin) / snratio : 0; 317 int fuzz = snratio ? (fmax - fmin) / snratio : 0;
299 input_set_abs_params(input, code, fmin, fmax, fuzz, 0); 318 input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
319 input_abs_set_res(input, code, hidinput_calc_abs_res(field, code));
300} 320}
301 321
302static void mt_store_field(struct hid_usage *usage, struct mt_device *td, 322static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
@@ -317,6 +337,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
317 struct mt_device *td = hid_get_drvdata(hdev); 337 struct mt_device *td = hid_get_drvdata(hdev);
318 struct mt_class *cls = &td->mtclass; 338 struct mt_class *cls = &td->mtclass;
319 int code; 339 int code;
340 struct hid_usage *prev_usage = NULL;
320 341
321 /* Only map fields from TouchScreen or TouchPad collections. 342 /* Only map fields from TouchScreen or TouchPad collections.
322 * We need to ignore fields that belong to other collections 343 * We need to ignore fields that belong to other collections
@@ -339,23 +360,42 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
339 if (field->physical == HID_DG_STYLUS) 360 if (field->physical == HID_DG_STYLUS)
340 return -1; 361 return -1;
341 362
363 if (usage->usage_index)
364 prev_usage = &field->usage[usage->usage_index - 1];
365
342 switch (usage->hid & HID_USAGE_PAGE) { 366 switch (usage->hid & HID_USAGE_PAGE) {
343 367
344 case HID_UP_GENDESK: 368 case HID_UP_GENDESK:
345 switch (usage->hid) { 369 switch (usage->hid) {
346 case HID_GD_X: 370 case HID_GD_X:
347 hid_map_usage(hi, usage, bit, max, 371 if (prev_usage && (prev_usage->hid == usage->hid)) {
372 hid_map_usage(hi, usage, bit, max,
373 EV_ABS, ABS_MT_TOOL_X);
374 set_abs(hi->input, ABS_MT_TOOL_X, field,
375 cls->sn_move);
376 } else {
377 hid_map_usage(hi, usage, bit, max,
348 EV_ABS, ABS_MT_POSITION_X); 378 EV_ABS, ABS_MT_POSITION_X);
349 set_abs(hi->input, ABS_MT_POSITION_X, field, 379 set_abs(hi->input, ABS_MT_POSITION_X, field,
350 cls->sn_move); 380 cls->sn_move);
381 }
382
351 mt_store_field(usage, td, hi); 383 mt_store_field(usage, td, hi);
352 td->last_field_index = field->index; 384 td->last_field_index = field->index;
353 return 1; 385 return 1;
354 case HID_GD_Y: 386 case HID_GD_Y:
355 hid_map_usage(hi, usage, bit, max, 387 if (prev_usage && (prev_usage->hid == usage->hid)) {
388 hid_map_usage(hi, usage, bit, max,
389 EV_ABS, ABS_MT_TOOL_Y);
390 set_abs(hi->input, ABS_MT_TOOL_Y, field,
391 cls->sn_move);
392 } else {
393 hid_map_usage(hi, usage, bit, max,
356 EV_ABS, ABS_MT_POSITION_Y); 394 EV_ABS, ABS_MT_POSITION_Y);
357 set_abs(hi->input, ABS_MT_POSITION_Y, field, 395 set_abs(hi->input, ABS_MT_POSITION_Y, field,
358 cls->sn_move); 396 cls->sn_move);
397 }
398
359 mt_store_field(usage, td, hi); 399 mt_store_field(usage, td, hi);
360 td->last_field_index = field->index; 400 td->last_field_index = field->index;
361 return 1; 401 return 1;
@@ -365,6 +405,12 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
365 case HID_UP_DIGITIZER: 405 case HID_UP_DIGITIZER:
366 switch (usage->hid) { 406 switch (usage->hid) {
367 case HID_DG_INRANGE: 407 case HID_DG_INRANGE:
408 if (cls->quirks & MT_QUIRK_HOVERING) {
409 hid_map_usage(hi, usage, bit, max,
410 EV_ABS, ABS_MT_DISTANCE);
411 input_set_abs_params(hi->input,
412 ABS_MT_DISTANCE, 0, 1, 0, 0);
413 }
368 mt_store_field(usage, td, hi); 414 mt_store_field(usage, td, hi);
369 td->last_field_index = field->index; 415 td->last_field_index = field->index;
370 return 1; 416 return 1;
@@ -477,18 +523,26 @@ static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
477 */ 523 */
478static void mt_complete_slot(struct mt_device *td, struct input_dev *input) 524static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
479{ 525{
480 if (td->curvalid) { 526 if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) {
481 int slotnum = mt_compute_slot(td, input); 527 int slotnum = mt_compute_slot(td, input);
482 struct mt_slot *s = &td->curdata; 528 struct mt_slot *s = &td->curdata;
529 struct input_mt *mt = input->mt;
483 530
484 if (slotnum < 0 || slotnum >= td->maxcontacts) 531 if (slotnum < 0 || slotnum >= td->maxcontacts)
485 return; 532 return;
486 533
534 if ((td->mtclass.quirks & MT_QUIRK_IGNORE_DUPLICATES) && mt) {
535 struct input_mt_slot *slot = &mt->slots[slotnum];
536 if (input_mt_is_active(slot) &&
537 input_mt_is_used(mt, slot))
538 return;
539 }
540
487 input_mt_slot(input, slotnum); 541 input_mt_slot(input, slotnum);
488 input_mt_report_slot_state(input, MT_TOOL_FINGER, 542 input_mt_report_slot_state(input, MT_TOOL_FINGER,
489 s->touch_state); 543 s->touch_state || s->inrange_state);
490 if (s->touch_state) { 544 if (s->touch_state || s->inrange_state) {
491 /* this finger is on the screen */ 545 /* this finger is in proximity of the sensor */
492 int wide = (s->w > s->h); 546 int wide = (s->w > s->h);
493 /* divided by two to match visual scale of touch */ 547 /* divided by two to match visual scale of touch */
494 int major = max(s->w, s->h) >> 1; 548 int major = max(s->w, s->h) >> 1;
@@ -496,6 +550,10 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
496 550
497 input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); 551 input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
498 input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); 552 input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
553 input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx);
554 input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
555 input_event(input, EV_ABS, ABS_MT_DISTANCE,
556 !s->touch_state);
499 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 557 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
500 input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); 558 input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
501 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 559 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
@@ -526,10 +584,10 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
526 if (hid->claimed & HID_CLAIMED_INPUT) { 584 if (hid->claimed & HID_CLAIMED_INPUT) {
527 switch (usage->hid) { 585 switch (usage->hid) {
528 case HID_DG_INRANGE: 586 case HID_DG_INRANGE:
529 if (quirks & MT_QUIRK_ALWAYS_VALID) 587 if (quirks & MT_QUIRK_VALID_IS_INRANGE)
530 td->curvalid = true;
531 else if (quirks & MT_QUIRK_VALID_IS_INRANGE)
532 td->curvalid = value; 588 td->curvalid = value;
589 if (quirks & MT_QUIRK_HOVERING)
590 td->curdata.inrange_state = value;
533 break; 591 break;
534 case HID_DG_TIPSWITCH: 592 case HID_DG_TIPSWITCH:
535 if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) 593 if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
@@ -547,10 +605,16 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
547 td->curdata.p = value; 605 td->curdata.p = value;
548 break; 606 break;
549 case HID_GD_X: 607 case HID_GD_X:
550 td->curdata.x = value; 608 if (usage->code == ABS_MT_TOOL_X)
609 td->curdata.cx = value;
610 else
611 td->curdata.x = value;
551 break; 612 break;
552 case HID_GD_Y: 613 case HID_GD_Y:
553 td->curdata.y = value; 614 if (usage->code == ABS_MT_TOOL_Y)
615 td->curdata.cy = value;
616 else
617 td->curdata.y = value;
554 break; 618 break;
555 case HID_DG_WIDTH: 619 case HID_DG_WIDTH:
556 td->curdata.w = value; 620 td->curdata.w = value;
@@ -575,12 +639,15 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
575 return 0; 639 return 0;
576 } 640 }
577 641
578 if (usage->hid == td->last_slot_field) 642 if (usage->usage_index + 1 == field->report_count) {
579 mt_complete_slot(td, field->hidinput->input); 643 /* we only take into account the last report. */
644 if (usage->hid == td->last_slot_field)
645 mt_complete_slot(td, field->hidinput->input);
580 646
581 if (field->index == td->last_field_index 647 if (field->index == td->last_field_index
582 && td->num_received >= td->num_expected) 648 && td->num_received >= td->num_expected)
583 mt_sync_frame(td, field->hidinput->input); 649 mt_sync_frame(td, field->hidinput->input);
650 }
584 651
585 } 652 }
586 653
diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c
index 5669916c2943..1219998a02d6 100644
--- a/drivers/hid/hid-roccat-isku.c
+++ b/drivers/hid/hid-roccat-isku.c
@@ -167,7 +167,7 @@ static ssize_t isku_sysfs_write_ ## thingy(struct file *fp, struct kobject *kobj
167 loff_t off, size_t count) \ 167 loff_t off, size_t count) \
168{ \ 168{ \
169 return isku_sysfs_write(fp, kobj, buf, off, count, \ 169 return isku_sysfs_write(fp, kobj, buf, off, count, \
170 sizeof(struct isku_ ## thingy), ISKU_COMMAND_ ## THINGY); \ 170 ISKU_SIZE_ ## THINGY, ISKU_COMMAND_ ## THINGY); \
171} 171}
172 172
173#define ISKU_SYSFS_R(thingy, THINGY) \ 173#define ISKU_SYSFS_R(thingy, THINGY) \
@@ -176,32 +176,32 @@ static ssize_t isku_sysfs_read_ ## thingy(struct file *fp, struct kobject *kobj,
176 loff_t off, size_t count) \ 176 loff_t off, size_t count) \
177{ \ 177{ \
178 return isku_sysfs_read(fp, kobj, buf, off, count, \ 178 return isku_sysfs_read(fp, kobj, buf, off, count, \
179 sizeof(struct isku_ ## thingy), ISKU_COMMAND_ ## THINGY); \ 179 ISKU_SIZE_ ## THINGY, ISKU_COMMAND_ ## THINGY); \
180} 180}
181 181
182#define ISKU_SYSFS_RW(thingy, THINGY) \ 182#define ISKU_SYSFS_RW(thingy, THINGY) \
183ISKU_SYSFS_R(thingy, THINGY) \ 183ISKU_SYSFS_R(thingy, THINGY) \
184ISKU_SYSFS_W(thingy, THINGY) 184ISKU_SYSFS_W(thingy, THINGY)
185 185
186#define ISKU_BIN_ATTR_RW(thingy) \ 186#define ISKU_BIN_ATTR_RW(thingy, THINGY) \
187{ \ 187{ \
188 .attr = { .name = #thingy, .mode = 0660 }, \ 188 .attr = { .name = #thingy, .mode = 0660 }, \
189 .size = sizeof(struct isku_ ## thingy), \ 189 .size = ISKU_SIZE_ ## THINGY, \
190 .read = isku_sysfs_read_ ## thingy, \ 190 .read = isku_sysfs_read_ ## thingy, \
191 .write = isku_sysfs_write_ ## thingy \ 191 .write = isku_sysfs_write_ ## thingy \
192} 192}
193 193
194#define ISKU_BIN_ATTR_R(thingy) \ 194#define ISKU_BIN_ATTR_R(thingy, THINGY) \
195{ \ 195{ \
196 .attr = { .name = #thingy, .mode = 0440 }, \ 196 .attr = { .name = #thingy, .mode = 0440 }, \
197 .size = sizeof(struct isku_ ## thingy), \ 197 .size = ISKU_SIZE_ ## THINGY, \
198 .read = isku_sysfs_read_ ## thingy, \ 198 .read = isku_sysfs_read_ ## thingy, \
199} 199}
200 200
201#define ISKU_BIN_ATTR_W(thingy) \ 201#define ISKU_BIN_ATTR_W(thingy, THINGY) \
202{ \ 202{ \
203 .attr = { .name = #thingy, .mode = 0220 }, \ 203 .attr = { .name = #thingy, .mode = 0220 }, \
204 .size = sizeof(struct isku_ ## thingy), \ 204 .size = ISKU_SIZE_ ## THINGY, \
205 .write = isku_sysfs_write_ ## thingy \ 205 .write = isku_sysfs_write_ ## thingy \
206} 206}
207 207
@@ -218,21 +218,23 @@ ISKU_SYSFS_RW(last_set, LAST_SET)
218ISKU_SYSFS_W(talk, TALK) 218ISKU_SYSFS_W(talk, TALK)
219ISKU_SYSFS_R(info, INFO) 219ISKU_SYSFS_R(info, INFO)
220ISKU_SYSFS_W(control, CONTROL) 220ISKU_SYSFS_W(control, CONTROL)
221ISKU_SYSFS_W(reset, RESET)
221 222
222static struct bin_attribute isku_bin_attributes[] = { 223static struct bin_attribute isku_bin_attributes[] = {
223 ISKU_BIN_ATTR_RW(macro), 224 ISKU_BIN_ATTR_RW(macro, MACRO),
224 ISKU_BIN_ATTR_RW(keys_function), 225 ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION),
225 ISKU_BIN_ATTR_RW(keys_easyzone), 226 ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE),
226 ISKU_BIN_ATTR_RW(keys_media), 227 ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA),
227 ISKU_BIN_ATTR_RW(keys_thumbster), 228 ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER),
228 ISKU_BIN_ATTR_RW(keys_macro), 229 ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO),
229 ISKU_BIN_ATTR_RW(keys_capslock), 230 ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK),
230 ISKU_BIN_ATTR_RW(light), 231 ISKU_BIN_ATTR_RW(light, LIGHT),
231 ISKU_BIN_ATTR_RW(key_mask), 232 ISKU_BIN_ATTR_RW(key_mask, KEY_MASK),
232 ISKU_BIN_ATTR_RW(last_set), 233 ISKU_BIN_ATTR_RW(last_set, LAST_SET),
233 ISKU_BIN_ATTR_W(talk), 234 ISKU_BIN_ATTR_W(talk, TALK),
234 ISKU_BIN_ATTR_R(info), 235 ISKU_BIN_ATTR_R(info, INFO),
235 ISKU_BIN_ATTR_W(control), 236 ISKU_BIN_ATTR_W(control, CONTROL),
237 ISKU_BIN_ATTR_W(reset, RESET),
236 __ATTR_NULL 238 __ATTR_NULL
237}; 239};
238 240
diff --git a/drivers/hid/hid-roccat-isku.h b/drivers/hid/hid-roccat-isku.h
index 605b3ce21638..cf6896c83867 100644
--- a/drivers/hid/hid-roccat-isku.h
+++ b/drivers/hid/hid-roccat-isku.h
@@ -15,76 +15,33 @@
15#include <linux/types.h> 15#include <linux/types.h>
16 16
17enum { 17enum {
18 ISKU_SIZE_CONTROL = 0x03,
19 ISKU_SIZE_INFO = 0x06,
20 ISKU_SIZE_KEY_MASK = 0x06,
21 ISKU_SIZE_KEYS_FUNCTION = 0x29,
22 ISKU_SIZE_KEYS_EASYZONE = 0x41,
23 ISKU_SIZE_KEYS_MEDIA = 0x1d,
24 ISKU_SIZE_KEYS_THUMBSTER = 0x17,
25 ISKU_SIZE_KEYS_MACRO = 0x23,
26 ISKU_SIZE_KEYS_CAPSLOCK = 0x06,
27 ISKU_SIZE_LAST_SET = 0x14,
28 ISKU_SIZE_LIGHT = 0x0a,
29 ISKU_SIZE_MACRO = 0x823,
30 ISKU_SIZE_RESET = 0x03,
31 ISKU_SIZE_TALK = 0x10,
32};
33
34enum {
18 ISKU_PROFILE_NUM = 5, 35 ISKU_PROFILE_NUM = 5,
19 ISKU_USB_INTERFACE_PROTOCOL = 0, 36 ISKU_USB_INTERFACE_PROTOCOL = 0,
20}; 37};
21 38
22struct isku_control {
23 uint8_t command; /* ISKU_COMMAND_CONTROL */
24 uint8_t value;
25 uint8_t request;
26} __packed;
27
28struct isku_actual_profile { 39struct isku_actual_profile {
29 uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */ 40 uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */
30 uint8_t size; /* always 3 */ 41 uint8_t size; /* always 3 */
31 uint8_t actual_profile; 42 uint8_t actual_profile;
32} __packed; 43} __packed;
33 44
34struct isku_key_mask {
35 uint8_t command; /* ISKU_COMMAND_KEY_MASK */
36 uint8_t size; /* 6 */
37 uint8_t profile_number; /* 0-4 */
38 uint8_t mask;
39 uint16_t checksum;
40} __packed;
41
42struct isku_keys_function {
43 uint8_t data[0x29];
44} __packed;
45
46struct isku_keys_easyzone {
47 uint8_t data[0x41];
48} __packed;
49
50struct isku_keys_media {
51 uint8_t data[0x1d];
52} __packed;
53
54struct isku_keys_thumbster {
55 uint8_t data[0x17];
56} __packed;
57
58struct isku_keys_macro {
59 uint8_t data[0x23];
60} __packed;
61
62struct isku_keys_capslock {
63 uint8_t data[0x6];
64} __packed;
65
66struct isku_macro {
67 uint8_t data[0x823];
68} __packed;
69
70struct isku_light {
71 uint8_t data[0xa];
72} __packed;
73
74struct isku_info {
75 uint8_t data[2];
76 uint8_t firmware_version;
77 uint8_t unknown[3];
78} __packed;
79
80struct isku_talk {
81 uint8_t data[0x10];
82} __packed;
83
84struct isku_last_set {
85 uint8_t data[0x14];
86} __packed;
87
88enum isku_commands { 45enum isku_commands {
89 ISKU_COMMAND_CONTROL = 0x4, 46 ISKU_COMMAND_CONTROL = 0x4,
90 ISKU_COMMAND_ACTUAL_PROFILE = 0x5, 47 ISKU_COMMAND_ACTUAL_PROFILE = 0x5,
@@ -97,6 +54,7 @@ enum isku_commands {
97 ISKU_COMMAND_MACRO = 0xe, 54 ISKU_COMMAND_MACRO = 0xe,
98 ISKU_COMMAND_INFO = 0xf, 55 ISKU_COMMAND_INFO = 0xf,
99 ISKU_COMMAND_LIGHT = 0x10, 56 ISKU_COMMAND_LIGHT = 0x10,
57 ISKU_COMMAND_RESET = 0x11,
100 ISKU_COMMAND_KEYS_CAPSLOCK = 0x13, 58 ISKU_COMMAND_KEYS_CAPSLOCK = 0x13,
101 ISKU_COMMAND_LAST_SET = 0x14, 59 ISKU_COMMAND_LAST_SET = 0x14,
102 ISKU_COMMAND_15 = 0x15, 60 ISKU_COMMAND_15 = 0x15,
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c
index f5602fec4865..6a48fa3c7da9 100644
--- a/drivers/hid/hid-roccat-koneplus.c
+++ b/drivers/hid/hid-roccat-koneplus.c
@@ -14,6 +14,7 @@
14/* 14/*
15 * Roccat Kone[+] is an updated/improved version of the Kone with more memory 15 * Roccat Kone[+] is an updated/improved version of the Kone with more memory
16 * and functionality and without the non-standard behaviours the Kone had. 16 * and functionality and without the non-standard behaviours the Kone had.
17 * KoneXTD has same capabilities but updated sensor.
17 */ 18 */
18 19
19#include <linux/device.h> 20#include <linux/device.h>
@@ -55,56 +56,6 @@ static int koneplus_send_control(struct usb_device *usb_dev, uint value,
55 &control, sizeof(struct roccat_common2_control)); 56 &control, sizeof(struct roccat_common2_control));
56} 57}
57 58
58static int koneplus_get_info(struct usb_device *usb_dev,
59 struct koneplus_info *buf)
60{
61 return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO,
62 buf, sizeof(struct koneplus_info));
63}
64
65static int koneplus_get_profile_settings(struct usb_device *usb_dev,
66 struct koneplus_profile_settings *buf, uint number)
67{
68 int retval;
69
70 retval = koneplus_send_control(usb_dev, number,
71 KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
72 if (retval)
73 return retval;
74
75 return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS,
76 buf, sizeof(struct koneplus_profile_settings));
77}
78
79static int koneplus_set_profile_settings(struct usb_device *usb_dev,
80 struct koneplus_profile_settings const *settings)
81{
82 return roccat_common2_send_with_status(usb_dev,
83 KONEPLUS_COMMAND_PROFILE_SETTINGS,
84 settings, sizeof(struct koneplus_profile_settings));
85}
86
87static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
88 struct koneplus_profile_buttons *buf, int number)
89{
90 int retval;
91
92 retval = koneplus_send_control(usb_dev, number,
93 KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
94 if (retval)
95 return retval;
96
97 return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS,
98 buf, sizeof(struct koneplus_profile_buttons));
99}
100
101static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
102 struct koneplus_profile_buttons const *buttons)
103{
104 return roccat_common2_send_with_status(usb_dev,
105 KONEPLUS_COMMAND_PROFILE_BUTTONS,
106 buttons, sizeof(struct koneplus_profile_buttons));
107}
108 59
109/* retval is 0-4 on success, < 0 on error */ 60/* retval is 0-4 on success, < 0 on error */
110static int koneplus_get_actual_profile(struct usb_device *usb_dev) 61static int koneplus_get_actual_profile(struct usb_device *usb_dev)
@@ -113,7 +64,7 @@ static int koneplus_get_actual_profile(struct usb_device *usb_dev)
113 int retval; 64 int retval;
114 65
115 retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, 66 retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE,
116 &buf, sizeof(struct koneplus_actual_profile)); 67 &buf, KONEPLUS_SIZE_ACTUAL_PROFILE);
117 68
118 return retval ? retval : buf.actual_profile; 69 return retval ? retval : buf.actual_profile;
119} 70}
@@ -124,12 +75,12 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev,
124 struct koneplus_actual_profile buf; 75 struct koneplus_actual_profile buf;
125 76
126 buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE; 77 buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE;
127 buf.size = sizeof(struct koneplus_actual_profile); 78 buf.size = KONEPLUS_SIZE_ACTUAL_PROFILE;
128 buf.actual_profile = new_profile; 79 buf.actual_profile = new_profile;
129 80
130 return roccat_common2_send_with_status(usb_dev, 81 return roccat_common2_send_with_status(usb_dev,
131 KONEPLUS_COMMAND_ACTUAL_PROFILE, 82 KONEPLUS_COMMAND_ACTUAL_PROFILE,
132 &buf, sizeof(struct koneplus_actual_profile)); 83 &buf, KONEPLUS_SIZE_ACTUAL_PROFILE);
133} 84}
134 85
135static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, 86static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
@@ -182,111 +133,77 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
182 return real_size; 133 return real_size;
183} 134}
184 135
185static ssize_t koneplus_sysfs_write_talk(struct file *fp, 136#define KONEPLUS_SYSFS_W(thingy, THINGY) \
186 struct kobject *kobj, struct bin_attribute *attr, char *buf, 137static ssize_t koneplus_sysfs_write_ ## thingy(struct file *fp, \
187 loff_t off, size_t count) 138 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
188{ 139 loff_t off, size_t count) \
189 return koneplus_sysfs_write(fp, kobj, buf, off, count, 140{ \
190 sizeof(struct koneplus_talk), KONEPLUS_COMMAND_TALK); 141 return koneplus_sysfs_write(fp, kobj, buf, off, count, \
142 KONEPLUS_SIZE_ ## THINGY, KONEPLUS_COMMAND_ ## THINGY); \
191} 143}
192 144
193static ssize_t koneplus_sysfs_write_macro(struct file *fp, 145#define KONEPLUS_SYSFS_R(thingy, THINGY) \
194 struct kobject *kobj, struct bin_attribute *attr, char *buf, 146static ssize_t koneplus_sysfs_read_ ## thingy(struct file *fp, \
195 loff_t off, size_t count) 147 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
196{ 148 loff_t off, size_t count) \
197 return koneplus_sysfs_write(fp, kobj, buf, off, count, 149{ \
198 sizeof(struct koneplus_macro), KONEPLUS_COMMAND_MACRO); 150 return koneplus_sysfs_read(fp, kobj, buf, off, count, \
151 KONEPLUS_SIZE_ ## THINGY, KONEPLUS_COMMAND_ ## THINGY); \
199} 152}
200 153
201static ssize_t koneplus_sysfs_read_sensor(struct file *fp, 154#define KONEPLUS_SYSFS_RW(thingy, THINGY) \
202 struct kobject *kobj, struct bin_attribute *attr, char *buf, 155KONEPLUS_SYSFS_W(thingy, THINGY) \
203 loff_t off, size_t count) 156KONEPLUS_SYSFS_R(thingy, THINGY)
204{
205 return koneplus_sysfs_read(fp, kobj, buf, off, count,
206 sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR);
207}
208 157
209static ssize_t koneplus_sysfs_write_sensor(struct file *fp, 158#define KONEPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \
210 struct kobject *kobj, struct bin_attribute *attr, char *buf, 159{ \
211 loff_t off, size_t count) 160 .attr = { .name = #thingy, .mode = 0660 }, \
212{ 161 .size = KONEPLUS_SIZE_ ## THINGY, \
213 return koneplus_sysfs_write(fp, kobj, buf, off, count, 162 .read = koneplus_sysfs_read_ ## thingy, \
214 sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR); 163 .write = koneplus_sysfs_write_ ## thingy \
215} 164}
216 165
217static ssize_t koneplus_sysfs_write_tcu(struct file *fp, 166#define KONEPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \
218 struct kobject *kobj, struct bin_attribute *attr, char *buf, 167{ \
219 loff_t off, size_t count) 168 .attr = { .name = #thingy, .mode = 0440 }, \
220{ 169 .size = KONEPLUS_SIZE_ ## THINGY, \
221 return koneplus_sysfs_write(fp, kobj, buf, off, count, 170 .read = koneplus_sysfs_read_ ## thingy, \
222 sizeof(struct koneplus_tcu), KONEPLUS_COMMAND_TCU);
223} 171}
224 172
225static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp, 173#define KONEPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \
226 struct kobject *kobj, struct bin_attribute *attr, char *buf, 174{ \
227 loff_t off, size_t count) 175 .attr = { .name = #thingy, .mode = 0220 }, \
228{ 176 .size = KONEPLUS_SIZE_ ## THINGY, \
229 return koneplus_sysfs_read(fp, kobj, buf, off, count, 177 .write = koneplus_sysfs_write_ ## thingy \
230 sizeof(struct koneplus_tcu_image), KONEPLUS_COMMAND_TCU);
231} 178}
232 179
233static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, 180KONEPLUS_SYSFS_W(control, CONTROL)
234 struct kobject *kobj, struct bin_attribute *attr, char *buf, 181KONEPLUS_SYSFS_RW(info, INFO)
235 loff_t off, size_t count) 182KONEPLUS_SYSFS_W(talk, TALK)
236{ 183KONEPLUS_SYSFS_W(macro, MACRO)
237 struct device *dev = 184KONEPLUS_SYSFS_RW(sensor, SENSOR)
238 container_of(kobj, struct device, kobj)->parent->parent; 185KONEPLUS_SYSFS_RW(tcu, TCU)
239 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); 186KONEPLUS_SYSFS_R(tcu_image, TCU_IMAGE)
240 187KONEPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
241 if (off >= sizeof(struct koneplus_profile_settings)) 188KONEPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
242 return 0;
243 189
244 if (off + count > sizeof(struct koneplus_profile_settings)) 190static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
245 count = sizeof(struct koneplus_profile_settings) - off;
246
247 mutex_lock(&koneplus->koneplus_lock);
248 memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off,
249 count);
250 mutex_unlock(&koneplus->koneplus_lock);
251
252 return count;
253}
254
255static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp,
256 struct kobject *kobj, struct bin_attribute *attr, char *buf, 191 struct kobject *kobj, struct bin_attribute *attr, char *buf,
257 loff_t off, size_t count) 192 loff_t off, size_t count)
258{ 193{
259 struct device *dev = 194 struct device *dev =
260 container_of(kobj, struct device, kobj)->parent->parent; 195 container_of(kobj, struct device, kobj)->parent->parent;
261 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
262 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 196 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
263 int retval = 0; 197 ssize_t retval;
264 int difference;
265 int profile_number;
266 struct koneplus_profile_settings *profile_settings;
267
268 if (off != 0 || count != sizeof(struct koneplus_profile_settings))
269 return -EINVAL;
270
271 profile_number = ((struct koneplus_profile_settings const *)buf)->number;
272 profile_settings = &koneplus->profile_settings[profile_number];
273
274 mutex_lock(&koneplus->koneplus_lock);
275 difference = memcmp(buf, profile_settings,
276 sizeof(struct koneplus_profile_settings));
277 if (difference) {
278 retval = koneplus_set_profile_settings(usb_dev,
279 (struct koneplus_profile_settings const *)buf);
280 if (!retval)
281 memcpy(profile_settings, buf,
282 sizeof(struct koneplus_profile_settings));
283 }
284 mutex_unlock(&koneplus->koneplus_lock);
285 198
199 retval = koneplus_send_control(usb_dev, *(uint *)(attr->private),
200 KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
286 if (retval) 201 if (retval)
287 return retval; 202 return retval;
288 203
289 return sizeof(struct koneplus_profile_settings); 204 return koneplus_sysfs_read(fp, kobj, buf, off, count,
205 KONEPLUS_SIZE_PROFILE_SETTINGS,
206 KONEPLUS_COMMAND_PROFILE_SETTINGS);
290} 207}
291 208
292static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, 209static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
@@ -295,57 +212,17 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
295{ 212{
296 struct device *dev = 213 struct device *dev =
297 container_of(kobj, struct device, kobj)->parent->parent; 214 container_of(kobj, struct device, kobj)->parent->parent;
298 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
299
300 if (off >= sizeof(struct koneplus_profile_buttons))
301 return 0;
302
303 if (off + count > sizeof(struct koneplus_profile_buttons))
304 count = sizeof(struct koneplus_profile_buttons) - off;
305
306 mutex_lock(&koneplus->koneplus_lock);
307 memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off,
308 count);
309 mutex_unlock(&koneplus->koneplus_lock);
310
311 return count;
312}
313
314static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp,
315 struct kobject *kobj, struct bin_attribute *attr, char *buf,
316 loff_t off, size_t count)
317{
318 struct device *dev =
319 container_of(kobj, struct device, kobj)->parent->parent;
320 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
321 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 215 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
322 int retval = 0; 216 ssize_t retval;
323 int difference;
324 uint profile_number;
325 struct koneplus_profile_buttons *profile_buttons;
326
327 if (off != 0 || count != sizeof(struct koneplus_profile_buttons))
328 return -EINVAL;
329
330 profile_number = ((struct koneplus_profile_buttons const *)buf)->number;
331 profile_buttons = &koneplus->profile_buttons[profile_number];
332
333 mutex_lock(&koneplus->koneplus_lock);
334 difference = memcmp(buf, profile_buttons,
335 sizeof(struct koneplus_profile_buttons));
336 if (difference) {
337 retval = koneplus_set_profile_buttons(usb_dev,
338 (struct koneplus_profile_buttons const *)buf);
339 if (!retval)
340 memcpy(profile_buttons, buf,
341 sizeof(struct koneplus_profile_buttons));
342 }
343 mutex_unlock(&koneplus->koneplus_lock);
344 217
218 retval = koneplus_send_control(usb_dev, *(uint *)(attr->private),
219 KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
345 if (retval) 220 if (retval)
346 return retval; 221 return retval;
347 222
348 return sizeof(struct koneplus_profile_buttons); 223 return koneplus_sysfs_read(fp, kobj, buf, off, count,
224 KONEPLUS_SIZE_PROFILE_BUTTONS,
225 KONEPLUS_COMMAND_PROFILE_BUTTONS);
349} 226}
350 227
351static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, 228static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev,
@@ -401,9 +278,20 @@ static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev,
401static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, 278static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev,
402 struct device_attribute *attr, char *buf) 279 struct device_attribute *attr, char *buf)
403{ 280{
404 struct koneplus_device *koneplus = 281 struct koneplus_device *koneplus;
405 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 282 struct usb_device *usb_dev;
406 return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version); 283 struct koneplus_info info;
284
285 dev = dev->parent->parent;
286 koneplus = hid_get_drvdata(dev_get_drvdata(dev));
287 usb_dev = interface_to_usbdev(to_usb_interface(dev));
288
289 mutex_lock(&koneplus->koneplus_lock);
290 roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO,
291 &info, KONEPLUS_SIZE_INFO);
292 mutex_unlock(&koneplus->koneplus_lock);
293
294 return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
407} 295}
408 296
409static struct device_attribute koneplus_attributes[] = { 297static struct device_attribute koneplus_attributes[] = {
@@ -419,132 +307,85 @@ static struct device_attribute koneplus_attributes[] = {
419}; 307};
420 308
421static struct bin_attribute koneplus_bin_attributes[] = { 309static struct bin_attribute koneplus_bin_attributes[] = {
422 { 310 KONEPLUS_BIN_ATTRIBUTE_W(control, CONTROL),
423 .attr = { .name = "sensor", .mode = 0660 }, 311 KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO),
424 .size = sizeof(struct koneplus_sensor), 312 KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK),
425 .read = koneplus_sysfs_read_sensor, 313 KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO),
426 .write = koneplus_sysfs_write_sensor 314 KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR),
427 }, 315 KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU),
428 { 316 KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE),
429 .attr = { .name = "tcu", .mode = 0220 }, 317 KONEPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
430 .size = sizeof(struct koneplus_tcu), 318 KONEPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
431 .write = koneplus_sysfs_write_tcu
432 },
433 {
434 .attr = { .name = "tcu_image", .mode = 0440 },
435 .size = sizeof(struct koneplus_tcu_image),
436 .read = koneplus_sysfs_read_tcu_image
437 },
438 {
439 .attr = { .name = "profile_settings", .mode = 0220 },
440 .size = sizeof(struct koneplus_profile_settings),
441 .write = koneplus_sysfs_write_profile_settings
442 },
443 { 319 {
444 .attr = { .name = "profile1_settings", .mode = 0440 }, 320 .attr = { .name = "profile1_settings", .mode = 0440 },
445 .size = sizeof(struct koneplus_profile_settings), 321 .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
446 .read = koneplus_sysfs_read_profilex_settings, 322 .read = koneplus_sysfs_read_profilex_settings,
447 .private = &profile_numbers[0] 323 .private = &profile_numbers[0]
448 }, 324 },
449 { 325 {
450 .attr = { .name = "profile2_settings", .mode = 0440 }, 326 .attr = { .name = "profile2_settings", .mode = 0440 },
451 .size = sizeof(struct koneplus_profile_settings), 327 .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
452 .read = koneplus_sysfs_read_profilex_settings, 328 .read = koneplus_sysfs_read_profilex_settings,
453 .private = &profile_numbers[1] 329 .private = &profile_numbers[1]
454 }, 330 },
455 { 331 {
456 .attr = { .name = "profile3_settings", .mode = 0440 }, 332 .attr = { .name = "profile3_settings", .mode = 0440 },
457 .size = sizeof(struct koneplus_profile_settings), 333 .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
458 .read = koneplus_sysfs_read_profilex_settings, 334 .read = koneplus_sysfs_read_profilex_settings,
459 .private = &profile_numbers[2] 335 .private = &profile_numbers[2]
460 }, 336 },
461 { 337 {
462 .attr = { .name = "profile4_settings", .mode = 0440 }, 338 .attr = { .name = "profile4_settings", .mode = 0440 },
463 .size = sizeof(struct koneplus_profile_settings), 339 .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
464 .read = koneplus_sysfs_read_profilex_settings, 340 .read = koneplus_sysfs_read_profilex_settings,
465 .private = &profile_numbers[3] 341 .private = &profile_numbers[3]
466 }, 342 },
467 { 343 {
468 .attr = { .name = "profile5_settings", .mode = 0440 }, 344 .attr = { .name = "profile5_settings", .mode = 0440 },
469 .size = sizeof(struct koneplus_profile_settings), 345 .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
470 .read = koneplus_sysfs_read_profilex_settings, 346 .read = koneplus_sysfs_read_profilex_settings,
471 .private = &profile_numbers[4] 347 .private = &profile_numbers[4]
472 }, 348 },
473 { 349 {
474 .attr = { .name = "profile_buttons", .mode = 0220 },
475 .size = sizeof(struct koneplus_profile_buttons),
476 .write = koneplus_sysfs_write_profile_buttons
477 },
478 {
479 .attr = { .name = "profile1_buttons", .mode = 0440 }, 350 .attr = { .name = "profile1_buttons", .mode = 0440 },
480 .size = sizeof(struct koneplus_profile_buttons), 351 .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
481 .read = koneplus_sysfs_read_profilex_buttons, 352 .read = koneplus_sysfs_read_profilex_buttons,
482 .private = &profile_numbers[0] 353 .private = &profile_numbers[0]
483 }, 354 },
484 { 355 {
485 .attr = { .name = "profile2_buttons", .mode = 0440 }, 356 .attr = { .name = "profile2_buttons", .mode = 0440 },
486 .size = sizeof(struct koneplus_profile_buttons), 357 .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
487 .read = koneplus_sysfs_read_profilex_buttons, 358 .read = koneplus_sysfs_read_profilex_buttons,
488 .private = &profile_numbers[1] 359 .private = &profile_numbers[1]
489 }, 360 },
490 { 361 {
491 .attr = { .name = "profile3_buttons", .mode = 0440 }, 362 .attr = { .name = "profile3_buttons", .mode = 0440 },
492 .size = sizeof(struct koneplus_profile_buttons), 363 .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
493 .read = koneplus_sysfs_read_profilex_buttons, 364 .read = koneplus_sysfs_read_profilex_buttons,
494 .private = &profile_numbers[2] 365 .private = &profile_numbers[2]
495 }, 366 },
496 { 367 {
497 .attr = { .name = "profile4_buttons", .mode = 0440 }, 368 .attr = { .name = "profile4_buttons", .mode = 0440 },
498 .size = sizeof(struct koneplus_profile_buttons), 369 .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
499 .read = koneplus_sysfs_read_profilex_buttons, 370 .read = koneplus_sysfs_read_profilex_buttons,
500 .private = &profile_numbers[3] 371 .private = &profile_numbers[3]
501 }, 372 },
502 { 373 {
503 .attr = { .name = "profile5_buttons", .mode = 0440 }, 374 .attr = { .name = "profile5_buttons", .mode = 0440 },
504 .size = sizeof(struct koneplus_profile_buttons), 375 .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
505 .read = koneplus_sysfs_read_profilex_buttons, 376 .read = koneplus_sysfs_read_profilex_buttons,
506 .private = &profile_numbers[4] 377 .private = &profile_numbers[4]
507 }, 378 },
508 {
509 .attr = { .name = "macro", .mode = 0220 },
510 .size = sizeof(struct koneplus_macro),
511 .write = koneplus_sysfs_write_macro
512 },
513 {
514 .attr = { .name = "talk", .mode = 0220 },
515 .size = sizeof(struct koneplus_talk),
516 .write = koneplus_sysfs_write_talk
517 },
518 __ATTR_NULL 379 __ATTR_NULL
519}; 380};
520 381
521static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, 382static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev,
522 struct koneplus_device *koneplus) 383 struct koneplus_device *koneplus)
523{ 384{
524 int retval, i; 385 int retval;
525 static uint wait = 200;
526 386
527 mutex_init(&koneplus->koneplus_lock); 387 mutex_init(&koneplus->koneplus_lock);
528 388
529 retval = koneplus_get_info(usb_dev, &koneplus->info);
530 if (retval)
531 return retval;
532
533 for (i = 0; i < 5; ++i) {
534 msleep(wait);
535 retval = koneplus_get_profile_settings(usb_dev,
536 &koneplus->profile_settings[i], i);
537 if (retval)
538 return retval;
539
540 msleep(wait);
541 retval = koneplus_get_profile_buttons(usb_dev,
542 &koneplus->profile_buttons[i], i);
543 if (retval)
544 return retval;
545 }
546
547 msleep(wait);
548 retval = koneplus_get_actual_profile(usb_dev); 389 retval = koneplus_get_actual_profile(usb_dev);
549 if (retval < 0) 390 if (retval < 0)
550 return retval; 391 return retval;
@@ -709,6 +550,7 @@ static int koneplus_raw_event(struct hid_device *hdev,
709 550
710static const struct hid_device_id koneplus_devices[] = { 551static const struct hid_device_id koneplus_devices[] = {
711 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, 552 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
553 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEXTD) },
712 { } 554 { }
713}; 555};
714 556
@@ -749,5 +591,5 @@ module_init(koneplus_init);
749module_exit(koneplus_exit); 591module_exit(koneplus_exit);
750 592
751MODULE_AUTHOR("Stefan Achatz"); 593MODULE_AUTHOR("Stefan Achatz");
752MODULE_DESCRIPTION("USB Roccat Kone[+] driver"); 594MODULE_DESCRIPTION("USB Roccat Kone[+]/XTD driver");
753MODULE_LICENSE("GPL v2"); 595MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h
index 7074b2a4b94b..af7f57e8cf3b 100644
--- a/drivers/hid/hid-roccat-koneplus.h
+++ b/drivers/hid/hid-roccat-koneplus.h
@@ -14,11 +14,19 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16 16
17struct koneplus_talk { 17enum {
18 uint8_t command; /* KONEPLUS_COMMAND_TALK */ 18 KONEPLUS_SIZE_ACTUAL_PROFILE = 0x03,
19 uint8_t size; /* always 0x10 */ 19 KONEPLUS_SIZE_CONTROL = 0x03,
20 uint8_t data[14]; 20 KONEPLUS_SIZE_FIRMWARE_WRITE = 0x0402,
21} __packed; 21 KONEPLUS_SIZE_INFO = 0x06,
22 KONEPLUS_SIZE_MACRO = 0x0822,
23 KONEPLUS_SIZE_PROFILE_SETTINGS = 0x2b,
24 KONEPLUS_SIZE_PROFILE_BUTTONS = 0x4d,
25 KONEPLUS_SIZE_SENSOR = 0x06,
26 KONEPLUS_SIZE_TALK = 0x10,
27 KONEPLUS_SIZE_TCU = 0x04,
28 KONEPLUS_SIZE_TCU_IMAGE = 0x0404,
29};
22 30
23enum koneplus_control_requests { 31enum koneplus_control_requests {
24 KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, 32 KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80,
@@ -31,45 +39,6 @@ struct koneplus_actual_profile {
31 uint8_t actual_profile; /* Range 0-4! */ 39 uint8_t actual_profile; /* Range 0-4! */
32} __attribute__ ((__packed__)); 40} __attribute__ ((__packed__));
33 41
34struct koneplus_profile_settings {
35 uint8_t command; /* KONEPLUS_COMMAND_PROFILE_SETTINGS */
36 uint8_t size; /* always 43 */
37 uint8_t number; /* range 0-4 */
38 uint8_t advanced_sensitivity;
39 uint8_t sensitivity_x;
40 uint8_t sensitivity_y;
41 uint8_t cpi_levels_enabled;
42 uint8_t cpi_levels_x[5];
43 uint8_t cpi_startup_level; /* range 0-4 */
44 uint8_t cpi_levels_y[5]; /* range 1-60 means 100-6000 cpi */
45 uint8_t unknown1;
46 uint8_t polling_rate;
47 uint8_t lights_enabled;
48 uint8_t light_effect_mode;
49 uint8_t color_flow_effect;
50 uint8_t light_effect_type;
51 uint8_t light_effect_speed;
52 uint8_t lights[16];
53 uint16_t checksum;
54} __attribute__ ((__packed__));
55
56struct koneplus_profile_buttons {
57 uint8_t command; /* KONEPLUS_COMMAND_PROFILE_BUTTONS */
58 uint8_t size; /* always 77 */
59 uint8_t number; /* range 0-4 */
60 uint8_t data[72];
61 uint16_t checksum;
62} __attribute__ ((__packed__));
63
64struct koneplus_macro {
65 uint8_t command; /* KONEPLUS_COMMAND_MACRO */
66 uint16_t size; /* always 0x822 little endian */
67 uint8_t profile; /* range 0-4 */
68 uint8_t button; /* range 0-23 */
69 uint8_t data[2075];
70 uint16_t checksum;
71} __attribute__ ((__packed__));
72
73struct koneplus_info { 42struct koneplus_info {
74 uint8_t command; /* KONEPLUS_COMMAND_INFO */ 43 uint8_t command; /* KONEPLUS_COMMAND_INFO */
75 uint8_t size; /* always 6 */ 44 uint8_t size; /* always 6 */
@@ -77,51 +46,15 @@ struct koneplus_info {
77 uint8_t unknown[3]; 46 uint8_t unknown[3];
78} __attribute__ ((__packed__)); 47} __attribute__ ((__packed__));
79 48
80struct koneplus_e {
81 uint8_t command; /* KONEPLUS_COMMAND_E */
82 uint8_t size; /* always 3 */
83 uint8_t unknown; /* TODO 1; 0 before firmware update */
84} __attribute__ ((__packed__));
85
86struct koneplus_sensor {
87 uint8_t command; /* KONEPLUS_COMMAND_SENSOR */
88 uint8_t size; /* always 6 */
89 uint8_t data[4];
90} __attribute__ ((__packed__));
91
92struct koneplus_firmware_write {
93 uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE */
94 uint8_t unknown[1025];
95} __attribute__ ((__packed__));
96
97struct koneplus_firmware_write_control {
98 uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL */
99 /*
100 * value is 1 on success
101 * 3 means "not finished yet"
102 */
103 uint8_t value;
104 uint8_t unknown; /* always 0x75 */
105} __attribute__ ((__packed__));
106
107struct koneplus_tcu {
108 uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
109 uint8_t data[2];
110} __attribute__ ((__packed__));
111
112struct koneplus_tcu_image {
113 uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
114 uint8_t data[1024];
115 uint16_t checksum;
116} __attribute__ ((__packed__));
117
118enum koneplus_commands { 49enum koneplus_commands {
119 KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, 50 KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
51 KONEPLUS_COMMAND_CONTROL = 0x4,
120 KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, 52 KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
121 KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, 53 KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
122 KONEPLUS_COMMAND_MACRO = 0x8, 54 KONEPLUS_COMMAND_MACRO = 0x8,
123 KONEPLUS_COMMAND_INFO = 0x9, 55 KONEPLUS_COMMAND_INFO = 0x9,
124 KONEPLUS_COMMAND_TCU = 0xc, 56 KONEPLUS_COMMAND_TCU = 0xc,
57 KONEPLUS_COMMAND_TCU_IMAGE = 0xc,
125 KONEPLUS_COMMAND_E = 0xe, 58 KONEPLUS_COMMAND_E = 0xe,
126 KONEPLUS_COMMAND_SENSOR = 0xf, 59 KONEPLUS_COMMAND_SENSOR = 0xf,
127 KONEPLUS_COMMAND_TALK = 0x10, 60 KONEPLUS_COMMAND_TALK = 0x10,
@@ -187,10 +120,6 @@ struct koneplus_device {
187 int chrdev_minor; 120 int chrdev_minor;
188 121
189 struct mutex koneplus_lock; 122 struct mutex koneplus_lock;
190
191 struct koneplus_info info;
192 struct koneplus_profile_settings profile_settings[5];
193 struct koneplus_profile_buttons profile_buttons[5];
194}; 123};
195 124
196#endif 125#endif
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c
index ca6527ac655d..b8b37789b864 100644
--- a/drivers/hid/hid-roccat-kovaplus.c
+++ b/drivers/hid/hid-roccat-kovaplus.c
@@ -70,13 +70,6 @@ static int kovaplus_select_profile(struct usb_device *usb_dev, uint number,
70 return kovaplus_send_control(usb_dev, number, request); 70 return kovaplus_send_control(usb_dev, number, request);
71} 71}
72 72
73static int kovaplus_get_info(struct usb_device *usb_dev,
74 struct kovaplus_info *buf)
75{
76 return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO,
77 buf, sizeof(struct kovaplus_info));
78}
79
80static int kovaplus_get_profile_settings(struct usb_device *usb_dev, 73static int kovaplus_get_profile_settings(struct usb_device *usb_dev,
81 struct kovaplus_profile_settings *buf, uint number) 74 struct kovaplus_profile_settings *buf, uint number)
82{ 75{
@@ -88,15 +81,7 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev,
88 return retval; 81 return retval;
89 82
90 return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, 83 return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS,
91 buf, sizeof(struct kovaplus_profile_settings)); 84 buf, KOVAPLUS_SIZE_PROFILE_SETTINGS);
92}
93
94static int kovaplus_set_profile_settings(struct usb_device *usb_dev,
95 struct kovaplus_profile_settings const *settings)
96{
97 return roccat_common2_send_with_status(usb_dev,
98 KOVAPLUS_COMMAND_PROFILE_SETTINGS,
99 settings, sizeof(struct kovaplus_profile_settings));
100} 85}
101 86
102static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, 87static int kovaplus_get_profile_buttons(struct usb_device *usb_dev,
@@ -110,15 +95,7 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev,
110 return retval; 95 return retval;
111 96
112 return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, 97 return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS,
113 buf, sizeof(struct kovaplus_profile_buttons)); 98 buf, KOVAPLUS_SIZE_PROFILE_BUTTONS);
114}
115
116static int kovaplus_set_profile_buttons(struct usb_device *usb_dev,
117 struct kovaplus_profile_buttons const *buttons)
118{
119 return roccat_common2_send_with_status(usb_dev,
120 KOVAPLUS_COMMAND_PROFILE_BUTTONS,
121 buttons, sizeof(struct kovaplus_profile_buttons));
122} 99}
123 100
124/* retval is 0-4 on success, < 0 on error */ 101/* retval is 0-4 on success, < 0 on error */
@@ -147,122 +124,141 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev,
147 &buf, sizeof(struct kovaplus_actual_profile)); 124 &buf, sizeof(struct kovaplus_actual_profile));
148} 125}
149 126
150static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp, 127static ssize_t kovaplus_sysfs_read(struct file *fp, struct kobject *kobj,
151 struct kobject *kobj, struct bin_attribute *attr, char *buf, 128 char *buf, loff_t off, size_t count,
152 loff_t off, size_t count) 129 size_t real_size, uint command)
153{ 130{
154 struct device *dev = 131 struct device *dev =
155 container_of(kobj, struct device, kobj)->parent->parent; 132 container_of(kobj, struct device, kobj)->parent->parent;
156 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); 133 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
134 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
135 int retval;
157 136
158 if (off >= sizeof(struct kovaplus_profile_settings)) 137 if (off >= real_size)
159 return 0; 138 return 0;
160 139
161 if (off + count > sizeof(struct kovaplus_profile_settings)) 140 if (off != 0 || count != real_size)
162 count = sizeof(struct kovaplus_profile_settings) - off; 141 return -EINVAL;
163 142
164 mutex_lock(&kovaplus->kovaplus_lock); 143 mutex_lock(&kovaplus->kovaplus_lock);
165 memcpy(buf, ((char const *)&kovaplus->profile_settings[*(uint *)(attr->private)]) + off, 144 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
166 count);
167 mutex_unlock(&kovaplus->kovaplus_lock); 145 mutex_unlock(&kovaplus->kovaplus_lock);
168 146
169 return count; 147 if (retval)
148 return retval;
149
150 return real_size;
170} 151}
171 152
172static ssize_t kovaplus_sysfs_write_profile_settings(struct file *fp, 153static ssize_t kovaplus_sysfs_write(struct file *fp, struct kobject *kobj,
173 struct kobject *kobj, struct bin_attribute *attr, char *buf, 154 void const *buf, loff_t off, size_t count,
174 loff_t off, size_t count) 155 size_t real_size, uint command)
175{ 156{
176 struct device *dev = 157 struct device *dev =
177 container_of(kobj, struct device, kobj)->parent->parent; 158 container_of(kobj, struct device, kobj)->parent->parent;
178 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); 159 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
179 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 160 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
180 int retval = 0; 161 int retval;
181 int difference;
182 int profile_index;
183 struct kovaplus_profile_settings *profile_settings;
184 162
185 if (off != 0 || count != sizeof(struct kovaplus_profile_settings)) 163 if (off != 0 || count != real_size)
186 return -EINVAL; 164 return -EINVAL;
187 165
188 profile_index = ((struct kovaplus_profile_settings const *)buf)->profile_index;
189 profile_settings = &kovaplus->profile_settings[profile_index];
190
191 mutex_lock(&kovaplus->kovaplus_lock); 166 mutex_lock(&kovaplus->kovaplus_lock);
192 difference = memcmp(buf, profile_settings, 167 retval = roccat_common2_send_with_status(usb_dev, command,
193 sizeof(struct kovaplus_profile_settings)); 168 buf, real_size);
194 if (difference) {
195 retval = kovaplus_set_profile_settings(usb_dev,
196 (struct kovaplus_profile_settings const *)buf);
197 if (!retval)
198 memcpy(profile_settings, buf,
199 sizeof(struct kovaplus_profile_settings));
200 }
201 mutex_unlock(&kovaplus->kovaplus_lock); 169 mutex_unlock(&kovaplus->kovaplus_lock);
202 170
203 if (retval) 171 if (retval)
204 return retval; 172 return retval;
205 173
206 return sizeof(struct kovaplus_profile_settings); 174 return real_size;
207} 175}
208 176
209static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp, 177#define KOVAPLUS_SYSFS_W(thingy, THINGY) \
210 struct kobject *kobj, struct bin_attribute *attr, char *buf, 178static ssize_t kovaplus_sysfs_write_ ## thingy(struct file *fp, \
211 loff_t off, size_t count) 179 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
212{ 180 loff_t off, size_t count) \
213 struct device *dev = 181{ \
214 container_of(kobj, struct device, kobj)->parent->parent; 182 return kovaplus_sysfs_write(fp, kobj, buf, off, count, \
215 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); 183 KOVAPLUS_SIZE_ ## THINGY, KOVAPLUS_COMMAND_ ## THINGY); \
184}
216 185
217 if (off >= sizeof(struct kovaplus_profile_buttons)) 186#define KOVAPLUS_SYSFS_R(thingy, THINGY) \
218 return 0; 187static ssize_t kovaplus_sysfs_read_ ## thingy(struct file *fp, \
188 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
189 loff_t off, size_t count) \
190{ \
191 return kovaplus_sysfs_read(fp, kobj, buf, off, count, \
192 KOVAPLUS_SIZE_ ## THINGY, KOVAPLUS_COMMAND_ ## THINGY); \
193}
219 194
220 if (off + count > sizeof(struct kovaplus_profile_buttons)) 195#define KOVAPLUS_SYSFS_RW(thingy, THINGY) \
221 count = sizeof(struct kovaplus_profile_buttons) - off; 196KOVAPLUS_SYSFS_W(thingy, THINGY) \
197KOVAPLUS_SYSFS_R(thingy, THINGY)
222 198
223 mutex_lock(&kovaplus->kovaplus_lock); 199#define KOVAPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \
224 memcpy(buf, ((char const *)&kovaplus->profile_buttons[*(uint *)(attr->private)]) + off, 200{ \
225 count); 201 .attr = { .name = #thingy, .mode = 0660 }, \
226 mutex_unlock(&kovaplus->kovaplus_lock); 202 .size = KOVAPLUS_SIZE_ ## THINGY, \
203 .read = kovaplus_sysfs_read_ ## thingy, \
204 .write = kovaplus_sysfs_write_ ## thingy \
205}
206
207#define KOVAPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \
208{ \
209 .attr = { .name = #thingy, .mode = 0440 }, \
210 .size = KOVAPLUS_SIZE_ ## THINGY, \
211 .read = kovaplus_sysfs_read_ ## thingy, \
212}
227 213
228 return count; 214#define KOVAPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \
215{ \
216 .attr = { .name = #thingy, .mode = 0220 }, \
217 .size = KOVAPLUS_SIZE_ ## THINGY, \
218 .write = kovaplus_sysfs_write_ ## thingy \
229} 219}
230 220
231static ssize_t kovaplus_sysfs_write_profile_buttons(struct file *fp, 221KOVAPLUS_SYSFS_W(control, CONTROL)
222KOVAPLUS_SYSFS_RW(info, INFO)
223KOVAPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
224KOVAPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
225
226static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp,
232 struct kobject *kobj, struct bin_attribute *attr, char *buf, 227 struct kobject *kobj, struct bin_attribute *attr, char *buf,
233 loff_t off, size_t count) 228 loff_t off, size_t count)
234{ 229{
235 struct device *dev = 230 struct device *dev =
236 container_of(kobj, struct device, kobj)->parent->parent; 231 container_of(kobj, struct device, kobj)->parent->parent;
237 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
238 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 232 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
239 int retval = 0; 233 ssize_t retval;
240 int difference;
241 uint profile_index;
242 struct kovaplus_profile_buttons *profile_buttons;
243 234
244 if (off != 0 || count != sizeof(struct kovaplus_profile_buttons)) 235 retval = kovaplus_select_profile(usb_dev, *(uint *)(attr->private),
245 return -EINVAL; 236 KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
237 if (retval)
238 return retval;
246 239
247 profile_index = ((struct kovaplus_profile_buttons const *)buf)->profile_index; 240 return kovaplus_sysfs_read(fp, kobj, buf, off, count,
248 profile_buttons = &kovaplus->profile_buttons[profile_index]; 241 KOVAPLUS_SIZE_PROFILE_SETTINGS,
242 KOVAPLUS_COMMAND_PROFILE_SETTINGS);
243}
249 244
250 mutex_lock(&kovaplus->kovaplus_lock); 245static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp,
251 difference = memcmp(buf, profile_buttons, 246 struct kobject *kobj, struct bin_attribute *attr, char *buf,
252 sizeof(struct kovaplus_profile_buttons)); 247 loff_t off, size_t count)
253 if (difference) { 248{
254 retval = kovaplus_set_profile_buttons(usb_dev, 249 struct device *dev =
255 (struct kovaplus_profile_buttons const *)buf); 250 container_of(kobj, struct device, kobj)->parent->parent;
256 if (!retval) 251 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
257 memcpy(profile_buttons, buf, 252 ssize_t retval;
258 sizeof(struct kovaplus_profile_buttons));
259 }
260 mutex_unlock(&kovaplus->kovaplus_lock);
261 253
254 retval = kovaplus_select_profile(usb_dev, *(uint *)(attr->private),
255 KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
262 if (retval) 256 if (retval)
263 return retval; 257 return retval;
264 258
265 return sizeof(struct kovaplus_profile_buttons); 259 return kovaplus_sysfs_read(fp, kobj, buf, off, count,
260 KOVAPLUS_SIZE_PROFILE_BUTTONS,
261 KOVAPLUS_COMMAND_PROFILE_BUTTONS);
266} 262}
267 263
268static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev, 264static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev,
@@ -342,9 +338,20 @@ static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev,
342static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev, 338static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev,
343 struct device_attribute *attr, char *buf) 339 struct device_attribute *attr, char *buf)
344{ 340{
345 struct kovaplus_device *kovaplus = 341 struct kovaplus_device *kovaplus;
346 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 342 struct usb_device *usb_dev;
347 return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->info.firmware_version); 343 struct kovaplus_info info;
344
345 dev = dev->parent->parent;
346 kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
347 usb_dev = interface_to_usbdev(to_usb_interface(dev));
348
349 mutex_lock(&kovaplus->kovaplus_lock);
350 roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO,
351 &info, KOVAPLUS_SIZE_INFO);
352 mutex_unlock(&kovaplus->kovaplus_lock);
353
354 return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
348} 355}
349 356
350static struct device_attribute kovaplus_attributes[] = { 357static struct device_attribute kovaplus_attributes[] = {
@@ -363,73 +370,67 @@ static struct device_attribute kovaplus_attributes[] = {
363}; 370};
364 371
365static struct bin_attribute kovaplus_bin_attributes[] = { 372static struct bin_attribute kovaplus_bin_attributes[] = {
366 { 373 KOVAPLUS_BIN_ATTRIBUTE_W(control, CONTROL),
367 .attr = { .name = "profile_settings", .mode = 0220 }, 374 KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO),
368 .size = sizeof(struct kovaplus_profile_settings), 375 KOVAPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
369 .write = kovaplus_sysfs_write_profile_settings 376 KOVAPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
370 },
371 { 377 {
372 .attr = { .name = "profile1_settings", .mode = 0440 }, 378 .attr = { .name = "profile1_settings", .mode = 0440 },
373 .size = sizeof(struct kovaplus_profile_settings), 379 .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
374 .read = kovaplus_sysfs_read_profilex_settings, 380 .read = kovaplus_sysfs_read_profilex_settings,
375 .private = &profile_numbers[0] 381 .private = &profile_numbers[0]
376 }, 382 },
377 { 383 {
378 .attr = { .name = "profile2_settings", .mode = 0440 }, 384 .attr = { .name = "profile2_settings", .mode = 0440 },
379 .size = sizeof(struct kovaplus_profile_settings), 385 .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
380 .read = kovaplus_sysfs_read_profilex_settings, 386 .read = kovaplus_sysfs_read_profilex_settings,
381 .private = &profile_numbers[1] 387 .private = &profile_numbers[1]
382 }, 388 },
383 { 389 {
384 .attr = { .name = "profile3_settings", .mode = 0440 }, 390 .attr = { .name = "profile3_settings", .mode = 0440 },
385 .size = sizeof(struct kovaplus_profile_settings), 391 .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
386 .read = kovaplus_sysfs_read_profilex_settings, 392 .read = kovaplus_sysfs_read_profilex_settings,
387 .private = &profile_numbers[2] 393 .private = &profile_numbers[2]
388 }, 394 },
389 { 395 {
390 .attr = { .name = "profile4_settings", .mode = 0440 }, 396 .attr = { .name = "profile4_settings", .mode = 0440 },
391 .size = sizeof(struct kovaplus_profile_settings), 397 .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
392 .read = kovaplus_sysfs_read_profilex_settings, 398 .read = kovaplus_sysfs_read_profilex_settings,
393 .private = &profile_numbers[3] 399 .private = &profile_numbers[3]
394 }, 400 },
395 { 401 {
396 .attr = { .name = "profile5_settings", .mode = 0440 }, 402 .attr = { .name = "profile5_settings", .mode = 0440 },
397 .size = sizeof(struct kovaplus_profile_settings), 403 .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
398 .read = kovaplus_sysfs_read_profilex_settings, 404 .read = kovaplus_sysfs_read_profilex_settings,
399 .private = &profile_numbers[4] 405 .private = &profile_numbers[4]
400 }, 406 },
401 { 407 {
402 .attr = { .name = "profile_buttons", .mode = 0220 },
403 .size = sizeof(struct kovaplus_profile_buttons),
404 .write = kovaplus_sysfs_write_profile_buttons
405 },
406 {
407 .attr = { .name = "profile1_buttons", .mode = 0440 }, 408 .attr = { .name = "profile1_buttons", .mode = 0440 },
408 .size = sizeof(struct kovaplus_profile_buttons), 409 .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
409 .read = kovaplus_sysfs_read_profilex_buttons, 410 .read = kovaplus_sysfs_read_profilex_buttons,
410 .private = &profile_numbers[0] 411 .private = &profile_numbers[0]
411 }, 412 },
412 { 413 {
413 .attr = { .name = "profile2_buttons", .mode = 0440 }, 414 .attr = { .name = "profile2_buttons", .mode = 0440 },
414 .size = sizeof(struct kovaplus_profile_buttons), 415 .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
415 .read = kovaplus_sysfs_read_profilex_buttons, 416 .read = kovaplus_sysfs_read_profilex_buttons,
416 .private = &profile_numbers[1] 417 .private = &profile_numbers[1]
417 }, 418 },
418 { 419 {
419 .attr = { .name = "profile3_buttons", .mode = 0440 }, 420 .attr = { .name = "profile3_buttons", .mode = 0440 },
420 .size = sizeof(struct kovaplus_profile_buttons), 421 .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
421 .read = kovaplus_sysfs_read_profilex_buttons, 422 .read = kovaplus_sysfs_read_profilex_buttons,
422 .private = &profile_numbers[2] 423 .private = &profile_numbers[2]
423 }, 424 },
424 { 425 {
425 .attr = { .name = "profile4_buttons", .mode = 0440 }, 426 .attr = { .name = "profile4_buttons", .mode = 0440 },
426 .size = sizeof(struct kovaplus_profile_buttons), 427 .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
427 .read = kovaplus_sysfs_read_profilex_buttons, 428 .read = kovaplus_sysfs_read_profilex_buttons,
428 .private = &profile_numbers[3] 429 .private = &profile_numbers[3]
429 }, 430 },
430 { 431 {
431 .attr = { .name = "profile5_buttons", .mode = 0440 }, 432 .attr = { .name = "profile5_buttons", .mode = 0440 },
432 .size = sizeof(struct kovaplus_profile_buttons), 433 .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
433 .read = kovaplus_sysfs_read_profilex_buttons, 434 .read = kovaplus_sysfs_read_profilex_buttons,
434 .private = &profile_numbers[4] 435 .private = &profile_numbers[4]
435 }, 436 },
@@ -444,10 +445,6 @@ static int kovaplus_init_kovaplus_device_struct(struct usb_device *usb_dev,
444 445
445 mutex_init(&kovaplus->kovaplus_lock); 446 mutex_init(&kovaplus->kovaplus_lock);
446 447
447 retval = kovaplus_get_info(usb_dev, &kovaplus->info);
448 if (retval)
449 return retval;
450
451 for (i = 0; i < 5; ++i) { 448 for (i = 0; i < 5; ++i) {
452 msleep(wait); 449 msleep(wait);
453 retval = kovaplus_get_profile_settings(usb_dev, 450 retval = kovaplus_get_profile_settings(usb_dev,
diff --git a/drivers/hid/hid-roccat-kovaplus.h b/drivers/hid/hid-roccat-kovaplus.h
index f82daa1cdcb9..fbb7a16a7e54 100644
--- a/drivers/hid/hid-roccat-kovaplus.h
+++ b/drivers/hid/hid-roccat-kovaplus.h
@@ -14,6 +14,13 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16 16
17enum {
18 KOVAPLUS_SIZE_CONTROL = 0x03,
19 KOVAPLUS_SIZE_INFO = 0x06,
20 KOVAPLUS_SIZE_PROFILE_SETTINGS = 0x10,
21 KOVAPLUS_SIZE_PROFILE_BUTTONS = 0x17,
22};
23
17enum kovaplus_control_requests { 24enum kovaplus_control_requests {
18 /* write; value = profile number range 0-4 */ 25 /* write; value = profile number range 0-4 */
19 KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, 26 KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
@@ -53,15 +60,9 @@ struct kovaplus_info {
53 uint8_t unknown[3]; 60 uint8_t unknown[3];
54} __packed; 61} __packed;
55 62
56/* writes 1 on plugin */
57struct kovaplus_a {
58 uint8_t command; /* KOVAPLUS_COMMAND_A */
59 uint8_t size; /* 3 */
60 uint8_t unknown;
61} __packed;
62
63enum kovaplus_commands { 63enum kovaplus_commands {
64 KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, 64 KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
65 KOVAPLUS_COMMAND_CONTROL = 0x4,
65 KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, 66 KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
66 KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7, 67 KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
67 KOVAPLUS_COMMAND_INFO = 0x9, 68 KOVAPLUS_COMMAND_INFO = 0x9,
@@ -125,7 +126,6 @@ struct kovaplus_device {
125 int roccat_claimed; 126 int roccat_claimed;
126 int chrdev_minor; 127 int chrdev_minor;
127 struct mutex kovaplus_lock; 128 struct mutex kovaplus_lock;
128 struct kovaplus_info info;
129 struct kovaplus_profile_settings profile_settings[5]; 129 struct kovaplus_profile_settings profile_settings[5];
130 struct kovaplus_profile_buttons profile_buttons[5]; 130 struct kovaplus_profile_buttons profile_buttons[5];
131}; 131};
diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c
new file mode 100644
index 000000000000..5084fb4b7e91
--- /dev/null
+++ b/drivers/hid/hid-roccat-lua.c
@@ -0,0 +1,227 @@
1/*
2 * Roccat Lua driver for Linux
3 *
4 * Copyright (c) 2012 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14/*
15 * Roccat Lua is a gamer mouse which cpi, button and light settings can be
16 * configured.
17 */
18
19#include <linux/device.h>
20#include <linux/input.h>
21#include <linux/hid.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/hid-roccat.h>
25#include "hid-ids.h"
26#include "hid-roccat-common.h"
27#include "hid-roccat-lua.h"
28
29static ssize_t lua_sysfs_read(struct file *fp, struct kobject *kobj,
30 char *buf, loff_t off, size_t count,
31 size_t real_size, uint command)
32{
33 struct device *dev = container_of(kobj, struct device, kobj);
34 struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev));
35 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
36 int retval;
37
38 if (off >= real_size)
39 return 0;
40
41 if (off != 0 || count != real_size)
42 return -EINVAL;
43
44 mutex_lock(&lua->lua_lock);
45 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
46 mutex_unlock(&lua->lua_lock);
47
48 return retval ? retval : real_size;
49}
50
51static ssize_t lua_sysfs_write(struct file *fp, struct kobject *kobj,
52 void const *buf, loff_t off, size_t count,
53 size_t real_size, uint command)
54{
55 struct device *dev = container_of(kobj, struct device, kobj);
56 struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev));
57 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
58 int retval;
59
60 if (off != 0 || count != real_size)
61 return -EINVAL;
62
63 mutex_lock(&lua->lua_lock);
64 retval = roccat_common2_send(usb_dev, command, (void *)buf, real_size);
65 mutex_unlock(&lua->lua_lock);
66
67 return retval ? retval : real_size;
68}
69
70#define LUA_SYSFS_W(thingy, THINGY) \
71static ssize_t lua_sysfs_write_ ## thingy(struct file *fp, \
72 struct kobject *kobj, struct bin_attribute *attr, \
73 char *buf, loff_t off, size_t count) \
74{ \
75 return lua_sysfs_write(fp, kobj, buf, off, count, \
76 LUA_SIZE_ ## THINGY, LUA_COMMAND_ ## THINGY); \
77}
78
79#define LUA_SYSFS_R(thingy, THINGY) \
80static ssize_t lua_sysfs_read_ ## thingy(struct file *fp, \
81 struct kobject *kobj, struct bin_attribute *attr, \
82 char *buf, loff_t off, size_t count) \
83{ \
84 return lua_sysfs_read(fp, kobj, buf, off, count, \
85 LUA_SIZE_ ## THINGY, LUA_COMMAND_ ## THINGY); \
86}
87
88#define LUA_BIN_ATTRIBUTE_RW(thingy, THINGY) \
89LUA_SYSFS_W(thingy, THINGY) \
90LUA_SYSFS_R(thingy, THINGY) \
91static struct bin_attribute lua_ ## thingy ## _attr = { \
92 .attr = { .name = #thingy, .mode = 0660 }, \
93 .size = LUA_SIZE_ ## THINGY, \
94 .read = lua_sysfs_read_ ## thingy, \
95 .write = lua_sysfs_write_ ## thingy \
96};
97
98LUA_BIN_ATTRIBUTE_RW(control, CONTROL)
99
100static int lua_create_sysfs_attributes(struct usb_interface *intf)
101{
102 return sysfs_create_bin_file(&intf->dev.kobj, &lua_control_attr);
103}
104
105static void lua_remove_sysfs_attributes(struct usb_interface *intf)
106{
107 sysfs_remove_bin_file(&intf->dev.kobj, &lua_control_attr);
108}
109
110static int lua_init_lua_device_struct(struct usb_device *usb_dev,
111 struct lua_device *lua)
112{
113 mutex_init(&lua->lua_lock);
114
115 return 0;
116}
117
118static int lua_init_specials(struct hid_device *hdev)
119{
120 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
121 struct usb_device *usb_dev = interface_to_usbdev(intf);
122 struct lua_device *lua;
123 int retval;
124
125 lua = kzalloc(sizeof(*lua), GFP_KERNEL);
126 if (!lua) {
127 hid_err(hdev, "can't alloc device descriptor\n");
128 return -ENOMEM;
129 }
130 hid_set_drvdata(hdev, lua);
131
132 retval = lua_init_lua_device_struct(usb_dev, lua);
133 if (retval) {
134 hid_err(hdev, "couldn't init struct lua_device\n");
135 goto exit;
136 }
137
138 retval = lua_create_sysfs_attributes(intf);
139 if (retval) {
140 hid_err(hdev, "cannot create sysfs files\n");
141 goto exit;
142 }
143
144 return 0;
145exit:
146 kfree(lua);
147 return retval;
148}
149
150static void lua_remove_specials(struct hid_device *hdev)
151{
152 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
153 struct lua_device *lua;
154
155 lua_remove_sysfs_attributes(intf);
156
157 lua = hid_get_drvdata(hdev);
158 kfree(lua);
159}
160
161static int lua_probe(struct hid_device *hdev,
162 const struct hid_device_id *id)
163{
164 int retval;
165
166 retval = hid_parse(hdev);
167 if (retval) {
168 hid_err(hdev, "parse failed\n");
169 goto exit;
170 }
171
172 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
173 if (retval) {
174 hid_err(hdev, "hw start failed\n");
175 goto exit;
176 }
177
178 retval = lua_init_specials(hdev);
179 if (retval) {
180 hid_err(hdev, "couldn't install mouse\n");
181 goto exit_stop;
182 }
183
184 return 0;
185
186exit_stop:
187 hid_hw_stop(hdev);
188exit:
189 return retval;
190}
191
192static void lua_remove(struct hid_device *hdev)
193{
194 lua_remove_specials(hdev);
195 hid_hw_stop(hdev);
196}
197
198static const struct hid_device_id lua_devices[] = {
199 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
200 { }
201};
202
203MODULE_DEVICE_TABLE(hid, lua_devices);
204
205static struct hid_driver lua_driver = {
206 .name = "lua",
207 .id_table = lua_devices,
208 .probe = lua_probe,
209 .remove = lua_remove
210};
211
212static int __init lua_init(void)
213{
214 return hid_register_driver(&lua_driver);
215}
216
217static void __exit lua_exit(void)
218{
219 hid_unregister_driver(&lua_driver);
220}
221
222module_init(lua_init);
223module_exit(lua_exit);
224
225MODULE_AUTHOR("Stefan Achatz");
226MODULE_DESCRIPTION("USB Roccat Lua driver");
227MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-lua.h b/drivers/hid/hid-roccat-lua.h
new file mode 100644
index 000000000000..547d77a375d1
--- /dev/null
+++ b/drivers/hid/hid-roccat-lua.h
@@ -0,0 +1,29 @@
1#ifndef __HID_ROCCAT_LUA_H
2#define __HID_ROCCAT_LUA_H
3
4/*
5 * Copyright (c) 2012 Stefan Achatz <erazor_de@users.sourceforge.net>
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/types.h>
16
17enum {
18 LUA_SIZE_CONTROL = 8,
19};
20
21enum lua_commands {
22 LUA_COMMAND_CONTROL = 3,
23};
24
25struct lua_device {
26 struct mutex lua_lock;
27};
28
29#endif
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
index 1317c177a3e2..d4f1e3bee590 100644
--- a/drivers/hid/hid-roccat-pyra.c
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -66,48 +66,14 @@ static int pyra_get_profile_settings(struct usb_device *usb_dev,
66 if (retval) 66 if (retval)
67 return retval; 67 return retval;
68 return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, 68 return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS,
69 buf, sizeof(struct pyra_profile_settings)); 69 buf, PYRA_SIZE_PROFILE_SETTINGS);
70}
71
72static int pyra_get_profile_buttons(struct usb_device *usb_dev,
73 struct pyra_profile_buttons *buf, int number)
74{
75 int retval;
76 retval = pyra_send_control(usb_dev, number,
77 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
78 if (retval)
79 return retval;
80 return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS,
81 buf, sizeof(struct pyra_profile_buttons));
82} 70}
83 71
84static int pyra_get_settings(struct usb_device *usb_dev, 72static int pyra_get_settings(struct usb_device *usb_dev,
85 struct pyra_settings *buf) 73 struct pyra_settings *buf)
86{ 74{
87 return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS, 75 return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
88 buf, sizeof(struct pyra_settings)); 76 buf, PYRA_SIZE_SETTINGS);
89}
90
91static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
92{
93 return roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO,
94 buf, sizeof(struct pyra_info));
95}
96
97static int pyra_set_profile_settings(struct usb_device *usb_dev,
98 struct pyra_profile_settings const *settings)
99{
100 return roccat_common2_send_with_status(usb_dev,
101 PYRA_COMMAND_PROFILE_SETTINGS, settings,
102 sizeof(struct pyra_profile_settings));
103}
104
105static int pyra_set_profile_buttons(struct usb_device *usb_dev,
106 struct pyra_profile_buttons const *buttons)
107{
108 return roccat_common2_send_with_status(usb_dev,
109 PYRA_COMMAND_PROFILE_BUTTONS, buttons,
110 sizeof(struct pyra_profile_buttons));
111} 77}
112 78
113static int pyra_set_settings(struct usb_device *usb_dev, 79static int pyra_set_settings(struct usb_device *usb_dev,
@@ -115,146 +81,144 @@ static int pyra_set_settings(struct usb_device *usb_dev,
115{ 81{
116 return roccat_common2_send_with_status(usb_dev, 82 return roccat_common2_send_with_status(usb_dev,
117 PYRA_COMMAND_SETTINGS, settings, 83 PYRA_COMMAND_SETTINGS, settings,
118 sizeof(struct pyra_settings)); 84 PYRA_SIZE_SETTINGS);
119} 85}
120 86
121static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, 87static ssize_t pyra_sysfs_read(struct file *fp, struct kobject *kobj,
122 struct kobject *kobj, struct bin_attribute *attr, char *buf, 88 char *buf, loff_t off, size_t count,
123 loff_t off, size_t count) 89 size_t real_size, uint command)
124{ 90{
125 struct device *dev = 91 struct device *dev =
126 container_of(kobj, struct device, kobj)->parent->parent; 92 container_of(kobj, struct device, kobj)->parent->parent;
127 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); 93 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
94 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
95 int retval;
128 96
129 if (off >= sizeof(struct pyra_profile_settings)) 97 if (off >= real_size)
130 return 0; 98 return 0;
131 99
132 if (off + count > sizeof(struct pyra_profile_settings)) 100 if (off != 0 || count != real_size)
133 count = sizeof(struct pyra_profile_settings) - off; 101 return -EINVAL;
134 102
135 mutex_lock(&pyra->pyra_lock); 103 mutex_lock(&pyra->pyra_lock);
136 memcpy(buf, ((char const *)&pyra->profile_settings[*(uint *)(attr->private)]) + off, 104 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
137 count);
138 mutex_unlock(&pyra->pyra_lock); 105 mutex_unlock(&pyra->pyra_lock);
139 106
140 return count; 107 if (retval)
108 return retval;
109
110 return real_size;
141} 111}
142 112
143static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, 113static ssize_t pyra_sysfs_write(struct file *fp, struct kobject *kobj,
144 struct kobject *kobj, struct bin_attribute *attr, char *buf, 114 void const *buf, loff_t off, size_t count,
145 loff_t off, size_t count) 115 size_t real_size, uint command)
146{ 116{
147 struct device *dev = 117 struct device *dev =
148 container_of(kobj, struct device, kobj)->parent->parent; 118 container_of(kobj, struct device, kobj)->parent->parent;
149 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); 119 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
120 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
121 int retval;
150 122
151 if (off >= sizeof(struct pyra_profile_buttons)) 123 if (off != 0 || count != real_size)
152 return 0; 124 return -EINVAL;
153
154 if (off + count > sizeof(struct pyra_profile_buttons))
155 count = sizeof(struct pyra_profile_buttons) - off;
156 125
157 mutex_lock(&pyra->pyra_lock); 126 mutex_lock(&pyra->pyra_lock);
158 memcpy(buf, ((char const *)&pyra->profile_buttons[*(uint *)(attr->private)]) + off, 127 retval = roccat_common2_send_with_status(usb_dev, command, (void *)buf, real_size);
159 count);
160 mutex_unlock(&pyra->pyra_lock); 128 mutex_unlock(&pyra->pyra_lock);
161 129
162 return count; 130 if (retval)
131 return retval;
132
133 return real_size;
163} 134}
164 135
165static ssize_t pyra_sysfs_write_profile_settings(struct file *fp, 136#define PYRA_SYSFS_W(thingy, THINGY) \
166 struct kobject *kobj, struct bin_attribute *attr, char *buf, 137static ssize_t pyra_sysfs_write_ ## thingy(struct file *fp, \
167 loff_t off, size_t count) 138 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
168{ 139 loff_t off, size_t count) \
169 struct device *dev = 140{ \
170 container_of(kobj, struct device, kobj)->parent->parent; 141 return pyra_sysfs_write(fp, kobj, buf, off, count, \
171 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); 142 PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
172 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 143}
173 int retval = 0;
174 int difference;
175 int profile_number;
176 struct pyra_profile_settings *profile_settings;
177 144
178 if (off != 0 || count != sizeof(struct pyra_profile_settings)) 145#define PYRA_SYSFS_R(thingy, THINGY) \
179 return -EINVAL; 146static ssize_t pyra_sysfs_read_ ## thingy(struct file *fp, \
147 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
148 loff_t off, size_t count) \
149{ \
150 return pyra_sysfs_read(fp, kobj, buf, off, count, \
151 PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
152}
180 153
181 profile_number = ((struct pyra_profile_settings const *)buf)->number; 154#define PYRA_SYSFS_RW(thingy, THINGY) \
182 profile_settings = &pyra->profile_settings[profile_number]; 155PYRA_SYSFS_W(thingy, THINGY) \
156PYRA_SYSFS_R(thingy, THINGY)
183 157
184 mutex_lock(&pyra->pyra_lock); 158#define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \
185 difference = memcmp(buf, profile_settings, 159{ \
186 sizeof(struct pyra_profile_settings)); 160 .attr = { .name = #thingy, .mode = 0660 }, \
187 if (difference) { 161 .size = PYRA_SIZE_ ## THINGY, \
188 retval = pyra_set_profile_settings(usb_dev, 162 .read = pyra_sysfs_read_ ## thingy, \
189 (struct pyra_profile_settings const *)buf); 163 .write = pyra_sysfs_write_ ## thingy \
190 if (!retval) 164}
191 memcpy(profile_settings, buf,
192 sizeof(struct pyra_profile_settings));
193 }
194 mutex_unlock(&pyra->pyra_lock);
195 165
196 if (retval) 166#define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \
197 return retval; 167{ \
168 .attr = { .name = #thingy, .mode = 0440 }, \
169 .size = PYRA_SIZE_ ## THINGY, \
170 .read = pyra_sysfs_read_ ## thingy, \
171}
198 172
199 return sizeof(struct pyra_profile_settings); 173#define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \
174{ \
175 .attr = { .name = #thingy, .mode = 0220 }, \
176 .size = PYRA_SIZE_ ## THINGY, \
177 .write = pyra_sysfs_write_ ## thingy \
200} 178}
201 179
202static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp, 180PYRA_SYSFS_W(control, CONTROL)
181PYRA_SYSFS_RW(info, INFO)
182PYRA_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
183PYRA_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
184PYRA_SYSFS_R(settings, SETTINGS)
185
186static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
203 struct kobject *kobj, struct bin_attribute *attr, char *buf, 187 struct kobject *kobj, struct bin_attribute *attr, char *buf,
204 loff_t off, size_t count) 188 loff_t off, size_t count)
205{ 189{
206 struct device *dev = 190 struct device *dev =
207 container_of(kobj, struct device, kobj)->parent->parent; 191 container_of(kobj, struct device, kobj)->parent->parent;
208 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
209 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 192 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
210 int retval = 0; 193 ssize_t retval;
211 int difference;
212 int profile_number;
213 struct pyra_profile_buttons *profile_buttons;
214
215 if (off != 0 || count != sizeof(struct pyra_profile_buttons))
216 return -EINVAL;
217
218 profile_number = ((struct pyra_profile_buttons const *)buf)->number;
219 profile_buttons = &pyra->profile_buttons[profile_number];
220
221 mutex_lock(&pyra->pyra_lock);
222 difference = memcmp(buf, profile_buttons,
223 sizeof(struct pyra_profile_buttons));
224 if (difference) {
225 retval = pyra_set_profile_buttons(usb_dev,
226 (struct pyra_profile_buttons const *)buf);
227 if (!retval)
228 memcpy(profile_buttons, buf,
229 sizeof(struct pyra_profile_buttons));
230 }
231 mutex_unlock(&pyra->pyra_lock);
232 194
195 retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
196 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
233 if (retval) 197 if (retval)
234 return retval; 198 return retval;
235 199
236 return sizeof(struct pyra_profile_buttons); 200 return pyra_sysfs_read(fp, kobj, buf, off, count,
201 PYRA_SIZE_PROFILE_SETTINGS,
202 PYRA_COMMAND_PROFILE_SETTINGS);
237} 203}
238 204
239static ssize_t pyra_sysfs_read_settings(struct file *fp, 205static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
240 struct kobject *kobj, struct bin_attribute *attr, char *buf, 206 struct kobject *kobj, struct bin_attribute *attr, char *buf,
241 loff_t off, size_t count) 207 loff_t off, size_t count)
242{ 208{
243 struct device *dev = 209 struct device *dev =
244 container_of(kobj, struct device, kobj)->parent->parent; 210 container_of(kobj, struct device, kobj)->parent->parent;
245 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); 211 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
246 212 ssize_t retval;
247 if (off >= sizeof(struct pyra_settings))
248 return 0;
249
250 if (off + count > sizeof(struct pyra_settings))
251 count = sizeof(struct pyra_settings) - off;
252 213
253 mutex_lock(&pyra->pyra_lock); 214 retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
254 memcpy(buf, ((char const *)&pyra->settings) + off, count); 215 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
255 mutex_unlock(&pyra->pyra_lock); 216 if (retval)
217 return retval;
256 218
257 return count; 219 return pyra_sysfs_read(fp, kobj, buf, off, count,
220 PYRA_SIZE_PROFILE_BUTTONS,
221 PYRA_COMMAND_PROFILE_BUTTONS);
258} 222}
259 223
260static ssize_t pyra_sysfs_write_settings(struct file *fp, 224static ssize_t pyra_sysfs_write_settings(struct file *fp,
@@ -266,35 +230,32 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
266 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); 230 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
267 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 231 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
268 int retval = 0; 232 int retval = 0;
269 int difference;
270 struct pyra_roccat_report roccat_report; 233 struct pyra_roccat_report roccat_report;
234 struct pyra_settings const *settings;
271 235
272 if (off != 0 || count != sizeof(struct pyra_settings)) 236 if (off != 0 || count != PYRA_SIZE_SETTINGS)
273 return -EINVAL; 237 return -EINVAL;
274 238
275 mutex_lock(&pyra->pyra_lock); 239 mutex_lock(&pyra->pyra_lock);
276 difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings));
277 if (difference) {
278 retval = pyra_set_settings(usb_dev,
279 (struct pyra_settings const *)buf);
280 if (retval) {
281 mutex_unlock(&pyra->pyra_lock);
282 return retval;
283 }
284
285 memcpy(&pyra->settings, buf,
286 sizeof(struct pyra_settings));
287 240
288 profile_activated(pyra, pyra->settings.startup_profile); 241 settings = (struct pyra_settings const *)buf;
289 242
290 roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2; 243 retval = pyra_set_settings(usb_dev, settings);
291 roccat_report.value = pyra->settings.startup_profile + 1; 244 if (retval) {
292 roccat_report.key = 0; 245 mutex_unlock(&pyra->pyra_lock);
293 roccat_report_event(pyra->chrdev_minor, 246 return retval;
294 (uint8_t const *)&roccat_report);
295 } 247 }
248
249 profile_activated(pyra, settings->startup_profile);
250
251 roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2;
252 roccat_report.value = settings->startup_profile + 1;
253 roccat_report.key = 0;
254 roccat_report_event(pyra->chrdev_minor,
255 (uint8_t const *)&roccat_report);
256
296 mutex_unlock(&pyra->pyra_lock); 257 mutex_unlock(&pyra->pyra_lock);
297 return sizeof(struct pyra_settings); 258 return PYRA_SIZE_SETTINGS;
298} 259}
299 260
300 261
@@ -311,23 +272,34 @@ static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
311{ 272{
312 struct pyra_device *pyra = 273 struct pyra_device *pyra =
313 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 274 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
314 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile); 275 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
276 struct pyra_settings settings;
277
278 mutex_lock(&pyra->pyra_lock);
279 roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
280 &settings, PYRA_SIZE_SETTINGS);
281 mutex_unlock(&pyra->pyra_lock);
282
283 return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile);
315} 284}
316 285
317static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, 286static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
318 struct device_attribute *attr, char *buf) 287 struct device_attribute *attr, char *buf)
319{ 288{
320 struct pyra_device *pyra = 289 struct pyra_device *pyra;
321 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 290 struct usb_device *usb_dev;
322 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version); 291 struct pyra_info info;
323}
324 292
325static ssize_t pyra_sysfs_show_startup_profile(struct device *dev, 293 dev = dev->parent->parent;
326 struct device_attribute *attr, char *buf) 294 pyra = hid_get_drvdata(dev_get_drvdata(dev));
327{ 295 usb_dev = interface_to_usbdev(to_usb_interface(dev));
328 struct pyra_device *pyra = 296
329 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 297 mutex_lock(&pyra->pyra_lock);
330 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile); 298 roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO,
299 &info, PYRA_SIZE_INFO);
300 mutex_unlock(&pyra->pyra_lock);
301
302 return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
331} 303}
332 304
333static struct device_attribute pyra_attributes[] = { 305static struct device_attribute pyra_attributes[] = {
@@ -336,105 +308,88 @@ static struct device_attribute pyra_attributes[] = {
336 __ATTR(firmware_version, 0440, 308 __ATTR(firmware_version, 0440,
337 pyra_sysfs_show_firmware_version, NULL), 309 pyra_sysfs_show_firmware_version, NULL),
338 __ATTR(startup_profile, 0440, 310 __ATTR(startup_profile, 0440,
339 pyra_sysfs_show_startup_profile, NULL), 311 pyra_sysfs_show_actual_profile, NULL),
340 __ATTR_NULL 312 __ATTR_NULL
341}; 313};
342 314
343static struct bin_attribute pyra_bin_attributes[] = { 315static struct bin_attribute pyra_bin_attributes[] = {
344 { 316 PYRA_BIN_ATTRIBUTE_W(control, CONTROL),
345 .attr = { .name = "profile_settings", .mode = 0220 }, 317 PYRA_BIN_ATTRIBUTE_RW(info, INFO),
346 .size = sizeof(struct pyra_profile_settings), 318 PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
347 .write = pyra_sysfs_write_profile_settings 319 PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
348 }, 320 PYRA_BIN_ATTRIBUTE_RW(settings, SETTINGS),
349 { 321 {
350 .attr = { .name = "profile1_settings", .mode = 0440 }, 322 .attr = { .name = "profile1_settings", .mode = 0440 },
351 .size = sizeof(struct pyra_profile_settings), 323 .size = PYRA_SIZE_PROFILE_SETTINGS,
352 .read = pyra_sysfs_read_profilex_settings, 324 .read = pyra_sysfs_read_profilex_settings,
353 .private = &profile_numbers[0] 325 .private = &profile_numbers[0]
354 }, 326 },
355 { 327 {
356 .attr = { .name = "profile2_settings", .mode = 0440 }, 328 .attr = { .name = "profile2_settings", .mode = 0440 },
357 .size = sizeof(struct pyra_profile_settings), 329 .size = PYRA_SIZE_PROFILE_SETTINGS,
358 .read = pyra_sysfs_read_profilex_settings, 330 .read = pyra_sysfs_read_profilex_settings,
359 .private = &profile_numbers[1] 331 .private = &profile_numbers[1]
360 }, 332 },
361 { 333 {
362 .attr = { .name = "profile3_settings", .mode = 0440 }, 334 .attr = { .name = "profile3_settings", .mode = 0440 },
363 .size = sizeof(struct pyra_profile_settings), 335 .size = PYRA_SIZE_PROFILE_SETTINGS,
364 .read = pyra_sysfs_read_profilex_settings, 336 .read = pyra_sysfs_read_profilex_settings,
365 .private = &profile_numbers[2] 337 .private = &profile_numbers[2]
366 }, 338 },
367 { 339 {
368 .attr = { .name = "profile4_settings", .mode = 0440 }, 340 .attr = { .name = "profile4_settings", .mode = 0440 },
369 .size = sizeof(struct pyra_profile_settings), 341 .size = PYRA_SIZE_PROFILE_SETTINGS,
370 .read = pyra_sysfs_read_profilex_settings, 342 .read = pyra_sysfs_read_profilex_settings,
371 .private = &profile_numbers[3] 343 .private = &profile_numbers[3]
372 }, 344 },
373 { 345 {
374 .attr = { .name = "profile5_settings", .mode = 0440 }, 346 .attr = { .name = "profile5_settings", .mode = 0440 },
375 .size = sizeof(struct pyra_profile_settings), 347 .size = PYRA_SIZE_PROFILE_SETTINGS,
376 .read = pyra_sysfs_read_profilex_settings, 348 .read = pyra_sysfs_read_profilex_settings,
377 .private = &profile_numbers[4] 349 .private = &profile_numbers[4]
378 }, 350 },
379 { 351 {
380 .attr = { .name = "profile_buttons", .mode = 0220 },
381 .size = sizeof(struct pyra_profile_buttons),
382 .write = pyra_sysfs_write_profile_buttons
383 },
384 {
385 .attr = { .name = "profile1_buttons", .mode = 0440 }, 352 .attr = { .name = "profile1_buttons", .mode = 0440 },
386 .size = sizeof(struct pyra_profile_buttons), 353 .size = PYRA_SIZE_PROFILE_BUTTONS,
387 .read = pyra_sysfs_read_profilex_buttons, 354 .read = pyra_sysfs_read_profilex_buttons,
388 .private = &profile_numbers[0] 355 .private = &profile_numbers[0]
389 }, 356 },
390 { 357 {
391 .attr = { .name = "profile2_buttons", .mode = 0440 }, 358 .attr = { .name = "profile2_buttons", .mode = 0440 },
392 .size = sizeof(struct pyra_profile_buttons), 359 .size = PYRA_SIZE_PROFILE_BUTTONS,
393 .read = pyra_sysfs_read_profilex_buttons, 360 .read = pyra_sysfs_read_profilex_buttons,
394 .private = &profile_numbers[1] 361 .private = &profile_numbers[1]
395 }, 362 },
396 { 363 {
397 .attr = { .name = "profile3_buttons", .mode = 0440 }, 364 .attr = { .name = "profile3_buttons", .mode = 0440 },
398 .size = sizeof(struct pyra_profile_buttons), 365 .size = PYRA_SIZE_PROFILE_BUTTONS,
399 .read = pyra_sysfs_read_profilex_buttons, 366 .read = pyra_sysfs_read_profilex_buttons,
400 .private = &profile_numbers[2] 367 .private = &profile_numbers[2]
401 }, 368 },
402 { 369 {
403 .attr = { .name = "profile4_buttons", .mode = 0440 }, 370 .attr = { .name = "profile4_buttons", .mode = 0440 },
404 .size = sizeof(struct pyra_profile_buttons), 371 .size = PYRA_SIZE_PROFILE_BUTTONS,
405 .read = pyra_sysfs_read_profilex_buttons, 372 .read = pyra_sysfs_read_profilex_buttons,
406 .private = &profile_numbers[3] 373 .private = &profile_numbers[3]
407 }, 374 },
408 { 375 {
409 .attr = { .name = "profile5_buttons", .mode = 0440 }, 376 .attr = { .name = "profile5_buttons", .mode = 0440 },
410 .size = sizeof(struct pyra_profile_buttons), 377 .size = PYRA_SIZE_PROFILE_BUTTONS,
411 .read = pyra_sysfs_read_profilex_buttons, 378 .read = pyra_sysfs_read_profilex_buttons,
412 .private = &profile_numbers[4] 379 .private = &profile_numbers[4]
413 }, 380 },
414 {
415 .attr = { .name = "settings", .mode = 0660 },
416 .size = sizeof(struct pyra_settings),
417 .read = pyra_sysfs_read_settings,
418 .write = pyra_sysfs_write_settings
419 },
420 __ATTR_NULL 381 __ATTR_NULL
421}; 382};
422 383
423static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, 384static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
424 struct pyra_device *pyra) 385 struct pyra_device *pyra)
425{ 386{
426 struct pyra_info info; 387 struct pyra_settings settings;
427 int retval, i; 388 int retval, i;
428 389
429 mutex_init(&pyra->pyra_lock); 390 mutex_init(&pyra->pyra_lock);
430 391
431 retval = pyra_get_info(usb_dev, &info); 392 retval = pyra_get_settings(usb_dev, &settings);
432 if (retval)
433 return retval;
434
435 pyra->firmware_version = info.firmware_version;
436
437 retval = pyra_get_settings(usb_dev, &pyra->settings);
438 if (retval) 393 if (retval)
439 return retval; 394 return retval;
440 395
@@ -443,14 +398,9 @@ static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
443 &pyra->profile_settings[i], i); 398 &pyra->profile_settings[i], i);
444 if (retval) 399 if (retval)
445 return retval; 400 return retval;
446
447 retval = pyra_get_profile_buttons(usb_dev,
448 &pyra->profile_buttons[i], i);
449 if (retval)
450 return retval;
451 } 401 }
452 402
453 profile_activated(pyra, pyra->settings.startup_profile); 403 profile_activated(pyra, settings.startup_profile);
454 404
455 return 0; 405 return 0;
456} 406}
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h
index eada7830fa99..beedcf001ceb 100644
--- a/drivers/hid/hid-roccat-pyra.h
+++ b/drivers/hid/hid-roccat-pyra.h
@@ -14,11 +14,13 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16 16
17struct pyra_b { 17enum {
18 uint8_t command; /* PYRA_COMMAND_B */ 18 PYRA_SIZE_CONTROL = 0x03,
19 uint8_t size; /* always 3 */ 19 PYRA_SIZE_INFO = 0x06,
20 uint8_t unknown; /* 1 */ 20 PYRA_SIZE_PROFILE_SETTINGS = 0x0d,
21} __attribute__ ((__packed__)); 21 PYRA_SIZE_PROFILE_BUTTONS = 0x13,
22 PYRA_SIZE_SETTINGS = 0x03,
23};
22 24
23enum pyra_control_requests { 25enum pyra_control_requests {
24 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, 26 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
@@ -46,14 +48,6 @@ struct pyra_profile_settings {
46 uint16_t checksum; /* byte sum */ 48 uint16_t checksum; /* byte sum */
47} __attribute__ ((__packed__)); 49} __attribute__ ((__packed__));
48 50
49struct pyra_profile_buttons {
50 uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */
51 uint8_t size; /* always 0x13 */
52 uint8_t number; /* Range 0-4 */
53 uint8_t buttons[14];
54 uint16_t checksum; /* byte sum */
55} __attribute__ ((__packed__));
56
57struct pyra_info { 51struct pyra_info {
58 uint8_t command; /* PYRA_COMMAND_INFO */ 52 uint8_t command; /* PYRA_COMMAND_INFO */
59 uint8_t size; /* always 6 */ 53 uint8_t size; /* always 6 */
@@ -64,6 +58,7 @@ struct pyra_info {
64} __attribute__ ((__packed__)); 58} __attribute__ ((__packed__));
65 59
66enum pyra_commands { 60enum pyra_commands {
61 PYRA_COMMAND_CONTROL = 0x4,
67 PYRA_COMMAND_SETTINGS = 0x5, 62 PYRA_COMMAND_SETTINGS = 0x5,
68 PYRA_COMMAND_PROFILE_SETTINGS = 0x6, 63 PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
69 PYRA_COMMAND_PROFILE_BUTTONS = 0x7, 64 PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
@@ -148,13 +143,10 @@ struct pyra_roccat_report {
148struct pyra_device { 143struct pyra_device {
149 int actual_profile; 144 int actual_profile;
150 int actual_cpi; 145 int actual_cpi;
151 int firmware_version;
152 int roccat_claimed; 146 int roccat_claimed;
153 int chrdev_minor; 147 int chrdev_minor;
154 struct mutex pyra_lock; 148 struct mutex pyra_lock;
155 struct pyra_settings settings;
156 struct pyra_profile_settings profile_settings[5]; 149 struct pyra_profile_settings profile_settings[5];
157 struct pyra_profile_buttons profile_buttons[5];
158}; 150};
159 151
160#endif 152#endif
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c
index 014afba407e0..31747a29c093 100644
--- a/drivers/hid/hid-roccat-savu.c
+++ b/drivers/hid/hid-roccat-savu.c
@@ -120,7 +120,7 @@ SAVU_SYSFS_RW(profile, PROFILE)
120SAVU_SYSFS_RW(general, GENERAL) 120SAVU_SYSFS_RW(general, GENERAL)
121SAVU_SYSFS_RW(buttons, BUTTONS) 121SAVU_SYSFS_RW(buttons, BUTTONS)
122SAVU_SYSFS_RW(macro, MACRO) 122SAVU_SYSFS_RW(macro, MACRO)
123SAVU_SYSFS_R(info, INFO) 123SAVU_SYSFS_RW(info, INFO)
124SAVU_SYSFS_RW(sensor, SENSOR) 124SAVU_SYSFS_RW(sensor, SENSOR)
125 125
126static struct bin_attribute savu_bin_attributes[] = { 126static struct bin_attribute savu_bin_attributes[] = {
@@ -129,7 +129,7 @@ static struct bin_attribute savu_bin_attributes[] = {
129 SAVU_BIN_ATTRIBUTE_RW(general, GENERAL), 129 SAVU_BIN_ATTRIBUTE_RW(general, GENERAL),
130 SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS), 130 SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS),
131 SAVU_BIN_ATTRIBUTE_RW(macro, MACRO), 131 SAVU_BIN_ATTRIBUTE_RW(macro, MACRO),
132 SAVU_BIN_ATTRIBUTE_R(info, INFO), 132 SAVU_BIN_ATTRIBUTE_RW(info, INFO),
133 SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR), 133 SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR),
134 __ATTR_NULL 134 __ATTR_NULL
135}; 135};
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index d9d73e9163eb..0bc58bd8d4f5 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -82,23 +82,6 @@ struct hid_sensor_hub_callbacks_list {
82 void *priv; 82 void *priv;
83}; 83};
84 84
85static int sensor_hub_check_for_sensor_page(struct hid_device *hdev)
86{
87 int i;
88 int ret = -EINVAL;
89
90 for (i = 0; i < hdev->maxcollection; i++) {
91 struct hid_collection *col = &hdev->collection[i];
92 if (col->type == HID_COLLECTION_PHYSICAL &&
93 (col->usage & HID_USAGE_PAGE) == HID_UP_SENSOR) {
94 ret = 0;
95 break;
96 }
97 }
98
99 return ret;
100}
101
102static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev, 85static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev,
103 int dir) 86 int dir)
104{ 87{
@@ -437,9 +420,6 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
437 ptr = raw_data; 420 ptr = raw_data;
438 ptr++; /*Skip report id*/ 421 ptr++; /*Skip report id*/
439 422
440 if (!report)
441 goto err_report;
442
443 spin_lock_irqsave(&pdata->lock, flags); 423 spin_lock_irqsave(&pdata->lock, flags);
444 424
445 for (i = 0; i < report->maxfield; ++i) { 425 for (i = 0; i < report->maxfield; ++i) {
@@ -485,7 +465,6 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
485 callback->pdev); 465 callback->pdev);
486 spin_unlock_irqrestore(&pdata->lock, flags); 466 spin_unlock_irqrestore(&pdata->lock, flags);
487 467
488err_report:
489 return 1; 468 return 1;
490} 469}
491 470
@@ -524,10 +503,6 @@ static int sensor_hub_probe(struct hid_device *hdev,
524 hid_err(hdev, "parse failed\n"); 503 hid_err(hdev, "parse failed\n");
525 goto err_free; 504 goto err_free;
526 } 505 }
527 if (sensor_hub_check_for_sensor_page(hdev) < 0) {
528 hid_err(hdev, "sensor page not found\n");
529 goto err_free;
530 }
531 INIT_LIST_HEAD(&hdev->inputs); 506 INIT_LIST_HEAD(&hdev->inputs);
532 507
533 ret = hid_hw_start(hdev, 0); 508 ret = hid_hw_start(hdev, 0);
@@ -630,16 +605,7 @@ static void sensor_hub_remove(struct hid_device *hdev)
630} 605}
631 606
632static const struct hid_device_id sensor_hub_devices[] = { 607static const struct hid_device_id sensor_hub_devices[] = {
633 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, 608 { HID_DEVICE(BUS_USB, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) },
634 USB_DEVICE_ID_SENSOR_HUB_1020) },
635 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087,
636 USB_DEVICE_ID_SENSOR_HUB_1020) },
637 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086,
638 USB_DEVICE_ID_SENSOR_HUB_09FA) },
639 { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087,
640 USB_DEVICE_ID_SENSOR_HUB_09FA) },
641 { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
642 USB_DEVICE_ID_SENSOR_HUB_7014) },
643 { } 609 { }
644}; 610};
645MODULE_DEVICE_TABLE(hid, sensor_hub_devices); 611MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 7c47fc3f7b2b..413a73187d33 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -57,10 +57,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
57 set_current_state(TASK_INTERRUPTIBLE); 57 set_current_state(TASK_INTERRUPTIBLE);
58 58
59 while (list->head == list->tail) { 59 while (list->head == list->tail) {
60 if (file->f_flags & O_NONBLOCK) {
61 ret = -EAGAIN;
62 break;
63 }
64 if (signal_pending(current)) { 60 if (signal_pending(current)) {
65 ret = -ERESTARTSYS; 61 ret = -ERESTARTSYS;
66 break; 62 break;
@@ -69,6 +65,10 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
69 ret = -EIO; 65 ret = -EIO;
70 break; 66 break;
71 } 67 }
68 if (file->f_flags & O_NONBLOCK) {
69 ret = -EAGAIN;
70 break;
71 }
72 72
73 /* allow O_NONBLOCK to work well from other threads */ 73 /* allow O_NONBLOCK to work well from other threads */
74 mutex_unlock(&list->read_mutex); 74 mutex_unlock(&list->read_mutex);
@@ -295,6 +295,13 @@ out:
295 295
296} 296}
297 297
298static int hidraw_fasync(int fd, struct file *file, int on)
299{
300 struct hidraw_list *list = file->private_data;
301
302 return fasync_helper(fd, file, on, &list->fasync);
303}
304
298static int hidraw_release(struct inode * inode, struct file * file) 305static int hidraw_release(struct inode * inode, struct file * file)
299{ 306{
300 unsigned int minor = iminor(inode); 307 unsigned int minor = iminor(inode);
@@ -438,6 +445,7 @@ static const struct file_operations hidraw_ops = {
438 .open = hidraw_open, 445 .open = hidraw_open,
439 .release = hidraw_release, 446 .release = hidraw_release,
440 .unlocked_ioctl = hidraw_ioctl, 447 .unlocked_ioctl = hidraw_ioctl,
448 .fasync = hidraw_fasync,
441#ifdef CONFIG_COMPAT 449#ifdef CONFIG_COMPAT
442 .compat_ioctl = hidraw_ioctl, 450 .compat_ioctl = hidraw_ioctl,
443#endif 451#endif
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 11c7932dc7e6..ac9e35228254 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -72,6 +72,7 @@ static const struct hid_blacklist {
72 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, 72 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
73 { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, 73 { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
74 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, 74 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
75 { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
75 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, 76 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
76 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, 77 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
77 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, 78 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS },
@@ -79,9 +80,11 @@ static const struct hid_blacklist {
79 { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET }, 80 { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET },
80 { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, 81 { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET },
81 { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, 82 { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET },
83 { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET },
82 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, 84 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
83 { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, 85 { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET },
84 { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, 86 { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET },
87 { USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN, HID_QUIRK_NOGET },
85 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, 88 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
86 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, 89 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
87 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, 90 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 14599e256791..87bd64959a91 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -361,10 +361,6 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
361 prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE); 361 prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE);
362 362
363 while (list->head == list->tail) { 363 while (list->head == list->tail) {
364 if (file->f_flags & O_NONBLOCK) {
365 retval = -EAGAIN;
366 break;
367 }
368 if (signal_pending(current)) { 364 if (signal_pending(current)) {
369 retval = -ERESTARTSYS; 365 retval = -ERESTARTSYS;
370 break; 366 break;
@@ -373,6 +369,10 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
373 retval = -EIO; 369 retval = -EIO;
374 break; 370 break;
375 } 371 }
372 if (file->f_flags & O_NONBLOCK) {
373 retval = -EAGAIN;
374 break;
375 }
376 376
377 /* let O_NONBLOCK tasks run */ 377 /* let O_NONBLOCK tasks run */
378 mutex_unlock(&list->thread_lock); 378 mutex_unlock(&list->thread_lock);
@@ -625,7 +625,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
625 break; 625 break;
626 626
627 case HIDIOCAPPLICATION: 627 case HIDIOCAPPLICATION:
628 if (arg < 0 || arg >= hid->maxapplication) 628 if (arg >= hid->maxapplication)
629 break; 629 break;
630 630
631 for (i = 0; i < hid->maxcollection; i++) 631 for (i = 0; i < hid->maxcollection; i++)