diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hid/hid-roccat-common.c | 58 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-common.h | 12 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-isku.c | 50 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-isku.h | 7 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-koneplus.c | 88 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-koneplus.h | 22 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-kovaplus.c | 63 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-kovaplus.h | 15 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-pyra.c | 51 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-pyra.h | 12 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-savu.c | 47 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-savu.h | 18 |
12 files changed, 111 insertions, 332 deletions
diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c index a6d93992c75a..291414eac279 100644 --- a/drivers/hid/hid-roccat-common.c +++ b/drivers/hid/hid-roccat-common.c | |||
@@ -64,6 +64,64 @@ int roccat_common_send(struct usb_device *usb_dev, uint report_id, | |||
64 | } | 64 | } |
65 | EXPORT_SYMBOL_GPL(roccat_common_send); | 65 | EXPORT_SYMBOL_GPL(roccat_common_send); |
66 | 66 | ||
67 | enum roccat_common_control_states { | ||
68 | ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD = 0, | ||
69 | ROCCAT_COMMON_CONTROL_STATUS_OK = 1, | ||
70 | ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2, | ||
71 | ROCCAT_COMMON_CONTROL_STATUS_WAIT = 3, | ||
72 | }; | ||
73 | |||
74 | static int roccat_common_receive_control_status(struct usb_device *usb_dev) | ||
75 | { | ||
76 | int retval; | ||
77 | struct roccat_common_control control; | ||
78 | |||
79 | do { | ||
80 | msleep(50); | ||
81 | retval = roccat_common_receive(usb_dev, | ||
82 | ROCCAT_COMMON_COMMAND_CONTROL, | ||
83 | &control, sizeof(struct roccat_common_control)); | ||
84 | |||
85 | if (retval) | ||
86 | return retval; | ||
87 | |||
88 | switch (control.value) { | ||
89 | case ROCCAT_COMMON_CONTROL_STATUS_OK: | ||
90 | return 0; | ||
91 | case ROCCAT_COMMON_CONTROL_STATUS_WAIT: | ||
92 | msleep(500); | ||
93 | continue; | ||
94 | case ROCCAT_COMMON_CONTROL_STATUS_INVALID: | ||
95 | |||
96 | case ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD: | ||
97 | /* seems to be critical - replug necessary */ | ||
98 | return -EINVAL; | ||
99 | default: | ||
100 | dev_err(&usb_dev->dev, | ||
101 | "roccat_common_receive_control_status: " | ||
102 | "unknown response value 0x%x\n", | ||
103 | control.value); | ||
104 | return -EINVAL; | ||
105 | } | ||
106 | |||
107 | } while (1); | ||
108 | } | ||
109 | |||
110 | int roccat_common_send_with_status(struct usb_device *usb_dev, | ||
111 | uint command, void const *buf, uint size) | ||
112 | { | ||
113 | int retval; | ||
114 | |||
115 | retval = roccat_common_send(usb_dev, command, buf, size); | ||
116 | if (retval) | ||
117 | return retval; | ||
118 | |||
119 | msleep(100); | ||
120 | |||
121 | return roccat_common_receive_control_status(usb_dev); | ||
122 | } | ||
123 | EXPORT_SYMBOL_GPL(roccat_common_send_with_status); | ||
124 | |||
67 | MODULE_AUTHOR("Stefan Achatz"); | 125 | MODULE_AUTHOR("Stefan Achatz"); |
68 | MODULE_DESCRIPTION("USB Roccat common driver"); | 126 | MODULE_DESCRIPTION("USB Roccat common driver"); |
69 | MODULE_LICENSE("GPL v2"); | 127 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/hid/hid-roccat-common.h b/drivers/hid/hid-roccat-common.h index 9a5bc61f9699..86bce05da013 100644 --- a/drivers/hid/hid-roccat-common.h +++ b/drivers/hid/hid-roccat-common.h | |||
@@ -15,9 +15,21 @@ | |||
15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | 17 | ||
18 | enum roccat_common_commands { | ||
19 | ROCCAT_COMMON_COMMAND_CONTROL = 0x4, | ||
20 | }; | ||
21 | |||
22 | struct roccat_common_control { | ||
23 | uint8_t command; | ||
24 | uint8_t value; | ||
25 | uint8_t request; /* always 0 on requesting write check */ | ||
26 | } __packed; | ||
27 | |||
18 | int roccat_common_receive(struct usb_device *usb_dev, uint report_id, | 28 | int roccat_common_receive(struct usb_device *usb_dev, uint report_id, |
19 | void *data, uint size); | 29 | void *data, uint size); |
20 | int roccat_common_send(struct usb_device *usb_dev, uint report_id, | 30 | int roccat_common_send(struct usb_device *usb_dev, uint report_id, |
21 | void const *data, uint size); | 31 | void const *data, uint size); |
32 | int roccat_common_send_with_status(struct usb_device *usb_dev, | ||
33 | uint command, void const *buf, uint size); | ||
22 | 34 | ||
23 | #endif | 35 | #endif |
diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 0e4a0ab47142..20e7f84ee832 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c | |||
@@ -39,50 +39,6 @@ static int isku_receive(struct usb_device *usb_dev, uint command, | |||
39 | return roccat_common_receive(usb_dev, command, buf, size); | 39 | return roccat_common_receive(usb_dev, command, buf, size); |
40 | } | 40 | } |
41 | 41 | ||
42 | static int isku_receive_control_status(struct usb_device *usb_dev) | ||
43 | { | ||
44 | int retval; | ||
45 | struct isku_control control; | ||
46 | |||
47 | do { | ||
48 | msleep(50); | ||
49 | retval = isku_receive(usb_dev, ISKU_COMMAND_CONTROL, | ||
50 | &control, sizeof(struct isku_control)); | ||
51 | |||
52 | if (retval) | ||
53 | return retval; | ||
54 | |||
55 | switch (control.value) { | ||
56 | case ISKU_CONTROL_VALUE_STATUS_OK: | ||
57 | return 0; | ||
58 | case ISKU_CONTROL_VALUE_STATUS_WAIT: | ||
59 | continue; | ||
60 | case ISKU_CONTROL_VALUE_STATUS_INVALID: | ||
61 | /* seems to be critical - replug necessary */ | ||
62 | case ISKU_CONTROL_VALUE_STATUS_OVERLOAD: | ||
63 | return -EINVAL; | ||
64 | default: | ||
65 | hid_err(usb_dev, "isku_receive_control_status: " | ||
66 | "unknown response value 0x%x\n", | ||
67 | control.value); | ||
68 | return -EINVAL; | ||
69 | } | ||
70 | |||
71 | } while (1); | ||
72 | } | ||
73 | |||
74 | static int isku_send(struct usb_device *usb_dev, uint command, | ||
75 | void const *buf, uint size) | ||
76 | { | ||
77 | int retval; | ||
78 | |||
79 | retval = roccat_common_send(usb_dev, command, buf, size); | ||
80 | if (retval) | ||
81 | return retval; | ||
82 | |||
83 | return isku_receive_control_status(usb_dev); | ||
84 | } | ||
85 | |||
86 | static int isku_get_actual_profile(struct usb_device *usb_dev) | 42 | static int isku_get_actual_profile(struct usb_device *usb_dev) |
87 | { | 43 | { |
88 | struct isku_actual_profile buf; | 44 | struct isku_actual_profile buf; |
@@ -100,7 +56,8 @@ static int isku_set_actual_profile(struct usb_device *usb_dev, int new_profile) | |||
100 | buf.command = ISKU_COMMAND_ACTUAL_PROFILE; | 56 | buf.command = ISKU_COMMAND_ACTUAL_PROFILE; |
101 | buf.size = sizeof(struct isku_actual_profile); | 57 | buf.size = sizeof(struct isku_actual_profile); |
102 | buf.actual_profile = new_profile; | 58 | buf.actual_profile = new_profile; |
103 | return isku_send(usb_dev, ISKU_COMMAND_ACTUAL_PROFILE, &buf, | 59 | return roccat_common_send_with_status(usb_dev, |
60 | ISKU_COMMAND_ACTUAL_PROFILE, &buf, | ||
104 | sizeof(struct isku_actual_profile)); | 61 | sizeof(struct isku_actual_profile)); |
105 | } | 62 | } |
106 | 63 | ||
@@ -197,7 +154,8 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, | |||
197 | return -EINVAL; | 154 | return -EINVAL; |
198 | 155 | ||
199 | mutex_lock(&isku->isku_lock); | 156 | mutex_lock(&isku->isku_lock); |
200 | retval = isku_send(usb_dev, command, (void *)buf, real_size); | 157 | retval = roccat_common_send_with_status(usb_dev, command, |
158 | (void *)buf, real_size); | ||
201 | mutex_unlock(&isku->isku_lock); | 159 | mutex_unlock(&isku->isku_lock); |
202 | 160 | ||
203 | return retval ? retval : real_size; | 161 | return retval ? retval : real_size; |
diff --git a/drivers/hid/hid-roccat-isku.h b/drivers/hid/hid-roccat-isku.h index 075f6efaec58..605b3ce21638 100644 --- a/drivers/hid/hid-roccat-isku.h +++ b/drivers/hid/hid-roccat-isku.h | |||
@@ -25,13 +25,6 @@ struct isku_control { | |||
25 | uint8_t request; | 25 | uint8_t request; |
26 | } __packed; | 26 | } __packed; |
27 | 27 | ||
28 | enum isku_control_values { | ||
29 | ISKU_CONTROL_VALUE_STATUS_OVERLOAD = 0, | ||
30 | ISKU_CONTROL_VALUE_STATUS_OK = 1, | ||
31 | ISKU_CONTROL_VALUE_STATUS_INVALID = 2, | ||
32 | ISKU_CONTROL_VALUE_STATUS_WAIT = 3, | ||
33 | }; | ||
34 | |||
35 | struct isku_actual_profile { | 28 | struct isku_actual_profile { |
36 | uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */ | 29 | uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */ |
37 | uint8_t size; /* always 3 */ | 30 | uint8_t size; /* always 3 */ |
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 59e47770fa10..01167a831258 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c | |||
@@ -39,82 +39,20 @@ static void koneplus_profile_activated(struct koneplus_device *koneplus, | |||
39 | static int koneplus_send_control(struct usb_device *usb_dev, uint value, | 39 | static 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 | struct koneplus_control control; | 42 | struct roccat_common_control control; |
43 | 43 | ||
44 | if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || | 44 | if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || |
45 | request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && | 45 | request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && |
46 | value > 4) | 46 | value > 4) |
47 | return -EINVAL; | 47 | return -EINVAL; |
48 | 48 | ||
49 | control.command = KONEPLUS_COMMAND_CONTROL; | 49 | control.command = ROCCAT_COMMON_COMMAND_CONTROL; |
50 | control.value = value; | 50 | control.value = value; |
51 | control.request = request; | 51 | control.request = request; |
52 | 52 | ||
53 | return roccat_common_send(usb_dev, KONEPLUS_COMMAND_CONTROL, | 53 | return roccat_common_send_with_status(usb_dev, |
54 | &control, sizeof(struct koneplus_control)); | 54 | ROCCAT_COMMON_COMMAND_CONTROL, |
55 | } | 55 | &control, sizeof(struct roccat_common_control)); |
56 | |||
57 | static int koneplus_receive_control_status(struct usb_device *usb_dev) | ||
58 | { | ||
59 | int retval; | ||
60 | struct koneplus_control control; | ||
61 | |||
62 | do { | ||
63 | retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_CONTROL, | ||
64 | &control, sizeof(struct koneplus_control)); | ||
65 | |||
66 | /* check if we get a completely wrong answer */ | ||
67 | if (retval) | ||
68 | return retval; | ||
69 | |||
70 | if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OK) | ||
71 | return 0; | ||
72 | |||
73 | /* indicates that hardware needs some more time to complete action */ | ||
74 | if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) { | ||
75 | msleep(500); /* windows driver uses 1000 */ | ||
76 | continue; | ||
77 | } | ||
78 | |||
79 | /* seems to be critical - replug necessary */ | ||
80 | if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) | ||
81 | return -EINVAL; | ||
82 | |||
83 | hid_err(usb_dev, "koneplus_receive_control_status: " | ||
84 | "unknown response value 0x%x\n", control.value); | ||
85 | return -EINVAL; | ||
86 | } while (1); | ||
87 | } | ||
88 | |||
89 | static int koneplus_send(struct usb_device *usb_dev, uint command, | ||
90 | void const *buf, uint size) | ||
91 | { | ||
92 | int retval; | ||
93 | |||
94 | retval = roccat_common_send(usb_dev, command, buf, size); | ||
95 | if (retval) | ||
96 | return retval; | ||
97 | |||
98 | return koneplus_receive_control_status(usb_dev); | ||
99 | } | ||
100 | |||
101 | static int koneplus_select_profile(struct usb_device *usb_dev, uint number, | ||
102 | enum koneplus_control_requests request) | ||
103 | { | ||
104 | int retval; | ||
105 | |||
106 | retval = koneplus_send_control(usb_dev, number, request); | ||
107 | if (retval) | ||
108 | return retval; | ||
109 | |||
110 | /* allow time to settle things - windows driver uses 500 */ | ||
111 | msleep(100); | ||
112 | |||
113 | retval = koneplus_receive_control_status(usb_dev); | ||
114 | if (retval) | ||
115 | return retval; | ||
116 | |||
117 | return 0; | ||
118 | } | 56 | } |
119 | 57 | ||
120 | static int koneplus_get_info(struct usb_device *usb_dev, | 58 | static int koneplus_get_info(struct usb_device *usb_dev, |
@@ -129,7 +67,7 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev, | |||
129 | { | 67 | { |
130 | int retval; | 68 | int retval; |
131 | 69 | ||
132 | retval = koneplus_select_profile(usb_dev, number, | 70 | retval = koneplus_send_control(usb_dev, number, |
133 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); | 71 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); |
134 | if (retval) | 72 | if (retval) |
135 | return retval; | 73 | return retval; |
@@ -141,7 +79,8 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev, | |||
141 | static int koneplus_set_profile_settings(struct usb_device *usb_dev, | 79 | static int koneplus_set_profile_settings(struct usb_device *usb_dev, |
142 | struct koneplus_profile_settings const *settings) | 80 | struct koneplus_profile_settings const *settings) |
143 | { | 81 | { |
144 | return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, | 82 | return roccat_common_send_with_status(usb_dev, |
83 | KONEPLUS_COMMAND_PROFILE_SETTINGS, | ||
145 | settings, sizeof(struct koneplus_profile_settings)); | 84 | settings, sizeof(struct koneplus_profile_settings)); |
146 | } | 85 | } |
147 | 86 | ||
@@ -150,7 +89,7 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev, | |||
150 | { | 89 | { |
151 | int retval; | 90 | int retval; |
152 | 91 | ||
153 | retval = koneplus_select_profile(usb_dev, number, | 92 | retval = koneplus_send_control(usb_dev, number, |
154 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); | 93 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); |
155 | if (retval) | 94 | if (retval) |
156 | return retval; | 95 | return retval; |
@@ -162,7 +101,8 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev, | |||
162 | static int koneplus_set_profile_buttons(struct usb_device *usb_dev, | 101 | static int koneplus_set_profile_buttons(struct usb_device *usb_dev, |
163 | struct koneplus_profile_buttons const *buttons) | 102 | struct koneplus_profile_buttons const *buttons) |
164 | { | 103 | { |
165 | return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, | 104 | return roccat_common_send_with_status(usb_dev, |
105 | KONEPLUS_COMMAND_PROFILE_BUTTONS, | ||
166 | buttons, sizeof(struct koneplus_profile_buttons)); | 106 | buttons, sizeof(struct koneplus_profile_buttons)); |
167 | } | 107 | } |
168 | 108 | ||
@@ -187,7 +127,8 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev, | |||
187 | buf.size = sizeof(struct koneplus_actual_profile); | 127 | buf.size = sizeof(struct koneplus_actual_profile); |
188 | buf.actual_profile = new_profile; | 128 | buf.actual_profile = new_profile; |
189 | 129 | ||
190 | return koneplus_send(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, | 130 | return roccat_common_send_with_status(usb_dev, |
131 | KONEPLUS_COMMAND_ACTUAL_PROFILE, | ||
191 | &buf, sizeof(struct koneplus_actual_profile)); | 132 | &buf, sizeof(struct koneplus_actual_profile)); |
192 | } | 133 | } |
193 | 134 | ||
@@ -231,7 +172,8 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, | |||
231 | return -EINVAL; | 172 | return -EINVAL; |
232 | 173 | ||
233 | mutex_lock(&koneplus->koneplus_lock); | 174 | mutex_lock(&koneplus->koneplus_lock); |
234 | retval = koneplus_send(usb_dev, command, buf, real_size); | 175 | retval = roccat_common_send_with_status(usb_dev, command, |
176 | buf, real_size); | ||
235 | mutex_unlock(&koneplus->koneplus_lock); | 177 | mutex_unlock(&koneplus->koneplus_lock); |
236 | 178 | ||
237 | if (retval) | 179 | if (retval) |
diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h index c03332a4fa9a..7074b2a4b94b 100644 --- a/drivers/hid/hid-roccat-koneplus.h +++ b/drivers/hid/hid-roccat-koneplus.h | |||
@@ -20,32 +20,11 @@ struct koneplus_talk { | |||
20 | uint8_t data[14]; | 20 | uint8_t data[14]; |
21 | } __packed; | 21 | } __packed; |
22 | 22 | ||
23 | /* | ||
24 | * case 1: writes request 80 and reads value 1 | ||
25 | * | ||
26 | */ | ||
27 | struct koneplus_control { | ||
28 | uint8_t command; /* KONEPLUS_COMMAND_CONTROL */ | ||
29 | /* | ||
30 | * value is profile number in range 0-4 for requesting settings and buttons | ||
31 | * 1 if status ok for requesting status | ||
32 | */ | ||
33 | uint8_t value; | ||
34 | uint8_t request; | ||
35 | } __attribute__ ((__packed__)); | ||
36 | |||
37 | enum koneplus_control_requests { | 23 | enum koneplus_control_requests { |
38 | KONEPLUS_CONTROL_REQUEST_STATUS = 0x00, | ||
39 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, | 24 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, |
40 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90, | 25 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90, |
41 | }; | 26 | }; |
42 | 27 | ||
43 | enum koneplus_control_values { | ||
44 | KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0, | ||
45 | KONEPLUS_CONTROL_REQUEST_STATUS_OK = 1, | ||
46 | KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, | ||
47 | }; | ||
48 | |||
49 | struct koneplus_actual_profile { | 28 | struct koneplus_actual_profile { |
50 | uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */ | 29 | uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */ |
51 | uint8_t size; /* always 3 */ | 30 | uint8_t size; /* always 3 */ |
@@ -137,7 +116,6 @@ struct koneplus_tcu_image { | |||
137 | } __attribute__ ((__packed__)); | 116 | } __attribute__ ((__packed__)); |
138 | 117 | ||
139 | enum koneplus_commands { | 118 | enum koneplus_commands { |
140 | KONEPLUS_COMMAND_CONTROL = 0x4, | ||
141 | KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, | 119 | KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, |
142 | KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, | 120 | KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, |
143 | KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, | 121 | KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, |
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index 112d934132c8..c219cff91555 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c | |||
@@ -47,69 +47,23 @@ static int kovaplus_send_control(struct usb_device *usb_dev, uint value, | |||
47 | enum kovaplus_control_requests request) | 47 | enum kovaplus_control_requests request) |
48 | { | 48 | { |
49 | int retval; | 49 | int retval; |
50 | struct kovaplus_control control; | 50 | struct roccat_common_control control; |
51 | 51 | ||
52 | if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || | 52 | if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || |
53 | request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && | 53 | request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && |
54 | value > 4) | 54 | value > 4) |
55 | return -EINVAL; | 55 | return -EINVAL; |
56 | 56 | ||
57 | control.command = KOVAPLUS_COMMAND_CONTROL; | 57 | control.command = ROCCAT_COMMON_COMMAND_CONTROL; |
58 | control.value = value; | 58 | control.value = value; |
59 | control.request = request; | 59 | control.request = request; |
60 | 60 | ||
61 | retval = roccat_common_send(usb_dev, KOVAPLUS_COMMAND_CONTROL, | 61 | retval = roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, |
62 | &control, sizeof(struct kovaplus_control)); | 62 | &control, sizeof(struct roccat_common_control)); |
63 | 63 | ||
64 | return retval; | 64 | return retval; |
65 | } | 65 | } |
66 | 66 | ||
67 | static int kovaplus_receive_control_status(struct usb_device *usb_dev) | ||
68 | { | ||
69 | int retval; | ||
70 | struct kovaplus_control control; | ||
71 | |||
72 | do { | ||
73 | retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_CONTROL, | ||
74 | &control, sizeof(struct kovaplus_control)); | ||
75 | |||
76 | /* check if we get a completely wrong answer */ | ||
77 | if (retval) | ||
78 | return retval; | ||
79 | |||
80 | if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OK) | ||
81 | return 0; | ||
82 | |||
83 | /* indicates that hardware needs some more time to complete action */ | ||
84 | if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT) { | ||
85 | msleep(500); /* windows driver uses 1000 */ | ||
86 | continue; | ||
87 | } | ||
88 | |||
89 | /* seems to be critical - replug necessary */ | ||
90 | if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) | ||
91 | return -EINVAL; | ||
92 | |||
93 | hid_err(usb_dev, "roccat_common_receive_control_status: " | ||
94 | "unknown response value 0x%x\n", control.value); | ||
95 | return -EINVAL; | ||
96 | } while (1); | ||
97 | } | ||
98 | |||
99 | static int kovaplus_send(struct usb_device *usb_dev, uint command, | ||
100 | void const *buf, uint size) | ||
101 | { | ||
102 | int retval; | ||
103 | |||
104 | retval = roccat_common_send(usb_dev, command, buf, size); | ||
105 | if (retval) | ||
106 | return retval; | ||
107 | |||
108 | msleep(100); | ||
109 | |||
110 | return kovaplus_receive_control_status(usb_dev); | ||
111 | } | ||
112 | |||
113 | static int kovaplus_select_profile(struct usb_device *usb_dev, uint number, | 67 | static int kovaplus_select_profile(struct usb_device *usb_dev, uint number, |
114 | enum kovaplus_control_requests request) | 68 | enum kovaplus_control_requests request) |
115 | { | 69 | { |
@@ -140,7 +94,8 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev, | |||
140 | static int kovaplus_set_profile_settings(struct usb_device *usb_dev, | 94 | static int kovaplus_set_profile_settings(struct usb_device *usb_dev, |
141 | struct kovaplus_profile_settings const *settings) | 95 | struct kovaplus_profile_settings const *settings) |
142 | { | 96 | { |
143 | return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, | 97 | return roccat_common_send_with_status(usb_dev, |
98 | KOVAPLUS_COMMAND_PROFILE_SETTINGS, | ||
144 | settings, sizeof(struct kovaplus_profile_settings)); | 99 | settings, sizeof(struct kovaplus_profile_settings)); |
145 | } | 100 | } |
146 | 101 | ||
@@ -161,7 +116,8 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, | |||
161 | static int kovaplus_set_profile_buttons(struct usb_device *usb_dev, | 116 | static int kovaplus_set_profile_buttons(struct usb_device *usb_dev, |
162 | struct kovaplus_profile_buttons const *buttons) | 117 | struct kovaplus_profile_buttons const *buttons) |
163 | { | 118 | { |
164 | return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, | 119 | return roccat_common_send_with_status(usb_dev, |
120 | KOVAPLUS_COMMAND_PROFILE_BUTTONS, | ||
165 | buttons, sizeof(struct kovaplus_profile_buttons)); | 121 | buttons, sizeof(struct kovaplus_profile_buttons)); |
166 | } | 122 | } |
167 | 123 | ||
@@ -186,7 +142,8 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev, | |||
186 | buf.size = sizeof(struct kovaplus_actual_profile); | 142 | buf.size = sizeof(struct kovaplus_actual_profile); |
187 | buf.actual_profile = new_profile; | 143 | buf.actual_profile = new_profile; |
188 | 144 | ||
189 | return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE, | 145 | return roccat_common_send_with_status(usb_dev, |
146 | KOVAPLUS_COMMAND_ACTUAL_PROFILE, | ||
190 | &buf, sizeof(struct kovaplus_actual_profile)); | 147 | &buf, sizeof(struct kovaplus_actual_profile)); |
191 | } | 148 | } |
192 | 149 | ||
diff --git a/drivers/hid/hid-roccat-kovaplus.h b/drivers/hid/hid-roccat-kovaplus.h index fb2aed44a8e0..f82daa1cdcb9 100644 --- a/drivers/hid/hid-roccat-kovaplus.h +++ b/drivers/hid/hid-roccat-kovaplus.h | |||
@@ -14,27 +14,13 @@ | |||
14 | 14 | ||
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | 16 | ||
17 | struct kovaplus_control { | ||
18 | uint8_t command; /* KOVAPLUS_COMMAND_CONTROL */ | ||
19 | uint8_t value; | ||
20 | uint8_t request; | ||
21 | } __packed; | ||
22 | |||
23 | enum kovaplus_control_requests { | 17 | enum kovaplus_control_requests { |
24 | /* read after write; value = 1 */ | ||
25 | KOVAPLUS_CONTROL_REQUEST_STATUS = 0x0, | ||
26 | /* write; value = profile number range 0-4 */ | 18 | /* write; value = profile number range 0-4 */ |
27 | KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, | 19 | KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, |
28 | /* write; value = profile number range 0-4 */ | 20 | /* write; value = profile number range 0-4 */ |
29 | KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20, | 21 | KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20, |
30 | }; | 22 | }; |
31 | 23 | ||
32 | enum kovaplus_control_values { | ||
33 | KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0, /* supposed */ | ||
34 | KOVAPLUS_CONTROL_REQUEST_STATUS_OK = 1, | ||
35 | KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, /* supposed */ | ||
36 | }; | ||
37 | |||
38 | struct kovaplus_actual_profile { | 24 | struct kovaplus_actual_profile { |
39 | uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */ | 25 | uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */ |
40 | uint8_t size; /* always 3 */ | 26 | uint8_t size; /* always 3 */ |
@@ -75,7 +61,6 @@ struct kovaplus_a { | |||
75 | } __packed; | 61 | } __packed; |
76 | 62 | ||
77 | enum kovaplus_commands { | 63 | enum kovaplus_commands { |
78 | KOVAPLUS_COMMAND_CONTROL = 0x4, | ||
79 | KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, | 64 | KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, |
80 | KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, | 65 | KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, |
81 | KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7, | 66 | KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7, |
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index df05c1b1064f..440cb1bd70d4 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c | |||
@@ -42,43 +42,19 @@ static void profile_activated(struct pyra_device *pyra, | |||
42 | static int pyra_send_control(struct usb_device *usb_dev, int value, | 42 | static int pyra_send_control(struct usb_device *usb_dev, int value, |
43 | enum pyra_control_requests request) | 43 | enum pyra_control_requests request) |
44 | { | 44 | { |
45 | struct pyra_control control; | 45 | struct roccat_common_control control; |
46 | 46 | ||
47 | if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || | 47 | if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || |
48 | request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && | 48 | request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && |
49 | (value < 0 || value > 4)) | 49 | (value < 0 || value > 4)) |
50 | return -EINVAL; | 50 | return -EINVAL; |
51 | 51 | ||
52 | control.command = PYRA_COMMAND_CONTROL; | 52 | control.command = ROCCAT_COMMON_COMMAND_CONTROL; |
53 | control.value = value; | 53 | control.value = value; |
54 | control.request = request; | 54 | control.request = request; |
55 | 55 | ||
56 | return roccat_common_send(usb_dev, PYRA_COMMAND_CONTROL, | 56 | return roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, |
57 | &control, sizeof(struct pyra_control)); | 57 | &control, sizeof(struct roccat_common_control)); |
58 | } | ||
59 | |||
60 | static int pyra_receive_control_status(struct usb_device *usb_dev) | ||
61 | { | ||
62 | int retval; | ||
63 | struct pyra_control control; | ||
64 | |||
65 | do { | ||
66 | msleep(10); | ||
67 | retval = roccat_common_receive(usb_dev, PYRA_COMMAND_CONTROL, | ||
68 | &control, sizeof(struct pyra_control)); | ||
69 | |||
70 | /* requested too early, try again */ | ||
71 | } while (retval == -EPROTO); | ||
72 | |||
73 | if (!retval && control.command == PYRA_COMMAND_CONTROL && | ||
74 | control.request == PYRA_CONTROL_REQUEST_STATUS && | ||
75 | control.value == 1) | ||
76 | return 0; | ||
77 | else { | ||
78 | hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n", | ||
79 | control.request, control.value); | ||
80 | return retval ? retval : -EINVAL; | ||
81 | } | ||
82 | } | 58 | } |
83 | 59 | ||
84 | static int pyra_get_profile_settings(struct usb_device *usb_dev, | 60 | static int pyra_get_profile_settings(struct usb_device *usb_dev, |
@@ -118,34 +94,27 @@ static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) | |||
118 | buf, sizeof(struct pyra_info)); | 94 | buf, sizeof(struct pyra_info)); |
119 | } | 95 | } |
120 | 96 | ||
121 | static int pyra_send(struct usb_device *usb_dev, uint command, | ||
122 | void const *buf, uint size) | ||
123 | { | ||
124 | int retval; | ||
125 | retval = roccat_common_send(usb_dev, command, buf, size); | ||
126 | if (retval) | ||
127 | return retval; | ||
128 | return pyra_receive_control_status(usb_dev); | ||
129 | } | ||
130 | |||
131 | static int pyra_set_profile_settings(struct usb_device *usb_dev, | 97 | static int pyra_set_profile_settings(struct usb_device *usb_dev, |
132 | struct pyra_profile_settings const *settings) | 98 | struct pyra_profile_settings const *settings) |
133 | { | 99 | { |
134 | return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, settings, | 100 | return roccat_common_send_with_status(usb_dev, |
101 | PYRA_COMMAND_PROFILE_SETTINGS, settings, | ||
135 | sizeof(struct pyra_profile_settings)); | 102 | sizeof(struct pyra_profile_settings)); |
136 | } | 103 | } |
137 | 104 | ||
138 | static int pyra_set_profile_buttons(struct usb_device *usb_dev, | 105 | static int pyra_set_profile_buttons(struct usb_device *usb_dev, |
139 | struct pyra_profile_buttons const *buttons) | 106 | struct pyra_profile_buttons const *buttons) |
140 | { | 107 | { |
141 | return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, buttons, | 108 | return roccat_common_send_with_status(usb_dev, |
109 | PYRA_COMMAND_PROFILE_BUTTONS, buttons, | ||
142 | sizeof(struct pyra_profile_buttons)); | 110 | sizeof(struct pyra_profile_buttons)); |
143 | } | 111 | } |
144 | 112 | ||
145 | static int pyra_set_settings(struct usb_device *usb_dev, | 113 | static int pyra_set_settings(struct usb_device *usb_dev, |
146 | struct pyra_settings const *settings) | 114 | struct pyra_settings const *settings) |
147 | { | 115 | { |
148 | return pyra_send(usb_dev, PYRA_COMMAND_SETTINGS, settings, | 116 | return roccat_common_send_with_status(usb_dev, |
117 | PYRA_COMMAND_SETTINGS, settings, | ||
149 | sizeof(struct pyra_settings)); | 118 | sizeof(struct pyra_settings)); |
150 | } | 119 | } |
151 | 120 | ||
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h index 0442d7fa2dcf..eada7830fa99 100644 --- a/drivers/hid/hid-roccat-pyra.h +++ b/drivers/hid/hid-roccat-pyra.h | |||
@@ -20,18 +20,7 @@ struct pyra_b { | |||
20 | uint8_t unknown; /* 1 */ | 20 | uint8_t unknown; /* 1 */ |
21 | } __attribute__ ((__packed__)); | 21 | } __attribute__ ((__packed__)); |
22 | 22 | ||
23 | struct pyra_control { | ||
24 | uint8_t command; /* PYRA_COMMAND_CONTROL */ | ||
25 | /* | ||
26 | * value is profile number for request_settings and request_buttons | ||
27 | * 1 if status ok for request_status | ||
28 | */ | ||
29 | uint8_t value; /* Range 0-4 */ | ||
30 | uint8_t request; | ||
31 | } __attribute__ ((__packed__)); | ||
32 | |||
33 | enum pyra_control_requests { | 23 | enum pyra_control_requests { |
34 | PYRA_CONTROL_REQUEST_STATUS = 0x00, | ||
35 | PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, | 24 | PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, |
36 | PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20 | 25 | PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20 |
37 | }; | 26 | }; |
@@ -75,7 +64,6 @@ struct pyra_info { | |||
75 | } __attribute__ ((__packed__)); | 64 | } __attribute__ ((__packed__)); |
76 | 65 | ||
77 | enum pyra_commands { | 66 | enum pyra_commands { |
78 | PYRA_COMMAND_CONTROL = 0x4, | ||
79 | PYRA_COMMAND_SETTINGS = 0x5, | 67 | PYRA_COMMAND_SETTINGS = 0x5, |
80 | PYRA_COMMAND_PROFILE_SETTINGS = 0x6, | 68 | PYRA_COMMAND_PROFILE_SETTINGS = 0x6, |
81 | PYRA_COMMAND_PROFILE_BUTTONS = 0x7, | 69 | PYRA_COMMAND_PROFILE_BUTTONS = 0x7, |
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index d6c82d57408a..19f9c47fc020 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c | |||
@@ -27,50 +27,6 @@ | |||
27 | 27 | ||
28 | static struct class *savu_class; | 28 | static struct class *savu_class; |
29 | 29 | ||
30 | static int savu_receive_control_status(struct usb_device *usb_dev) | ||
31 | { | ||
32 | int retval; | ||
33 | struct savu_control control; | ||
34 | |||
35 | do { | ||
36 | msleep(50); | ||
37 | retval = roccat_common_receive(usb_dev, SAVU_COMMAND_CONTROL, | ||
38 | &control, sizeof(struct savu_control)); | ||
39 | |||
40 | if (retval) | ||
41 | return retval; | ||
42 | |||
43 | switch (control.value) { | ||
44 | case SAVU_CONTROL_REQUEST_WRITE_CHECK_OK: | ||
45 | return 0; | ||
46 | case SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT: | ||
47 | continue; | ||
48 | case SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID: | ||
49 | /* seems to be critical - replug necessary */ | ||
50 | case SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD: | ||
51 | return -EINVAL; | ||
52 | default: | ||
53 | hid_err(usb_dev, "savu_receive_control_status: " | ||
54 | "unknown response value 0x%x\n", | ||
55 | control.value); | ||
56 | return -EINVAL; | ||
57 | } | ||
58 | |||
59 | } while (1); | ||
60 | } | ||
61 | |||
62 | static int savu_send(struct usb_device *usb_dev, uint command, | ||
63 | void const *buf, uint size) | ||
64 | { | ||
65 | int retval; | ||
66 | |||
67 | retval = roccat_common_send(usb_dev, command, buf, size); | ||
68 | if (retval) | ||
69 | return retval; | ||
70 | |||
71 | return savu_receive_control_status(usb_dev); | ||
72 | } | ||
73 | |||
74 | static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj, | 30 | static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj, |
75 | char *buf, loff_t off, size_t count, | 31 | char *buf, loff_t off, size_t count, |
76 | size_t real_size, uint command) | 32 | size_t real_size, uint command) |
@@ -108,7 +64,8 @@ static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj, | |||
108 | return -EINVAL; | 64 | return -EINVAL; |
109 | 65 | ||
110 | mutex_lock(&savu->savu_lock); | 66 | mutex_lock(&savu->savu_lock); |
111 | retval = savu_send(usb_dev, command, (void *)buf, real_size); | 67 | retval = roccat_common_send_with_status(usb_dev, command, |
68 | (void *)buf, real_size); | ||
112 | mutex_unlock(&savu->savu_lock); | 69 | mutex_unlock(&savu->savu_lock); |
113 | 70 | ||
114 | return retval ? retval : real_size; | 71 | return retval ? retval : real_size; |
diff --git a/drivers/hid/hid-roccat-savu.h b/drivers/hid/hid-roccat-savu.h index 97b43d5b0477..b15a1bbb66fb 100644 --- a/drivers/hid/hid-roccat-savu.h +++ b/drivers/hid/hid-roccat-savu.h | |||
@@ -23,29 +23,11 @@ enum { | |||
23 | SAVU_SIZE_INFO = 0x08, | 23 | SAVU_SIZE_INFO = 0x08, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | struct savu_control { | ||
27 | uint8_t command; /* SAVU_COMMAND_CONTROL */ | ||
28 | /* | ||
29 | * value is profile number in range 0-4 for requesting settings and buttons | ||
30 | * 1 if status ok for requesting status | ||
31 | */ | ||
32 | uint8_t value; | ||
33 | uint8_t request; | ||
34 | } __packed; | ||
35 | |||
36 | enum savu_control_requests { | 26 | enum savu_control_requests { |
37 | SAVU_CONTROL_REQUEST_WRITE_CHECK = 0x00, | ||
38 | SAVU_CONTROL_REQUEST_GENERAL = 0x80, | 27 | SAVU_CONTROL_REQUEST_GENERAL = 0x80, |
39 | SAVU_CONTROL_REQUEST_BUTTONS = 0x90, | 28 | SAVU_CONTROL_REQUEST_BUTTONS = 0x90, |
40 | }; | 29 | }; |
41 | 30 | ||
42 | enum savu_control_values { | ||
43 | SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD = 0, | ||
44 | SAVU_CONTROL_REQUEST_WRITE_CHECK_OK = 1, | ||
45 | SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID = 2, | ||
46 | SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT = 3, | ||
47 | }; | ||
48 | |||
49 | enum savu_commands { | 31 | enum savu_commands { |
50 | SAVU_COMMAND_CONTROL = 0x4, | 32 | SAVU_COMMAND_CONTROL = 0x4, |
51 | SAVU_COMMAND_PROFILE = 0x5, | 33 | SAVU_COMMAND_PROFILE = 0x5, |