diff options
Diffstat (limited to 'drivers/hid/hid-roccat-kone.c')
-rw-r--r-- | drivers/hid/hid-roccat-kone.c | 156 |
1 files changed, 44 insertions, 112 deletions
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index cbd8cc42e75a..a57838d15267 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c | |||
@@ -28,11 +28,11 @@ | |||
28 | #include <linux/device.h> | 28 | #include <linux/device.h> |
29 | #include <linux/input.h> | 29 | #include <linux/input.h> |
30 | #include <linux/hid.h> | 30 | #include <linux/hid.h> |
31 | #include <linux/usb.h> | ||
32 | #include <linux/module.h> | 31 | #include <linux/module.h> |
33 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/hid-roccat.h> | ||
34 | #include "hid-ids.h" | 34 | #include "hid-ids.h" |
35 | #include "hid-roccat.h" | 35 | #include "hid-roccat-common.h" |
36 | #include "hid-roccat-kone.h" | 36 | #include "hid-roccat-kone.h" |
37 | 37 | ||
38 | static uint profile_numbers[5] = {0, 1, 2, 3, 4}; | 38 | static uint profile_numbers[5] = {0, 1, 2, 3, 4}; |
@@ -58,12 +58,8 @@ static void kone_set_settings_checksum(struct kone_settings *settings) | |||
58 | */ | 58 | */ |
59 | static int kone_check_write(struct usb_device *usb_dev) | 59 | static int kone_check_write(struct usb_device *usb_dev) |
60 | { | 60 | { |
61 | int len; | 61 | int retval; |
62 | unsigned char *data; | 62 | uint8_t data; |
63 | |||
64 | data = kmalloc(1, GFP_KERNEL); | ||
65 | if (!data) | ||
66 | return -ENOMEM; | ||
67 | 63 | ||
68 | do { | 64 | do { |
69 | /* | 65 | /* |
@@ -72,56 +68,36 @@ static int kone_check_write(struct usb_device *usb_dev) | |||
72 | */ | 68 | */ |
73 | msleep(80); | 69 | msleep(80); |
74 | 70 | ||
75 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 71 | retval = roccat_common_receive(usb_dev, |
76 | USB_REQ_CLEAR_FEATURE, | 72 | kone_command_confirm_write, &data, 1); |
77 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | | 73 | if (retval) |
78 | USB_DIR_IN, | 74 | return retval; |
79 | kone_command_confirm_write, 0, data, 1, | ||
80 | USB_CTRL_SET_TIMEOUT); | ||
81 | |||
82 | if (len != 1) { | ||
83 | kfree(data); | ||
84 | return -EIO; | ||
85 | } | ||
86 | 75 | ||
87 | /* | 76 | /* |
88 | * value of 3 seems to mean something like | 77 | * value of 3 seems to mean something like |
89 | * "not finished yet, but it looks good" | 78 | * "not finished yet, but it looks good" |
90 | * So check again after a moment. | 79 | * So check again after a moment. |
91 | */ | 80 | */ |
92 | } while (*data == 3); | 81 | } while (data == 3); |
93 | 82 | ||
94 | if (*data == 1) { /* everything alright */ | 83 | if (data == 1) /* everything alright */ |
95 | kfree(data); | ||
96 | return 0; | 84 | return 0; |
97 | } else { /* unknown answer */ | 85 | |
98 | hid_err(usb_dev, "got retval %d when checking write\n", *data); | 86 | /* unknown answer */ |
99 | kfree(data); | 87 | hid_err(usb_dev, "got retval %d when checking write\n", data); |
100 | return -EIO; | 88 | return -EIO; |
101 | } | ||
102 | } | 89 | } |
103 | 90 | ||
104 | /* | 91 | /* |
105 | * Reads settings from mouse and stores it in @buf | 92 | * Reads settings from mouse and stores it in @buf |
106 | * @buf has to be alloced with GFP_KERNEL | ||
107 | * On success returns 0 | 93 | * On success returns 0 |
108 | * On failure returns errno | 94 | * On failure returns errno |
109 | */ | 95 | */ |
110 | static int kone_get_settings(struct usb_device *usb_dev, | 96 | static int kone_get_settings(struct usb_device *usb_dev, |
111 | struct kone_settings *buf) | 97 | struct kone_settings *buf) |
112 | { | 98 | { |
113 | int len; | 99 | return roccat_common_receive(usb_dev, kone_command_settings, buf, |
114 | 100 | sizeof(struct kone_settings)); | |
115 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
116 | USB_REQ_CLEAR_FEATURE, | ||
117 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
118 | kone_command_settings, 0, buf, | ||
119 | sizeof(struct kone_settings), USB_CTRL_SET_TIMEOUT); | ||
120 | |||
121 | if (len != sizeof(struct kone_settings)) | ||
122 | return -EIO; | ||
123 | |||
124 | return 0; | ||
125 | } | 101 | } |
126 | 102 | ||
127 | /* | 103 | /* |
@@ -132,22 +108,12 @@ static int kone_get_settings(struct usb_device *usb_dev, | |||
132 | static int kone_set_settings(struct usb_device *usb_dev, | 108 | static int kone_set_settings(struct usb_device *usb_dev, |
133 | struct kone_settings const *settings) | 109 | struct kone_settings const *settings) |
134 | { | 110 | { |
135 | int len; | 111 | int retval; |
136 | 112 | retval = roccat_common_send(usb_dev, kone_command_settings, | |
137 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | 113 | settings, sizeof(struct kone_settings)); |
138 | USB_REQ_SET_CONFIGURATION, | 114 | if (retval) |
139 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | 115 | return retval; |
140 | kone_command_settings, 0, (char *)settings, | 116 | return kone_check_write(usb_dev); |
141 | sizeof(struct kone_settings), | ||
142 | USB_CTRL_SET_TIMEOUT); | ||
143 | |||
144 | if (len != sizeof(struct kone_settings)) | ||
145 | return -EIO; | ||
146 | |||
147 | if (kone_check_write(usb_dev)) | ||
148 | return -EIO; | ||
149 | |||
150 | return 0; | ||
151 | } | 117 | } |
152 | 118 | ||
153 | /* | 119 | /* |
@@ -193,7 +159,7 @@ static int kone_set_profile(struct usb_device *usb_dev, | |||
193 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | 159 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), |
194 | USB_REQ_SET_CONFIGURATION, | 160 | USB_REQ_SET_CONFIGURATION, |
195 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | 161 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, |
196 | kone_command_profile, number, (char *)profile, | 162 | kone_command_profile, number, (void *)profile, |
197 | sizeof(struct kone_profile), | 163 | sizeof(struct kone_profile), |
198 | USB_CTRL_SET_TIMEOUT); | 164 | USB_CTRL_SET_TIMEOUT); |
199 | 165 | ||
@@ -213,24 +179,15 @@ static int kone_set_profile(struct usb_device *usb_dev, | |||
213 | */ | 179 | */ |
214 | static int kone_get_weight(struct usb_device *usb_dev, int *result) | 180 | static int kone_get_weight(struct usb_device *usb_dev, int *result) |
215 | { | 181 | { |
216 | int len; | 182 | int retval; |
217 | uint8_t *data; | 183 | uint8_t data; |
218 | 184 | ||
219 | data = kmalloc(1, GFP_KERNEL); | 185 | retval = roccat_common_receive(usb_dev, kone_command_weight, &data, 1); |
220 | if (!data) | ||
221 | return -ENOMEM; | ||
222 | 186 | ||
223 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 187 | if (retval) |
224 | USB_REQ_CLEAR_FEATURE, | 188 | return retval; |
225 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
226 | kone_command_weight, 0, data, 1, USB_CTRL_SET_TIMEOUT); | ||
227 | 189 | ||
228 | if (len != 1) { | 190 | *result = (int)data; |
229 | kfree(data); | ||
230 | return -EIO; | ||
231 | } | ||
232 | *result = (int)*data; | ||
233 | kfree(data); | ||
234 | return 0; | 191 | return 0; |
235 | } | 192 | } |
236 | 193 | ||
@@ -241,25 +198,15 @@ static int kone_get_weight(struct usb_device *usb_dev, int *result) | |||
241 | */ | 198 | */ |
242 | static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) | 199 | static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) |
243 | { | 200 | { |
244 | int len; | 201 | int retval; |
245 | unsigned char *data; | 202 | uint16_t data; |
246 | |||
247 | data = kmalloc(2, GFP_KERNEL); | ||
248 | if (!data) | ||
249 | return -ENOMEM; | ||
250 | 203 | ||
251 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 204 | retval = roccat_common_receive(usb_dev, kone_command_firmware_version, |
252 | USB_REQ_CLEAR_FEATURE, | 205 | &data, 2); |
253 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 206 | if (retval) |
254 | kone_command_firmware_version, 0, data, 2, | 207 | return retval; |
255 | USB_CTRL_SET_TIMEOUT); | ||
256 | 208 | ||
257 | if (len != 2) { | 209 | *result = le16_to_cpu(data); |
258 | kfree(data); | ||
259 | return -EIO; | ||
260 | } | ||
261 | *result = le16_to_cpu(*data); | ||
262 | kfree(data); | ||
263 | return 0; | 210 | return 0; |
264 | } | 211 | } |
265 | 212 | ||
@@ -435,23 +382,9 @@ static ssize_t kone_sysfs_show_tcu(struct device *dev, | |||
435 | 382 | ||
436 | static int kone_tcu_command(struct usb_device *usb_dev, int number) | 383 | static int kone_tcu_command(struct usb_device *usb_dev, int number) |
437 | { | 384 | { |
438 | int len; | 385 | unsigned char value; |
439 | char *value; | 386 | value = number; |
440 | 387 | return roccat_common_send(usb_dev, kone_command_calibrate, &value, 1); | |
441 | value = kmalloc(1, GFP_KERNEL); | ||
442 | if (!value) | ||
443 | return -ENOMEM; | ||
444 | |||
445 | *value = number; | ||
446 | |||
447 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
448 | USB_REQ_SET_CONFIGURATION, | ||
449 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
450 | kone_command_calibrate, 0, value, 1, | ||
451 | USB_CTRL_SET_TIMEOUT); | ||
452 | |||
453 | kfree(value); | ||
454 | return ((len != 1) ? -EIO : 0); | ||
455 | } | 388 | } |
456 | 389 | ||
457 | /* | 390 | /* |
@@ -727,7 +660,8 @@ static int kone_init_specials(struct hid_device *hdev) | |||
727 | goto exit_free; | 660 | goto exit_free; |
728 | } | 661 | } |
729 | 662 | ||
730 | retval = roccat_connect(kone_class, hdev); | 663 | retval = roccat_connect(kone_class, hdev, |
664 | sizeof(struct kone_roccat_report)); | ||
731 | if (retval < 0) { | 665 | if (retval < 0) { |
732 | hid_err(hdev, "couldn't init char dev\n"); | 666 | hid_err(hdev, "couldn't init char dev\n"); |
733 | /* be tolerant about not getting chrdev */ | 667 | /* be tolerant about not getting chrdev */ |
@@ -827,8 +761,7 @@ static void kone_report_to_chrdev(struct kone_device const *kone, | |||
827 | roccat_report.value = event->value; | 761 | roccat_report.value = event->value; |
828 | roccat_report.key = 0; | 762 | roccat_report.key = 0; |
829 | roccat_report_event(kone->chrdev_minor, | 763 | roccat_report_event(kone->chrdev_minor, |
830 | (uint8_t *)&roccat_report, | 764 | (uint8_t *)&roccat_report); |
831 | sizeof(struct kone_roccat_report)); | ||
832 | break; | 765 | break; |
833 | case kone_mouse_event_call_overlong_macro: | 766 | case kone_mouse_event_call_overlong_macro: |
834 | if (event->value == kone_keystroke_action_press) { | 767 | if (event->value == kone_keystroke_action_press) { |
@@ -836,8 +769,7 @@ static void kone_report_to_chrdev(struct kone_device const *kone, | |||
836 | roccat_report.value = kone->actual_profile; | 769 | roccat_report.value = kone->actual_profile; |
837 | roccat_report.key = event->macro_key; | 770 | roccat_report.key = event->macro_key; |
838 | roccat_report_event(kone->chrdev_minor, | 771 | roccat_report_event(kone->chrdev_minor, |
839 | (uint8_t *)&roccat_report, | 772 | (uint8_t *)&roccat_report); |
840 | sizeof(struct kone_roccat_report)); | ||
841 | } | 773 | } |
842 | break; | 774 | break; |
843 | } | 775 | } |
@@ -912,8 +844,8 @@ static int __init kone_init(void) | |||
912 | 844 | ||
913 | static void __exit kone_exit(void) | 845 | static void __exit kone_exit(void) |
914 | { | 846 | { |
915 | class_destroy(kone_class); | ||
916 | hid_unregister_driver(&kone_driver); | 847 | hid_unregister_driver(&kone_driver); |
848 | class_destroy(kone_class); | ||
917 | } | 849 | } |
918 | 850 | ||
919 | module_init(kone_init); | 851 | module_init(kone_init); |