diff options
Diffstat (limited to 'sound/usb/caiaq')
-rw-r--r-- | sound/usb/caiaq/device.c | 8 | ||||
-rw-r--r-- | sound/usb/caiaq/device.h | 1 | ||||
-rw-r--r-- | sound/usb/caiaq/input.c | 155 |
3 files changed, 161 insertions, 3 deletions
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 45bc4a2dc6f0..3eb605bd9503 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
@@ -50,7 +50,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | |||
50 | "{Native Instruments, Session I/O}," | 50 | "{Native Instruments, Session I/O}," |
51 | "{Native Instruments, GuitarRig mobile}" | 51 | "{Native Instruments, GuitarRig mobile}" |
52 | "{Native Instruments, Traktor Kontrol X1}" | 52 | "{Native Instruments, Traktor Kontrol X1}" |
53 | "{Native Instruments, Traktor Kontrol S4}"); | 53 | "{Native Instruments, Traktor Kontrol S4}" |
54 | "{Native Instruments, Maschine Controller}"); | ||
54 | 55 | ||
55 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 56 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
56 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 57 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ |
@@ -146,6 +147,11 @@ static struct usb_device_id snd_usb_id_table[] = { | |||
146 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 147 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
147 | .idProduct = USB_PID_TRAKTORAUDIO2 | 148 | .idProduct = USB_PID_TRAKTORAUDIO2 |
148 | }, | 149 | }, |
150 | { | ||
151 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
152 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | ||
153 | .idProduct = USB_PID_MASCHINECONTROLLER | ||
154 | }, | ||
149 | { /* terminator */ } | 155 | { /* terminator */ } |
150 | }; | 156 | }; |
151 | 157 | ||
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index 3f9c6339ae90..562b0bff9c41 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define USB_PID_TRAKTORKONTROLX1 0x2305 | 18 | #define USB_PID_TRAKTORKONTROLX1 0x2305 |
19 | #define USB_PID_TRAKTORKONTROLS4 0xbaff | 19 | #define USB_PID_TRAKTORKONTROLS4 0xbaff |
20 | #define USB_PID_TRAKTORAUDIO2 0x041d | 20 | #define USB_PID_TRAKTORAUDIO2 0x041d |
21 | #define USB_PID_MASCHINECONTROLLER 0x0808 | ||
21 | 22 | ||
22 | #define EP1_BUFSIZE 64 | 23 | #define EP1_BUFSIZE 64 |
23 | #define EP4_BUFSIZE 512 | 24 | #define EP4_BUFSIZE 512 |
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index a213813487bd..26a121b42c3c 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c | |||
@@ -67,6 +67,61 @@ static unsigned short keycode_kore[] = { | |||
67 | KEY_BRL_DOT5 | 67 | KEY_BRL_DOT5 |
68 | }; | 68 | }; |
69 | 69 | ||
70 | #define MASCHINE_BUTTONS (42) | ||
71 | #define MASCHINE_BUTTON(X) ((X) + BTN_MISC) | ||
72 | #define MASCHINE_PADS (16) | ||
73 | #define MASCHINE_PAD(X) ((X) + ABS_PRESSURE) | ||
74 | |||
75 | static unsigned short keycode_maschine[] = { | ||
76 | MASCHINE_BUTTON(40), /* mute */ | ||
77 | MASCHINE_BUTTON(39), /* solo */ | ||
78 | MASCHINE_BUTTON(38), /* select */ | ||
79 | MASCHINE_BUTTON(37), /* duplicate */ | ||
80 | MASCHINE_BUTTON(36), /* navigate */ | ||
81 | MASCHINE_BUTTON(35), /* pad mode */ | ||
82 | MASCHINE_BUTTON(34), /* pattern */ | ||
83 | MASCHINE_BUTTON(33), /* scene */ | ||
84 | KEY_RESERVED, /* spacer */ | ||
85 | |||
86 | MASCHINE_BUTTON(30), /* rec */ | ||
87 | MASCHINE_BUTTON(31), /* erase */ | ||
88 | MASCHINE_BUTTON(32), /* shift */ | ||
89 | MASCHINE_BUTTON(28), /* grid */ | ||
90 | MASCHINE_BUTTON(27), /* > */ | ||
91 | MASCHINE_BUTTON(26), /* < */ | ||
92 | MASCHINE_BUTTON(25), /* restart */ | ||
93 | |||
94 | MASCHINE_BUTTON(21), /* E */ | ||
95 | MASCHINE_BUTTON(22), /* F */ | ||
96 | MASCHINE_BUTTON(23), /* G */ | ||
97 | MASCHINE_BUTTON(24), /* H */ | ||
98 | MASCHINE_BUTTON(20), /* D */ | ||
99 | MASCHINE_BUTTON(19), /* C */ | ||
100 | MASCHINE_BUTTON(18), /* B */ | ||
101 | MASCHINE_BUTTON(17), /* A */ | ||
102 | |||
103 | MASCHINE_BUTTON(0), /* control */ | ||
104 | MASCHINE_BUTTON(2), /* browse */ | ||
105 | MASCHINE_BUTTON(4), /* < */ | ||
106 | MASCHINE_BUTTON(6), /* snap */ | ||
107 | MASCHINE_BUTTON(7), /* autowrite */ | ||
108 | MASCHINE_BUTTON(5), /* > */ | ||
109 | MASCHINE_BUTTON(3), /* sampling */ | ||
110 | MASCHINE_BUTTON(1), /* step */ | ||
111 | |||
112 | MASCHINE_BUTTON(15), /* 8 softkeys */ | ||
113 | MASCHINE_BUTTON(14), | ||
114 | MASCHINE_BUTTON(13), | ||
115 | MASCHINE_BUTTON(12), | ||
116 | MASCHINE_BUTTON(11), | ||
117 | MASCHINE_BUTTON(10), | ||
118 | MASCHINE_BUTTON(9), | ||
119 | MASCHINE_BUTTON(8), | ||
120 | |||
121 | MASCHINE_BUTTON(16), /* note repeat */ | ||
122 | MASCHINE_BUTTON(29) /* play */ | ||
123 | }; | ||
124 | |||
70 | #define KONTROLX1_INPUTS (40) | 125 | #define KONTROLX1_INPUTS (40) |
71 | #define KONTROLS4_BUTTONS (12 * 8) | 126 | #define KONTROLS4_BUTTONS (12 * 8) |
72 | #define KONTROLS4_AXIS (46) | 127 | #define KONTROLS4_AXIS (46) |
@@ -218,6 +273,29 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, | |||
218 | input_report_abs(input_dev, ABS_HAT3Y, i); | 273 | input_report_abs(input_dev, ABS_HAT3Y, i); |
219 | input_sync(input_dev); | 274 | input_sync(input_dev); |
220 | break; | 275 | break; |
276 | |||
277 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
278 | /* 4 under the left screen */ | ||
279 | input_report_abs(input_dev, ABS_HAT0X, decode_erp(buf[21], buf[20])); | ||
280 | input_report_abs(input_dev, ABS_HAT0Y, decode_erp(buf[15], buf[14])); | ||
281 | input_report_abs(input_dev, ABS_HAT1X, decode_erp(buf[9], buf[8])); | ||
282 | input_report_abs(input_dev, ABS_HAT1Y, decode_erp(buf[3], buf[2])); | ||
283 | |||
284 | /* 4 under the right screen */ | ||
285 | input_report_abs(input_dev, ABS_HAT2X, decode_erp(buf[19], buf[18])); | ||
286 | input_report_abs(input_dev, ABS_HAT2Y, decode_erp(buf[13], buf[12])); | ||
287 | input_report_abs(input_dev, ABS_HAT3X, decode_erp(buf[7], buf[6])); | ||
288 | input_report_abs(input_dev, ABS_HAT3Y, decode_erp(buf[1], buf[0])); | ||
289 | |||
290 | /* volume */ | ||
291 | input_report_abs(input_dev, ABS_RX, decode_erp(buf[17], buf[16])); | ||
292 | /* tempo */ | ||
293 | input_report_abs(input_dev, ABS_RY, decode_erp(buf[11], buf[10])); | ||
294 | /* swing */ | ||
295 | input_report_abs(input_dev, ABS_RZ, decode_erp(buf[5], buf[4])); | ||
296 | |||
297 | input_sync(input_dev); | ||
298 | break; | ||
221 | } | 299 | } |
222 | } | 300 | } |
223 | 301 | ||
@@ -400,6 +478,25 @@ static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev, | |||
400 | input_sync(dev->input_dev); | 478 | input_sync(dev->input_dev); |
401 | } | 479 | } |
402 | 480 | ||
481 | #define MASCHINE_MSGBLOCK_SIZE 2 | ||
482 | |||
483 | static void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *dev, | ||
484 | const unsigned char *buf, | ||
485 | unsigned int len) | ||
486 | { | ||
487 | unsigned int i, pad_id; | ||
488 | uint16_t pressure; | ||
489 | |||
490 | for (i = 0; i < MASCHINE_PADS; i++) { | ||
491 | pressure = be16_to_cpu(buf[i * 2] << 8 | buf[(i * 2) + 1]); | ||
492 | pad_id = pressure >> 12; | ||
493 | |||
494 | input_report_abs(dev->input_dev, MASCHINE_PAD(pad_id), pressure & 0xfff); | ||
495 | } | ||
496 | |||
497 | input_sync(dev->input_dev); | ||
498 | } | ||
499 | |||
403 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | 500 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) |
404 | { | 501 | { |
405 | struct snd_usb_caiaqdev *dev = urb->context; | 502 | struct snd_usb_caiaqdev *dev = urb->context; |
@@ -425,6 +522,13 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | |||
425 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 522 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
426 | snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length); | 523 | snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length); |
427 | break; | 524 | break; |
525 | |||
526 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
527 | if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE)) | ||
528 | goto requeue; | ||
529 | |||
530 | snd_usb_caiaq_maschine_dispatch(dev, buf, urb->actual_length); | ||
531 | break; | ||
428 | } | 532 | } |
429 | 533 | ||
430 | requeue: | 534 | requeue: |
@@ -444,6 +548,7 @@ static int snd_usb_caiaq_input_open(struct input_dev *idev) | |||
444 | switch (dev->chip.usb_id) { | 548 | switch (dev->chip.usb_id) { |
445 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 549 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
446 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 550 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
551 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
447 | if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) | 552 | if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) |
448 | return -EIO; | 553 | return -EIO; |
449 | break; | 554 | break; |
@@ -462,6 +567,7 @@ static void snd_usb_caiaq_input_close(struct input_dev *idev) | |||
462 | switch (dev->chip.usb_id) { | 567 | switch (dev->chip.usb_id) { |
463 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 568 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
464 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 569 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
570 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
465 | usb_kill_urb(dev->ep4_in_urb); | 571 | usb_kill_urb(dev->ep4_in_urb); |
466 | break; | 572 | break; |
467 | } | 573 | } |
@@ -652,6 +758,50 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
652 | 758 | ||
653 | break; | 759 | break; |
654 | 760 | ||
761 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
762 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
763 | input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) | | ||
764 | BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) | | ||
765 | BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) | | ||
766 | BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) | | ||
767 | BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) | | ||
768 | BIT_MASK(ABS_RZ); | ||
769 | |||
770 | BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_maschine)); | ||
771 | memcpy(dev->keycode, keycode_maschine, sizeof(keycode_maschine)); | ||
772 | input->keycodemax = ARRAY_SIZE(keycode_maschine); | ||
773 | |||
774 | for (i = 0; i < MASCHINE_PADS; i++) { | ||
775 | input->absbit[0] |= MASCHINE_PAD(i); | ||
776 | input_set_abs_params(input, MASCHINE_PAD(i), 0, 0xfff, 5, 10); | ||
777 | } | ||
778 | |||
779 | input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10); | ||
780 | input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10); | ||
781 | input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10); | ||
782 | input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10); | ||
783 | input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10); | ||
784 | input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10); | ||
785 | input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10); | ||
786 | input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10); | ||
787 | input_set_abs_params(input, ABS_RX, 0, 999, 0, 10); | ||
788 | input_set_abs_params(input, ABS_RY, 0, 999, 0, 10); | ||
789 | input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10); | ||
790 | |||
791 | dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
792 | if (!dev->ep4_in_urb) { | ||
793 | ret = -ENOMEM; | ||
794 | goto exit_free_idev; | ||
795 | } | ||
796 | |||
797 | usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev, | ||
798 | usb_rcvbulkpipe(usb_dev, 0x4), | ||
799 | dev->ep4_in_buf, EP4_BUFSIZE, | ||
800 | snd_usb_caiaq_ep4_reply_dispatch, dev); | ||
801 | |||
802 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | ||
803 | break; | ||
804 | |||
655 | default: | 805 | default: |
656 | /* no input methods supported on this device */ | 806 | /* no input methods supported on this device */ |
657 | goto exit_free_idev; | 807 | goto exit_free_idev; |
@@ -664,15 +814,17 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
664 | for (i = 0; i < input->keycodemax; i++) | 814 | for (i = 0; i < input->keycodemax; i++) |
665 | __set_bit(dev->keycode[i], input->keybit); | 815 | __set_bit(dev->keycode[i], input->keybit); |
666 | 816 | ||
817 | dev->input_dev = input; | ||
818 | |||
667 | ret = input_register_device(input); | 819 | ret = input_register_device(input); |
668 | if (ret < 0) | 820 | if (ret < 0) |
669 | goto exit_free_idev; | 821 | goto exit_free_idev; |
670 | 822 | ||
671 | dev->input_dev = input; | ||
672 | return 0; | 823 | return 0; |
673 | 824 | ||
674 | exit_free_idev: | 825 | exit_free_idev: |
675 | input_free_device(input); | 826 | input_free_device(input); |
827 | dev->input_dev = NULL; | ||
676 | return ret; | 828 | return ret; |
677 | } | 829 | } |
678 | 830 | ||
@@ -688,4 +840,3 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) | |||
688 | input_unregister_device(dev->input_dev); | 840 | input_unregister_device(dev->input_dev); |
689 | dev->input_dev = NULL; | 841 | dev->input_dev = NULL; |
690 | } | 842 | } |
691 | |||