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