aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Achatz <erazor_de@users.sourceforge.net>2010-08-29 06:30:18 -0400
committerJiri Kosina <jkosina@suse.cz>2010-09-01 06:41:17 -0400
commitcb7cf3da0daa9830e00640da8f7d2380f4b4de42 (patch)
tree709b4c7dd0d0d99fd41e74824a1188585f7d0cd4
parent763008c4357b73c8d18396dfd8d79dc58fa3f99d (diff)
HID: roccat: add driver for Roccat Pyra mouse
This patch add support for Pyra mobile gaming mouse from Roccat. It provides access to profiles, settings, actual settings etc. through sysfs attributes. This driver is conceptual similar to the existing Kone driver. Userland tools can soon be found at http://sourceforge.net/projects/roccat Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra98
-rw-r--r--drivers/hid/Kconfig7
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/hid/hid-roccat-pyra.c964
-rw-r--r--drivers/hid/hid-roccat-pyra.h186
7 files changed, 1259 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
new file mode 100644
index 000000000000..ad1125b02ff4
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
@@ -0,0 +1,98 @@
1What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_cpi
2Date: August 2010
3Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
4Description: It is possible to switch the cpi setting of the mouse with the
5 press of a button.
6 When read, this file returns the raw number of the actual cpi
7 setting reported by the mouse. This number has to be further
8 processed to receive the real dpi value.
9
10 VALUE DPI
11 1 400
12 2 800
13 4 1600
14
15 This file is readonly.
16
17What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_profile
18Date: August 2010
19Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
20Description: When read, this file returns the number of the actual profile in
21 range 0-4.
22 This file is readonly.
23
24What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/firmware_version
25Date: August 2010
26Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
27Description: When read, this file returns the raw integer version number of the
28 firmware reported by the mouse. Using the integer value eases
29 further usage in other programs. To receive the real version
30 number the decimal point has to be shifted 2 positions to the
31 left. E.g. a returned value of 138 means 1.38
32 This file is readonly.
33
34What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile_settings
35Date: August 2010
36Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
37Description: The mouse can store 5 profiles which can be switched by the
38 press of a button. A profile is split in settings and buttons.
39 profile_settings holds informations like resolution, sensitivity
40 and light effects.
41 When written, this file lets one write the respective profile
42 settings back to the mouse. The data has to be 13 bytes long.
43 The mouse will reject invalid data.
44 Which profile to write is determined by the profile number
45 contained in the data.
46 This file is writeonly.
47
48What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]_settings
49Date: August 2010
50Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
51Description: The mouse can store 5 profiles which can be switched by the
52 press of a button. A profile is split in settings and buttons.
53 profile_settings holds informations like resolution, sensitivity
54 and light effects.
55 When read, these files return the respective profile settings.
56 The returned data is 13 bytes in size.
57 This file is readonly.
58
59What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile_buttons
60Date: August 2010
61Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
62Description: The mouse can store 5 profiles which can be switched by the
63 press of a button. A profile is split in settings and buttons.
64 profile_buttons holds informations about button layout.
65 When written, this file lets one write the respective profile
66 buttons back to the mouse. The data has to be 19 bytes long.
67 The mouse will reject invalid data.
68 Which profile to write is determined by the profile number
69 contained in the data.
70 This file is writeonly.
71
72What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]_buttons
73Date: August 2010
74Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
75Description: The mouse can store 5 profiles which can be switched by the
76 press of a button. A profile is split in settings and buttons.
77 profile_buttons holds informations about button layout.
78 When read, these files return the respective profile buttons.
79 The returned data is 19 bytes in size.
80 This file is readonly.
81
82What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/startup_profile
83Date: August 2010
84Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
85Description: The integer value of this attribute ranges from 0-4.
86 When read, this attribute returns the number of the profile
87 that's active when the mouse is powered on.
88 This file is readonly.
89
90What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/settings
91Date: August 2010
92Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
93Description: When read, this file returns the settings stored in the mouse.
94 The size of the data is 3 bytes and holds information on the
95 startup_profile.
96 When written, this file lets write settings back to the mouse.
97 The data has to be 3 bytes long. The mouse will reject invalid
98 data.
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 6369ba7f96f8..b07440a172b5 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -376,6 +376,13 @@ config HID_ROCCAT_KONE
376 ---help--- 376 ---help---
377 Support for Roccat Kone mouse. 377 Support for Roccat Kone mouse.
378 378
379config HID_ROCCAT_PYRA
380 tristate "Roccat Pyra mouse support"
381 depends on USB_HID
382 select HID_ROCCAT
383 ---help---
384 Support for Roccat Pyra mouse.
385
379config HID_SAMSUNG 386config HID_SAMSUNG
380 tristate "Samsung" 387 tristate "Samsung"
381 depends on USB_HID 388 depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 46f037f3df80..d224fa342187 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
52obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o 52obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
53obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o 53obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
54obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o 54obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
55obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
55obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 56obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
56obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 57obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
57obj-$(CONFIG_HID_SONY) += hid-sony.o 58obj-$(CONFIG_HID_SONY) += hid-sony.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 0c52899be964..18608b89e76b 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1367,6 +1367,7 @@ static const struct hid_device_id hid_blacklist[] = {
1367 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 1367 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
1368 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, 1368 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
1369 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, 1369 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
1370 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
1370 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1371 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1371 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, 1372 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
1372 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1373 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 85c6d13c9ffa..5787b1a1339f 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -459,6 +459,8 @@
459 459
460#define USB_VENDOR_ID_ROCCAT 0x1e7d 460#define USB_VENDOR_ID_ROCCAT 0x1e7d
461#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced 461#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
462#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
463#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
462 464
463#define USB_VENDOR_ID_SAITEK 0x06a3 465#define USB_VENDOR_ID_SAITEK 0x06a3
464#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 466#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
new file mode 100644
index 000000000000..6c09c15d93ed
--- /dev/null
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -0,0 +1,964 @@
1/*
2 * Roccat Pyra driver for Linux
3 *
4 * Copyright (c) 2010 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 Pyra is a mobile gamer mouse which comes in wired and wireless
16 * variant. Wireless variant is not tested.
17 * Userland tools can be found at http://sourceforge.net/projects/roccat
18 */
19
20#include <linux/device.h>
21#include <linux/input.h>
22#include <linux/hid.h>
23#include <linux/usb.h>
24#include <linux/module.h>
25#include <linux/slab.h>
26#include "hid-ids.h"
27#include "hid-roccat.h"
28#include "hid-roccat-pyra.h"
29
30static void profile_activated(struct pyra_device *pyra,
31 unsigned int new_profile)
32{
33 pyra->actual_profile = new_profile;
34 pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
35}
36
37static int pyra_send_control(struct usb_device *usb_dev, int value,
38 enum pyra_control_requests request)
39{
40 int len;
41 struct pyra_control control;
42
43 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
44 request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
45 (value < 0 || value > 4))
46 return -EINVAL;
47
48 control.command = PYRA_COMMAND_CONTROL;
49 control.value = value;
50 control.request = request;
51
52 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
53 USB_REQ_SET_CONFIGURATION,
54 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
55 PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
56 sizeof(struct pyra_control),
57 USB_CTRL_SET_TIMEOUT);
58
59 if (len != sizeof(struct pyra_control))
60 return len;
61
62 return 0;
63}
64
65static int pyra_receive_control_status(struct usb_device *usb_dev)
66{
67 int len;
68 struct pyra_control control;
69
70 do {
71 msleep(10);
72
73 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
74 USB_REQ_CLEAR_FEATURE,
75 USB_TYPE_CLASS | USB_RECIP_INTERFACE |
76 USB_DIR_IN,
77 PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
78 sizeof(struct pyra_control),
79 USB_CTRL_SET_TIMEOUT);
80
81 /* requested too early, try again */
82 } while (len == -EPROTO);
83
84 if (len == sizeof(struct pyra_control) &&
85 control.command == PYRA_COMMAND_CONTROL &&
86 control.request == PYRA_CONTROL_REQUEST_STATUS &&
87 control.value == 1)
88 return 0;
89 else {
90 dev_err(&usb_dev->dev, "receive control status: "
91 "unknown response 0x%x 0x%x\n",
92 control.request, control.value);
93 return -EINVAL;
94 }
95}
96
97static int pyra_get_profile_settings(struct usb_device *usb_dev,
98 struct pyra_profile_settings *buf, int number)
99{
100 int retval;
101
102 retval = pyra_send_control(usb_dev, number,
103 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
104
105 if (retval)
106 return retval;
107
108 retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
109 USB_REQ_CLEAR_FEATURE,
110 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
111 PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)buf,
112 sizeof(struct pyra_profile_settings),
113 USB_CTRL_SET_TIMEOUT);
114
115 if (retval != sizeof(struct pyra_profile_settings))
116 return retval;
117
118 return 0;
119}
120
121static int pyra_get_profile_buttons(struct usb_device *usb_dev,
122 struct pyra_profile_buttons *buf, int number)
123{
124 int retval;
125
126 retval = pyra_send_control(usb_dev, number,
127 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
128
129 if (retval)
130 return retval;
131
132 retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
133 USB_REQ_CLEAR_FEATURE,
134 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
135 PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buf,
136 sizeof(struct pyra_profile_buttons),
137 USB_CTRL_SET_TIMEOUT);
138
139 if (retval != sizeof(struct pyra_profile_buttons))
140 return retval;
141
142 return 0;
143}
144
145static int pyra_get_settings(struct usb_device *usb_dev,
146 struct pyra_settings *buf)
147{
148 int len;
149 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
150 USB_REQ_CLEAR_FEATURE,
151 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
152 PYRA_USB_COMMAND_SETTINGS, 0, buf,
153 sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
154 if (len != sizeof(struct pyra_settings))
155 return -EIO;
156 return 0;
157}
158
159static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
160{
161 int len;
162 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
163 USB_REQ_CLEAR_FEATURE,
164 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
165 PYRA_USB_COMMAND_INFO, 0, buf,
166 sizeof(struct pyra_info), USB_CTRL_SET_TIMEOUT);
167 if (len != sizeof(struct pyra_info))
168 return -EIO;
169 return 0;
170}
171
172static int pyra_set_profile_settings(struct usb_device *usb_dev,
173 struct pyra_profile_settings const *settings)
174{
175 int len;
176 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
177 USB_REQ_SET_CONFIGURATION,
178 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
179 PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)settings,
180 sizeof(struct pyra_profile_settings),
181 USB_CTRL_SET_TIMEOUT);
182 if (len != sizeof(struct pyra_profile_settings))
183 return -EIO;
184 if (pyra_receive_control_status(usb_dev))
185 return -EIO;
186 return 0;
187}
188
189static int pyra_set_profile_buttons(struct usb_device *usb_dev,
190 struct pyra_profile_buttons const *buttons)
191{
192 int len;
193 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
194 USB_REQ_SET_CONFIGURATION,
195 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
196 PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buttons,
197 sizeof(struct pyra_profile_buttons),
198 USB_CTRL_SET_TIMEOUT);
199 if (len != sizeof(struct pyra_profile_buttons))
200 return -EIO;
201 if (pyra_receive_control_status(usb_dev))
202 return -EIO;
203 return 0;
204}
205
206static int pyra_set_settings(struct usb_device *usb_dev,
207 struct pyra_settings const *settings)
208{
209 int len;
210 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
211 USB_REQ_SET_CONFIGURATION,
212 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
213 PYRA_USB_COMMAND_SETTINGS, 0, (char *)settings,
214 sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
215 if (len != sizeof(struct pyra_settings))
216 return -EIO;
217 if (pyra_receive_control_status(usb_dev))
218 return -EIO;
219 return 0;
220}
221
222static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
223 struct kobject *kobj, struct bin_attribute *attr, char *buf,
224 loff_t off, size_t count, int number)
225{
226 struct device *dev = container_of(kobj, struct device, kobj);
227 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
228
229 if (off >= sizeof(struct pyra_profile_settings))
230 return 0;
231
232 if (off + count > sizeof(struct pyra_profile_settings))
233 count = sizeof(struct pyra_profile_settings) - off;
234
235 mutex_lock(&pyra->pyra_lock);
236 memcpy(buf, ((char const *)&pyra->profile_settings[number]) + off,
237 count);
238 mutex_unlock(&pyra->pyra_lock);
239
240 return count;
241}
242
243static ssize_t pyra_sysfs_read_profile1_settings(struct file *fp,
244 struct kobject *kobj, struct bin_attribute *attr, char *buf,
245 loff_t off, size_t count)
246{
247 return pyra_sysfs_read_profilex_settings(fp, kobj,
248 attr, buf, off, count, 0);
249}
250
251static ssize_t pyra_sysfs_read_profile2_settings(struct file *fp,
252 struct kobject *kobj, struct bin_attribute *attr, char *buf,
253 loff_t off, size_t count)
254{
255 return pyra_sysfs_read_profilex_settings(fp, kobj,
256 attr, buf, off, count, 1);
257}
258
259static ssize_t pyra_sysfs_read_profile3_settings(struct file *fp,
260 struct kobject *kobj, struct bin_attribute *attr, char *buf,
261 loff_t off, size_t count)
262{
263 return pyra_sysfs_read_profilex_settings(fp, kobj,
264 attr, buf, off, count, 2);
265}
266
267static ssize_t pyra_sysfs_read_profile4_settings(struct file *fp,
268 struct kobject *kobj, struct bin_attribute *attr, char *buf,
269 loff_t off, size_t count)
270{
271 return pyra_sysfs_read_profilex_settings(fp, kobj,
272 attr, buf, off, count, 3);
273}
274
275static ssize_t pyra_sysfs_read_profile5_settings(struct file *fp,
276 struct kobject *kobj, struct bin_attribute *attr, char *buf,
277 loff_t off, size_t count)
278{
279 return pyra_sysfs_read_profilex_settings(fp, kobj,
280 attr, buf, off, count, 4);
281}
282
283static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
284 struct kobject *kobj, struct bin_attribute *attr, char *buf,
285 loff_t off, size_t count, int number)
286{
287 struct device *dev = container_of(kobj, struct device, kobj);
288 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
289
290 if (off >= sizeof(struct pyra_profile_buttons))
291 return 0;
292
293 if (off + count > sizeof(struct pyra_profile_buttons))
294 count = sizeof(struct pyra_profile_buttons) - off;
295
296 mutex_lock(&pyra->pyra_lock);
297 memcpy(buf, ((char const *)&pyra->profile_buttons[number]) + off,
298 count);
299 mutex_unlock(&pyra->pyra_lock);
300
301 return count;
302}
303
304static ssize_t pyra_sysfs_read_profile1_buttons(struct file *fp,
305 struct kobject *kobj, struct bin_attribute *attr, char *buf,
306 loff_t off, size_t count)
307{
308 return pyra_sysfs_read_profilex_buttons(fp, kobj,
309 attr, buf, off, count, 0);
310}
311
312static ssize_t pyra_sysfs_read_profile2_buttons(struct file *fp,
313 struct kobject *kobj, struct bin_attribute *attr, char *buf,
314 loff_t off, size_t count)
315{
316 return pyra_sysfs_read_profilex_buttons(fp, kobj,
317 attr, buf, off, count, 1);
318}
319
320static ssize_t pyra_sysfs_read_profile3_buttons(struct file *fp,
321 struct kobject *kobj, struct bin_attribute *attr, char *buf,
322 loff_t off, size_t count)
323{
324 return pyra_sysfs_read_profilex_buttons(fp, kobj,
325 attr, buf, off, count, 2);
326}
327
328static ssize_t pyra_sysfs_read_profile4_buttons(struct file *fp,
329 struct kobject *kobj, struct bin_attribute *attr, char *buf,
330 loff_t off, size_t count)
331{
332 return pyra_sysfs_read_profilex_buttons(fp, kobj,
333 attr, buf, off, count, 3);
334}
335
336static ssize_t pyra_sysfs_read_profile5_buttons(struct file *fp,
337 struct kobject *kobj, struct bin_attribute *attr, char *buf,
338 loff_t off, size_t count)
339{
340 return pyra_sysfs_read_profilex_buttons(fp, kobj,
341 attr, buf, off, count, 4);
342}
343
344static ssize_t pyra_sysfs_write_profile_settings(struct file *fp,
345 struct kobject *kobj, struct bin_attribute *attr, char *buf,
346 loff_t off, size_t count)
347{
348 struct device *dev = container_of(kobj, struct device, kobj);
349 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
350 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
351 int retval = 0;
352 int difference;
353 int profile_number;
354 struct pyra_profile_settings *profile_settings;
355
356 if (off != 0 || count != sizeof(struct pyra_profile_settings))
357 return -EINVAL;
358
359 profile_number = ((struct pyra_profile_settings const *)buf)->number;
360 profile_settings = &pyra->profile_settings[profile_number];
361
362 mutex_lock(&pyra->pyra_lock);
363 difference = memcmp(buf, profile_settings,
364 sizeof(struct pyra_profile_settings));
365 if (difference) {
366 retval = pyra_set_profile_settings(usb_dev,
367 (struct pyra_profile_settings const *)buf);
368 if (!retval)
369 memcpy(profile_settings, buf,
370 sizeof(struct pyra_profile_settings));
371 }
372 mutex_unlock(&pyra->pyra_lock);
373
374 if (retval)
375 return retval;
376
377 return sizeof(struct pyra_profile_settings);
378}
379
380static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp,
381 struct kobject *kobj, struct bin_attribute *attr, char *buf,
382 loff_t off, size_t count)
383{
384 struct device *dev = container_of(kobj, struct device, kobj);
385 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
386 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
387 int retval = 0;
388 int difference;
389 int profile_number;
390 struct pyra_profile_buttons *profile_buttons;
391
392 if (off != 0 || count != sizeof(struct pyra_profile_buttons))
393 return -EINVAL;
394
395 profile_number = ((struct pyra_profile_buttons const *)buf)->number;
396 profile_buttons = &pyra->profile_buttons[profile_number];
397
398 mutex_lock(&pyra->pyra_lock);
399 difference = memcmp(buf, profile_buttons,
400 sizeof(struct pyra_profile_buttons));
401 if (difference) {
402 retval = pyra_set_profile_buttons(usb_dev,
403 (struct pyra_profile_buttons const *)buf);
404 if (!retval)
405 memcpy(profile_buttons, buf,
406 sizeof(struct pyra_profile_buttons));
407 }
408 mutex_unlock(&pyra->pyra_lock);
409
410 if (retval)
411 return retval;
412
413 return sizeof(struct pyra_profile_buttons);
414}
415
416static ssize_t pyra_sysfs_read_settings(struct file *fp,
417 struct kobject *kobj, struct bin_attribute *attr, char *buf,
418 loff_t off, size_t count)
419{
420 struct device *dev = container_of(kobj, struct device, kobj);
421 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
422
423 if (off >= sizeof(struct pyra_settings))
424 return 0;
425
426 if (off + count > sizeof(struct pyra_settings))
427 count = sizeof(struct pyra_settings) - off;
428
429 mutex_lock(&pyra->pyra_lock);
430 memcpy(buf, ((char const *)&pyra->settings) + off, count);
431 mutex_unlock(&pyra->pyra_lock);
432
433 return count;
434}
435
436static ssize_t pyra_sysfs_write_settings(struct file *fp,
437 struct kobject *kobj, struct bin_attribute *attr, char *buf,
438 loff_t off, size_t count)
439{
440 struct device *dev = container_of(kobj, struct device, kobj);
441 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
442 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
443 int retval = 0;
444 int difference;
445
446 if (off != 0 || count != sizeof(struct pyra_settings))
447 return -EINVAL;
448
449 mutex_lock(&pyra->pyra_lock);
450 difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings));
451 if (difference) {
452 retval = pyra_set_settings(usb_dev,
453 (struct pyra_settings const *)buf);
454 if (!retval)
455 memcpy(&pyra->settings, buf,
456 sizeof(struct pyra_settings));
457 }
458 mutex_unlock(&pyra->pyra_lock);
459
460 if (retval)
461 return retval;
462
463 profile_activated(pyra, pyra->settings.startup_profile);
464
465 return sizeof(struct pyra_settings);
466}
467
468
469static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
470 struct device_attribute *attr, char *buf)
471{
472 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
473 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
474}
475
476static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
477 struct device_attribute *attr, char *buf)
478{
479 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
480 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile);
481}
482
483static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
484 struct device_attribute *attr, char *buf)
485{
486 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
487 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version);
488}
489
490static ssize_t pyra_sysfs_show_startup_profile(struct device *dev,
491 struct device_attribute *attr, char *buf)
492{
493 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
494 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile);
495}
496
497static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL);
498
499static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
500
501static DEVICE_ATTR(firmware_version, 0440,
502 pyra_sysfs_show_firmware_version, NULL);
503
504static DEVICE_ATTR(startup_profile, 0440,
505 pyra_sysfs_show_startup_profile, NULL);
506
507static struct attribute *pyra_attributes[] = {
508 &dev_attr_actual_cpi.attr,
509 &dev_attr_actual_profile.attr,
510 &dev_attr_firmware_version.attr,
511 &dev_attr_startup_profile.attr,
512 NULL
513};
514
515static struct attribute_group pyra_attribute_group = {
516 .attrs = pyra_attributes
517};
518
519static struct bin_attribute pyra_profile_settings_attr = {
520 .attr = { .name = "profile_settings", .mode = 0220 },
521 .size = sizeof(struct pyra_profile_settings),
522 .write = pyra_sysfs_write_profile_settings
523};
524
525static struct bin_attribute pyra_profile1_settings_attr = {
526 .attr = { .name = "profile1_settings", .mode = 0440 },
527 .size = sizeof(struct pyra_profile_settings),
528 .read = pyra_sysfs_read_profile1_settings
529};
530
531static struct bin_attribute pyra_profile2_settings_attr = {
532 .attr = { .name = "profile2_settings", .mode = 0440 },
533 .size = sizeof(struct pyra_profile_settings),
534 .read = pyra_sysfs_read_profile2_settings
535};
536
537static struct bin_attribute pyra_profile3_settings_attr = {
538 .attr = { .name = "profile3_settings", .mode = 0440 },
539 .size = sizeof(struct pyra_profile_settings),
540 .read = pyra_sysfs_read_profile3_settings
541};
542
543static struct bin_attribute pyra_profile4_settings_attr = {
544 .attr = { .name = "profile4_settings", .mode = 0440 },
545 .size = sizeof(struct pyra_profile_settings),
546 .read = pyra_sysfs_read_profile4_settings
547};
548
549static struct bin_attribute pyra_profile5_settings_attr = {
550 .attr = { .name = "profile5_settings", .mode = 0440 },
551 .size = sizeof(struct pyra_profile_settings),
552 .read = pyra_sysfs_read_profile5_settings
553};
554
555static struct bin_attribute pyra_profile_buttons_attr = {
556 .attr = { .name = "profile_buttons", .mode = 0220 },
557 .size = sizeof(struct pyra_profile_buttons),
558 .write = pyra_sysfs_write_profile_buttons
559};
560
561static struct bin_attribute pyra_profile1_buttons_attr = {
562 .attr = { .name = "profile1_buttons", .mode = 0440 },
563 .size = sizeof(struct pyra_profile_buttons),
564 .read = pyra_sysfs_read_profile1_buttons
565};
566
567static struct bin_attribute pyra_profile2_buttons_attr = {
568 .attr = { .name = "profile2_buttons", .mode = 0440 },
569 .size = sizeof(struct pyra_profile_buttons),
570 .read = pyra_sysfs_read_profile2_buttons
571};
572
573static struct bin_attribute pyra_profile3_buttons_attr = {
574 .attr = { .name = "profile3_buttons", .mode = 0440 },
575 .size = sizeof(struct pyra_profile_buttons),
576 .read = pyra_sysfs_read_profile3_buttons
577};
578
579static struct bin_attribute pyra_profile4_buttons_attr = {
580 .attr = { .name = "profile4_buttons", .mode = 0440 },
581 .size = sizeof(struct pyra_profile_buttons),
582 .read = pyra_sysfs_read_profile4_buttons
583};
584
585static struct bin_attribute pyra_profile5_buttons_attr = {
586 .attr = { .name = "profile5_buttons", .mode = 0440 },
587 .size = sizeof(struct pyra_profile_buttons),
588 .read = pyra_sysfs_read_profile5_buttons
589};
590
591static struct bin_attribute pyra_settings_attr = {
592 .attr = { .name = "settings", .mode = 0660 },
593 .size = sizeof(struct pyra_settings),
594 .read = pyra_sysfs_read_settings,
595 .write = pyra_sysfs_write_settings
596};
597
598static int pyra_create_sysfs_attributes(struct usb_interface *intf)
599{
600 int retval;
601
602 retval = sysfs_create_group(&intf->dev.kobj, &pyra_attribute_group);
603 if (retval)
604 goto exit_1;
605
606 retval = sysfs_create_bin_file(&intf->dev.kobj,
607 &pyra_profile_settings_attr);
608 if (retval)
609 goto exit_2;
610
611 retval = sysfs_create_bin_file(&intf->dev.kobj,
612 &pyra_profile1_settings_attr);
613 if (retval)
614 goto exit_3;
615
616 retval = sysfs_create_bin_file(&intf->dev.kobj,
617 &pyra_profile2_settings_attr);
618 if (retval)
619 goto exit_4;
620
621 retval = sysfs_create_bin_file(&intf->dev.kobj,
622 &pyra_profile3_settings_attr);
623 if (retval)
624 goto exit_5;
625
626 retval = sysfs_create_bin_file(&intf->dev.kobj,
627 &pyra_profile4_settings_attr);
628 if (retval)
629 goto exit_6;
630
631 retval = sysfs_create_bin_file(&intf->dev.kobj,
632 &pyra_profile5_settings_attr);
633 if (retval)
634 goto exit_7;
635
636 retval = sysfs_create_bin_file(&intf->dev.kobj,
637 &pyra_profile_buttons_attr);
638 if (retval)
639 goto exit_8;
640
641 retval = sysfs_create_bin_file(&intf->dev.kobj,
642 &pyra_profile1_buttons_attr);
643 if (retval)
644 goto exit_9;
645
646 retval = sysfs_create_bin_file(&intf->dev.kobj,
647 &pyra_profile2_buttons_attr);
648 if (retval)
649 goto exit_10;
650
651 retval = sysfs_create_bin_file(&intf->dev.kobj,
652 &pyra_profile3_buttons_attr);
653 if (retval)
654 goto exit_11;
655
656 retval = sysfs_create_bin_file(&intf->dev.kobj,
657 &pyra_profile4_buttons_attr);
658 if (retval)
659 goto exit_12;
660
661 retval = sysfs_create_bin_file(&intf->dev.kobj,
662 &pyra_profile5_buttons_attr);
663 if (retval)
664 goto exit_13;
665
666 retval = sysfs_create_bin_file(&intf->dev.kobj,
667 &pyra_settings_attr);
668 if (retval)
669 goto exit_14;
670
671 return 0;
672
673exit_14:
674 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
675exit_13:
676 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
677exit_12:
678 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
679exit_11:
680 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
681exit_10:
682 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
683exit_9:
684 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
685exit_8:
686 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
687exit_7:
688 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
689exit_6:
690 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
691exit_5:
692 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
693exit_4:
694 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
695exit_3:
696 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
697exit_2:
698 sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
699exit_1:
700 return retval;
701}
702
703static void pyra_remove_sysfs_attributes(struct usb_interface *intf)
704{
705 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_settings_attr);
706 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
707 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
708 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
709 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
710 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
711 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
712 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
713 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
714 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
715 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
716 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
717 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
718 sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
719}
720
721static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
722 struct pyra_device *pyra)
723{
724 struct pyra_info *info;
725 int retval, i;
726
727 mutex_init(&pyra->pyra_lock);
728
729 info = kmalloc(sizeof(struct pyra_info), GFP_KERNEL);
730 if (!info)
731 return -ENOMEM;
732 retval = pyra_get_info(usb_dev, info);
733 if (retval) {
734 kfree(info);
735 return retval;
736 }
737 pyra->firmware_version = info->firmware_version;
738 kfree(info);
739
740 retval = pyra_get_settings(usb_dev, &pyra->settings);
741 if (retval)
742 return retval;
743
744 for (i = 0; i < 5; ++i) {
745 retval = pyra_get_profile_settings(usb_dev,
746 &pyra->profile_settings[i], i);
747 if (retval)
748 return retval;
749
750 retval = pyra_get_profile_buttons(usb_dev,
751 &pyra->profile_buttons[i], i);
752 if (retval)
753 return retval;
754 }
755
756 profile_activated(pyra, pyra->settings.startup_profile);
757
758 return 0;
759}
760
761static int pyra_init_specials(struct hid_device *hdev)
762{
763 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
764 struct usb_device *usb_dev = interface_to_usbdev(intf);
765 struct pyra_device *pyra;
766 int retval;
767
768 if (intf->cur_altsetting->desc.bInterfaceProtocol
769 == USB_INTERFACE_PROTOCOL_MOUSE) {
770
771 pyra = kzalloc(sizeof(*pyra), GFP_KERNEL);
772 if (!pyra) {
773 dev_err(&hdev->dev, "can't alloc device descriptor\n");
774 return -ENOMEM;
775 }
776 hid_set_drvdata(hdev, pyra);
777
778 retval = pyra_init_pyra_device_struct(usb_dev, pyra);
779 if (retval) {
780 dev_err(&hdev->dev,
781 "couldn't init struct pyra_device\n");
782 goto exit_free;
783 }
784
785 retval = roccat_connect(hdev);
786 if (retval < 0) {
787 dev_err(&hdev->dev, "couldn't init char dev\n");
788 } else {
789 pyra->chrdev_minor = retval;
790 pyra->roccat_claimed = 1;
791 }
792
793 retval = pyra_create_sysfs_attributes(intf);
794 if (retval) {
795 dev_err(&hdev->dev, "cannot create sysfs files\n");
796 goto exit_free;
797 }
798 } else {
799 hid_set_drvdata(hdev, NULL);
800 }
801
802 return 0;
803exit_free:
804 kfree(pyra);
805 return retval;
806}
807
808static void pyra_remove_specials(struct hid_device *hdev)
809{
810 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
811 struct pyra_device *pyra;
812
813 if (intf->cur_altsetting->desc.bInterfaceProtocol
814 == USB_INTERFACE_PROTOCOL_MOUSE) {
815 pyra_remove_sysfs_attributes(intf);
816 pyra = hid_get_drvdata(hdev);
817 if (pyra->roccat_claimed)
818 roccat_disconnect(pyra->chrdev_minor);
819 kfree(hid_get_drvdata(hdev));
820 }
821}
822
823static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
824{
825 int retval;
826
827 retval = hid_parse(hdev);
828 if (retval) {
829 dev_err(&hdev->dev, "parse failed\n");
830 goto exit;
831 }
832
833 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
834 if (retval) {
835 dev_err(&hdev->dev, "hw start failed\n");
836 goto exit;
837 }
838
839 retval = pyra_init_specials(hdev);
840 if (retval) {
841 dev_err(&hdev->dev, "couldn't install mouse\n");
842 goto exit_stop;
843 }
844 return 0;
845
846exit_stop:
847 hid_hw_stop(hdev);
848exit:
849 return retval;
850}
851
852static void pyra_remove(struct hid_device *hdev)
853{
854 pyra_remove_specials(hdev);
855 hid_hw_stop(hdev);
856}
857
858static void pyra_keep_values_up_to_date(struct pyra_device *pyra,
859 u8 const *data)
860{
861 struct pyra_mouse_event_button const *button_event;
862
863 switch (data[0]) {
864 case PYRA_MOUSE_REPORT_NUMBER_BUTTON:
865 button_event = (struct pyra_mouse_event_button const *)data;
866 switch (button_event->type) {
867 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
868 profile_activated(pyra, button_event->data1 - 1);
869 break;
870 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
871 pyra->actual_cpi = button_event->data1;
872 break;
873 }
874 break;
875 }
876}
877
878static void pyra_report_to_chrdev(struct pyra_device const *pyra,
879 u8 const *data)
880{
881 struct pyra_roccat_report roccat_report;
882 struct pyra_mouse_event_button const *button_event;
883
884 if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON)
885 return;
886
887 button_event = (struct pyra_mouse_event_button const *)data;
888
889 switch (button_event->type) {
890 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
891 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
892 roccat_report.type = button_event->type;
893 roccat_report.value = button_event->data1;
894 roccat_report.key = 0;
895 roccat_report_event(pyra->chrdev_minor,
896 (uint8_t const *)&roccat_report,
897 sizeof(struct pyra_roccat_report));
898 break;
899 case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO:
900 case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT:
901 case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH:
902 if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) {
903 roccat_report.type = button_event->type;
904 roccat_report.key = button_event->data1;
905 roccat_report.value = pyra->actual_profile;
906 roccat_report_event(pyra->chrdev_minor,
907 (uint8_t const *)&roccat_report,
908 sizeof(struct pyra_roccat_report));
909 }
910 break;
911 }
912}
913
914static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report,
915 u8 *data, int size)
916{
917 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
918 struct pyra_device *pyra = hid_get_drvdata(hdev);
919
920 if (intf->cur_altsetting->desc.bInterfaceProtocol
921 != USB_INTERFACE_PROTOCOL_MOUSE)
922 return 0;
923
924 pyra_keep_values_up_to_date(pyra, data);
925
926 if (pyra->roccat_claimed)
927 pyra_report_to_chrdev(pyra, data);
928
929 return 0;
930}
931
932static const struct hid_device_id pyra_devices[] = {
933 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
934 USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
935 /* TODO add USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS after testing */
936 { }
937};
938
939MODULE_DEVICE_TABLE(hid, pyra_devices);
940
941static struct hid_driver pyra_driver = {
942 .name = "pyra",
943 .id_table = pyra_devices,
944 .probe = pyra_probe,
945 .remove = pyra_remove,
946 .raw_event = pyra_raw_event
947};
948
949static int __init pyra_init(void)
950{
951 return hid_register_driver(&pyra_driver);
952}
953
954static void __exit pyra_exit(void)
955{
956 hid_unregister_driver(&pyra_driver);
957}
958
959module_init(pyra_init);
960module_exit(pyra_exit);
961
962MODULE_AUTHOR("Stefan Achatz");
963MODULE_DESCRIPTION("USB Roccat Pyra driver");
964MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h
new file mode 100644
index 000000000000..22f80a8f26f9
--- /dev/null
+++ b/drivers/hid/hid-roccat-pyra.h
@@ -0,0 +1,186 @@
1#ifndef __HID_ROCCAT_PYRA_H
2#define __HID_ROCCAT_PYRA_H
3
4/*
5 * Copyright (c) 2010 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
17#pragma pack(push)
18#pragma pack(1)
19
20struct pyra_b {
21 uint8_t command; /* PYRA_COMMAND_B */
22 uint8_t size; /* always 3 */
23 uint8_t unknown; /* 1 */
24};
25
26struct pyra_control {
27 uint8_t command; /* PYRA_COMMAND_CONTROL */
28 /*
29 * value is profile number for request_settings and request_buttons
30 * 1 if status ok for request_status
31 */
32 uint8_t value; /* Range 0-4 */
33 uint8_t request;
34};
35
36enum pyra_control_requests {
37 PYRA_CONTROL_REQUEST_STATUS = 0x00,
38 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
39 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20
40};
41
42struct pyra_settings {
43 uint8_t command; /* PYRA_COMMAND_SETTINGS */
44 uint8_t size; /* always 3 */
45 uint8_t startup_profile; /* Range 0-4! */
46};
47
48struct pyra_profile_settings {
49 uint8_t command; /* PYRA_COMMAND_PROFILE_SETTINGS */
50 uint8_t size; /* always 0xd */
51 uint8_t number; /* Range 0-4 */
52 uint8_t xysync;
53 uint8_t x_sensitivity; /* 0x1-0xa */
54 uint8_t y_sensitivity;
55 uint8_t x_cpi; /* unused */
56 uint8_t y_cpi; /* this value is for x and y */
57 uint8_t lightswitch; /* 0 = off, 1 = on */
58 uint8_t light_effect;
59 uint8_t handedness;
60 uint16_t checksum; /* byte sum */
61};
62
63struct pyra_profile_buttons {
64 uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */
65 uint8_t size; /* always 0x13 */
66 uint8_t number; /* Range 0-4 */
67 uint8_t buttons[14];
68 uint16_t checksum; /* byte sum */
69};
70
71struct pyra_info {
72 uint8_t command; /* PYRA_COMMAND_INFO */
73 uint8_t size; /* always 6 */
74 uint8_t firmware_version;
75 uint8_t unknown1; /* always 0 */
76 uint8_t unknown2; /* always 1 */
77 uint8_t unknown3; /* always 0 */
78};
79
80enum pyra_commands {
81 PYRA_COMMAND_CONTROL = 0x4,
82 PYRA_COMMAND_SETTINGS = 0x5,
83 PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
84 PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
85 PYRA_COMMAND_INFO = 0x9,
86 PYRA_COMMAND_B = 0xb
87};
88
89enum pyra_usb_commands {
90 PYRA_USB_COMMAND_CONTROL = 0x304,
91 PYRA_USB_COMMAND_SETTINGS = 0x305,
92 PYRA_USB_COMMAND_PROFILE_SETTINGS = 0x306,
93 PYRA_USB_COMMAND_PROFILE_BUTTONS = 0x307,
94 PYRA_USB_COMMAND_INFO = 0x309,
95 PYRA_USB_COMMAND_B = 0x30b /* writes 3 bytes */
96};
97
98enum pyra_mouse_report_numbers {
99 PYRA_MOUSE_REPORT_NUMBER_HID = 1,
100 PYRA_MOUSE_REPORT_NUMBER_AUDIO = 2,
101 PYRA_MOUSE_REPORT_NUMBER_BUTTON = 3,
102};
103
104struct pyra_mouse_event_button {
105 uint8_t report_number; /* always 3 */
106 uint8_t unknown; /* always 0 */
107 uint8_t type;
108 uint8_t data1;
109 uint8_t data2;
110};
111
112struct pyra_mouse_event_audio {
113 uint8_t report_number; /* always 2 */
114 uint8_t type;
115 uint8_t unused; /* always 0 */
116};
117
118/* hid audio controls */
119enum pyra_mouse_event_audio_types {
120 PYRA_MOUSE_EVENT_AUDIO_TYPE_MUTE = 0xe2,
121 PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_UP = 0xe9,
122 PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_DOWN = 0xea,
123};
124
125enum pyra_mouse_event_button_types {
126 /*
127 * Mouse sends tilt events on report_number 1 and 3
128 * Tilt events are sent repeatedly with 0.94s between first and second
129 * event and 0.22s on subsequent
130 */
131 PYRA_MOUSE_EVENT_BUTTON_TYPE_TILT = 0x10,
132
133 /*
134 * These are sent sequentially
135 * data1 contains new profile number in range 1-5
136 */
137 PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_1 = 0x20,
138 PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2 = 0x30,
139
140 /*
141 * data1 = button_number (rmp index)
142 * data2 = pressed/released
143 */
144 PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO = 0x40,
145 PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT = 0x50,
146
147 /*
148 * data1 = button_number (rmp index)
149 */
150 PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
151
152 /* data1 = new cpi */
153 PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI = 0xb0,
154
155 /* data1 and data2 = new sensitivity */
156 PYRA_MOUSE_EVENT_BUTTON_TYPE_SENSITIVITY = 0xc0,
157
158 PYRA_MOUSE_EVENT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
159};
160
161enum {
162 PYRA_MOUSE_EVENT_BUTTON_PRESS = 0,
163 PYRA_MOUSE_EVENT_BUTTON_RELEASE = 1,
164};
165
166struct pyra_roccat_report {
167 uint8_t type;
168 uint8_t value;
169 uint8_t key;
170};
171
172#pragma pack(pop)
173
174struct pyra_device {
175 int actual_profile;
176 int actual_cpi;
177 int firmware_version;
178 int roccat_claimed;
179 int chrdev_minor;
180 struct mutex pyra_lock;
181 struct pyra_settings settings;
182 struct pyra_profile_settings profile_settings[5];
183 struct pyra_profile_buttons profile_buttons[5];
184};
185
186#endif