aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-roccat-koneplus.c
diff options
context:
space:
mode:
authorStefan Achatz <erazor_de@users.sourceforge.net>2011-01-30 07:38:23 -0500
committerJiri Kosina <jkosina@suse.cz>2011-02-03 10:37:27 -0500
commit5772f63613ce0a6777e82a7e8fb553e49da27719 (patch)
tree83c066e175d38323bccd4fd511c45dada6ba8ec0 /drivers/hid/hid-roccat-koneplus.c
parenta28764ef80dd5aef657f810a9c295ccda421c823 (diff)
HID: roccat: Introduce module hid-roccat-common
Module hid-roccat-common contains functions used by roccat device driver modules to reduce code duplication. At the moment it contains just two wrapper methods for usb_control_msg that ensure that the buffer used for transfer is dma capable which wasn't the case before. The kconfig option is not visible to the user but will be selected by the device specific drivers. Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
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