Source
20
20
#include <linux/hid.h>
21
21
#include <linux/module.h>
22
22
#include <linux/slab.h>
23
23
#include <linux/hid-roccat.h>
24
24
#include "hid-ids.h"
25
25
#include "hid-roccat-common.h"
26
26
#include "hid-roccat-savu.h"
27
27
28
28
static struct class *savu_class;
29
29
30
-
static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj,
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 savu_device *savu = 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(&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
-
53
-
static 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) \
75
-
static 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) \
84
-
static 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) \
93
-
SAVU_SYSFS_W(thingy, THINGY) \
94
-
SAVU_SYSFS_R(thingy, THINGY)
95
-
96
-
#define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \
97
-
SAVU_SYSFS_RW(thingy, THINGY); \
98
-
static 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) \
106
-
SAVU_SYSFS_W(thingy, THINGY); \
107
-
static 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
-
113
-
SAVU_BIN_ATTRIBUTE_W(control, CONTROL);
114
-
SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE);
115
-
SAVU_BIN_ATTRIBUTE_RW(general, GENERAL);
116
-
SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS);
117
-
SAVU_BIN_ATTRIBUTE_RW(macro, MACRO);
118
-
SAVU_BIN_ATTRIBUTE_RW(info, INFO);
119
-
SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR);
120
-
121
-
static struct bin_attribute *savu_bin_attributes[] = {
30
+
ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x4, 0x03);
31
+
ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile, 0x5, 0x03);
32
+
ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(general, 0x6, 0x10);
33
+
ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(buttons, 0x7, 0x2f);
34
+
ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(macro, 0x8, 0x0823);
35
+
ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(info, 0x9, 0x08);
36
+
ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(sensor, 0xc, 0x04);
37
+
38
+
static struct bin_attribute *savu_bin_attrs[] = {
122
39
&bin_attr_control,
123
40
&bin_attr_profile,
124
41
&bin_attr_general,
125
42
&bin_attr_buttons,
126
43
&bin_attr_macro,
127
44
&bin_attr_info,
128
45
&bin_attr_sensor,
129
46
NULL,
130
47
};
131
48
132
49
static const struct attribute_group savu_group = {
133
-
.bin_attrs = savu_bin_attributes,
50
+
.bin_attrs = savu_bin_attrs,
134
51
};
135
52
136
53
static const struct attribute_group *savu_groups[] = {
137
54
&savu_group,
138
55
NULL,
139
56
};
140
57
141
-
static 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
-
149
58
static int savu_init_specials(struct hid_device *hdev)
150
59
{
151
60
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
152
61
struct usb_device *usb_dev = interface_to_usbdev(intf);
153
-
struct savu_device *savu;
62
+
struct roccat_common2_device *savu;
154
63
int retval;
155
64
156
65
if (intf->cur_altsetting->desc.bInterfaceProtocol
157
66
!= USB_INTERFACE_PROTOCOL_MOUSE) {
158
67
hid_set_drvdata(hdev, NULL);
159
68
return 0;
160
69
}
161
70
162
71
savu = kzalloc(sizeof(*savu), GFP_KERNEL);
163
72
if (!savu) {
164
73
hid_err(hdev, "can't alloc device descriptor\n");
165
74
return -ENOMEM;
166
75
}
167
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
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
81
goto exit_free;
173
82
}
174
83
175
84
retval = roccat_connect(savu_class, hdev,
176
85
sizeof(struct savu_roccat_report));
177
86
if (retval < 0) {
178
87
hid_err(hdev, "couldn't init char dev\n");
179
88
} else {
180
89
savu->chrdev_minor = retval;
181
90
savu->roccat_claimed = 1;
183
92
184
93
return 0;
185
94
exit_free:
186
95
kfree(savu);
187
96
return retval;
188
97
}
189
98
190
99
static void savu_remove_specials(struct hid_device *hdev)
191
100
{
192
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
104
if (intf->cur_altsetting->desc.bInterfaceProtocol
196
105
!= USB_INTERFACE_PROTOCOL_MOUSE)
197
106
return;
198
107
199
108
savu = hid_get_drvdata(hdev);
200
109
if (savu->roccat_claimed)
201
110
roccat_disconnect(savu->chrdev_minor);
202
111
kfree(savu);
203
112
}
232
141
exit:
233
142
return retval;
234
143
}
235
144
236
145
static void savu_remove(struct hid_device *hdev)
237
146
{
238
147
savu_remove_specials(hdev);
239
148
hid_hw_stop(hdev);
240
149
}
241
150
242
-
static void savu_report_to_chrdev(struct savu_device const *savu,
151
+
static void savu_report_to_chrdev(struct roccat_common2_device const *savu,
243
152
u8 const *data)
244
153
{
245
154
struct savu_roccat_report roccat_report;
246
155
struct savu_mouse_report_special const *special_report;
247
156
248
157
if (data[0] != SAVU_MOUSE_REPORT_NUMBER_SPECIAL)
249
158
return;
250
159
251
160
special_report = (struct savu_mouse_report_special const *)data;
252
161
254
163
roccat_report.data[0] = special_report->data[0];
255
164
roccat_report.data[1] = special_report->data[1];
256
165
roccat_report_event(savu->chrdev_minor,
257
166
(uint8_t const *)&roccat_report);
258
167
}
259
168
260
169
static int savu_raw_event(struct hid_device *hdev,
261
170
struct hid_report *report, u8 *data, int size)
262
171
{
263
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
175
if (intf->cur_altsetting->desc.bInterfaceProtocol
267
176
!= USB_INTERFACE_PROTOCOL_MOUSE)
268
177
return 0;
269
178
270
179
if (savu == NULL)
271
180
return 0;
272
181
273
182
if (savu->roccat_claimed)
274
183
savu_report_to_chrdev(savu, data);