1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * HID driver for the Prodikeys PC-MIDI Keyboard 4 * providing midi & extra multimedia keys functionality 5 * 6 * Copyright (c) 2009 Don Prince <dhprince.devel@yahoo.co.uk> 7 * 8 * Controls for Octave Shift Up/Down, Channel, and 9 * Sustain Duration available via sysfs. 10 */ 11 12 /* 13 */ 14 15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 16 17 #include <linux/device.h> 18 #include <linux/module.h> 19 #include <linux/usb.h> 20 #include <linux/mutex.h> 21 #include <linux/hid.h> 22 #include <sound/core.h> 23 #include <sound/initval.h> 24 #include <sound/rawmidi.h> 25 #include "hid-ids.h" 26 27 28 #define pk_debug(format, arg...) \ 29 pr_debug("hid-prodikeys: " format "\n" , ## arg) 30 #define pk_error(format, arg...) \ 31 pr_err("hid-prodikeys: " format "\n" , ## arg) 32 33 struct pcmidi_snd; 34 35 struct pcmidi_sustain { 36 unsigned long in_use; 37 struct pcmidi_snd *pm; 38 struct timer_list timer; 39 unsigned char status; 40 unsigned char note; 41 unsigned char velocity; 42 }; 43 44 #define PCMIDI_SUSTAINED_MAX 32 45 struct pcmidi_snd { 46 struct hid_device *hdev; 47 unsigned short ifnum; 48 struct hid_report *pcmidi_report6; 49 struct input_dev *input_ep82; 50 unsigned short midi_mode; 51 unsigned short midi_sustain_mode; 52 unsigned short midi_sustain; 53 unsigned short midi_channel; 54 short midi_octave; 55 struct pcmidi_sustain sustained_notes[PCMIDI_SUSTAINED_MAX]; 56 unsigned short fn_state; 57 unsigned short last_key[24]; 58 spinlock_t rawmidi_in_lock; 59 struct snd_card *card; 60 struct snd_rawmidi *rwmidi; 61 struct snd_rawmidi_substream *in_substream; 62 unsigned long in_triggered; 63 }; 64 65 #define PK_QUIRK_NOGET 0x00010000 66 #define PCMIDI_MIDDLE_C 60 67 #define PCMIDI_CHANNEL_MIN 0 68 #define PCMIDI_CHANNEL_MAX 15 69 #define PCMIDI_OCTAVE_MIN (-2) 70 #define PCMIDI_OCTAVE_MAX 2 71 #define PCMIDI_SUSTAIN_MIN 0 72 #define PCMIDI_SUSTAIN_MAX 5000 73 74 static const char shortname[] = "PC-MIDI"; 75 static const char longname[] = "Prodikeys PC-MIDI Keyboard"; 76 77 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 78 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 79 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 80 81 module_param_array(index, int, NULL, 0444); 82 module_param_array(id, charp, NULL, 0444); 83 module_param_array(enable, bool, NULL, 0444); 84 MODULE_PARM_DESC(index, "Index value for the PC-MIDI virtual audio driver"); 85 MODULE_PARM_DESC(id, "ID string for the PC-MIDI virtual audio driver"); 86 MODULE_PARM_DESC(enable, "Enable for the PC-MIDI virtual audio driver"); 87 88 89 /* Output routine for the sysfs channel file */ 90 static ssize_t show_channel(struct device *dev, 91 struct device_attribute *attr, char *buf) 92 { 93 struct hid_device *hdev = to_hid_device(dev); 94 struct pcmidi_snd *pm = hid_get_drvdata(hdev); 95 96 dbg_hid("pcmidi sysfs read channel=%u\n", pm->midi_channel); 97 98 return sprintf(buf, "%u (min:%u, max:%u)\n", pm->midi_channel, 99 PCMIDI_CHANNEL_MIN, PCMIDI_CHANNEL_MAX); 100 } 101 102 /* Input routine for the sysfs channel file */ 103 static ssize_t store_channel(struct device *dev, 104 struct device_attribute *attr, const char *buf, size_t count) 105 { 106 struct hid_device *hdev = to_hid_device(dev); 107 struct pcmidi_snd *pm = hid_get_drvdata(hdev); 108 109 unsigned channel = 0; 110 111 if (sscanf(buf, "%u", &channel) > 0 && channel <= PCMIDI_CHANNEL_MAX) { 112 dbg_hid("pcmidi sysfs write channel=%u\n", channel); 113 pm->midi_channel = channel; 114 return strlen(buf); 115 } 116 return -EINVAL; 117 } 118 119 static DEVICE_ATTR(channel, S_IRUGO | S_IWUSR | S_IWGRP , show_channel, 120 store_channel); 121 122 static struct device_attribute *sysfs_device_attr_channel = { 123 &dev_attr_channel, 124 }; 125 126 /* Output routine for the sysfs sustain file */ 127 static ssize_t show_sustain(struct device *dev, 128 struct device_attribute *attr, char *buf) 129 { 130 struct hid_device *hdev = to_hid_device(dev); 131 struct pcmidi_snd *pm = hid_get_drvdata(hdev); 132 133 dbg_hid("pcmidi sysfs read sustain=%u\n", pm->midi_sustain); 134 135 return sprintf(buf, "%u (off:%u, max:%u (ms))\n", pm->midi_sustain, 136 PCMIDI_SUSTAIN_MIN, PCMIDI_SUSTAIN_MAX); 137 } 138 139 /* Input routine for the sysfs sustain file */ 140 static ssize_t store_sustain(struct device *dev, 141 struct device_attribute *attr, const char *buf, size_t count) 142 { 143 struct hid_device *hdev = to_hid_device(dev); 144 struct pcmidi_snd *pm = hid_get_drvdata(hdev); 145 146 unsigned sustain = 0; 147 148 if (sscanf(buf, "%u", &sustain) > 0 && sustain <= PCMIDI_SUSTAIN_MAX) { 149 dbg_hid("pcmidi sysfs write sustain=%u\n", sustain); 150 pm->midi_sustain = sustain; 151 pm->midi_sustain_mode = (0 == sustain || !pm->midi_mode) ? 0 : 1; 152 return strlen(buf); 153 } 154 return -EINVAL; 155 } 156 157 static DEVICE_ATTR(sustain, S_IRUGO | S_IWUSR | S_IWGRP, show_sustain, 158 store_sustain); 159 160 static struct device_attribute *sysfs_device_attr_sustain = { 161 &dev_attr_sustain, 162 }; 163 164 /* Output routine for the sysfs octave file */ 165 static ssize_t show_octave(struct device *dev, 166 struct device_attribute *attr, char *buf) 167 { 168 struct hid_device *hdev = to_hid_device(dev); 169 struct pcmidi_snd *pm = hid_get_drvdata(hdev); 170 171 dbg_hid("pcmidi sysfs read octave=%d\n", pm->midi_octave); 172 173 return sprintf(buf, "%d (min:%d, max:%d)\n", pm->midi_octave, 174 PCMIDI_OCTAVE_MIN, PCMIDI_OCTAVE_MAX); 175 } 176 177 /* Input routine for the sysfs octave file */ 178 static ssize_t store_octave(struct device *dev, 179 struct device_attribute *attr, const char *buf, size_t count) 180 { 181 struct hid_device *hdev = to_hid_device(dev); 182 struct pcmidi_snd *pm = hid_get_drvdata(hdev); 183 184 int octave = 0; 185 186 if (sscanf(buf, "%d", &octave) > 0 && 187 octave >= PCMIDI_OCTAVE_MIN && octave <= PCMIDI_OCTAVE_MAX) { 188 dbg_hid("pcmidi sysfs write octave=%d\n", octave); 189 pm->midi_octave = octave; 190 return strlen(buf); 191 } 192 return -EINVAL; 193 } 194 195 static DEVICE_ATTR(octave, S_IRUGO | S_IWUSR | S_IWGRP, show_octave, 196 store_octave); 197 198 static struct device_attribute *sysfs_device_attr_octave = { 199 &dev_attr_octave, 200 }; 201 202 203 static void pcmidi_send_note(struct pcmidi_snd *pm, 204 unsigned char status, unsigned char note, unsigned char velocity) 205 { 206 unsigned long flags; 207 unsigned char buffer[3]; 208 209 buffer[0] = status; 210 buffer[1] = note; 211 buffer[2] = velocity; 212 213 spin_lock_irqsave(&pm->rawmidi_in_lock, flags); 214 215 if (!pm->in_substream) 216 goto drop_note; 217 if (!test_bit(pm->in_substream->number, &pm->in_triggered)) 218 goto drop_note; 219 220 snd_rawmidi_receive(pm->in_substream, buffer, 3); 221 222 drop_note: 223 spin_unlock_irqrestore(&pm->rawmidi_in_lock, flags); 224 225 return; 226 } 227 228 static void pcmidi_sustained_note_release(struct timer_list *t) 229 { 230 struct pcmidi_sustain *pms = from_timer(pms, t, timer); 231 232 pcmidi_send_note(pms->pm, pms->status, pms->note, pms->velocity); 233 pms->in_use = 0; 234 } 235 236 static void init_sustain_timers(struct pcmidi_snd *pm) 237 { 238 struct pcmidi_sustain *pms; 239 unsigned i; 240 241 for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) { 242 pms = &pm->sustained_notes[i]; 243 pms->in_use = 0; 244 pms->pm = pm; 245 timer_setup(&pms->timer, pcmidi_sustained_note_release, 0); 246 } 247 } 248 249 static void stop_sustain_timers(struct pcmidi_snd *pm) 250 { 251 struct pcmidi_sustain *pms; 252 unsigned i; 253 254 for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) { 255 pms = &pm->sustained_notes[i]; 256 pms->in_use = 1; 257 del_timer_sync(&pms->timer); 258 } 259 } 260 261 static int pcmidi_get_output_report(struct pcmidi_snd *pm) 262 { 263 struct hid_device *hdev = pm->hdev; 264 struct hid_report *report; 265 266 list_for_each_entry(report, 267 &hdev->report_enum[HID_OUTPUT_REPORT].report_list, list) { 268 if (!(6 == report->id)) 269 continue; 270 271 if (report->maxfield < 1) { 272 hid_err(hdev, "output report is empty\n"); 273 break; 274 } 275 if (report->field[0]->report_count != 2) { 276 hid_err(hdev, "field count too low\n"); 277 break; 278 } 279 pm->pcmidi_report6 = report; 280 return 0; 281 } 282 /* should never get here */ 283 return -ENODEV; 284 } 285 286 static void pcmidi_submit_output_report(struct pcmidi_snd *pm, int state) 287 { 288 struct hid_device *hdev = pm->hdev; 289 struct hid_report *report = pm->pcmidi_report6; 290 report->field[0]->value[0] = 0x01; 291 report->field[0]->value[1] = state; 292 293 hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 294 } 295 296 static int pcmidi_handle_report1(struct pcmidi_snd *pm, u8 *data) 297 { 298 u32 bit_mask; 299 300 bit_mask = data[1]; 301 bit_mask = (bit_mask << 8) | data[2]; 302 bit_mask = (bit_mask << 8) | data[3]; 303 304 dbg_hid("pcmidi mode: %d\n", pm->midi_mode); 305 306 /*KEY_MAIL or octave down*/ 307 if (pm->midi_mode && bit_mask == 0x004000) { 308 /* octave down */ 309 pm->midi_octave--; 310 if (pm->midi_octave < -2) 311 pm->midi_octave = -2; 312 dbg_hid("pcmidi mode: %d octave: %d\n", 313 pm->midi_mode, pm->midi_octave); 314 return 1; 315 } 316 /*KEY_WWW or sustain*/ 317 else if (pm->midi_mode && bit_mask == 0x000004) { 318 /* sustain on/off*/ 319 pm->midi_sustain_mode ^= 0x1; 320 return 1; 321 } 322 323 return 0; /* continue key processing */ 324 } 325 326 static int pcmidi_handle_report3(struct pcmidi_snd *pm, u8 *data, int size) 327 { 328 struct pcmidi_sustain *pms; 329 unsigned i, j; 330 unsigned char status, note, velocity; 331 332 unsigned num_notes = (size-1)/2; 333 for (j = 0; j < num_notes; j++) { 334 note = data[j*2+1]; 335 velocity = data[j*2+2]; 336 337 if (note < 0x81) { /* note on */ 338 status = 128 + 16 + pm->midi_channel; /* 1001nnnn */ 339 note = note - 0x54 + PCMIDI_MIDDLE_C + 340 (pm->midi_octave * 12); 341 if (0 == velocity) 342 velocity = 1; /* force note on */ 343 } else { /* note off */ 344 status = 128 + pm->midi_channel; /* 1000nnnn */ 345 note = note - 0x94 + PCMIDI_MIDDLE_C + 346 (pm->midi_octave*12); 347 348 if (pm->midi_sustain_mode) { 349 for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) { 350 pms = &pm->sustained_notes[i]; 351 if (!pms->in_use) { 352 pms->status = status; 353 pms->note = note; 354 pms->velocity = velocity; 355 pms->in_use = 1; 356 357 mod_timer(&pms->timer, 358 jiffies + 359 msecs_to_jiffies(pm->midi_sustain)); 360 return 1; 361 } 362 } 363 } 364 } 365 pcmidi_send_note(pm, status, note, velocity); 366 } 367 368 return 1; 369 } 370 371 static int pcmidi_handle_report4(struct pcmidi_snd *pm, u8 *data) 372 { 373 unsigned key; 374 u32 bit_mask; 375 u32 bit_index; 376 377 bit_mask = data[1]; 378 bit_mask = (bit_mask << 8) | data[2]; 379 bit_mask = (bit_mask << 8) | data[3]; 380 381 /* break keys */ 382 for (bit_index = 0; bit_index < 24; bit_index++) { 383 if (!((0x01 << bit_index) & bit_mask)) { 384 input_event(pm->input_ep82, EV_KEY, 385 pm->last_key[bit_index], 0); 386 pm->last_key[bit_index] = 0; 387 } 388 } 389 390 /* make keys */ 391 for (bit_index = 0; bit_index < 24; bit_index++) { 392 key = 0; 393 switch ((0x01 << bit_index) & bit_mask) { 394 case 0x000010: /* Fn lock*/ 395 pm->fn_state ^= 0x000010; 396 if (pm->fn_state) 397 pcmidi_submit_output_report(pm, 0xc5); 398 else 399 pcmidi_submit_output_report(pm, 0xc6); 400 continue; 401 case 0x020000: /* midi launcher..send a key (qwerty) or not? */ 402 pcmidi_submit_output_report(pm, 0xc1); 403 pm->midi_mode ^= 0x01; 404 405 dbg_hid("pcmidi mode: %d\n", pm->midi_mode); 406 continue; 407 case 0x100000: /* KEY_MESSENGER or octave up */ 408 dbg_hid("pcmidi mode: %d\n", pm->midi_mode); 409 if (pm->midi_mode) { 410 pm->midi_octave++; 411 if (pm->midi_octave > 2) 412 pm->midi_octave = 2; 413 dbg_hid("pcmidi mode: %d octave: %d\n", 414 pm->midi_mode, pm->midi_octave); 415 continue; 416 } else 417 key = KEY_MESSENGER; 418 break; 419 case 0x400000: 420 key = KEY_CALENDAR; 421 break; 422 case 0x080000: 423 key = KEY_ADDRESSBOOK; 424 break; 425 case 0x040000: 426 key = KEY_DOCUMENTS; 427 break; 428 case 0x800000: 429 key = KEY_WORDPROCESSOR; 430 break; 431 case 0x200000: 432 key = KEY_SPREADSHEET; 433 break; 434 case 0x010000: 435 key = KEY_COFFEE; 436 break; 437 case 0x000100: 438 key = KEY_HELP; 439 break; 440 case 0x000200: 441 key = KEY_SEND; 442 break; 443 case 0x000400: 444 key = KEY_REPLY; 445 break; 446 case 0x000800: 447 key = KEY_FORWARDMAIL; 448 break; 449 case 0x001000: 450 key = KEY_NEW; 451 break; 452 case 0x002000: 453 key = KEY_OPEN; 454 break; 455 case 0x004000: 456 key = KEY_CLOSE; 457 break; 458 case 0x008000: 459 key = KEY_SAVE; 460 break; 461 case 0x000001: 462 key = KEY_UNDO; 463 break; 464 case 0x000002: 465 key = KEY_REDO; 466 break; 467 case 0x000004: 468 key = KEY_SPELLCHECK; 469 break; 470 case 0x000008: 471 key = KEY_PRINT; 472 break; 473 } 474 if (key) { 475 input_event(pm->input_ep82, EV_KEY, key, 1); 476 pm->last_key[bit_index] = key; 477 } 478 } 479 480 return 1; 481 } 482 483 static int pcmidi_handle_report( 484 struct pcmidi_snd *pm, unsigned report_id, u8 *data, int size) 485 { 486 int ret = 0; 487 488 switch (report_id) { 489 case 0x01: /* midi keys (qwerty)*/ 490 ret = pcmidi_handle_report1(pm, data); 491 break; 492 case 0x03: /* midi keyboard (musical)*/ 493 ret = pcmidi_handle_report3(pm, data, size); 494 break; 495 case 0x04: /* multimedia/midi keys (qwerty)*/ 496 ret = pcmidi_handle_report4(pm, data); 497 break; 498 } 499 return ret; 500 } 501 502 static void pcmidi_setup_extra_keys( 503 struct pcmidi_snd *pm, struct input_dev *input) 504 { 505 /* reassigned functionality for N/A keys 506 MY PICTURES => KEY_WORDPROCESSOR 507 MY MUSIC=> KEY_SPREADSHEET 508 */ 509 static const unsigned int keys[] = { 510 KEY_FN, 511 KEY_MESSENGER, KEY_CALENDAR, 512 KEY_ADDRESSBOOK, KEY_DOCUMENTS, 513 KEY_WORDPROCESSOR, 514 KEY_SPREADSHEET, 515 KEY_COFFEE, 516 KEY_HELP, KEY_SEND, 517 KEY_REPLY, KEY_FORWARDMAIL, 518 KEY_NEW, KEY_OPEN, 519 KEY_CLOSE, KEY_SAVE, 520 KEY_UNDO, KEY_REDO, 521 KEY_SPELLCHECK, KEY_PRINT, 522 0 523 }; 524 525 const unsigned int *pkeys = &keys[0]; 526 unsigned short i; 527 528 if (pm->ifnum != 1) /* only set up ONCE for interace 1 */ 529 return; 530 531 pm->input_ep82 = input; 532 533 for (i = 0; i < 24; i++) 534 pm->last_key[i] = 0; 535 536 while (*pkeys != 0) { 537 set_bit(*pkeys, pm->input_ep82->keybit); 538 ++pkeys; 539 } 540 } 541 542 static int pcmidi_set_operational(struct pcmidi_snd *pm) 543 { 544 int rc; 545 546 if (pm->ifnum != 1) 547 return 0; /* only set up ONCE for interace 1 */ 548 549 rc = pcmidi_get_output_report(pm); 550 if (rc < 0) 551 return rc; 552 pcmidi_submit_output_report(pm, 0xc1); 553 return 0; 554 } 555 556 static int pcmidi_snd_free(struct snd_device *dev) 557 { 558 return 0; 559 } 560 561 static int pcmidi_in_open(struct snd_rawmidi_substream *substream) 562 { 563 struct pcmidi_snd *pm = substream->rmidi->private_data; 564 565 dbg_hid("pcmidi in open\n"); 566 pm->in_substream = substream; 567 return 0; 568 } 569 570 static int pcmidi_in_close(struct snd_rawmidi_substream *substream) 571 { 572 dbg_hid("pcmidi in close\n"); 573 return 0; 574 } 575 576 static void pcmidi_in_trigger(struct snd_rawmidi_substream *substream, int up) 577 { 578 struct pcmidi_snd *pm = substream->rmidi->private_data; 579 580 dbg_hid("pcmidi in trigger %d\n", up); 581 582 pm->in_triggered = up; 583 } 584 585 static const struct snd_rawmidi_ops pcmidi_in_ops = { 586 .open = pcmidi_in_open, 587 .close = pcmidi_in_close, 588 .trigger = pcmidi_in_trigger 589 }; 590 591 static int pcmidi_snd_initialise(struct pcmidi_snd *pm) 592 { 593 static int dev; 594 struct snd_card *card; 595 struct snd_rawmidi *rwmidi; 596 int err; 597 598 static struct snd_device_ops ops = { 599 .dev_free = pcmidi_snd_free, 600 }; 601 602 if (pm->ifnum != 1) 603 return 0; /* only set up midi device ONCE for interace 1 */ 604 605 if (dev >= SNDRV_CARDS) 606 return -ENODEV; 607 608 if (!enable[dev]) { 609 dev++; 610 return -ENOENT; 611 } 612 613 /* Setup sound card */ 614 615 err = snd_card_new(&pm->hdev->dev, index[dev], id[dev], 616 THIS_MODULE, 0, &card); 617 if (err < 0) { 618 pk_error("failed to create pc-midi sound card\n"); 619 err = -ENOMEM; 620 goto fail; 621 } 622 pm->card = card; 623 624 /* Setup sound device */ 625 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pm, &ops); 626 if (err < 0) { 627 pk_error("failed to create pc-midi sound device: error %d\n", 628 err); 629 goto fail; 630 } 631 632 strscpy(card->driver, shortname, sizeof(card->driver)); 633 strscpy(card->shortname, shortname, sizeof(card->shortname)); 634 strscpy(card->longname, longname, sizeof(card->longname)); 635 636 /* Set up rawmidi */ 637 err = snd_rawmidi_new(card, card->shortname, 0, 638 0, 1, &rwmidi); 639 if (err < 0) { 640 pk_error("failed to create pc-midi rawmidi device: error %d\n", 641 err); 642 goto fail; 643 } 644 pm->rwmidi = rwmidi; 645 strscpy(rwmidi->name, card->shortname, sizeof(rwmidi->name)); 646 rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT; 647 rwmidi->private_data = pm; 648 649 snd_rawmidi_set_ops(rwmidi, SNDRV_RAWMIDI_STREAM_INPUT, 650 &pcmidi_in_ops); 651 652 /* create sysfs variables */ 653 err = device_create_file(&pm->hdev->dev, 654 sysfs_device_attr_channel); 655 if (err < 0) { 656 pk_error("failed to create sysfs attribute channel: error %d\n", 657 err); 658 goto fail; 659 } 660 661 err = device_create_file(&pm->hdev->dev, 662 sysfs_device_attr_sustain); 663 if (err < 0) { 664 pk_error("failed to create sysfs attribute sustain: error %d\n", 665 err); 666 goto fail_attr_sustain; 667 } 668 669 err = device_create_file(&pm->hdev->dev, 670 sysfs_device_attr_octave); 671 if (err < 0) { 672 pk_error("failed to create sysfs attribute octave: error %d\n", 673 err); 674 goto fail_attr_octave; 675 } 676 677 spin_lock_init(&pm->rawmidi_in_lock); 678 679 init_sustain_timers(pm); 680 err = pcmidi_set_operational(pm); 681 if (err < 0) { 682 pk_error("failed to find output report\n"); 683 goto fail_register; 684 } 685 686 /* register it */ 687 err = snd_card_register(card); 688 if (err < 0) { 689 pk_error("failed to register pc-midi sound card: error %d\n", 690 err); 691 goto fail_register; 692 } 693 694 dbg_hid("pcmidi_snd_initialise finished ok\n"); 695 return 0; 696 697 fail_register: 698 stop_sustain_timers(pm); 699 device_remove_file(&pm->hdev->dev, sysfs_device_attr_octave); 700 fail_attr_octave: 701 device_remove_file(&pm->hdev->dev, sysfs_device_attr_sustain); 702 fail_attr_sustain: 703 device_remove_file(&pm->hdev->dev, sysfs_device_attr_channel); 704 fail: 705 if (pm->card) { 706 snd_card_free(pm->card); 707 pm->card = NULL; 708 } 709 return err; 710 } 711 712 static int pcmidi_snd_terminate(struct pcmidi_snd *pm) 713 { 714 if (pm->card) { 715 stop_sustain_timers(pm); 716 717 device_remove_file(&pm->hdev->dev, sysfs_device_attr_channel); 718 device_remove_file(&pm->hdev->dev, sysfs_device_attr_sustain); 719 device_remove_file(&pm->hdev->dev, sysfs_device_attr_octave); 720 721 snd_card_disconnect(pm->card); 722 snd_card_free_when_closed(pm->card); 723 } 724 725 return 0; 726 } 727 728 /* 729 * PC-MIDI report descriptor for report id is wrong. 730 */ 731 static const __u8 *pk_report_fixup(struct hid_device *hdev, __u8 *rdesc, 732 unsigned int *rsize) 733 { 734 if (*rsize == 178 && 735 rdesc[111] == 0x06 && rdesc[112] == 0x00 && 736 rdesc[113] == 0xff) { 737 hid_info(hdev, 738 "fixing up pc-midi keyboard report descriptor\n"); 739 740 rdesc[144] = 0x18; /* report 4: was 0x10 report count */ 741 } 742 return rdesc; 743 } 744 745 static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi, 746 struct hid_field *field, struct hid_usage *usage, 747 unsigned long **bit, int *max) 748 { 749 struct pcmidi_snd *pm = hid_get_drvdata(hdev); 750 751 if (HID_UP_MSVENDOR == (usage->hid & HID_USAGE_PAGE) && 752 1 == pm->ifnum) { 753 pcmidi_setup_extra_keys(pm, hi->input); 754 return 0; 755 } 756 757 return 0; 758 } 759 760 761 static int pk_raw_event(struct hid_device *hdev, struct hid_report *report, 762 u8 *data, int size) 763 { 764 struct pcmidi_snd *pm = hid_get_drvdata(hdev); 765 int ret = 0; 766 767 if (1 == pm->ifnum) { 768 if (report->id == data[0]) 769 switch (report->id) { 770 case 0x01: /* midi keys (qwerty)*/ 771 case 0x03: /* midi keyboard (musical)*/ 772 case 0x04: /* extra/midi keys (qwerty)*/ 773 ret = pcmidi_handle_report(pm, 774 report->id, data, size); 775 break; 776 } 777 } 778 779 return ret; 780 } 781 782 static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) 783 { 784 int ret; 785 struct usb_interface *intf; 786 unsigned short ifnum; 787 unsigned long quirks = id->driver_data; 788 struct pcmidi_snd *pm; 789 790 if (!hid_is_usb(hdev)) 791 return -EINVAL; 792 793 intf = to_usb_interface(hdev->dev.parent); 794 ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 795 796 pm = kzalloc(sizeof(*pm), GFP_KERNEL); 797 if (pm == NULL) { 798 hid_err(hdev, "can't alloc descriptor\n"); 799 return -ENOMEM; 800 } 801 802 pm->hdev = hdev; 803 pm->ifnum = ifnum; 804 805 hid_set_drvdata(hdev, pm); 806 807 ret = hid_parse(hdev); 808 if (ret) { 809 hid_err(hdev, "hid parse failed\n"); 810 goto err_free; 811 } 812 813 if (quirks & PK_QUIRK_NOGET) { /* hid_parse cleared all the quirks */ 814 hdev->quirks |= HID_QUIRK_NOGET; 815 } 816 817 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 818 if (ret) { 819 hid_err(hdev, "hw start failed\n"); 820 goto err_free; 821 } 822 823 ret = pcmidi_snd_initialise(pm); 824 if (ret < 0) 825 goto err_stop; 826 827 return 0; 828 err_stop: 829 hid_hw_stop(hdev); 830 err_free: 831 kfree(pm); 832 833 return ret; 834 } 835 836 static void pk_remove(struct hid_device *hdev) 837 { 838 struct pcmidi_snd *pm = hid_get_drvdata(hdev); 839 840 pcmidi_snd_terminate(pm); 841 hid_hw_stop(hdev); 842 843 kfree(pm); 844 } 845 846 static const struct hid_device_id pk_devices[] = { 847 {HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, 848 USB_DEVICE_ID_PRODIKEYS_PCMIDI), 849 .driver_data = PK_QUIRK_NOGET}, 850 { } 851 }; 852 MODULE_DEVICE_TABLE(hid, pk_devices); 853 854 static struct hid_driver pk_driver = { 855 .name = "prodikeys", 856 .id_table = pk_devices, 857 .report_fixup = pk_report_fixup, 858 .input_mapping = pk_input_mapping, 859 .raw_event = pk_raw_event, 860 .probe = pk_probe, 861 .remove = pk_remove, 862 }; 863 module_hid_driver(pk_driver); 864 865 MODULE_DESCRIPTION("HID driver for the Prodikeys PC-MIDI Keyboard"); 866 MODULE_LICENSE("GPL"); 867