1 /* 2 * Roccat Kone[+] driver for Linux 3 * 4 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> 5 */ 6 7 /* 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the Free 10 * Software Foundation; either version 2 of the License, or (at your option) 11 * any later version. 12 */ 13 14 /* 15 * Roccat Kone[+] is an updated/improved version of the Kone with more memory 16 * and functionality and without the non-standard behaviours the Kone had. 17 */ 18 19 #include <linux/device.h> 20 #include <linux/input.h> 21 #include <linux/hid.h> 22 #include <linux/module.h> 23 #include <linux/slab.h> 24 #include <linux/hid-roccat.h> 25 #include "hid-ids.h" 26 #include "hid-roccat-common.h" 27 #include "hid-roccat-koneplus.h" 28 29 static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 30 31 static struct class *koneplus_class; 32 33 static void koneplus_profile_activated(struct koneplus_device *koneplus, 34 uint new_profile) 35 { 36 koneplus->actual_profile = new_profile; 37 } 38 39 static int koneplus_send_control(struct usb_device *usb_dev, uint value, 40 enum koneplus_control_requests request) 41 { 42 struct roccat_common2_control control; 43 44 if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || 45 request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && 46 value > 4) 47 return -EINVAL; 48 49 control.command = ROCCAT_COMMON_COMMAND_CONTROL; 50 control.value = value; 51 control.request = request; 52 53 return roccat_common2_send_with_status(usb_dev, 54 ROCCAT_COMMON_COMMAND_CONTROL, 55 &control, sizeof(struct roccat_common2_control)); 56 } 57 58 static int koneplus_get_info(struct usb_device *usb_dev, 59 struct koneplus_info *buf) 60 { 61 return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO, 62 buf, sizeof(struct koneplus_info)); 63 } 64 65 static int koneplus_get_profile_settings(struct usb_device *usb_dev, 66 struct koneplus_profile_settings *buf, uint number) 67 { 68 int retval; 69 70 retval = koneplus_send_control(usb_dev, number, 71 KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); 72 if (retval) 73 return retval; 74 75 return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, 76 buf, sizeof(struct koneplus_profile_settings)); 77 } 78 79 static int koneplus_set_profile_settings(struct usb_device *usb_dev, 80 struct koneplus_profile_settings const *settings) 81 { 82 return roccat_common2_send_with_status(usb_dev, 83 KONEPLUS_COMMAND_PROFILE_SETTINGS, 84 settings, sizeof(struct koneplus_profile_settings)); 85 } 86 87 static int koneplus_get_profile_buttons(struct usb_device *usb_dev, 88 struct koneplus_profile_buttons *buf, int number) 89 { 90 int retval; 91 92 retval = koneplus_send_control(usb_dev, number, 93 KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); 94 if (retval) 95 return retval; 96 97 return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, 98 buf, sizeof(struct koneplus_profile_buttons)); 99 } 100 101 static int koneplus_set_profile_buttons(struct usb_device *usb_dev, 102 struct koneplus_profile_buttons const *buttons) 103 { 104 return roccat_common2_send_with_status(usb_dev, 105 KONEPLUS_COMMAND_PROFILE_BUTTONS, 106 buttons, sizeof(struct koneplus_profile_buttons)); 107 } 108 109 /* retval is 0-4 on success, < 0 on error */ 110 static int koneplus_get_actual_profile(struct usb_device *usb_dev) 111 { 112 struct koneplus_actual_profile buf; 113 int retval; 114 115 retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, 116 &buf, sizeof(struct koneplus_actual_profile)); 117 118 return retval ? retval : buf.actual_profile; 119 } 120 121 static int koneplus_set_actual_profile(struct usb_device *usb_dev, 122 int new_profile) 123 { 124 struct koneplus_actual_profile buf; 125 126 buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE; 127 buf.size = sizeof(struct koneplus_actual_profile); 128 buf.actual_profile = new_profile; 129 130 return roccat_common2_send_with_status(usb_dev, 131 KONEPLUS_COMMAND_ACTUAL_PROFILE, 132 &buf, sizeof(struct koneplus_actual_profile)); 133 } 134 135 static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, 136 char *buf, loff_t off, size_t count, 137 size_t real_size, uint command) 138 { 139 struct device *dev = 140 container_of(kobj, struct device, kobj)->parent->parent; 141 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); 142 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 143 int retval; 144 145 if (off >= real_size) 146 return 0; 147 148 if (off != 0 || count != real_size) 149 return -EINVAL; 150 151 mutex_lock(&koneplus->koneplus_lock); 152 retval = roccat_common2_receive(usb_dev, command, buf, real_size); 153 mutex_unlock(&koneplus->koneplus_lock); 154 155 if (retval) 156 return retval; 157 158 return real_size; 159 } 160 161 static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, 162 void const *buf, loff_t off, size_t count, 163 size_t real_size, uint command) 164 { 165 struct device *dev = 166 container_of(kobj, struct device, kobj)->parent->parent; 167 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); 168 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 169 int retval; 170 171 if (off != 0 || count != real_size) 172 return -EINVAL; 173 174 mutex_lock(&koneplus->koneplus_lock); 175 retval = roccat_common2_send_with_status(usb_dev, command, 176 buf, real_size); 177 mutex_unlock(&koneplus->koneplus_lock); 178 179 if (retval) 180 return retval; 181 182 return real_size; 183 } 184 185 static ssize_t koneplus_sysfs_write_talk(struct file *fp, 186 struct kobject *kobj, struct bin_attribute *attr, char *buf, 187 loff_t off, size_t count) 188 { 189 return koneplus_sysfs_write(fp, kobj, buf, off, count, 190 sizeof(struct koneplus_talk), KONEPLUS_COMMAND_TALK); 191 } 192 193 static ssize_t koneplus_sysfs_write_macro(struct file *fp, 194 struct kobject *kobj, struct bin_attribute *attr, char *buf, 195 loff_t off, size_t count) 196 { 197 return koneplus_sysfs_write(fp, kobj, buf, off, count, 198 sizeof(struct koneplus_macro), KONEPLUS_COMMAND_MACRO); 199 } 200 201 static ssize_t koneplus_sysfs_read_sensor(struct file *fp, 202 struct kobject *kobj, struct bin_attribute *attr, char *buf, 203 loff_t off, size_t count) 204 { 205 return koneplus_sysfs_read(fp, kobj, buf, off, count, 206 sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR); 207 } 208 209 static ssize_t koneplus_sysfs_write_sensor(struct file *fp, 210 struct kobject *kobj, struct bin_attribute *attr, char *buf, 211 loff_t off, size_t count) 212 { 213 return koneplus_sysfs_write(fp, kobj, buf, off, count, 214 sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR); 215 } 216 217 static ssize_t koneplus_sysfs_write_tcu(struct file *fp, 218 struct kobject *kobj, struct bin_attribute *attr, char *buf, 219 loff_t off, size_t count) 220 { 221 return koneplus_sysfs_write(fp, kobj, buf, off, count, 222 sizeof(struct koneplus_tcu), KONEPLUS_COMMAND_TCU); 223 } 224 225 static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp, 226 struct kobject *kobj, struct bin_attribute *attr, char *buf, 227 loff_t off, size_t count) 228 { 229 return koneplus_sysfs_read(fp, kobj, buf, off, count, 230 sizeof(struct koneplus_tcu_image), KONEPLUS_COMMAND_TCU); 231 } 232 233 static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, 234 struct kobject *kobj, struct bin_attribute *attr, char *buf, 235 loff_t off, size_t count) 236 { 237 struct device *dev = 238 container_of(kobj, struct device, kobj)->parent->parent; 239 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); 240 241 if (off >= sizeof(struct koneplus_profile_settings)) 242 return 0; 243 244 if (off + count > sizeof(struct koneplus_profile_settings)) 245 count = sizeof(struct koneplus_profile_settings) - off; 246 247 mutex_lock(&koneplus->koneplus_lock); 248 memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off, 249 count); 250 mutex_unlock(&koneplus->koneplus_lock); 251 252 return count; 253 } 254 255 static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp, 256 struct kobject *kobj, struct bin_attribute *attr, char *buf, 257 loff_t off, size_t count) 258 { 259 struct device *dev = 260 container_of(kobj, struct device, kobj)->parent->parent; 261 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); 262 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 263 int retval = 0; 264 int difference; 265 int profile_number; 266 struct koneplus_profile_settings *profile_settings; 267 268 if (off != 0 || count != sizeof(struct koneplus_profile_settings)) 269 return -EINVAL; 270 271 profile_number = ((struct koneplus_profile_settings const *)buf)->number; 272 profile_settings = &koneplus->profile_settings[profile_number]; 273 274 mutex_lock(&koneplus->koneplus_lock); 275 difference = memcmp(buf, profile_settings, 276 sizeof(struct koneplus_profile_settings)); 277 if (difference) { 278 retval = koneplus_set_profile_settings(usb_dev, 279 (struct koneplus_profile_settings const *)buf); 280 if (!retval) 281 memcpy(profile_settings, buf, 282 sizeof(struct koneplus_profile_settings)); 283 } 284 mutex_unlock(&koneplus->koneplus_lock); 285 286 if (retval) 287 return retval; 288 289 return sizeof(struct koneplus_profile_settings); 290 } 291 292 static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, 293 struct kobject *kobj, struct bin_attribute *attr, char *buf, 294 loff_t off, size_t count) 295 { 296 struct device *dev = 297 container_of(kobj, struct device, kobj)->parent->parent; 298 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); 299 300 if (off >= sizeof(struct koneplus_profile_buttons)) 301 return 0; 302 303 if (off + count > sizeof(struct koneplus_profile_buttons)) 304 count = sizeof(struct koneplus_profile_buttons) - off; 305 306 mutex_lock(&koneplus->koneplus_lock); 307 memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off, 308 count); 309 mutex_unlock(&koneplus->koneplus_lock); 310 311 return count; 312 } 313 314 static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp, 315 struct kobject *kobj, struct bin_attribute *attr, char *buf, 316 loff_t off, size_t count) 317 { 318 struct device *dev = 319 container_of(kobj, struct device, kobj)->parent->parent; 320 struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); 321 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 322 int retval = 0; 323 int difference; 324 uint profile_number; 325 struct koneplus_profile_buttons *profile_buttons; 326 327 if (off != 0 || count != sizeof(struct koneplus_profile_buttons)) 328 return -EINVAL; 329 330 profile_number = ((struct koneplus_profile_buttons const *)buf)->number; 331 profile_buttons = &koneplus->profile_buttons[profile_number]; 332 333 mutex_lock(&koneplus->koneplus_lock); 334 difference = memcmp(buf, profile_buttons, 335 sizeof(struct koneplus_profile_buttons)); 336 if (difference) { 337 retval = koneplus_set_profile_buttons(usb_dev, 338 (struct koneplus_profile_buttons const *)buf); 339 if (!retval) 340 memcpy(profile_buttons, buf, 341 sizeof(struct koneplus_profile_buttons)); 342 } 343 mutex_unlock(&koneplus->koneplus_lock); 344 345 if (retval) 346 return retval; 347 348 return sizeof(struct koneplus_profile_buttons); 349 } 350 351 static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, 352 struct device_attribute *attr, char *buf) 353 { 354 struct koneplus_device *koneplus = 355 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 356 return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile); 357 } 358 359 static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev, 360 struct device_attribute *attr, char const *buf, size_t size) 361 { 362 struct koneplus_device *koneplus; 363 struct usb_device *usb_dev; 364 unsigned long profile; 365 int retval; 366 struct koneplus_roccat_report roccat_report; 367 368 dev = dev->parent->parent; 369 koneplus = hid_get_drvdata(dev_get_drvdata(dev)); 370 usb_dev = interface_to_usbdev(to_usb_interface(dev)); 371 372 retval = strict_strtoul(buf, 10, &profile); 373 if (retval) 374 return retval; 375 376 if (profile > 4) 377 return -EINVAL; 378 379 mutex_lock(&koneplus->koneplus_lock); 380 381 retval = koneplus_set_actual_profile(usb_dev, profile); 382 if (retval) { 383 mutex_unlock(&koneplus->koneplus_lock); 384 return retval; 385 } 386 387 koneplus_profile_activated(koneplus, profile); 388 389 roccat_report.type = KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE; 390 roccat_report.data1 = profile + 1; 391 roccat_report.data2 = 0; 392 roccat_report.profile = profile + 1; 393 roccat_report_event(koneplus->chrdev_minor, 394 (uint8_t const *)&roccat_report); 395 396 mutex_unlock(&koneplus->koneplus_lock); 397 398 return size; 399 } 400 401 static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, 402 struct device_attribute *attr, char *buf) 403 { 404 struct koneplus_device *koneplus = 405 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 406 return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version); 407 } 408 409 static struct device_attribute koneplus_attributes[] = { 410 __ATTR(actual_profile, 0660, 411 koneplus_sysfs_show_actual_profile, 412 koneplus_sysfs_set_actual_profile), 413 __ATTR(startup_profile, 0660, 414 koneplus_sysfs_show_actual_profile, 415 koneplus_sysfs_set_actual_profile), 416 __ATTR(firmware_version, 0440, 417 koneplus_sysfs_show_firmware_version, NULL), 418 __ATTR_NULL 419 }; 420 421 static struct bin_attribute koneplus_bin_attributes[] = { 422 { 423 .attr = { .name = "sensor", .mode = 0660 }, 424 .size = sizeof(struct koneplus_sensor), 425 .read = koneplus_sysfs_read_sensor, 426 .write = koneplus_sysfs_write_sensor 427 }, 428 { 429 .attr = { .name = "tcu", .mode = 0220 }, 430 .size = sizeof(struct koneplus_tcu), 431 .write = koneplus_sysfs_write_tcu 432 }, 433 { 434 .attr = { .name = "tcu_image", .mode = 0440 }, 435 .size = sizeof(struct koneplus_tcu_image), 436 .read = koneplus_sysfs_read_tcu_image 437 }, 438 { 439 .attr = { .name = "profile_settings", .mode = 0220 }, 440 .size = sizeof(struct koneplus_profile_settings), 441 .write = koneplus_sysfs_write_profile_settings 442 }, 443 { 444 .attr = { .name = "profile1_settings", .mode = 0440 }, 445 .size = sizeof(struct koneplus_profile_settings), 446 .read = koneplus_sysfs_read_profilex_settings, 447 .private = &profile_numbers[0] 448 }, 449 { 450 .attr = { .name = "profile2_settings", .mode = 0440 }, 451 .size = sizeof(struct koneplus_profile_settings), 452 .read = koneplus_sysfs_read_profilex_settings, 453 .private = &profile_numbers[1] 454 }, 455 { 456 .attr = { .name = "profile3_settings", .mode = 0440 }, 457 .size = sizeof(struct koneplus_profile_settings), 458 .read = koneplus_sysfs_read_profilex_settings, 459 .private = &profile_numbers[2] 460 }, 461 { 462 .attr = { .name = "profile4_settings", .mode = 0440 }, 463 .size = sizeof(struct koneplus_profile_settings), 464 .read = koneplus_sysfs_read_profilex_settings, 465 .private = &profile_numbers[3] 466 }, 467 { 468 .attr = { .name = "profile5_settings", .mode = 0440 }, 469 .size = sizeof(struct koneplus_profile_settings), 470 .read = koneplus_sysfs_read_profilex_settings, 471 .private = &profile_numbers[4] 472 }, 473 { 474 .attr = { .name = "profile_buttons", .mode = 0220 }, 475 .size = sizeof(struct koneplus_profile_buttons), 476 .write = koneplus_sysfs_write_profile_buttons 477 }, 478 { 479 .attr = { .name = "profile1_buttons", .mode = 0440 }, 480 .size = sizeof(struct koneplus_profile_buttons), 481 .read = koneplus_sysfs_read_profilex_buttons, 482 .private = &profile_numbers[0] 483 }, 484 { 485 .attr = { .name = "profile2_buttons", .mode = 0440 }, 486 .size = sizeof(struct koneplus_profile_buttons), 487 .read = koneplus_sysfs_read_profilex_buttons, 488 .private = &profile_numbers[1] 489 }, 490 { 491 .attr = { .name = "profile3_buttons", .mode = 0440 }, 492 .size = sizeof(struct koneplus_profile_buttons), 493 .read = koneplus_sysfs_read_profilex_buttons, 494 .private = &profile_numbers[2] 495 }, 496 { 497 .attr = { .name = "profile4_buttons", .mode = 0440 }, 498 .size = sizeof(struct koneplus_profile_buttons), 499 .read = koneplus_sysfs_read_profilex_buttons, 500 .private = &profile_numbers[3] 501 }, 502 { 503 .attr = { .name = "profile5_buttons", .mode = 0440 }, 504 .size = sizeof(struct koneplus_profile_buttons), 505 .read = koneplus_sysfs_read_profilex_buttons, 506 .private = &profile_numbers[4] 507 }, 508 { 509 .attr = { .name = "macro", .mode = 0220 }, 510 .size = sizeof(struct koneplus_macro), 511 .write = koneplus_sysfs_write_macro 512 }, 513 { 514 .attr = { .name = "talk", .mode = 0220 }, 515 .size = sizeof(struct koneplus_talk), 516 .write = koneplus_sysfs_write_talk 517 }, 518 __ATTR_NULL 519 }; 520 521 static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, 522 struct koneplus_device *koneplus) 523 { 524 int retval, i; 525 static uint wait = 200; 526 527 mutex_init(&koneplus->koneplus_lock); 528 529 retval = koneplus_get_info(usb_dev, &koneplus->info); 530 if (retval) 531 return retval; 532 533 for (i = 0; i < 5; ++i) { 534 msleep(wait); 535 retval = koneplus_get_profile_settings(usb_dev, 536 &koneplus->profile_settings[i], i); 537 if (retval) 538 return retval; 539 540 msleep(wait); 541 retval = koneplus_get_profile_buttons(usb_dev, 542 &koneplus->profile_buttons[i], i); 543 if (retval) 544 return retval; 545 } 546 547 msleep(wait); 548 retval = koneplus_get_actual_profile(usb_dev); 549 if (retval < 0) 550 return retval; 551 koneplus_profile_activated(koneplus, retval); 552 553 return 0; 554 } 555 556 static int koneplus_init_specials(struct hid_device *hdev) 557 { 558 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 559 struct usb_device *usb_dev = interface_to_usbdev(intf); 560 struct koneplus_device *koneplus; 561 int retval; 562 563 if (intf->cur_altsetting->desc.bInterfaceProtocol 564 == USB_INTERFACE_PROTOCOL_MOUSE) { 565 566 koneplus = kzalloc(sizeof(*koneplus), GFP_KERNEL); 567 if (!koneplus) { 568 hid_err(hdev, "can't alloc device descriptor\n"); 569 return -ENOMEM; 570 } 571 hid_set_drvdata(hdev, koneplus); 572 573 retval = koneplus_init_koneplus_device_struct(usb_dev, koneplus); 574 if (retval) { 575 hid_err(hdev, "couldn't init struct koneplus_device\n"); 576 goto exit_free; 577 } 578 579 retval = roccat_connect(koneplus_class, hdev, 580 sizeof(struct koneplus_roccat_report)); 581 if (retval < 0) { 582 hid_err(hdev, "couldn't init char dev\n"); 583 } else { 584 koneplus->chrdev_minor = retval; 585 koneplus->roccat_claimed = 1; 586 } 587 } else { 588 hid_set_drvdata(hdev, NULL); 589 } 590 591 return 0; 592 exit_free: 593 kfree(koneplus); 594 return retval; 595 } 596 597 static void koneplus_remove_specials(struct hid_device *hdev) 598 { 599 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 600 struct koneplus_device *koneplus; 601 602 if (intf->cur_altsetting->desc.bInterfaceProtocol 603 == USB_INTERFACE_PROTOCOL_MOUSE) { 604 koneplus = hid_get_drvdata(hdev); 605 if (koneplus->roccat_claimed) 606 roccat_disconnect(koneplus->chrdev_minor); 607 kfree(koneplus); 608 } 609 } 610 611 static int koneplus_probe(struct hid_device *hdev, 612 const struct hid_device_id *id) 613 { 614 int retval; 615 616 retval = hid_parse(hdev); 617 if (retval) { 618 hid_err(hdev, "parse failed\n"); 619 goto exit; 620 } 621 622 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 623 if (retval) { 624 hid_err(hdev, "hw start failed\n"); 625 goto exit; 626 } 627 628 retval = koneplus_init_specials(hdev); 629 if (retval) { 630 hid_err(hdev, "couldn't install mouse\n"); 631 goto exit_stop; 632 } 633 634 return 0; 635 636 exit_stop: 637 hid_hw_stop(hdev); 638 exit: 639 return retval; 640 } 641 642 static void koneplus_remove(struct hid_device *hdev) 643 { 644 koneplus_remove_specials(hdev); 645 hid_hw_stop(hdev); 646 } 647 648 static void koneplus_keep_values_up_to_date(struct koneplus_device *koneplus, 649 u8 const *data) 650 { 651 struct koneplus_mouse_report_button const *button_report; 652 653 switch (data[0]) { 654 case KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON: 655 button_report = (struct koneplus_mouse_report_button const *)data; 656 switch (button_report->type) { 657 case KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE: 658 koneplus_profile_activated(koneplus, button_report->data1 - 1); 659 break; 660 } 661 break; 662 } 663 } 664 665 static void koneplus_report_to_chrdev(struct koneplus_device const *koneplus, 666 u8 const *data) 667 { 668 struct koneplus_roccat_report roccat_report; 669 struct koneplus_mouse_report_button const *button_report; 670 671 if (data[0] != KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON) 672 return; 673 674 button_report = (struct koneplus_mouse_report_button const *)data; 675 676 if ((button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH || 677 button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER) && 678 button_report->data2 != KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS) 679 return; 680 681 roccat_report.type = button_report->type; 682 roccat_report.data1 = button_report->data1; 683 roccat_report.data2 = button_report->data2; 684 roccat_report.profile = koneplus->actual_profile + 1; 685 roccat_report_event(koneplus->chrdev_minor, 686 (uint8_t const *)&roccat_report); 687 } 688 689 static int koneplus_raw_event(struct hid_device *hdev, 690 struct hid_report *report, u8 *data, int size) 691 { 692 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 693 struct koneplus_device *koneplus = hid_get_drvdata(hdev); 694 695 if (intf->cur_altsetting->desc.bInterfaceProtocol 696 != USB_INTERFACE_PROTOCOL_MOUSE) 697 return 0; 698 699 if (koneplus == NULL) 700 return 0; 701 702 koneplus_keep_values_up_to_date(koneplus, data); 703 704 if (koneplus->roccat_claimed) 705 koneplus_report_to_chrdev(koneplus, data); 706 707 return 0; 708 } 709 710 static const struct hid_device_id koneplus_devices[] = { 711 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, 712 { } 713 }; 714 715 MODULE_DEVICE_TABLE(hid, koneplus_devices); 716 717 static struct hid_driver koneplus_driver = { 718 .name = "koneplus", 719 .id_table = koneplus_devices, 720 .probe = koneplus_probe, 721 .remove = koneplus_remove, 722 .raw_event = koneplus_raw_event 723 }; 724 725 static int __init koneplus_init(void) 726 { 727 int retval; 728 729 /* class name has to be same as driver name */ 730 koneplus_class = class_create(THIS_MODULE, "koneplus"); 731 if (IS_ERR(koneplus_class)) 732 return PTR_ERR(koneplus_class); 733 koneplus_class->dev_attrs = koneplus_attributes; 734 koneplus_class->dev_bin_attrs = koneplus_bin_attributes; 735 736 retval = hid_register_driver(&koneplus_driver); 737 if (retval) 738 class_destroy(koneplus_class); 739 return retval; 740 } 741 742 static void __exit koneplus_exit(void) 743 { 744 hid_unregister_driver(&koneplus_driver); 745 class_destroy(koneplus_class); 746 } 747 748 module_init(koneplus_init); 749 module_exit(koneplus_exit); 750 751 MODULE_AUTHOR("Stefan Achatz"); 752 MODULE_DESCRIPTION("USB Roccat Kone[+] driver"); 753 MODULE_LICENSE("GPL v2"); 754