aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-roccat-koneplus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-roccat-koneplus.c')
-rw-r--r--drivers/hid/hid-roccat-koneplus.c135
1 files changed, 39 insertions, 96 deletions
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c
index c826c0d6c872..d1c3a02109a8 100644
--- a/drivers/hid/hid-roccat-koneplus.c
+++ b/drivers/hid/hid-roccat-koneplus.c
@@ -19,11 +19,11 @@
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/input.h> 20#include <linux/input.h>
21#include <linux/hid.h> 21#include <linux/hid.h>
22#include <linux/usb.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include "hid-ids.h" 24#include "hid-ids.h"
26#include "hid-roccat.h" 25#include "hid-roccat.h"
26#include "hid-roccat-common.h"
27#include "hid-roccat-koneplus.h" 27#include "hid-roccat-koneplus.h"
28 28
29static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 29static uint profile_numbers[5] = {0, 1, 2, 3, 4};
@@ -39,110 +39,63 @@ static void koneplus_profile_activated(struct koneplus_device *koneplus,
39static int koneplus_send_control(struct usb_device *usb_dev, uint value, 39static int koneplus_send_control(struct usb_device *usb_dev, uint value,
40 enum koneplus_control_requests request) 40 enum koneplus_control_requests request)
41{ 41{
42 int len; 42 struct koneplus_control control;
43 struct koneplus_control *control;
44 43
45 if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || 44 if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
46 request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && 45 request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
47 value > 4) 46 value > 4)
48 return -EINVAL; 47 return -EINVAL;
49 48
50 control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL); 49 control.command = KONEPLUS_COMMAND_CONTROL;
51 if (!control) 50 control.value = value;
52 return -ENOMEM; 51 control.request = request;
53 52
54 control->command = KONEPLUS_COMMAND_CONTROL; 53 return roccat_common_send(usb_dev, KONEPLUS_USB_COMMAND_CONTROL,
55 control->value = value; 54 &control, sizeof(struct koneplus_control));
56 control->request = request;
57
58 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
59 USB_REQ_SET_CONFIGURATION,
60 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
61 KONEPLUS_USB_COMMAND_CONTROL, 0, control,
62 sizeof(struct koneplus_control),
63 USB_CTRL_SET_TIMEOUT);
64
65 kfree(control);
66
67 if (len != sizeof(struct koneplus_control))
68 return len;
69
70 return 0;
71}
72
73static int koneplus_receive(struct usb_device *usb_dev, uint usb_command,
74 void *buf, uint size) {
75 int len;
76
77 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
78 USB_REQ_CLEAR_FEATURE,
79 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
80 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
81
82 return (len != size) ? -EIO : 0;
83} 55}
84 56
85static int koneplus_receive_control_status(struct usb_device *usb_dev) 57static int koneplus_receive_control_status(struct usb_device *usb_dev)
86{ 58{
87 int retval; 59 int retval;
88 struct koneplus_control *control; 60 struct koneplus_control control;
89
90 control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL);
91 if (!control)
92 return -ENOMEM;
93 61
94 do { 62 do {
95 retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_CONTROL, 63 retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_CONTROL,
96 control, sizeof(struct koneplus_control)); 64 &control, sizeof(struct koneplus_control));
97 65
98 /* check if we get a completely wrong answer */ 66 /* check if we get a completely wrong answer */
99 if (retval) 67 if (retval)
100 goto out; 68 return retval;
101 69
102 if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OK) { 70 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OK)
103 retval = 0; 71 return 0;
104 goto out;
105 }
106 72
107 /* indicates that hardware needs some more time to complete action */ 73 /* indicates that hardware needs some more time to complete action */
108 if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) { 74 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) {
109 msleep(500); /* windows driver uses 1000 */ 75 msleep(500); /* windows driver uses 1000 */
110 continue; 76 continue;
111 } 77 }
112 78
113 /* seems to be critical - replug necessary */ 79 /* seems to be critical - replug necessary */
114 if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) { 80 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
115 retval = -EINVAL; 81 return -EINVAL;
116 goto out;
117 }
118 82
119 hid_err(usb_dev, "koneplus_receive_control_status: " 83 hid_err(usb_dev, "koneplus_receive_control_status: "
120 "unknown response value 0x%x\n", control->value); 84 "unknown response value 0x%x\n", control.value);
121 retval = -EINVAL; 85 return -EINVAL;
122 goto out;
123
124 } while (1); 86 } while (1);
125out:
126 kfree(control);
127 return retval;
128} 87}
129 88
130static int koneplus_send(struct usb_device *usb_dev, uint command, 89static int koneplus_send(struct usb_device *usb_dev, uint command,
131 void *buf, uint size) { 90 void const *buf, uint size)
132 int len; 91{
133 92 int retval;
134 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
135 USB_REQ_SET_CONFIGURATION,
136 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
137 command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
138
139 if (len != size)
140 return -EIO;
141 93
142 if (koneplus_receive_control_status(usb_dev)) 94 retval = roccat_common_send(usb_dev, command, buf, size);
143 return -EIO; 95 if (retval)
96 return retval;
144 97
145 return 0; 98 return koneplus_receive_control_status(usb_dev);
146} 99}
147 100
148static int koneplus_select_profile(struct usb_device *usb_dev, uint number, 101static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
@@ -167,7 +120,7 @@ static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
167static int koneplus_get_info(struct usb_device *usb_dev, 120static int koneplus_get_info(struct usb_device *usb_dev,
168 struct koneplus_info *buf) 121 struct koneplus_info *buf)
169{ 122{
170 return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_INFO, 123 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_INFO,
171 buf, sizeof(struct koneplus_info)); 124 buf, sizeof(struct koneplus_info));
172} 125}
173 126
@@ -181,7 +134,7 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev,
181 if (retval) 134 if (retval)
182 return retval; 135 return retval;
183 136
184 return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, 137 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS,
185 buf, sizeof(struct koneplus_profile_settings)); 138 buf, sizeof(struct koneplus_profile_settings));
186} 139}
187 140
@@ -189,7 +142,7 @@ static int koneplus_set_profile_settings(struct usb_device *usb_dev,
189 struct koneplus_profile_settings const *settings) 142 struct koneplus_profile_settings const *settings)
190{ 143{
191 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, 144 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS,
192 (void *)settings, sizeof(struct koneplus_profile_settings)); 145 settings, sizeof(struct koneplus_profile_settings));
193} 146}
194 147
195static int koneplus_get_profile_buttons(struct usb_device *usb_dev, 148static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
@@ -202,7 +155,7 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
202 if (retval) 155 if (retval)
203 return retval; 156 return retval;
204 157
205 return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, 158 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS,
206 buf, sizeof(struct koneplus_profile_buttons)); 159 buf, sizeof(struct koneplus_profile_buttons));
207} 160}
208 161
@@ -210,29 +163,19 @@ static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
210 struct koneplus_profile_buttons const *buttons) 163 struct koneplus_profile_buttons const *buttons)
211{ 164{
212 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, 165 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS,
213 (void *)buttons, sizeof(struct koneplus_profile_buttons)); 166 buttons, sizeof(struct koneplus_profile_buttons));
214} 167}
215 168
216/* retval is 0-4 on success, < 0 on error */ 169/* retval is 0-4 on success, < 0 on error */
217static int koneplus_get_startup_profile(struct usb_device *usb_dev) 170static int koneplus_get_startup_profile(struct usb_device *usb_dev)
218{ 171{
219 struct koneplus_startup_profile *buf; 172 struct koneplus_startup_profile buf;
220 int retval; 173 int retval;
221 174
222 buf = kmalloc(sizeof(struct koneplus_startup_profile), GFP_KERNEL); 175 retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
223 if (buf == NULL) 176 &buf, sizeof(struct koneplus_startup_profile));
224 return -ENOMEM;
225
226 retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
227 buf, sizeof(struct koneplus_startup_profile));
228 177
229 if (retval) 178 return retval ? retval : buf.startup_profile;
230 goto out;
231
232 retval = buf->startup_profile;
233out:
234 kfree(buf);
235 return retval;
236} 179}
237 180
238static int koneplus_set_startup_profile(struct usb_device *usb_dev, 181static int koneplus_set_startup_profile(struct usb_device *usb_dev,
@@ -245,7 +188,7 @@ static int koneplus_set_startup_profile(struct usb_device *usb_dev,
245 buf.startup_profile = startup_profile; 188 buf.startup_profile = startup_profile;
246 189
247 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, 190 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
248 (char *)&buf, sizeof(struct koneplus_profile_buttons)); 191 &buf, sizeof(struct koneplus_profile_buttons));
249} 192}
250 193
251static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, 194static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
@@ -265,7 +208,7 @@ static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
265 return -EINVAL; 208 return -EINVAL;
266 209
267 mutex_lock(&koneplus->koneplus_lock); 210 mutex_lock(&koneplus->koneplus_lock);
268 retval = koneplus_receive(usb_dev, command, buf, real_size); 211 retval = roccat_common_receive(usb_dev, command, buf, real_size);
269 mutex_unlock(&koneplus->koneplus_lock); 212 mutex_unlock(&koneplus->koneplus_lock);
270 213
271 if (retval) 214 if (retval)
@@ -288,7 +231,7 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
288 return -EINVAL; 231 return -EINVAL;
289 232
290 mutex_lock(&koneplus->koneplus_lock); 233 mutex_lock(&koneplus->koneplus_lock);
291 retval = koneplus_send(usb_dev, command, (void *)buf, real_size); 234 retval = koneplus_send(usb_dev, command, buf, real_size);
292 mutex_unlock(&koneplus->koneplus_lock); 235 mutex_unlock(&koneplus->koneplus_lock);
293 236
294 if (retval) 237 if (retval)
@@ -352,7 +295,7 @@ static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
352 count = sizeof(struct koneplus_profile_settings) - off; 295 count = sizeof(struct koneplus_profile_settings) - off;
353 296
354 mutex_lock(&koneplus->koneplus_lock); 297 mutex_lock(&koneplus->koneplus_lock);
355 memcpy(buf, ((void const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off, 298 memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off,
356 count); 299 count);
357 mutex_unlock(&koneplus->koneplus_lock); 300 mutex_unlock(&koneplus->koneplus_lock);
358 301
@@ -411,7 +354,7 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
411 count = sizeof(struct koneplus_profile_buttons) - off; 354 count = sizeof(struct koneplus_profile_buttons) - off;
412 355
413 mutex_lock(&koneplus->koneplus_lock); 356 mutex_lock(&koneplus->koneplus_lock);
414 memcpy(buf, ((void const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off, 357 memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off,
415 count); 358 count);
416 mutex_unlock(&koneplus->koneplus_lock); 359 mutex_unlock(&koneplus->koneplus_lock);
417 360