diff options
| -rw-r--r-- | drivers/hid/hid-roccat-koneplus.c | 371 | ||||
| -rw-r--r-- | drivers/hid/hid-roccat-koneplus.h | 99 |
2 files changed, 102 insertions, 368 deletions
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 69592f427579..9fe445082308 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c | |||
| @@ -56,56 +56,6 @@ static int koneplus_send_control(struct usb_device *usb_dev, uint value, | |||
| 56 | &control, sizeof(struct roccat_common2_control)); | 56 | &control, sizeof(struct roccat_common2_control)); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static int koneplus_get_info(struct usb_device *usb_dev, | ||
| 60 | struct koneplus_info *buf) | ||
| 61 | { | ||
| 62 | return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO, | ||
| 63 | buf, sizeof(struct koneplus_info)); | ||
| 64 | } | ||
| 65 | |||
| 66 | static int koneplus_get_profile_settings(struct usb_device *usb_dev, | ||
| 67 | struct koneplus_profile_settings *buf, uint number) | ||
| 68 | { | ||
| 69 | int retval; | ||
| 70 | |||
| 71 | retval = koneplus_send_control(usb_dev, number, | ||
| 72 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); | ||
| 73 | if (retval) | ||
| 74 | return retval; | ||
| 75 | |||
| 76 | return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, | ||
| 77 | buf, sizeof(struct koneplus_profile_settings)); | ||
| 78 | } | ||
| 79 | |||
| 80 | static int koneplus_set_profile_settings(struct usb_device *usb_dev, | ||
| 81 | struct koneplus_profile_settings const *settings) | ||
| 82 | { | ||
| 83 | return roccat_common2_send_with_status(usb_dev, | ||
| 84 | KONEPLUS_COMMAND_PROFILE_SETTINGS, | ||
| 85 | settings, sizeof(struct koneplus_profile_settings)); | ||
| 86 | } | ||
| 87 | |||
| 88 | static int koneplus_get_profile_buttons(struct usb_device *usb_dev, | ||
| 89 | struct koneplus_profile_buttons *buf, int number) | ||
| 90 | { | ||
| 91 | int retval; | ||
| 92 | |||
| 93 | retval = koneplus_send_control(usb_dev, number, | ||
| 94 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); | ||
| 95 | if (retval) | ||
| 96 | return retval; | ||
| 97 | |||
| 98 | return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, | ||
| 99 | buf, sizeof(struct koneplus_profile_buttons)); | ||
| 100 | } | ||
| 101 | |||
| 102 | static int koneplus_set_profile_buttons(struct usb_device *usb_dev, | ||
| 103 | struct koneplus_profile_buttons const *buttons) | ||
| 104 | { | ||
| 105 | return roccat_common2_send_with_status(usb_dev, | ||
| 106 | KONEPLUS_COMMAND_PROFILE_BUTTONS, | ||
| 107 | buttons, sizeof(struct koneplus_profile_buttons)); | ||
| 108 | } | ||
| 109 | 59 | ||
| 110 | /* retval is 0-4 on success, < 0 on error */ | 60 | /* retval is 0-4 on success, < 0 on error */ |
| 111 | static int koneplus_get_actual_profile(struct usb_device *usb_dev) | 61 | static int koneplus_get_actual_profile(struct usb_device *usb_dev) |
| @@ -114,7 +64,7 @@ static int koneplus_get_actual_profile(struct usb_device *usb_dev) | |||
| 114 | int retval; | 64 | int retval; |
| 115 | 65 | ||
| 116 | retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, | 66 | retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, |
| 117 | &buf, sizeof(struct koneplus_actual_profile)); | 67 | &buf, KONEPLUS_SIZE_ACTUAL_PROFILE); |
| 118 | 68 | ||
| 119 | return retval ? retval : buf.actual_profile; | 69 | return retval ? retval : buf.actual_profile; |
| 120 | } | 70 | } |
| @@ -125,12 +75,12 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev, | |||
| 125 | struct koneplus_actual_profile buf; | 75 | struct koneplus_actual_profile buf; |
| 126 | 76 | ||
| 127 | buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE; | 77 | buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE; |
| 128 | buf.size = sizeof(struct koneplus_actual_profile); | 78 | buf.size = KONEPLUS_SIZE_ACTUAL_PROFILE; |
| 129 | buf.actual_profile = new_profile; | 79 | buf.actual_profile = new_profile; |
| 130 | 80 | ||
| 131 | return roccat_common2_send_with_status(usb_dev, | 81 | return roccat_common2_send_with_status(usb_dev, |
| 132 | KONEPLUS_COMMAND_ACTUAL_PROFILE, | 82 | KONEPLUS_COMMAND_ACTUAL_PROFILE, |
| 133 | &buf, sizeof(struct koneplus_actual_profile)); | 83 | &buf, KONEPLUS_SIZE_ACTUAL_PROFILE); |
| 134 | } | 84 | } |
| 135 | 85 | ||
| 136 | static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, | 86 | static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, |
| @@ -183,77 +133,58 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, | |||
| 183 | return real_size; | 133 | return real_size; |
| 184 | } | 134 | } |
| 185 | 135 | ||
| 186 | static ssize_t koneplus_sysfs_read_info(struct file *fp, | 136 | #define KONEPLUS_SYSFS_W(thingy, THINGY) \ |
| 187 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 137 | static ssize_t koneplus_sysfs_write_ ## thingy(struct file *fp, \ |
| 188 | loff_t off, size_t count) | 138 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ |
| 189 | { | 139 | loff_t off, size_t count) \ |
| 190 | return koneplus_sysfs_read(fp, kobj, buf, off, count, | 140 | { \ |
| 191 | sizeof(struct koneplus_info), KONEPLUS_COMMAND_INFO); | 141 | return koneplus_sysfs_write(fp, kobj, buf, off, count, \ |
| 142 | KONEPLUS_SIZE_ ## THINGY, KONEPLUS_COMMAND_ ## THINGY); \ | ||
| 192 | } | 143 | } |
| 193 | 144 | ||
| 194 | static ssize_t koneplus_sysfs_write_info(struct file *fp, | 145 | #define KONEPLUS_SYSFS_R(thingy, THINGY) \ |
| 195 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 146 | static ssize_t koneplus_sysfs_read_ ## thingy(struct file *fp, \ |
| 196 | loff_t off, size_t count) | 147 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ |
| 197 | { | 148 | loff_t off, size_t count) \ |
| 198 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 149 | { \ |
| 199 | sizeof(struct koneplus_info), KONEPLUS_COMMAND_INFO); | 150 | return koneplus_sysfs_read(fp, kobj, buf, off, count, \ |
| 151 | KONEPLUS_SIZE_ ## THINGY, KONEPLUS_COMMAND_ ## THINGY); \ | ||
| 200 | } | 152 | } |
| 201 | 153 | ||
| 202 | static ssize_t koneplus_sysfs_write_talk(struct file *fp, | 154 | #define KONEPLUS_SYSFS_RW(thingy, THINGY) \ |
| 203 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 155 | KONEPLUS_SYSFS_W(thingy, THINGY) \ |
| 204 | loff_t off, size_t count) | 156 | KONEPLUS_SYSFS_R(thingy, THINGY) |
| 205 | { | ||
| 206 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | ||
| 207 | sizeof(struct koneplus_talk), KONEPLUS_COMMAND_TALK); | ||
| 208 | } | ||
| 209 | 157 | ||
| 210 | static ssize_t koneplus_sysfs_write_macro(struct file *fp, | 158 | #define KONEPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
| 211 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 159 | { \ |
| 212 | loff_t off, size_t count) | 160 | .attr = { .name = #thingy, .mode = 0660 }, \ |
| 213 | { | 161 | .size = KONEPLUS_SIZE_ ## THINGY, \ |
| 214 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 162 | .read = koneplus_sysfs_read_ ## thingy, \ |
| 215 | sizeof(struct koneplus_macro), KONEPLUS_COMMAND_MACRO); | 163 | .write = koneplus_sysfs_write_ ## thingy \ |
| 216 | } | 164 | } |
| 217 | 165 | ||
| 218 | static ssize_t koneplus_sysfs_read_sensor(struct file *fp, | 166 | #define KONEPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \ |
| 219 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 167 | { \ |
| 220 | loff_t off, size_t count) | 168 | .attr = { .name = #thingy, .mode = 0440 }, \ |
| 221 | { | 169 | .size = KONEPLUS_SIZE_ ## THINGY, \ |
| 222 | return koneplus_sysfs_read(fp, kobj, buf, off, count, | 170 | .read = koneplus_sysfs_read_ ## thingy, \ |
| 223 | sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR); | ||
| 224 | } | 171 | } |
| 225 | 172 | ||
| 226 | static ssize_t koneplus_sysfs_write_sensor(struct file *fp, | 173 | #define KONEPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
| 227 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 174 | { \ |
| 228 | loff_t off, size_t count) | 175 | .attr = { .name = #thingy, .mode = 0220 }, \ |
| 229 | { | 176 | .size = KONEPLUS_SIZE_ ## THINGY, \ |
| 230 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 177 | .write = koneplus_sysfs_write_ ## thingy \ |
| 231 | sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR); | ||
| 232 | } | 178 | } |
| 233 | 179 | ||
| 234 | static ssize_t koneplus_sysfs_write_tcu(struct file *fp, | 180 | KONEPLUS_SYSFS_RW(info, INFO) |
| 235 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 181 | KONEPLUS_SYSFS_W(talk, TALK) |
| 236 | loff_t off, size_t count) | 182 | KONEPLUS_SYSFS_W(macro, MACRO) |
| 237 | { | 183 | KONEPLUS_SYSFS_RW(sensor, SENSOR) |
| 238 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 184 | KONEPLUS_SYSFS_RW(tcu, TCU) |
| 239 | sizeof(struct koneplus_tcu), KONEPLUS_COMMAND_TCU); | 185 | KONEPLUS_SYSFS_R(tcu_image, TCU_IMAGE) |
| 240 | } | 186 | KONEPLUS_SYSFS_W(profile_settings, PROFILE_SETTINGS) |
| 241 | 187 | KONEPLUS_SYSFS_W(profile_buttons, PROFILE_BUTTONS) | |
| 242 | static ssize_t koneplus_sysfs_read_tcu(struct file *fp, | ||
| 243 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
| 244 | loff_t off, size_t count) | ||
| 245 | { | ||
| 246 | return koneplus_sysfs_read(fp, kobj, buf, off, count, | ||
| 247 | sizeof(struct koneplus_tcu), KONEPLUS_COMMAND_TCU); | ||
| 248 | } | ||
| 249 | |||
| 250 | static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp, | ||
| 251 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
| 252 | loff_t off, size_t count) | ||
| 253 | { | ||
| 254 | return koneplus_sysfs_read(fp, kobj, buf, off, count, | ||
| 255 | sizeof(struct koneplus_tcu_image), KONEPLUS_COMMAND_TCU); | ||
| 256 | } | ||
| 257 | 188 | ||
| 258 | static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, | 189 | static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, |
| 259 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 190 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
| @@ -261,57 +192,17 @@ static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, | |||
| 261 | { | 192 | { |
| 262 | struct device *dev = | 193 | struct device *dev = |
| 263 | container_of(kobj, struct device, kobj)->parent->parent; | 194 | container_of(kobj, struct device, kobj)->parent->parent; |
| 264 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 265 | |||
| 266 | if (off >= sizeof(struct koneplus_profile_settings)) | ||
| 267 | return 0; | ||
| 268 | |||
| 269 | if (off + count > sizeof(struct koneplus_profile_settings)) | ||
| 270 | count = sizeof(struct koneplus_profile_settings) - off; | ||
| 271 | |||
| 272 | mutex_lock(&koneplus->koneplus_lock); | ||
| 273 | memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off, | ||
| 274 | count); | ||
| 275 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 276 | |||
| 277 | return count; | ||
| 278 | } | ||
| 279 | |||
| 280 | static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp, | ||
| 281 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
| 282 | loff_t off, size_t count) | ||
| 283 | { | ||
| 284 | struct device *dev = | ||
| 285 | container_of(kobj, struct device, kobj)->parent->parent; | ||
| 286 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 287 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 195 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 288 | int retval = 0; | 196 | ssize_t retval; |
| 289 | int difference; | ||
| 290 | int profile_number; | ||
| 291 | struct koneplus_profile_settings *profile_settings; | ||
| 292 | |||
| 293 | if (off != 0 || count != sizeof(struct koneplus_profile_settings)) | ||
| 294 | return -EINVAL; | ||
| 295 | |||
| 296 | profile_number = ((struct koneplus_profile_settings const *)buf)->number; | ||
| 297 | profile_settings = &koneplus->profile_settings[profile_number]; | ||
| 298 | |||
| 299 | mutex_lock(&koneplus->koneplus_lock); | ||
| 300 | difference = memcmp(buf, profile_settings, | ||
| 301 | sizeof(struct koneplus_profile_settings)); | ||
| 302 | if (difference) { | ||
| 303 | retval = koneplus_set_profile_settings(usb_dev, | ||
| 304 | (struct koneplus_profile_settings const *)buf); | ||
| 305 | if (!retval) | ||
| 306 | memcpy(profile_settings, buf, | ||
| 307 | sizeof(struct koneplus_profile_settings)); | ||
| 308 | } | ||
| 309 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 310 | 197 | ||
| 198 | retval = koneplus_send_control(usb_dev, *(uint *)(attr->private), | ||
| 199 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); | ||
| 311 | if (retval) | 200 | if (retval) |
| 312 | return retval; | 201 | return retval; |
| 313 | 202 | ||
| 314 | return sizeof(struct koneplus_profile_settings); | 203 | return koneplus_sysfs_read(fp, kobj, buf, off, count, |
| 204 | KONEPLUS_SIZE_PROFILE_SETTINGS, | ||
| 205 | KONEPLUS_COMMAND_PROFILE_SETTINGS); | ||
| 315 | } | 206 | } |
| 316 | 207 | ||
| 317 | static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, | 208 | static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, |
| @@ -320,57 +211,17 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, | |||
| 320 | { | 211 | { |
| 321 | struct device *dev = | 212 | struct device *dev = |
| 322 | container_of(kobj, struct device, kobj)->parent->parent; | 213 | container_of(kobj, struct device, kobj)->parent->parent; |
| 323 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 324 | |||
| 325 | if (off >= sizeof(struct koneplus_profile_buttons)) | ||
| 326 | return 0; | ||
| 327 | |||
| 328 | if (off + count > sizeof(struct koneplus_profile_buttons)) | ||
| 329 | count = sizeof(struct koneplus_profile_buttons) - off; | ||
| 330 | |||
| 331 | mutex_lock(&koneplus->koneplus_lock); | ||
| 332 | memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off, | ||
| 333 | count); | ||
| 334 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 335 | |||
| 336 | return count; | ||
| 337 | } | ||
| 338 | |||
| 339 | static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp, | ||
| 340 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
| 341 | loff_t off, size_t count) | ||
| 342 | { | ||
| 343 | struct device *dev = | ||
| 344 | container_of(kobj, struct device, kobj)->parent->parent; | ||
| 345 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 346 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 214 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 347 | int retval = 0; | 215 | ssize_t retval; |
| 348 | int difference; | ||
| 349 | uint profile_number; | ||
| 350 | struct koneplus_profile_buttons *profile_buttons; | ||
| 351 | |||
| 352 | if (off != 0 || count != sizeof(struct koneplus_profile_buttons)) | ||
| 353 | return -EINVAL; | ||
| 354 | |||
| 355 | profile_number = ((struct koneplus_profile_buttons const *)buf)->number; | ||
| 356 | profile_buttons = &koneplus->profile_buttons[profile_number]; | ||
| 357 | |||
| 358 | mutex_lock(&koneplus->koneplus_lock); | ||
| 359 | difference = memcmp(buf, profile_buttons, | ||
| 360 | sizeof(struct koneplus_profile_buttons)); | ||
| 361 | if (difference) { | ||
| 362 | retval = koneplus_set_profile_buttons(usb_dev, | ||
| 363 | (struct koneplus_profile_buttons const *)buf); | ||
| 364 | if (!retval) | ||
| 365 | memcpy(profile_buttons, buf, | ||
| 366 | sizeof(struct koneplus_profile_buttons)); | ||
| 367 | } | ||
| 368 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 369 | 216 | ||
| 217 | retval = koneplus_send_control(usb_dev, *(uint *)(attr->private), | ||
| 218 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); | ||
| 370 | if (retval) | 219 | if (retval) |
| 371 | return retval; | 220 | return retval; |
| 372 | 221 | ||
| 373 | return sizeof(struct koneplus_profile_buttons); | 222 | return koneplus_sysfs_read(fp, kobj, buf, off, count, |
| 223 | KONEPLUS_SIZE_PROFILE_BUTTONS, | ||
| 224 | KONEPLUS_COMMAND_PROFILE_BUTTONS); | ||
| 374 | } | 225 | } |
| 375 | 226 | ||
| 376 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, | 227 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, |
| @@ -426,9 +277,20 @@ static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev, | |||
| 426 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, | 277 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, |
| 427 | struct device_attribute *attr, char *buf) | 278 | struct device_attribute *attr, char *buf) |
| 428 | { | 279 | { |
| 429 | struct koneplus_device *koneplus = | 280 | struct koneplus_device *koneplus; |
| 430 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 281 | struct usb_device *usb_dev; |
| 431 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version); | 282 | struct koneplus_info info; |
| 283 | |||
| 284 | dev = dev->parent->parent; | ||
| 285 | koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 286 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 287 | |||
| 288 | mutex_lock(&koneplus->koneplus_lock); | ||
| 289 | roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO, | ||
| 290 | &info, KONEPLUS_SIZE_INFO); | ||
| 291 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 292 | |||
| 293 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); | ||
| 432 | } | 294 | } |
| 433 | 295 | ||
| 434 | static struct device_attribute koneplus_attributes[] = { | 296 | static struct device_attribute koneplus_attributes[] = { |
| @@ -444,139 +306,84 @@ static struct device_attribute koneplus_attributes[] = { | |||
| 444 | }; | 306 | }; |
| 445 | 307 | ||
| 446 | static struct bin_attribute koneplus_bin_attributes[] = { | 308 | static struct bin_attribute koneplus_bin_attributes[] = { |
| 447 | { | 309 | KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO), |
| 448 | .attr = { .name = "info", .mode = 0660 }, | 310 | KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK), |
| 449 | .size = sizeof(struct koneplus_info), | 311 | KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO), |
| 450 | .read = koneplus_sysfs_read_info, | 312 | KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR), |
| 451 | .write = koneplus_sysfs_write_info | 313 | KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU), |
| 452 | }, | 314 | KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE), |
| 453 | { | 315 | KONEPLUS_BIN_ATTRIBUTE_W(profile_settings, PROFILE_SETTINGS), |
| 454 | .attr = { .name = "sensor", .mode = 0660 }, | 316 | KONEPLUS_BIN_ATTRIBUTE_W(profile_buttons, PROFILE_BUTTONS), |
| 455 | .size = sizeof(struct koneplus_sensor), | ||
| 456 | .read = koneplus_sysfs_read_sensor, | ||
| 457 | .write = koneplus_sysfs_write_sensor | ||
| 458 | }, | ||
| 459 | { | ||
| 460 | .attr = { .name = "tcu", .mode = 0660 }, | ||
| 461 | .size = sizeof(struct koneplus_tcu), | ||
| 462 | .read = koneplus_sysfs_read_tcu, | ||
| 463 | .write = koneplus_sysfs_write_tcu | ||
| 464 | }, | ||
| 465 | { | ||
| 466 | .attr = { .name = "tcu_image", .mode = 0440 }, | ||
| 467 | .size = sizeof(struct koneplus_tcu_image), | ||
| 468 | .read = koneplus_sysfs_read_tcu_image | ||
| 469 | }, | ||
| 470 | { | ||
| 471 | .attr = { .name = "profile_settings", .mode = 0220 }, | ||
| 472 | .size = sizeof(struct koneplus_profile_settings), | ||
| 473 | .write = koneplus_sysfs_write_profile_settings | ||
| 474 | }, | ||
| 475 | { | 317 | { |
| 476 | .attr = { .name = "profile1_settings", .mode = 0440 }, | 318 | .attr = { .name = "profile1_settings", .mode = 0440 }, |
| 477 | .size = sizeof(struct koneplus_profile_settings), | 319 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 478 | .read = koneplus_sysfs_read_profilex_settings, | 320 | .read = koneplus_sysfs_read_profilex_settings, |
| 479 | .private = &profile_numbers[0] | 321 | .private = &profile_numbers[0] |
| 480 | }, | 322 | }, |
| 481 | { | 323 | { |
| 482 | .attr = { .name = "profile2_settings", .mode = 0440 }, | 324 | .attr = { .name = "profile2_settings", .mode = 0440 }, |
| 483 | .size = sizeof(struct koneplus_profile_settings), | 325 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 484 | .read = koneplus_sysfs_read_profilex_settings, | 326 | .read = koneplus_sysfs_read_profilex_settings, |
| 485 | .private = &profile_numbers[1] | 327 | .private = &profile_numbers[1] |
| 486 | }, | 328 | }, |
| 487 | { | 329 | { |
| 488 | .attr = { .name = "profile3_settings", .mode = 0440 }, | 330 | .attr = { .name = "profile3_settings", .mode = 0440 }, |
| 489 | .size = sizeof(struct koneplus_profile_settings), | 331 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 490 | .read = koneplus_sysfs_read_profilex_settings, | 332 | .read = koneplus_sysfs_read_profilex_settings, |
| 491 | .private = &profile_numbers[2] | 333 | .private = &profile_numbers[2] |
| 492 | }, | 334 | }, |
| 493 | { | 335 | { |
| 494 | .attr = { .name = "profile4_settings", .mode = 0440 }, | 336 | .attr = { .name = "profile4_settings", .mode = 0440 }, |
| 495 | .size = sizeof(struct koneplus_profile_settings), | 337 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 496 | .read = koneplus_sysfs_read_profilex_settings, | 338 | .read = koneplus_sysfs_read_profilex_settings, |
| 497 | .private = &profile_numbers[3] | 339 | .private = &profile_numbers[3] |
| 498 | }, | 340 | }, |
| 499 | { | 341 | { |
| 500 | .attr = { .name = "profile5_settings", .mode = 0440 }, | 342 | .attr = { .name = "profile5_settings", .mode = 0440 }, |
| 501 | .size = sizeof(struct koneplus_profile_settings), | 343 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 502 | .read = koneplus_sysfs_read_profilex_settings, | 344 | .read = koneplus_sysfs_read_profilex_settings, |
| 503 | .private = &profile_numbers[4] | 345 | .private = &profile_numbers[4] |
| 504 | }, | 346 | }, |
| 505 | { | 347 | { |
| 506 | .attr = { .name = "profile_buttons", .mode = 0220 }, | ||
| 507 | .size = sizeof(struct koneplus_profile_buttons), | ||
| 508 | .write = koneplus_sysfs_write_profile_buttons | ||
| 509 | }, | ||
| 510 | { | ||
| 511 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | 348 | .attr = { .name = "profile1_buttons", .mode = 0440 }, |
| 512 | .size = sizeof(struct koneplus_profile_buttons), | 349 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 513 | .read = koneplus_sysfs_read_profilex_buttons, | 350 | .read = koneplus_sysfs_read_profilex_buttons, |
| 514 | .private = &profile_numbers[0] | 351 | .private = &profile_numbers[0] |
| 515 | }, | 352 | }, |
| 516 | { | 353 | { |
| 517 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | 354 | .attr = { .name = "profile2_buttons", .mode = 0440 }, |
| 518 | .size = sizeof(struct koneplus_profile_buttons), | 355 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 519 | .read = koneplus_sysfs_read_profilex_buttons, | 356 | .read = koneplus_sysfs_read_profilex_buttons, |
| 520 | .private = &profile_numbers[1] | 357 | .private = &profile_numbers[1] |
| 521 | }, | 358 | }, |
| 522 | { | 359 | { |
| 523 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | 360 | .attr = { .name = "profile3_buttons", .mode = 0440 }, |
| 524 | .size = sizeof(struct koneplus_profile_buttons), | 361 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 525 | .read = koneplus_sysfs_read_profilex_buttons, | 362 | .read = koneplus_sysfs_read_profilex_buttons, |
| 526 | .private = &profile_numbers[2] | 363 | .private = &profile_numbers[2] |
| 527 | }, | 364 | }, |
| 528 | { | 365 | { |
| 529 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | 366 | .attr = { .name = "profile4_buttons", .mode = 0440 }, |
| 530 | .size = sizeof(struct koneplus_profile_buttons), | 367 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 531 | .read = koneplus_sysfs_read_profilex_buttons, | 368 | .read = koneplus_sysfs_read_profilex_buttons, |
| 532 | .private = &profile_numbers[3] | 369 | .private = &profile_numbers[3] |
| 533 | }, | 370 | }, |
| 534 | { | 371 | { |
| 535 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | 372 | .attr = { .name = "profile5_buttons", .mode = 0440 }, |
| 536 | .size = sizeof(struct koneplus_profile_buttons), | 373 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 537 | .read = koneplus_sysfs_read_profilex_buttons, | 374 | .read = koneplus_sysfs_read_profilex_buttons, |
| 538 | .private = &profile_numbers[4] | 375 | .private = &profile_numbers[4] |
| 539 | }, | 376 | }, |
| 540 | { | ||
| 541 | .attr = { .name = "macro", .mode = 0220 }, | ||
| 542 | .size = sizeof(struct koneplus_macro), | ||
| 543 | .write = koneplus_sysfs_write_macro | ||
| 544 | }, | ||
| 545 | { | ||
| 546 | .attr = { .name = "talk", .mode = 0220 }, | ||
| 547 | .size = sizeof(struct koneplus_talk), | ||
| 548 | .write = koneplus_sysfs_write_talk | ||
| 549 | }, | ||
| 550 | __ATTR_NULL | 377 | __ATTR_NULL |
| 551 | }; | 378 | }; |
| 552 | 379 | ||
| 553 | static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, | 380 | static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, |
| 554 | struct koneplus_device *koneplus) | 381 | struct koneplus_device *koneplus) |
| 555 | { | 382 | { |
| 556 | int retval, i; | 383 | int retval; |
| 557 | static uint wait = 200; | ||
| 558 | 384 | ||
| 559 | mutex_init(&koneplus->koneplus_lock); | 385 | mutex_init(&koneplus->koneplus_lock); |
| 560 | 386 | ||
| 561 | retval = koneplus_get_info(usb_dev, &koneplus->info); | ||
| 562 | if (retval) | ||
| 563 | return retval; | ||
| 564 | |||
| 565 | for (i = 0; i < 5; ++i) { | ||
| 566 | msleep(wait); | ||
| 567 | retval = koneplus_get_profile_settings(usb_dev, | ||
| 568 | &koneplus->profile_settings[i], i); | ||
| 569 | if (retval) | ||
| 570 | return retval; | ||
| 571 | |||
| 572 | msleep(wait); | ||
| 573 | retval = koneplus_get_profile_buttons(usb_dev, | ||
| 574 | &koneplus->profile_buttons[i], i); | ||
| 575 | if (retval) | ||
| 576 | return retval; | ||
| 577 | } | ||
| 578 | |||
| 579 | msleep(wait); | ||
| 580 | retval = koneplus_get_actual_profile(usb_dev); | 387 | retval = koneplus_get_actual_profile(usb_dev); |
| 581 | if (retval < 0) | 388 | if (retval < 0) |
| 582 | return retval; | 389 | return retval; |
diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h index 7074b2a4b94b..563b9d3fe5fb 100644 --- a/drivers/hid/hid-roccat-koneplus.h +++ b/drivers/hid/hid-roccat-koneplus.h | |||
| @@ -14,11 +14,18 @@ | |||
| 14 | 14 | ||
| 15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 16 | 16 | ||
| 17 | struct koneplus_talk { | 17 | enum { |
| 18 | uint8_t command; /* KONEPLUS_COMMAND_TALK */ | 18 | KONEPLUS_SIZE_ACTUAL_PROFILE = 0x03, |
| 19 | uint8_t size; /* always 0x10 */ | 19 | KONEPLUS_SIZE_FIRMWARE_WRITE = 0x0402, |
| 20 | uint8_t data[14]; | 20 | KONEPLUS_SIZE_INFO = 0x06, |
| 21 | } __packed; | 21 | KONEPLUS_SIZE_MACRO = 0x0822, |
| 22 | KONEPLUS_SIZE_PROFILE_SETTINGS = 0x2b, | ||
| 23 | KONEPLUS_SIZE_PROFILE_BUTTONS = 0x4d, | ||
| 24 | KONEPLUS_SIZE_SENSOR = 0x06, | ||
| 25 | KONEPLUS_SIZE_TALK = 0x10, | ||
| 26 | KONEPLUS_SIZE_TCU = 0x03, | ||
| 27 | KONEPLUS_SIZE_TCU_IMAGE = 0x0404, | ||
| 28 | }; | ||
| 22 | 29 | ||
| 23 | enum koneplus_control_requests { | 30 | enum koneplus_control_requests { |
| 24 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, | 31 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, |
| @@ -31,45 +38,6 @@ struct koneplus_actual_profile { | |||
| 31 | uint8_t actual_profile; /* Range 0-4! */ | 38 | uint8_t actual_profile; /* Range 0-4! */ |
| 32 | } __attribute__ ((__packed__)); | 39 | } __attribute__ ((__packed__)); |
| 33 | 40 | ||
| 34 | struct koneplus_profile_settings { | ||
| 35 | uint8_t command; /* KONEPLUS_COMMAND_PROFILE_SETTINGS */ | ||
| 36 | uint8_t size; /* always 43 */ | ||
| 37 | uint8_t number; /* range 0-4 */ | ||
| 38 | uint8_t advanced_sensitivity; | ||
| 39 | uint8_t sensitivity_x; | ||
| 40 | uint8_t sensitivity_y; | ||
| 41 | uint8_t cpi_levels_enabled; | ||
| 42 | uint8_t cpi_levels_x[5]; | ||
| 43 | uint8_t cpi_startup_level; /* range 0-4 */ | ||
| 44 | uint8_t cpi_levels_y[5]; /* range 1-60 means 100-6000 cpi */ | ||
| 45 | uint8_t unknown1; | ||
| 46 | uint8_t polling_rate; | ||
| 47 | uint8_t lights_enabled; | ||
| 48 | uint8_t light_effect_mode; | ||
| 49 | uint8_t color_flow_effect; | ||
| 50 | uint8_t light_effect_type; | ||
| 51 | uint8_t light_effect_speed; | ||
| 52 | uint8_t lights[16]; | ||
| 53 | uint16_t checksum; | ||
| 54 | } __attribute__ ((__packed__)); | ||
| 55 | |||
| 56 | struct koneplus_profile_buttons { | ||
| 57 | uint8_t command; /* KONEPLUS_COMMAND_PROFILE_BUTTONS */ | ||
| 58 | uint8_t size; /* always 77 */ | ||
| 59 | uint8_t number; /* range 0-4 */ | ||
| 60 | uint8_t data[72]; | ||
| 61 | uint16_t checksum; | ||
| 62 | } __attribute__ ((__packed__)); | ||
| 63 | |||
| 64 | struct koneplus_macro { | ||
| 65 | uint8_t command; /* KONEPLUS_COMMAND_MACRO */ | ||
| 66 | uint16_t size; /* always 0x822 little endian */ | ||
| 67 | uint8_t profile; /* range 0-4 */ | ||
| 68 | uint8_t button; /* range 0-23 */ | ||
| 69 | uint8_t data[2075]; | ||
| 70 | uint16_t checksum; | ||
| 71 | } __attribute__ ((__packed__)); | ||
| 72 | |||
| 73 | struct koneplus_info { | 41 | struct koneplus_info { |
| 74 | uint8_t command; /* KONEPLUS_COMMAND_INFO */ | 42 | uint8_t command; /* KONEPLUS_COMMAND_INFO */ |
| 75 | uint8_t size; /* always 6 */ | 43 | uint8_t size; /* always 6 */ |
| @@ -77,44 +45,6 @@ struct koneplus_info { | |||
| 77 | uint8_t unknown[3]; | 45 | uint8_t unknown[3]; |
| 78 | } __attribute__ ((__packed__)); | 46 | } __attribute__ ((__packed__)); |
| 79 | 47 | ||
| 80 | struct koneplus_e { | ||
| 81 | uint8_t command; /* KONEPLUS_COMMAND_E */ | ||
| 82 | uint8_t size; /* always 3 */ | ||
| 83 | uint8_t unknown; /* TODO 1; 0 before firmware update */ | ||
| 84 | } __attribute__ ((__packed__)); | ||
| 85 | |||
| 86 | struct koneplus_sensor { | ||
| 87 | uint8_t command; /* KONEPLUS_COMMAND_SENSOR */ | ||
| 88 | uint8_t size; /* always 6 */ | ||
| 89 | uint8_t data[4]; | ||
| 90 | } __attribute__ ((__packed__)); | ||
| 91 | |||
| 92 | struct koneplus_firmware_write { | ||
| 93 | uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE */ | ||
| 94 | uint8_t unknown[1025]; | ||
| 95 | } __attribute__ ((__packed__)); | ||
| 96 | |||
| 97 | struct koneplus_firmware_write_control { | ||
| 98 | uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL */ | ||
| 99 | /* | ||
| 100 | * value is 1 on success | ||
| 101 | * 3 means "not finished yet" | ||
| 102 | */ | ||
| 103 | uint8_t value; | ||
| 104 | uint8_t unknown; /* always 0x75 */ | ||
| 105 | } __attribute__ ((__packed__)); | ||
| 106 | |||
| 107 | struct koneplus_tcu { | ||
| 108 | uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */ | ||
| 109 | uint8_t data[2]; | ||
| 110 | } __attribute__ ((__packed__)); | ||
| 111 | |||
| 112 | struct koneplus_tcu_image { | ||
| 113 | uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */ | ||
| 114 | uint8_t data[1024]; | ||
| 115 | uint16_t checksum; | ||
| 116 | } __attribute__ ((__packed__)); | ||
| 117 | |||
| 118 | enum koneplus_commands { | 48 | enum koneplus_commands { |
| 119 | KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, | 49 | KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, |
| 120 | KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, | 50 | KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, |
| @@ -122,6 +52,7 @@ enum koneplus_commands { | |||
| 122 | KONEPLUS_COMMAND_MACRO = 0x8, | 52 | KONEPLUS_COMMAND_MACRO = 0x8, |
| 123 | KONEPLUS_COMMAND_INFO = 0x9, | 53 | KONEPLUS_COMMAND_INFO = 0x9, |
| 124 | KONEPLUS_COMMAND_TCU = 0xc, | 54 | KONEPLUS_COMMAND_TCU = 0xc, |
| 55 | KONEPLUS_COMMAND_TCU_IMAGE = 0xc, | ||
| 125 | KONEPLUS_COMMAND_E = 0xe, | 56 | KONEPLUS_COMMAND_E = 0xe, |
| 126 | KONEPLUS_COMMAND_SENSOR = 0xf, | 57 | KONEPLUS_COMMAND_SENSOR = 0xf, |
| 127 | KONEPLUS_COMMAND_TALK = 0x10, | 58 | KONEPLUS_COMMAND_TALK = 0x10, |
| @@ -187,10 +118,6 @@ struct koneplus_device { | |||
| 187 | int chrdev_minor; | 118 | int chrdev_minor; |
| 188 | 119 | ||
| 189 | struct mutex koneplus_lock; | 120 | struct mutex koneplus_lock; |
| 190 | |||
| 191 | struct koneplus_info info; | ||
| 192 | struct koneplus_profile_settings profile_settings[5]; | ||
| 193 | struct koneplus_profile_buttons profile_buttons[5]; | ||
| 194 | }; | 121 | }; |
| 195 | 122 | ||
| 196 | #endif | 123 | #endif |
