aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorStefan Achatz <erazor_de@users.sourceforge.net>2013-10-28 13:52:05 -0400
committerJiri Kosina <jkosina@suse.cz>2013-10-30 09:17:31 -0400
commit71304f5a269abc25b9277744dfd6925f3e29e26a (patch)
tree1a6f6b7d9480a19f9a2a2d9bc7f6b6bc6dfe178f /drivers/hid
parent14fc4290df2fb94a28f39dab9ed32feaa5527bef (diff)
HID: roccat: generalize some common code
Reduced some duplicate code by moving it to hid-roccat-common. Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-roccat-common.c53
-rw-r--r--drivers/hid/hid-roccat-common.h62
-rw-r--r--drivers/hid/hid-roccat-konepure.c158
-rw-r--r--drivers/hid/hid-roccat-konepure.h72
-rw-r--r--drivers/hid/hid-roccat-savu.c123
-rw-r--r--drivers/hid/hid-roccat-savu.h32
6 files changed, 167 insertions, 333 deletions
diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c
index e84089998900..02e28e9f4ea7 100644
--- a/drivers/hid/hid-roccat-common.c
+++ b/drivers/hid/hid-roccat-common.c
@@ -122,6 +122,59 @@ int roccat_common2_send_with_status(struct usb_device *usb_dev,
122} 122}
123EXPORT_SYMBOL_GPL(roccat_common2_send_with_status); 123EXPORT_SYMBOL_GPL(roccat_common2_send_with_status);
124 124
125int roccat_common2_device_init_struct(struct usb_device *usb_dev,
126 struct roccat_common2_device *dev)
127{
128 mutex_init(&dev->lock);
129 return 0;
130}
131EXPORT_SYMBOL_GPL(roccat_common2_device_init_struct);
132
133ssize_t roccat_common2_sysfs_read(struct file *fp, struct kobject *kobj,
134 char *buf, loff_t off, size_t count,
135 size_t real_size, uint command)
136{
137 struct device *dev =
138 container_of(kobj, struct device, kobj)->parent->parent;
139 struct roccat_common2_device *roccat_dev = hid_get_drvdata(dev_get_drvdata(dev));
140 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
141 int retval;
142
143 if (off >= real_size)
144 return 0;
145
146 if (off != 0 || count != real_size)
147 return -EINVAL;
148
149 mutex_lock(&roccat_dev->lock);
150 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
151 mutex_unlock(&roccat_dev->lock);
152
153 return retval ? retval : real_size;
154}
155EXPORT_SYMBOL_GPL(roccat_common2_sysfs_read);
156
157ssize_t roccat_common2_sysfs_write(struct file *fp, struct kobject *kobj,
158 void const *buf, loff_t off, size_t count,
159 size_t real_size, uint command)
160{
161 struct device *dev =
162 container_of(kobj, struct device, kobj)->parent->parent;
163 struct roccat_common2_device *roccat_dev = hid_get_drvdata(dev_get_drvdata(dev));
164 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
165 int retval;
166
167 if (off != 0 || count != real_size)
168 return -EINVAL;
169
170 mutex_lock(&roccat_dev->lock);
171 retval = roccat_common2_send_with_status(usb_dev, command, buf, real_size);
172 mutex_unlock(&roccat_dev->lock);
173
174 return retval ? retval : real_size;
175}
176EXPORT_SYMBOL_GPL(roccat_common2_sysfs_write);
177
125MODULE_AUTHOR("Stefan Achatz"); 178MODULE_AUTHOR("Stefan Achatz");
126MODULE_DESCRIPTION("USB Roccat common driver"); 179MODULE_DESCRIPTION("USB Roccat common driver");
127MODULE_LICENSE("GPL v2"); 180MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-common.h b/drivers/hid/hid-roccat-common.h
index a97746a63b70..eaa56eb7d5d1 100644
--- a/drivers/hid/hid-roccat-common.h
+++ b/drivers/hid/hid-roccat-common.h
@@ -32,4 +32,66 @@ int roccat_common2_send(struct usb_device *usb_dev, uint report_id,
32int roccat_common2_send_with_status(struct usb_device *usb_dev, 32int roccat_common2_send_with_status(struct usb_device *usb_dev,
33 uint command, void const *buf, uint size); 33 uint command, void const *buf, uint size);
34 34
35struct roccat_common2_device {
36 int roccat_claimed;
37 int chrdev_minor;
38 struct mutex lock;
39};
40
41int roccat_common2_device_init_struct(struct usb_device *usb_dev,
42 struct roccat_common2_device *dev);
43ssize_t roccat_common2_sysfs_read(struct file *fp, struct kobject *kobj,
44 char *buf, loff_t off, size_t count,
45 size_t real_size, uint command);
46ssize_t roccat_common2_sysfs_write(struct file *fp, struct kobject *kobj,
47 void const *buf, loff_t off, size_t count,
48 size_t real_size, uint command);
49
50#define ROCCAT_COMMON2_SYSFS_W(thingy, COMMAND, SIZE) \
51static ssize_t roccat_common2_sysfs_write_ ## thingy(struct file *fp, \
52 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
53 loff_t off, size_t count) \
54{ \
55 return roccat_common2_sysfs_write(fp, kobj, buf, off, count, \
56 SIZE, COMMAND); \
57}
58
59#define ROCCAT_COMMON2_SYSFS_R(thingy, COMMAND, SIZE) \
60static ssize_t roccat_common2_sysfs_read_ ## thingy(struct file *fp, \
61 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
62 loff_t off, size_t count) \
63{ \
64 return roccat_common2_sysfs_read(fp, kobj, buf, off, count, \
65 SIZE, COMMAND); \
66}
67
68#define ROCCAT_COMMON2_SYSFS_RW(thingy, COMMAND, SIZE) \
69ROCCAT_COMMON2_SYSFS_W(thingy, COMMAND, SIZE) \
70ROCCAT_COMMON2_SYSFS_R(thingy, COMMAND, SIZE)
71
72#define ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(thingy, COMMAND, SIZE) \
73ROCCAT_COMMON2_SYSFS_RW(thingy, COMMAND, SIZE); \
74static struct bin_attribute bin_attr_ ## thingy = { \
75 .attr = { .name = #thingy, .mode = 0660 }, \
76 .size = SIZE, \
77 .read = roccat_common2_sysfs_read_ ## thingy, \
78 .write = roccat_common2_sysfs_write_ ## thingy \
79}
80
81#define ROCCAT_COMMON2_BIN_ATTRIBUTE_R(thingy, COMMAND, SIZE) \
82ROCCAT_COMMON2_SYSFS_R(thingy, COMMAND, SIZE); \
83static struct bin_attribute bin_attr_ ## thingy = { \
84 .attr = { .name = #thingy, .mode = 0440 }, \
85 .size = SIZE, \
86 .read = roccat_common2_sysfs_read_ ## thingy, \
87}
88
89#define ROCCAT_COMMON2_BIN_ATTRIBUTE_W(thingy, COMMAND, SIZE) \
90ROCCAT_COMMON2_SYSFS_W(thingy, COMMAND, SIZE); \
91static struct bin_attribute bin_attr_ ## thingy = { \
92 .attr = { .name = #thingy, .mode = 0220 }, \
93 .size = SIZE, \
94 .write = roccat_common2_sysfs_write_ ## thingy \
95}
96
35#endif 97#endif
diff --git a/drivers/hid/hid-roccat-konepure.c b/drivers/hid/hid-roccat-konepure.c
index 99a605ebb665..07de2f9014c6 100644
--- a/drivers/hid/hid-roccat-konepure.c
+++ b/drivers/hid/hid-roccat-konepure.c
@@ -15,6 +15,7 @@
15 * Roccat KonePure is a smaller version of KoneXTD with less buttons and lights. 15 * Roccat KonePure is a smaller version of KoneXTD with less buttons and lights.
16 */ 16 */
17 17
18#include <linux/types.h>
18#include <linux/device.h> 19#include <linux/device.h>
19#include <linux/input.h> 20#include <linux/input.h>
20#include <linux/hid.h> 21#include <linux/hid.h>
@@ -23,128 +24,50 @@
23#include <linux/hid-roccat.h> 24#include <linux/hid-roccat.h>
24#include "hid-ids.h" 25#include "hid-ids.h"
25#include "hid-roccat-common.h" 26#include "hid-roccat-common.h"
26#include "hid-roccat-konepure.h"
27 27
28static struct class *konepure_class; 28enum {
29 29 KONEPURE_MOUSE_REPORT_NUMBER_BUTTON = 3,
30static ssize_t konepure_sysfs_read(struct file *fp, struct kobject *kobj, 30};
31 char *buf, loff_t off, size_t count,
32 size_t real_size, uint command)
33{
34 struct device *dev =
35 container_of(kobj, struct device, kobj)->parent->parent;
36 struct konepure_device *konepure = hid_get_drvdata(dev_get_drvdata(dev));
37 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
38 int retval;
39
40 if (off >= real_size)
41 return 0;
42
43 if (off != 0 || count != real_size)
44 return -EINVAL;
45
46 mutex_lock(&konepure->konepure_lock);
47 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
48 mutex_unlock(&konepure->konepure_lock);
49
50 return retval ? retval : real_size;
51}
52
53static ssize_t konepure_sysfs_write(struct file *fp, struct kobject *kobj,
54 void const *buf, loff_t off, size_t count,
55 size_t real_size, uint command)
56{
57 struct device *dev =
58 container_of(kobj, struct device, kobj)->parent->parent;
59 struct konepure_device *konepure = hid_get_drvdata(dev_get_drvdata(dev));
60 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
61 int retval;
62
63 if (off != 0 || count != real_size)
64 return -EINVAL;
65
66 mutex_lock(&konepure->konepure_lock);
67 retval = roccat_common2_send_with_status(usb_dev, command,
68 (void *)buf, real_size);
69 mutex_unlock(&konepure->konepure_lock);
70
71 return retval ? retval : real_size;
72}
73
74#define KONEPURE_SYSFS_W(thingy, THINGY) \
75static ssize_t konepure_sysfs_write_ ## thingy(struct file *fp, \
76 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
77 loff_t off, size_t count) \
78{ \
79 return konepure_sysfs_write(fp, kobj, buf, off, count, \
80 KONEPURE_SIZE_ ## THINGY, KONEPURE_COMMAND_ ## THINGY); \
81}
82
83#define KONEPURE_SYSFS_R(thingy, THINGY) \
84static ssize_t konepure_sysfs_read_ ## thingy(struct file *fp, \
85 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
86 loff_t off, size_t count) \
87{ \
88 return konepure_sysfs_read(fp, kobj, buf, off, count, \
89 KONEPURE_SIZE_ ## THINGY, KONEPURE_COMMAND_ ## THINGY); \
90}
91 31
92#define KONEPURE_SYSFS_RW(thingy, THINGY) \ 32struct konepure_mouse_report_button {
93KONEPURE_SYSFS_W(thingy, THINGY) \ 33 uint8_t report_number; /* always KONEPURE_MOUSE_REPORT_NUMBER_BUTTON */
94KONEPURE_SYSFS_R(thingy, THINGY) 34 uint8_t zero;
95 35 uint8_t type;
96#define KONEPURE_BIN_ATTRIBUTE_RW(thingy, THINGY) \ 36 uint8_t data1;
97KONEPURE_SYSFS_RW(thingy, THINGY); \ 37 uint8_t data2;
98static struct bin_attribute bin_attr_##thingy = { \ 38 uint8_t zero2;
99 .attr = { .name = #thingy, .mode = 0660 }, \ 39 uint8_t unknown[2];
100 .size = KONEPURE_SIZE_ ## THINGY, \ 40} __packed;
101 .read = konepure_sysfs_read_ ## thingy, \
102 .write = konepure_sysfs_write_ ## thingy \
103}
104 41
105#define KONEPURE_BIN_ATTRIBUTE_R(thingy, THINGY) \ 42static struct class *konepure_class;
106KONEPURE_SYSFS_R(thingy, THINGY); \
107static struct bin_attribute bin_attr_##thingy = { \
108 .attr = { .name = #thingy, .mode = 0440 }, \
109 .size = KONEPURE_SIZE_ ## THINGY, \
110 .read = konepure_sysfs_read_ ## thingy, \
111}
112
113#define KONEPURE_BIN_ATTRIBUTE_W(thingy, THINGY) \
114KONEPURE_SYSFS_W(thingy, THINGY); \
115static struct bin_attribute bin_attr_##thingy = { \
116 .attr = { .name = #thingy, .mode = 0220 }, \
117 .size = KONEPURE_SIZE_ ## THINGY, \
118 .write = konepure_sysfs_write_ ## thingy \
119}
120 43
121KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE); 44ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x04, 0x03);
122KONEPURE_BIN_ATTRIBUTE_RW(info, INFO); 45ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(actual_profile, 0x05, 0x03);
123KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR); 46ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile_settings, 0x06, 0x1f);
124KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU); 47ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile_buttons, 0x07, 0x3b);
125KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS); 48ROCCAT_COMMON2_BIN_ATTRIBUTE_W(macro, 0x08, 0x0822);
126KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS); 49ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(info, 0x09, 0x06);
127KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL); 50ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(tcu, 0x0c, 0x04);
128KONEPURE_BIN_ATTRIBUTE_W(talk, TALK); 51ROCCAT_COMMON2_BIN_ATTRIBUTE_R(tcu_image, 0x0c, 0x0404);
129KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO); 52ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(sensor, 0x0f, 0x06);
130KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE); 53ROCCAT_COMMON2_BIN_ATTRIBUTE_W(talk, 0x10, 0x10);
131 54
132static struct bin_attribute *konepure_bin_attributes[] = { 55static struct bin_attribute *konepure_bin_attrs[] = {
133 &bin_attr_actual_profile, 56 &bin_attr_actual_profile,
57 &bin_attr_control,
134 &bin_attr_info, 58 &bin_attr_info,
59 &bin_attr_talk,
60 &bin_attr_macro,
135 &bin_attr_sensor, 61 &bin_attr_sensor,
136 &bin_attr_tcu, 62 &bin_attr_tcu,
63 &bin_attr_tcu_image,
137 &bin_attr_profile_settings, 64 &bin_attr_profile_settings,
138 &bin_attr_profile_buttons, 65 &bin_attr_profile_buttons,
139 &bin_attr_control,
140 &bin_attr_talk,
141 &bin_attr_macro,
142 &bin_attr_tcu_image,
143 NULL, 66 NULL,
144}; 67};
145 68
146static const struct attribute_group konepure_group = { 69static const struct attribute_group konepure_group = {
147 .bin_attrs = konepure_bin_attributes, 70 .bin_attrs = konepure_bin_attrs,
148}; 71};
149 72
150static const struct attribute_group *konepure_groups[] = { 73static const struct attribute_group *konepure_groups[] = {
@@ -152,20 +75,11 @@ static const struct attribute_group *konepure_groups[] = {
152 NULL, 75 NULL,
153}; 76};
154 77
155
156static int konepure_init_konepure_device_struct(struct usb_device *usb_dev,
157 struct konepure_device *konepure)
158{
159 mutex_init(&konepure->konepure_lock);
160
161 return 0;
162}
163
164static int konepure_init_specials(struct hid_device *hdev) 78static int konepure_init_specials(struct hid_device *hdev)
165{ 79{
166 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 80 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
167 struct usb_device *usb_dev = interface_to_usbdev(intf); 81 struct usb_device *usb_dev = interface_to_usbdev(intf);
168 struct konepure_device *konepure; 82 struct roccat_common2_device *konepure;
169 int retval; 83 int retval;
170 84
171 if (intf->cur_altsetting->desc.bInterfaceProtocol 85 if (intf->cur_altsetting->desc.bInterfaceProtocol
@@ -181,9 +95,9 @@ static int konepure_init_specials(struct hid_device *hdev)
181 } 95 }
182 hid_set_drvdata(hdev, konepure); 96 hid_set_drvdata(hdev, konepure);
183 97
184 retval = konepure_init_konepure_device_struct(usb_dev, konepure); 98 retval = roccat_common2_device_init_struct(usb_dev, konepure);
185 if (retval) { 99 if (retval) {
186 hid_err(hdev, "couldn't init struct konepure_device\n"); 100 hid_err(hdev, "couldn't init KonePure device\n");
187 goto exit_free; 101 goto exit_free;
188 } 102 }
189 103
@@ -205,7 +119,7 @@ exit_free:
205static void konepure_remove_specials(struct hid_device *hdev) 119static void konepure_remove_specials(struct hid_device *hdev)
206{ 120{
207 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 121 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
208 struct konepure_device *konepure; 122 struct roccat_common2_device *konepure;
209 123
210 if (intf->cur_altsetting->desc.bInterfaceProtocol 124 if (intf->cur_altsetting->desc.bInterfaceProtocol
211 != USB_INTERFACE_PROTOCOL_MOUSE) 125 != USB_INTERFACE_PROTOCOL_MOUSE)
@@ -258,7 +172,7 @@ static int konepure_raw_event(struct hid_device *hdev,
258 struct hid_report *report, u8 *data, int size) 172 struct hid_report *report, u8 *data, int size)
259{ 173{
260 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 174 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
261 struct konepure_device *konepure = hid_get_drvdata(hdev); 175 struct roccat_common2_device *konepure = hid_get_drvdata(hdev);
262 176
263 if (intf->cur_altsetting->desc.bInterfaceProtocol 177 if (intf->cur_altsetting->desc.bInterfaceProtocol
264 != USB_INTERFACE_PROTOCOL_MOUSE) 178 != USB_INTERFACE_PROTOCOL_MOUSE)
diff --git a/drivers/hid/hid-roccat-konepure.h b/drivers/hid/hid-roccat-konepure.h
deleted file mode 100644
index 2cd24e93dfd6..000000000000
--- a/drivers/hid/hid-roccat-konepure.h
+++ /dev/null
@@ -1,72 +0,0 @@
1#ifndef __HID_ROCCAT_KONEPURE_H
2#define __HID_ROCCAT_KONEPURE_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 KONEPURE_SIZE_ACTUAL_PROFILE = 0x03,
19 KONEPURE_SIZE_CONTROL = 0x03,
20 KONEPURE_SIZE_FIRMWARE_WRITE = 0x0402,
21 KONEPURE_SIZE_INFO = 0x06,
22 KONEPURE_SIZE_MACRO = 0x0822,
23 KONEPURE_SIZE_PROFILE_SETTINGS = 0x1f,
24 KONEPURE_SIZE_PROFILE_BUTTONS = 0x3b,
25 KONEPURE_SIZE_SENSOR = 0x06,
26 KONEPURE_SIZE_TALK = 0x10,
27 KONEPURE_SIZE_TCU = 0x04,
28 KONEPURE_SIZE_TCU_IMAGE = 0x0404,
29};
30
31enum konepure_control_requests {
32 KONEPURE_CONTROL_REQUEST_GENERAL = 0x80,
33 KONEPURE_CONTROL_REQUEST_BUTTONS = 0x90,
34};
35
36enum konepure_commands {
37 KONEPURE_COMMAND_CONTROL = 0x04,
38 KONEPURE_COMMAND_ACTUAL_PROFILE = 0x05,
39 KONEPURE_COMMAND_PROFILE_SETTINGS = 0x06,
40 KONEPURE_COMMAND_PROFILE_BUTTONS = 0x07,
41 KONEPURE_COMMAND_MACRO = 0x08,
42 KONEPURE_COMMAND_INFO = 0x09,
43 KONEPURE_COMMAND_TCU = 0x0c,
44 KONEPURE_COMMAND_TCU_IMAGE = 0x0c,
45 KONEPURE_COMMAND_E = 0x0e,
46 KONEPURE_COMMAND_SENSOR = 0x0f,
47 KONEPURE_COMMAND_TALK = 0x10,
48 KONEPURE_COMMAND_FIRMWARE_WRITE = 0x1b,
49 KONEPURE_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c,
50};
51
52enum {
53 KONEPURE_MOUSE_REPORT_NUMBER_BUTTON = 3,
54};
55
56struct konepure_mouse_report_button {
57 uint8_t report_number; /* always KONEPURE_MOUSE_REPORT_NUMBER_BUTTON */
58 uint8_t zero;
59 uint8_t type;
60 uint8_t data1;
61 uint8_t data2;
62 uint8_t zero2;
63 uint8_t unknown[2];
64} __packed;
65
66struct konepure_device {
67 int roccat_claimed;
68 int chrdev_minor;
69 struct mutex konepure_lock;
70};
71
72#endif
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c
index 0332267199d5..6dbf6e04dce7 100644
--- a/drivers/hid/hid-roccat-savu.c
+++ b/drivers/hid/hid-roccat-savu.c
@@ -27,98 +27,15 @@
27 27
28static struct class *savu_class; 28static struct class *savu_class;
29 29
30static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj, 30ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x4, 0x03);
31 char *buf, loff_t off, size_t count, 31ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile, 0x5, 0x03);
32 size_t real_size, uint command) 32ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(general, 0x6, 0x10);
33{ 33ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(buttons, 0x7, 0x2f);
34 struct device *dev = 34ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(macro, 0x8, 0x0823);
35 container_of(kobj, struct device, kobj)->parent->parent; 35ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(info, 0x9, 0x08);
36 struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev)); 36ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(sensor, 0xc, 0x04);
37 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 37
38 int retval; 38static struct bin_attribute *savu_bin_attrs[] = {
39
40 if (off >= real_size)
41 return 0;
42
43 if (off != 0 || count != real_size)
44 return -EINVAL;
45
46 mutex_lock(&savu->savu_lock);
47 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
48 mutex_unlock(&savu->savu_lock);
49
50 return retval ? retval : real_size;
51}
52
53static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj,
54 void const *buf, loff_t off, size_t count,
55 size_t real_size, uint command)
56{
57 struct device *dev =
58 container_of(kobj, struct device, kobj)->parent->parent;
59 struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev));
60 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
61 int retval;
62
63 if (off != 0 || count != real_size)
64 return -EINVAL;
65
66 mutex_lock(&savu->savu_lock);
67 retval = roccat_common2_send_with_status(usb_dev, command,
68 (void *)buf, real_size);
69 mutex_unlock(&savu->savu_lock);
70
71 return retval ? retval : real_size;
72}
73
74#define SAVU_SYSFS_W(thingy, THINGY) \
75static ssize_t savu_sysfs_write_ ## thingy(struct file *fp, \
76 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
77 loff_t off, size_t count) \
78{ \
79 return savu_sysfs_write(fp, kobj, buf, off, count, \
80 SAVU_SIZE_ ## THINGY, SAVU_COMMAND_ ## THINGY); \
81}
82
83#define SAVU_SYSFS_R(thingy, THINGY) \
84static ssize_t savu_sysfs_read_ ## thingy(struct file *fp, \
85 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
86 loff_t off, size_t count) \
87{ \
88 return savu_sysfs_read(fp, kobj, buf, off, count, \
89 SAVU_SIZE_ ## THINGY, SAVU_COMMAND_ ## THINGY); \
90}
91
92#define SAVU_SYSFS_RW(thingy, THINGY) \
93SAVU_SYSFS_W(thingy, THINGY) \
94SAVU_SYSFS_R(thingy, THINGY)
95
96#define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \
97SAVU_SYSFS_RW(thingy, THINGY); \
98static struct bin_attribute bin_attr_##thingy = { \
99 .attr = { .name = #thingy, .mode = 0660 }, \
100 .size = SAVU_SIZE_ ## THINGY, \
101 .read = savu_sysfs_read_ ## thingy, \
102 .write = savu_sysfs_write_ ## thingy \
103}
104
105#define SAVU_BIN_ATTRIBUTE_W(thingy, THINGY) \
106SAVU_SYSFS_W(thingy, THINGY); \
107static struct bin_attribute bin_attr_##thingy = { \
108 .attr = { .name = #thingy, .mode = 0220 }, \
109 .size = SAVU_SIZE_ ## THINGY, \
110 .write = savu_sysfs_write_ ## thingy \
111}
112
113SAVU_BIN_ATTRIBUTE_W(control, CONTROL);
114SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE);
115SAVU_BIN_ATTRIBUTE_RW(general, GENERAL);
116SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS);
117SAVU_BIN_ATTRIBUTE_RW(macro, MACRO);
118SAVU_BIN_ATTRIBUTE_RW(info, INFO);
119SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR);
120
121static struct bin_attribute *savu_bin_attributes[] = {
122 &bin_attr_control, 39 &bin_attr_control,
123 &bin_attr_profile, 40 &bin_attr_profile,
124 &bin_attr_general, 41 &bin_attr_general,
@@ -130,7 +47,7 @@ static struct bin_attribute *savu_bin_attributes[] = {
130}; 47};
131 48
132static const struct attribute_group savu_group = { 49static const struct attribute_group savu_group = {
133 .bin_attrs = savu_bin_attributes, 50 .bin_attrs = savu_bin_attrs,
134}; 51};
135 52
136static const struct attribute_group *savu_groups[] = { 53static const struct attribute_group *savu_groups[] = {
@@ -138,19 +55,11 @@ static const struct attribute_group *savu_groups[] = {
138 NULL, 55 NULL,
139}; 56};
140 57
141static int savu_init_savu_device_struct(struct usb_device *usb_dev,
142 struct savu_device *savu)
143{
144 mutex_init(&savu->savu_lock);
145
146 return 0;
147}
148
149static int savu_init_specials(struct hid_device *hdev) 58static int savu_init_specials(struct hid_device *hdev)
150{ 59{
151 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 60 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
152 struct usb_device *usb_dev = interface_to_usbdev(intf); 61 struct usb_device *usb_dev = interface_to_usbdev(intf);
153 struct savu_device *savu; 62 struct roccat_common2_device *savu;
154 int retval; 63 int retval;
155 64
156 if (intf->cur_altsetting->desc.bInterfaceProtocol 65 if (intf->cur_altsetting->desc.bInterfaceProtocol
@@ -166,9 +75,9 @@ static int savu_init_specials(struct hid_device *hdev)
166 } 75 }
167 hid_set_drvdata(hdev, savu); 76 hid_set_drvdata(hdev, savu);
168 77
169 retval = savu_init_savu_device_struct(usb_dev, savu); 78 retval = roccat_common2_device_init_struct(usb_dev, savu);
170 if (retval) { 79 if (retval) {
171 hid_err(hdev, "couldn't init struct savu_device\n"); 80 hid_err(hdev, "couldn't init Savu device\n");
172 goto exit_free; 81 goto exit_free;
173 } 82 }
174 83
@@ -190,7 +99,7 @@ exit_free:
190static void savu_remove_specials(struct hid_device *hdev) 99static void savu_remove_specials(struct hid_device *hdev)
191{ 100{
192 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 101 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
193 struct savu_device *savu; 102 struct roccat_common2_device *savu;
194 103
195 if (intf->cur_altsetting->desc.bInterfaceProtocol 104 if (intf->cur_altsetting->desc.bInterfaceProtocol
196 != USB_INTERFACE_PROTOCOL_MOUSE) 105 != USB_INTERFACE_PROTOCOL_MOUSE)
@@ -239,7 +148,7 @@ static void savu_remove(struct hid_device *hdev)
239 hid_hw_stop(hdev); 148 hid_hw_stop(hdev);
240} 149}
241 150
242static void savu_report_to_chrdev(struct savu_device const *savu, 151static void savu_report_to_chrdev(struct roccat_common2_device const *savu,
243 u8 const *data) 152 u8 const *data)
244{ 153{
245 struct savu_roccat_report roccat_report; 154 struct savu_roccat_report roccat_report;
@@ -261,7 +170,7 @@ static int savu_raw_event(struct hid_device *hdev,
261 struct hid_report *report, u8 *data, int size) 170 struct hid_report *report, u8 *data, int size)
262{ 171{
263 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 172 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
264 struct savu_device *savu = hid_get_drvdata(hdev); 173 struct roccat_common2_device *savu = hid_get_drvdata(hdev);
265 174
266 if (intf->cur_altsetting->desc.bInterfaceProtocol 175 if (intf->cur_altsetting->desc.bInterfaceProtocol
267 != USB_INTERFACE_PROTOCOL_MOUSE) 176 != USB_INTERFACE_PROTOCOL_MOUSE)
diff --git a/drivers/hid/hid-roccat-savu.h b/drivers/hid/hid-roccat-savu.h
index 9120ba72087f..d23217bd2b86 100644
--- a/drivers/hid/hid-roccat-savu.h
+++ b/drivers/hid/hid-roccat-savu.h
@@ -14,31 +14,6 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16 16
17enum {
18 SAVU_SIZE_CONTROL = 0x03,
19 SAVU_SIZE_PROFILE = 0x03,
20 SAVU_SIZE_GENERAL = 0x10,
21 SAVU_SIZE_BUTTONS = 0x2f,
22 SAVU_SIZE_MACRO = 0x0823,
23 SAVU_SIZE_INFO = 0x08,
24 SAVU_SIZE_SENSOR = 0x04,
25};
26
27enum savu_control_requests {
28 SAVU_CONTROL_REQUEST_GENERAL = 0x80,
29 SAVU_CONTROL_REQUEST_BUTTONS = 0x90,
30};
31
32enum savu_commands {
33 SAVU_COMMAND_CONTROL = 0x4,
34 SAVU_COMMAND_PROFILE = 0x5,
35 SAVU_COMMAND_GENERAL = 0x6,
36 SAVU_COMMAND_BUTTONS = 0x7,
37 SAVU_COMMAND_MACRO = 0x8,
38 SAVU_COMMAND_INFO = 0x9,
39 SAVU_COMMAND_SENSOR = 0xc,
40};
41
42struct savu_mouse_report_special { 17struct savu_mouse_report_special {
43 uint8_t report_number; /* always 3 */ 18 uint8_t report_number; /* always 3 */
44 uint8_t zero; 19 uint8_t zero;
@@ -77,11 +52,4 @@ struct savu_roccat_report {
77 uint8_t data[2]; 52 uint8_t data[2];
78} __packed; 53} __packed;
79 54
80struct savu_device {
81 int roccat_claimed;
82 int chrdev_minor;
83
84 struct mutex savu_lock;
85};
86
87#endif 55#endif