diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/Kconfig | 2 | ||||
-rw-r--r-- | sound/usb/caiaq/audio.c | 175 | ||||
-rw-r--r-- | sound/usb/caiaq/control.c | 208 | ||||
-rw-r--r-- | sound/usb/caiaq/device.c | 8 | ||||
-rw-r--r-- | sound/usb/caiaq/device.h | 6 | ||||
-rw-r--r-- | sound/usb/caiaq/input.c | 248 |
6 files changed, 598 insertions, 49 deletions
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index 44d6d2ec964f..112984f4080f 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -65,6 +65,7 @@ config SND_USB_CAIAQ | |||
65 | * Native Instruments Guitar Rig Session I/O | 65 | * Native Instruments Guitar Rig Session I/O |
66 | * Native Instruments Guitar Rig mobile | 66 | * Native Instruments Guitar Rig mobile |
67 | * Native Instruments Traktor Kontrol X1 | 67 | * Native Instruments Traktor Kontrol X1 |
68 | * Native Instruments Traktor Kontrol S4 | ||
68 | 69 | ||
69 | To compile this driver as a module, choose M here: the module | 70 | To compile this driver as a module, choose M here: the module |
70 | will be called snd-usb-caiaq. | 71 | will be called snd-usb-caiaq. |
@@ -82,6 +83,7 @@ config SND_USB_CAIAQ_INPUT | |||
82 | * Native Instruments Kore Controller | 83 | * Native Instruments Kore Controller |
83 | * Native Instruments Kore Controller 2 | 84 | * Native Instruments Kore Controller 2 |
84 | * Native Instruments Audio Kontrol 1 | 85 | * Native Instruments Audio Kontrol 1 |
86 | * Native Instruments Traktor Kontrol S4 | ||
85 | 87 | ||
86 | config SND_USB_US122L | 88 | config SND_USB_US122L |
87 | tristate "Tascam US-122L USB driver" | 89 | tristate "Tascam US-122L USB driver" |
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 4328cad6c3a2..68b97477577b 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c | |||
@@ -111,7 +111,7 @@ static int stream_start(struct snd_usb_caiaqdev *dev) | |||
111 | memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); | 111 | memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); |
112 | dev->input_panic = 0; | 112 | dev->input_panic = 0; |
113 | dev->output_panic = 0; | 113 | dev->output_panic = 0; |
114 | dev->first_packet = 1; | 114 | dev->first_packet = 4; |
115 | dev->streaming = 1; | 115 | dev->streaming = 1; |
116 | dev->warned = 0; | 116 | dev->warned = 0; |
117 | 117 | ||
@@ -169,7 +169,7 @@ static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) | |||
169 | } | 169 | } |
170 | 170 | ||
171 | static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, | 171 | static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, |
172 | struct snd_pcm_hw_params *hw_params) | 172 | struct snd_pcm_hw_params *hw_params) |
173 | { | 173 | { |
174 | debug("%s(%p)\n", __func__, sub); | 174 | debug("%s(%p)\n", __func__, sub); |
175 | return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); | 175 | return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); |
@@ -189,7 +189,7 @@ static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub) | |||
189 | #endif | 189 | #endif |
190 | 190 | ||
191 | static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, | 191 | static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, |
192 | 48000, 64000, 88200, 96000, 176400, 192000 }; | 192 | 48000, 64000, 88200, 96000, 176400, 192000 }; |
193 | 193 | ||
194 | static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | 194 | static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) |
195 | { | 195 | { |
@@ -201,12 +201,39 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | |||
201 | debug("%s(%p)\n", __func__, substream); | 201 | debug("%s(%p)\n", __func__, substream); |
202 | 202 | ||
203 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 203 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
204 | dev->period_out_count[index] = BYTES_PER_SAMPLE + 1; | 204 | int out_pos; |
205 | dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1; | 205 | |
206 | switch (dev->spec.data_alignment) { | ||
207 | case 0: | ||
208 | case 2: | ||
209 | out_pos = BYTES_PER_SAMPLE + 1; | ||
210 | break; | ||
211 | case 3: | ||
212 | default: | ||
213 | out_pos = 0; | ||
214 | break; | ||
215 | } | ||
216 | |||
217 | dev->period_out_count[index] = out_pos; | ||
218 | dev->audio_out_buf_pos[index] = out_pos; | ||
206 | } else { | 219 | } else { |
207 | int in_pos = (dev->spec.data_alignment == 2) ? 0 : 2; | 220 | int in_pos; |
208 | dev->period_in_count[index] = BYTES_PER_SAMPLE + in_pos; | 221 | |
209 | dev->audio_in_buf_pos[index] = BYTES_PER_SAMPLE + in_pos; | 222 | switch (dev->spec.data_alignment) { |
223 | case 0: | ||
224 | in_pos = BYTES_PER_SAMPLE + 2; | ||
225 | break; | ||
226 | case 2: | ||
227 | in_pos = BYTES_PER_SAMPLE; | ||
228 | break; | ||
229 | case 3: | ||
230 | default: | ||
231 | in_pos = 0; | ||
232 | break; | ||
233 | } | ||
234 | |||
235 | dev->period_in_count[index] = in_pos; | ||
236 | dev->audio_in_buf_pos[index] = in_pos; | ||
210 | } | 237 | } |
211 | 238 | ||
212 | if (dev->streaming) | 239 | if (dev->streaming) |
@@ -221,7 +248,7 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | |||
221 | snd_pcm_limit_hw_rates(runtime); | 248 | snd_pcm_limit_hw_rates(runtime); |
222 | 249 | ||
223 | bytes_per_sample = BYTES_PER_SAMPLE; | 250 | bytes_per_sample = BYTES_PER_SAMPLE; |
224 | if (dev->spec.data_alignment == 2) | 251 | if (dev->spec.data_alignment >= 2) |
225 | bytes_per_sample++; | 252 | bytes_per_sample++; |
226 | 253 | ||
227 | bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) | 254 | bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) |
@@ -253,6 +280,8 @@ static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd) | |||
253 | { | 280 | { |
254 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); | 281 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); |
255 | 282 | ||
283 | debug("%s(%p) cmd %d\n", __func__, sub, cmd); | ||
284 | |||
256 | switch (cmd) { | 285 | switch (cmd) { |
257 | case SNDRV_PCM_TRIGGER_START: | 286 | case SNDRV_PCM_TRIGGER_START: |
258 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 287 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
@@ -402,6 +431,61 @@ static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, | |||
402 | } | 431 | } |
403 | } | 432 | } |
404 | 433 | ||
434 | static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev, | ||
435 | const struct urb *urb, | ||
436 | const struct usb_iso_packet_descriptor *iso) | ||
437 | { | ||
438 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; | ||
439 | int stream, i; | ||
440 | |||
441 | /* paranoia check */ | ||
442 | if (iso->actual_length % (BYTES_PER_SAMPLE_USB * CHANNELS_PER_STREAM)) | ||
443 | return; | ||
444 | |||
445 | for (i = 0; i < iso->actual_length;) { | ||
446 | for (stream = 0; stream < dev->n_streams; stream++) { | ||
447 | struct snd_pcm_substream *sub = dev->sub_capture[stream]; | ||
448 | char *audio_buf = NULL; | ||
449 | int c, n, sz = 0; | ||
450 | |||
451 | if (sub && !dev->input_panic) { | ||
452 | struct snd_pcm_runtime *rt = sub->runtime; | ||
453 | audio_buf = rt->dma_area; | ||
454 | sz = frames_to_bytes(rt, rt->buffer_size); | ||
455 | } | ||
456 | |||
457 | for (c = 0; c < CHANNELS_PER_STREAM; c++) { | ||
458 | /* 3 audio data bytes, followed by 1 check byte */ | ||
459 | if (audio_buf) { | ||
460 | for (n = 0; n < BYTES_PER_SAMPLE; n++) { | ||
461 | audio_buf[dev->audio_in_buf_pos[stream]++] = usb_buf[i+n]; | ||
462 | |||
463 | if (dev->audio_in_buf_pos[stream] == sz) | ||
464 | dev->audio_in_buf_pos[stream] = 0; | ||
465 | } | ||
466 | |||
467 | dev->period_in_count[stream] += BYTES_PER_SAMPLE; | ||
468 | } | ||
469 | |||
470 | i += BYTES_PER_SAMPLE; | ||
471 | |||
472 | if (usb_buf[i] != ((stream << 1) | c) && | ||
473 | !dev->first_packet) { | ||
474 | if (!dev->input_panic) | ||
475 | printk(" EXPECTED: %02x got %02x, c %d, stream %d, i %d\n", | ||
476 | ((stream << 1) | c), usb_buf[i], c, stream, i); | ||
477 | dev->input_panic = 1; | ||
478 | } | ||
479 | |||
480 | i++; | ||
481 | } | ||
482 | } | ||
483 | } | ||
484 | |||
485 | if (dev->first_packet > 0) | ||
486 | dev->first_packet--; | ||
487 | } | ||
488 | |||
405 | static void read_in_urb(struct snd_usb_caiaqdev *dev, | 489 | static void read_in_urb(struct snd_usb_caiaqdev *dev, |
406 | const struct urb *urb, | 490 | const struct urb *urb, |
407 | const struct usb_iso_packet_descriptor *iso) | 491 | const struct usb_iso_packet_descriptor *iso) |
@@ -419,6 +503,9 @@ static void read_in_urb(struct snd_usb_caiaqdev *dev, | |||
419 | case 2: | 503 | case 2: |
420 | read_in_urb_mode2(dev, urb, iso); | 504 | read_in_urb_mode2(dev, urb, iso); |
421 | break; | 505 | break; |
506 | case 3: | ||
507 | read_in_urb_mode3(dev, urb, iso); | ||
508 | break; | ||
422 | } | 509 | } |
423 | 510 | ||
424 | if ((dev->input_panic || dev->output_panic) && !dev->warned) { | 511 | if ((dev->input_panic || dev->output_panic) && !dev->warned) { |
@@ -429,9 +516,9 @@ static void read_in_urb(struct snd_usb_caiaqdev *dev, | |||
429 | } | 516 | } |
430 | } | 517 | } |
431 | 518 | ||
432 | static void fill_out_urb(struct snd_usb_caiaqdev *dev, | 519 | static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev, |
433 | struct urb *urb, | 520 | struct urb *urb, |
434 | const struct usb_iso_packet_descriptor *iso) | 521 | const struct usb_iso_packet_descriptor *iso) |
435 | { | 522 | { |
436 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; | 523 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; |
437 | struct snd_pcm_substream *sub; | 524 | struct snd_pcm_substream *sub; |
@@ -457,9 +544,67 @@ static void fill_out_urb(struct snd_usb_caiaqdev *dev, | |||
457 | /* fill in the check bytes */ | 544 | /* fill in the check bytes */ |
458 | if (dev->spec.data_alignment == 2 && | 545 | if (dev->spec.data_alignment == 2 && |
459 | i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == | 546 | i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == |
460 | (dev->n_streams * CHANNELS_PER_STREAM)) | 547 | (dev->n_streams * CHANNELS_PER_STREAM)) |
461 | for (stream = 0; stream < dev->n_streams; stream++, i++) | 548 | for (stream = 0; stream < dev->n_streams; stream++, i++) |
462 | usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); | 549 | usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); |
550 | } | ||
551 | } | ||
552 | |||
553 | static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev, | ||
554 | struct urb *urb, | ||
555 | const struct usb_iso_packet_descriptor *iso) | ||
556 | { | ||
557 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; | ||
558 | int stream, i; | ||
559 | |||
560 | for (i = 0; i < iso->length;) { | ||
561 | for (stream = 0; stream < dev->n_streams; stream++) { | ||
562 | struct snd_pcm_substream *sub = dev->sub_playback[stream]; | ||
563 | char *audio_buf = NULL; | ||
564 | int c, n, sz = 0; | ||
565 | |||
566 | if (sub) { | ||
567 | struct snd_pcm_runtime *rt = sub->runtime; | ||
568 | audio_buf = rt->dma_area; | ||
569 | sz = frames_to_bytes(rt, rt->buffer_size); | ||
570 | } | ||
571 | |||
572 | for (c = 0; c < CHANNELS_PER_STREAM; c++) { | ||
573 | for (n = 0; n < BYTES_PER_SAMPLE; n++) { | ||
574 | if (audio_buf) { | ||
575 | usb_buf[i+n] = audio_buf[dev->audio_out_buf_pos[stream]++]; | ||
576 | |||
577 | if (dev->audio_out_buf_pos[stream] == sz) | ||
578 | dev->audio_out_buf_pos[stream] = 0; | ||
579 | } else { | ||
580 | usb_buf[i+n] = 0; | ||
581 | } | ||
582 | } | ||
583 | |||
584 | if (audio_buf) | ||
585 | dev->period_out_count[stream] += BYTES_PER_SAMPLE; | ||
586 | |||
587 | i += BYTES_PER_SAMPLE; | ||
588 | |||
589 | /* fill in the check byte pattern */ | ||
590 | usb_buf[i++] = (stream << 1) | c; | ||
591 | } | ||
592 | } | ||
593 | } | ||
594 | } | ||
595 | |||
596 | static inline void fill_out_urb(struct snd_usb_caiaqdev *dev, | ||
597 | struct urb *urb, | ||
598 | const struct usb_iso_packet_descriptor *iso) | ||
599 | { | ||
600 | switch (dev->spec.data_alignment) { | ||
601 | case 0: | ||
602 | case 2: | ||
603 | fill_out_urb_mode_0(dev, urb, iso); | ||
604 | break; | ||
605 | case 3: | ||
606 | fill_out_urb_mode_3(dev, urb, iso); | ||
607 | break; | ||
463 | } | 608 | } |
464 | } | 609 | } |
465 | 610 | ||
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c index 91c804cd2782..00e5d0a469e1 100644 --- a/sound/usb/caiaq/control.c +++ b/sound/usb/caiaq/control.c | |||
@@ -55,6 +55,10 @@ static int control_info(struct snd_kcontrol *kcontrol, | |||
55 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 55 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
56 | maxval = 127; | 56 | maxval = 127; |
57 | break; | 57 | break; |
58 | |||
59 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | ||
60 | maxval = 31; | ||
61 | break; | ||
58 | } | 62 | } |
59 | 63 | ||
60 | if (is_intval) { | 64 | if (is_intval) { |
@@ -93,6 +97,7 @@ static int control_put(struct snd_kcontrol *kcontrol, | |||
93 | struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); | 97 | struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); |
94 | struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); | 98 | struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); |
95 | int pos = kcontrol->private_value; | 99 | int pos = kcontrol->private_value; |
100 | int v = ucontrol->value.integer.value[0]; | ||
96 | unsigned char cmd = EP1_CMD_WRITE_IO; | 101 | unsigned char cmd = EP1_CMD_WRITE_IO; |
97 | 102 | ||
98 | if (dev->chip.usb_id == | 103 | if (dev->chip.usb_id == |
@@ -100,12 +105,27 @@ static int control_put(struct snd_kcontrol *kcontrol, | |||
100 | cmd = EP1_CMD_DIMM_LEDS; | 105 | cmd = EP1_CMD_DIMM_LEDS; |
101 | 106 | ||
102 | if (pos & CNT_INTVAL) { | 107 | if (pos & CNT_INTVAL) { |
103 | dev->control_state[pos & ~CNT_INTVAL] | 108 | int i = pos & ~CNT_INTVAL; |
104 | = ucontrol->value.integer.value[0]; | 109 | |
105 | snd_usb_caiaq_send_command(dev, cmd, | 110 | dev->control_state[i] = v; |
106 | dev->control_state, sizeof(dev->control_state)); | 111 | |
112 | if (dev->chip.usb_id == | ||
113 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4)) { | ||
114 | int actual_len; | ||
115 | |||
116 | dev->ep8_out_buf[0] = i; | ||
117 | dev->ep8_out_buf[1] = v; | ||
118 | |||
119 | usb_bulk_msg(dev->chip.dev, | ||
120 | usb_sndbulkpipe(dev->chip.dev, 8), | ||
121 | dev->ep8_out_buf, sizeof(dev->ep8_out_buf), | ||
122 | &actual_len, 200); | ||
123 | } else { | ||
124 | snd_usb_caiaq_send_command(dev, cmd, | ||
125 | dev->control_state, sizeof(dev->control_state)); | ||
126 | } | ||
107 | } else { | 127 | } else { |
108 | if (ucontrol->value.integer.value[0]) | 128 | if (v) |
109 | dev->control_state[pos / 8] |= 1 << (pos % 8); | 129 | dev->control_state[pos / 8] |= 1 << (pos % 8); |
110 | else | 130 | else |
111 | dev->control_state[pos / 8] &= ~(1 << (pos % 8)); | 131 | dev->control_state[pos / 8] &= ~(1 << (pos % 8)); |
@@ -296,6 +316,179 @@ static struct caiaq_controller kontrolx1_controller[] = { | |||
296 | { "LED Deck B: SYNC", 8 | CNT_INTVAL }, | 316 | { "LED Deck B: SYNC", 8 | CNT_INTVAL }, |
297 | }; | 317 | }; |
298 | 318 | ||
319 | static struct caiaq_controller kontrols4_controller[] = { | ||
320 | { "LED: Master: Quant", 10 | CNT_INTVAL }, | ||
321 | { "LED: Master: Headphone", 11 | CNT_INTVAL }, | ||
322 | { "LED: Master: Master", 12 | CNT_INTVAL }, | ||
323 | { "LED: Master: Snap", 14 | CNT_INTVAL }, | ||
324 | { "LED: Master: Warning", 15 | CNT_INTVAL }, | ||
325 | { "LED: Master: Master button", 112 | CNT_INTVAL }, | ||
326 | { "LED: Master: Snap button", 113 | CNT_INTVAL }, | ||
327 | { "LED: Master: Rec", 118 | CNT_INTVAL }, | ||
328 | { "LED: Master: Size", 119 | CNT_INTVAL }, | ||
329 | { "LED: Master: Quant button", 120 | CNT_INTVAL }, | ||
330 | { "LED: Master: Browser button", 121 | CNT_INTVAL }, | ||
331 | { "LED: Master: Play button", 126 | CNT_INTVAL }, | ||
332 | { "LED: Master: Undo button", 127 | CNT_INTVAL }, | ||
333 | |||
334 | { "LED: Channel A: >", 4 | CNT_INTVAL }, | ||
335 | { "LED: Channel A: <", 5 | CNT_INTVAL }, | ||
336 | { "LED: Channel A: Meter 1", 97 | CNT_INTVAL }, | ||
337 | { "LED: Channel A: Meter 2", 98 | CNT_INTVAL }, | ||
338 | { "LED: Channel A: Meter 3", 99 | CNT_INTVAL }, | ||
339 | { "LED: Channel A: Meter 4", 100 | CNT_INTVAL }, | ||
340 | { "LED: Channel A: Meter 5", 101 | CNT_INTVAL }, | ||
341 | { "LED: Channel A: Meter 6", 102 | CNT_INTVAL }, | ||
342 | { "LED: Channel A: Meter clip", 103 | CNT_INTVAL }, | ||
343 | { "LED: Channel A: Active", 114 | CNT_INTVAL }, | ||
344 | { "LED: Channel A: Cue", 116 | CNT_INTVAL }, | ||
345 | { "LED: Channel A: FX1", 149 | CNT_INTVAL }, | ||
346 | { "LED: Channel A: FX2", 148 | CNT_INTVAL }, | ||
347 | |||
348 | { "LED: Channel B: >", 2 | CNT_INTVAL }, | ||
349 | { "LED: Channel B: <", 3 | CNT_INTVAL }, | ||
350 | { "LED: Channel B: Meter 1", 89 | CNT_INTVAL }, | ||
351 | { "LED: Channel B: Meter 2", 90 | CNT_INTVAL }, | ||
352 | { "LED: Channel B: Meter 3", 91 | CNT_INTVAL }, | ||
353 | { "LED: Channel B: Meter 4", 92 | CNT_INTVAL }, | ||
354 | { "LED: Channel B: Meter 5", 93 | CNT_INTVAL }, | ||
355 | { "LED: Channel B: Meter 6", 94 | CNT_INTVAL }, | ||
356 | { "LED: Channel B: Meter clip", 95 | CNT_INTVAL }, | ||
357 | { "LED: Channel B: Active", 122 | CNT_INTVAL }, | ||
358 | { "LED: Channel B: Cue", 125 | CNT_INTVAL }, | ||
359 | { "LED: Channel B: FX1", 147 | CNT_INTVAL }, | ||
360 | { "LED: Channel B: FX2", 146 | CNT_INTVAL }, | ||
361 | |||
362 | { "LED: Channel C: >", 6 | CNT_INTVAL }, | ||
363 | { "LED: Channel C: <", 7 | CNT_INTVAL }, | ||
364 | { "LED: Channel C: Meter 1", 105 | CNT_INTVAL }, | ||
365 | { "LED: Channel C: Meter 2", 106 | CNT_INTVAL }, | ||
366 | { "LED: Channel C: Meter 3", 107 | CNT_INTVAL }, | ||
367 | { "LED: Channel C: Meter 4", 108 | CNT_INTVAL }, | ||
368 | { "LED: Channel C: Meter 5", 109 | CNT_INTVAL }, | ||
369 | { "LED: Channel C: Meter 6", 110 | CNT_INTVAL }, | ||
370 | { "LED: Channel C: Meter clip", 111 | CNT_INTVAL }, | ||
371 | { "LED: Channel C: Active", 115 | CNT_INTVAL }, | ||
372 | { "LED: Channel C: Cue", 117 | CNT_INTVAL }, | ||
373 | { "LED: Channel C: FX1", 151 | CNT_INTVAL }, | ||
374 | { "LED: Channel C: FX2", 150 | CNT_INTVAL }, | ||
375 | |||
376 | { "LED: Channel D: >", 0 | CNT_INTVAL }, | ||
377 | { "LED: Channel D: <", 1 | CNT_INTVAL }, | ||
378 | { "LED: Channel D: Meter 1", 81 | CNT_INTVAL }, | ||
379 | { "LED: Channel D: Meter 2", 82 | CNT_INTVAL }, | ||
380 | { "LED: Channel D: Meter 3", 83 | CNT_INTVAL }, | ||
381 | { "LED: Channel D: Meter 4", 84 | CNT_INTVAL }, | ||
382 | { "LED: Channel D: Meter 5", 85 | CNT_INTVAL }, | ||
383 | { "LED: Channel D: Meter 6", 86 | CNT_INTVAL }, | ||
384 | { "LED: Channel D: Meter clip", 87 | CNT_INTVAL }, | ||
385 | { "LED: Channel D: Active", 123 | CNT_INTVAL }, | ||
386 | { "LED: Channel D: Cue", 124 | CNT_INTVAL }, | ||
387 | { "LED: Channel D: FX1", 145 | CNT_INTVAL }, | ||
388 | { "LED: Channel D: FX2", 144 | CNT_INTVAL }, | ||
389 | |||
390 | { "LED: Deck A: 1 (blue)", 22 | CNT_INTVAL }, | ||
391 | { "LED: Deck A: 1 (green)", 23 | CNT_INTVAL }, | ||
392 | { "LED: Deck A: 2 (blue)", 20 | CNT_INTVAL }, | ||
393 | { "LED: Deck A: 2 (green)", 21 | CNT_INTVAL }, | ||
394 | { "LED: Deck A: 3 (blue)", 18 | CNT_INTVAL }, | ||
395 | { "LED: Deck A: 3 (green)", 19 | CNT_INTVAL }, | ||
396 | { "LED: Deck A: 4 (blue)", 16 | CNT_INTVAL }, | ||
397 | { "LED: Deck A: 4 (green)", 17 | CNT_INTVAL }, | ||
398 | { "LED: Deck A: Load", 44 | CNT_INTVAL }, | ||
399 | { "LED: Deck A: Deck C button", 45 | CNT_INTVAL }, | ||
400 | { "LED: Deck A: In", 47 | CNT_INTVAL }, | ||
401 | { "LED: Deck A: Out", 46 | CNT_INTVAL }, | ||
402 | { "LED: Deck A: Shift", 24 | CNT_INTVAL }, | ||
403 | { "LED: Deck A: Sync", 27 | CNT_INTVAL }, | ||
404 | { "LED: Deck A: Cue", 26 | CNT_INTVAL }, | ||
405 | { "LED: Deck A: Play", 25 | CNT_INTVAL }, | ||
406 | { "LED: Deck A: Tempo up", 33 | CNT_INTVAL }, | ||
407 | { "LED: Deck A: Tempo down", 32 | CNT_INTVAL }, | ||
408 | { "LED: Deck A: Master", 34 | CNT_INTVAL }, | ||
409 | { "LED: Deck A: Keylock", 35 | CNT_INTVAL }, | ||
410 | { "LED: Deck A: Deck A", 37 | CNT_INTVAL }, | ||
411 | { "LED: Deck A: Deck C", 36 | CNT_INTVAL }, | ||
412 | { "LED: Deck A: Samples", 38 | CNT_INTVAL }, | ||
413 | { "LED: Deck A: On Air", 39 | CNT_INTVAL }, | ||
414 | { "LED: Deck A: Sample 1", 31 | CNT_INTVAL }, | ||
415 | { "LED: Deck A: Sample 2", 30 | CNT_INTVAL }, | ||
416 | { "LED: Deck A: Sample 3", 29 | CNT_INTVAL }, | ||
417 | { "LED: Deck A: Sample 4", 28 | CNT_INTVAL }, | ||
418 | { "LED: Deck A: Digit 1 - A", 55 | CNT_INTVAL }, | ||
419 | { "LED: Deck A: Digit 1 - B", 54 | CNT_INTVAL }, | ||
420 | { "LED: Deck A: Digit 1 - C", 53 | CNT_INTVAL }, | ||
421 | { "LED: Deck A: Digit 1 - D", 52 | CNT_INTVAL }, | ||
422 | { "LED: Deck A: Digit 1 - E", 51 | CNT_INTVAL }, | ||
423 | { "LED: Deck A: Digit 1 - F", 50 | CNT_INTVAL }, | ||
424 | { "LED: Deck A: Digit 1 - G", 49 | CNT_INTVAL }, | ||
425 | { "LED: Deck A: Digit 1 - dot", 48 | CNT_INTVAL }, | ||
426 | { "LED: Deck A: Digit 2 - A", 63 | CNT_INTVAL }, | ||
427 | { "LED: Deck A: Digit 2 - B", 62 | CNT_INTVAL }, | ||
428 | { "LED: Deck A: Digit 2 - C", 61 | CNT_INTVAL }, | ||
429 | { "LED: Deck A: Digit 2 - D", 60 | CNT_INTVAL }, | ||
430 | { "LED: Deck A: Digit 2 - E", 59 | CNT_INTVAL }, | ||
431 | { "LED: Deck A: Digit 2 - F", 58 | CNT_INTVAL }, | ||
432 | { "LED: Deck A: Digit 2 - G", 57 | CNT_INTVAL }, | ||
433 | { "LED: Deck A: Digit 2 - dot", 56 | CNT_INTVAL }, | ||
434 | |||
435 | { "LED: Deck B: 1 (blue)", 78 | CNT_INTVAL }, | ||
436 | { "LED: Deck B: 1 (green)", 79 | CNT_INTVAL }, | ||
437 | { "LED: Deck B: 2 (blue)", 76 | CNT_INTVAL }, | ||
438 | { "LED: Deck B: 2 (green)", 77 | CNT_INTVAL }, | ||
439 | { "LED: Deck B: 3 (blue)", 74 | CNT_INTVAL }, | ||
440 | { "LED: Deck B: 3 (green)", 75 | CNT_INTVAL }, | ||
441 | { "LED: Deck B: 4 (blue)", 72 | CNT_INTVAL }, | ||
442 | { "LED: Deck B: 4 (green)", 73 | CNT_INTVAL }, | ||
443 | { "LED: Deck B: Load", 180 | CNT_INTVAL }, | ||
444 | { "LED: Deck B: Deck D button", 181 | CNT_INTVAL }, | ||
445 | { "LED: Deck B: In", 183 | CNT_INTVAL }, | ||
446 | { "LED: Deck B: Out", 182 | CNT_INTVAL }, | ||
447 | { "LED: Deck B: Shift", 64 | CNT_INTVAL }, | ||
448 | { "LED: Deck B: Sync", 67 | CNT_INTVAL }, | ||
449 | { "LED: Deck B: Cue", 66 | CNT_INTVAL }, | ||
450 | { "LED: Deck B: Play", 65 | CNT_INTVAL }, | ||
451 | { "LED: Deck B: Tempo up", 185 | CNT_INTVAL }, | ||
452 | { "LED: Deck B: Tempo down", 184 | CNT_INTVAL }, | ||
453 | { "LED: Deck B: Master", 186 | CNT_INTVAL }, | ||
454 | { "LED: Deck B: Keylock", 187 | CNT_INTVAL }, | ||
455 | { "LED: Deck B: Deck B", 189 | CNT_INTVAL }, | ||
456 | { "LED: Deck B: Deck D", 188 | CNT_INTVAL }, | ||
457 | { "LED: Deck B: Samples", 190 | CNT_INTVAL }, | ||
458 | { "LED: Deck B: On Air", 191 | CNT_INTVAL }, | ||
459 | { "LED: Deck B: Sample 1", 71 | CNT_INTVAL }, | ||
460 | { "LED: Deck B: Sample 2", 70 | CNT_INTVAL }, | ||
461 | { "LED: Deck B: Sample 3", 69 | CNT_INTVAL }, | ||
462 | { "LED: Deck B: Sample 4", 68 | CNT_INTVAL }, | ||
463 | { "LED: Deck B: Digit 1 - A", 175 | CNT_INTVAL }, | ||
464 | { "LED: Deck B: Digit 1 - B", 174 | CNT_INTVAL }, | ||
465 | { "LED: Deck B: Digit 1 - C", 173 | CNT_INTVAL }, | ||
466 | { "LED: Deck B: Digit 1 - D", 172 | CNT_INTVAL }, | ||
467 | { "LED: Deck B: Digit 1 - E", 171 | CNT_INTVAL }, | ||
468 | { "LED: Deck B: Digit 1 - F", 170 | CNT_INTVAL }, | ||
469 | { "LED: Deck B: Digit 1 - G", 169 | CNT_INTVAL }, | ||
470 | { "LED: Deck B: Digit 1 - dot", 168 | CNT_INTVAL }, | ||
471 | { "LED: Deck B: Digit 2 - A", 167 | CNT_INTVAL }, | ||
472 | { "LED: Deck B: Digit 2 - B", 166 | CNT_INTVAL }, | ||
473 | { "LED: Deck B: Digit 2 - C", 165 | CNT_INTVAL }, | ||
474 | { "LED: Deck B: Digit 2 - D", 164 | CNT_INTVAL }, | ||
475 | { "LED: Deck B: Digit 2 - E", 163 | CNT_INTVAL }, | ||
476 | { "LED: Deck B: Digit 2 - F", 162 | CNT_INTVAL }, | ||
477 | { "LED: Deck B: Digit 2 - G", 161 | CNT_INTVAL }, | ||
478 | { "LED: Deck B: Digit 2 - dot", 160 | CNT_INTVAL }, | ||
479 | |||
480 | { "LED: FX1: dry/wet", 153 | CNT_INTVAL }, | ||
481 | { "LED: FX1: 1", 154 | CNT_INTVAL }, | ||
482 | { "LED: FX1: 2", 155 | CNT_INTVAL }, | ||
483 | { "LED: FX1: 3", 156 | CNT_INTVAL }, | ||
484 | { "LED: FX1: Mode", 157 | CNT_INTVAL }, | ||
485 | { "LED: FX2: dry/wet", 129 | CNT_INTVAL }, | ||
486 | { "LED: FX2: 1", 130 | CNT_INTVAL }, | ||
487 | { "LED: FX2: 2", 131 | CNT_INTVAL }, | ||
488 | { "LED: FX2: 3", 132 | CNT_INTVAL }, | ||
489 | { "LED: FX2: Mode", 133 | CNT_INTVAL }, | ||
490 | }; | ||
491 | |||
299 | static int __devinit add_controls(struct caiaq_controller *c, int num, | 492 | static int __devinit add_controls(struct caiaq_controller *c, int num, |
300 | struct snd_usb_caiaqdev *dev) | 493 | struct snd_usb_caiaqdev *dev) |
301 | { | 494 | { |
@@ -354,6 +547,11 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev) | |||
354 | ret = add_controls(kontrolx1_controller, | 547 | ret = add_controls(kontrolx1_controller, |
355 | ARRAY_SIZE(kontrolx1_controller), dev); | 548 | ARRAY_SIZE(kontrolx1_controller), dev); |
356 | break; | 549 | break; |
550 | |||
551 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | ||
552 | ret = add_controls(kontrols4_controller, | ||
553 | ARRAY_SIZE(kontrols4_controller), dev); | ||
554 | break; | ||
357 | } | 555 | } |
358 | 556 | ||
359 | return ret; | 557 | return ret; |
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index da9cb6dcee2a..6480c3283c05 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
@@ -48,7 +48,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | |||
48 | "{Native Instruments, Audio 8 DJ}," | 48 | "{Native Instruments, Audio 8 DJ}," |
49 | "{Native Instruments, Session I/O}," | 49 | "{Native Instruments, Session I/O}," |
50 | "{Native Instruments, GuitarRig mobile}" | 50 | "{Native Instruments, GuitarRig mobile}" |
51 | "{Native Instruments, Traktor Kontrol X1}"); | 51 | "{Native Instruments, Traktor Kontrol X1}" |
52 | "{Native Instruments, Traktor Kontrol S4}"); | ||
52 | 53 | ||
53 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 54 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
54 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 55 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ |
@@ -134,6 +135,11 @@ static struct usb_device_id snd_usb_id_table[] = { | |||
134 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 135 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
135 | .idProduct = USB_PID_TRAKTORKONTROLX1 | 136 | .idProduct = USB_PID_TRAKTORKONTROLX1 |
136 | }, | 137 | }, |
138 | { | ||
139 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
140 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | ||
141 | .idProduct = USB_PID_TRAKTORKONTROLS4 | ||
142 | }, | ||
137 | { /* terminator */ } | 143 | { /* terminator */ } |
138 | }; | 144 | }; |
139 | 145 | ||
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index f1117ecc84fd..e3d8a3efb35b 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #define USB_PID_SESSIONIO 0x1915 | 16 | #define USB_PID_SESSIONIO 0x1915 |
17 | #define USB_PID_GUITARRIGMOBILE 0x0d8d | 17 | #define USB_PID_GUITARRIGMOBILE 0x0d8d |
18 | #define USB_PID_TRAKTORKONTROLX1 0x2305 | 18 | #define USB_PID_TRAKTORKONTROLX1 0x2305 |
19 | #define USB_PID_TRAKTORKONTROLS4 0xbaff | ||
19 | 20 | ||
20 | #define EP1_BUFSIZE 64 | 21 | #define EP1_BUFSIZE 64 |
21 | #define EP4_BUFSIZE 512 | 22 | #define EP4_BUFSIZE 512 |
@@ -99,13 +100,14 @@ struct snd_usb_caiaqdev { | |||
99 | struct snd_pcm_substream *sub_capture[MAX_STREAMS]; | 100 | struct snd_pcm_substream *sub_capture[MAX_STREAMS]; |
100 | 101 | ||
101 | /* Controls */ | 102 | /* Controls */ |
102 | unsigned char control_state[64]; | 103 | unsigned char control_state[256]; |
104 | unsigned char ep8_out_buf[2]; | ||
103 | 105 | ||
104 | /* Linux input */ | 106 | /* Linux input */ |
105 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 107 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
106 | struct input_dev *input_dev; | 108 | struct input_dev *input_dev; |
107 | char phys[64]; /* physical device path */ | 109 | char phys[64]; /* physical device path */ |
108 | unsigned short keycode[64]; | 110 | unsigned short keycode[128]; |
109 | struct urb *ep4_in_urb; | 111 | struct urb *ep4_in_urb; |
110 | unsigned char ep4_in_buf[EP4_BUFSIZE]; | 112 | unsigned char ep4_in_buf[EP4_BUFSIZE]; |
111 | #endif | 113 | #endif |
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index dcb620796d9e..4432ef7a70a9 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c | |||
@@ -67,7 +67,12 @@ static unsigned short keycode_kore[] = { | |||
67 | KEY_BRL_DOT5 | 67 | KEY_BRL_DOT5 |
68 | }; | 68 | }; |
69 | 69 | ||
70 | #define KONTROLX1_INPUTS 40 | 70 | #define KONTROLX1_INPUTS (40) |
71 | #define KONTROLS4_BUTTONS (12 * 8) | ||
72 | #define KONTROLS4_AXIS (46) | ||
73 | |||
74 | #define KONTROLS4_BUTTON(X) ((X) + BTN_MISC) | ||
75 | #define KONTROLS4_ABS(X) ((X) + ABS_HAT0X) | ||
71 | 76 | ||
72 | #define DEG90 (range / 2) | 77 | #define DEG90 (range / 2) |
73 | #define DEG180 (range) | 78 | #define DEG180 (range) |
@@ -139,6 +144,13 @@ static unsigned int decode_erp(unsigned char a, unsigned char b) | |||
139 | #undef HIGH_PEAK | 144 | #undef HIGH_PEAK |
140 | #undef LOW_PEAK | 145 | #undef LOW_PEAK |
141 | 146 | ||
147 | static inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *dev, | ||
148 | int axis, const unsigned char *buf, | ||
149 | int offset) | ||
150 | { | ||
151 | input_report_abs(dev->input_dev, axis, | ||
152 | (buf[offset * 2] << 8) | buf[offset * 2 + 1]); | ||
153 | } | ||
142 | 154 | ||
143 | static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, | 155 | static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, |
144 | const unsigned char *buf, | 156 | const unsigned char *buf, |
@@ -148,36 +160,30 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, | |||
148 | 160 | ||
149 | switch (dev->chip.usb_id) { | 161 | switch (dev->chip.usb_id) { |
150 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | 162 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): |
151 | input_report_abs(input_dev, ABS_X, (buf[4] << 8) | buf[5]); | 163 | snd_caiaq_input_report_abs(dev, ABS_X, buf, 2); |
152 | input_report_abs(input_dev, ABS_Y, (buf[0] << 8) | buf[1]); | 164 | snd_caiaq_input_report_abs(dev, ABS_Y, buf, 0); |
153 | input_report_abs(input_dev, ABS_Z, (buf[2] << 8) | buf[3]); | 165 | snd_caiaq_input_report_abs(dev, ABS_Z, buf, 1); |
154 | input_sync(input_dev); | ||
155 | break; | 166 | break; |
156 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 167 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): |
157 | input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]); | ||
158 | input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]); | ||
159 | input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); | ||
160 | input_sync(input_dev); | ||
161 | break; | ||
162 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): | 168 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): |
163 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): | 169 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): |
164 | input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]); | 170 | snd_caiaq_input_report_abs(dev, ABS_X, buf, 0); |
165 | input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]); | 171 | snd_caiaq_input_report_abs(dev, ABS_Y, buf, 1); |
166 | input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); | 172 | snd_caiaq_input_report_abs(dev, ABS_Z, buf, 2); |
167 | input_sync(input_dev); | ||
168 | break; | 173 | break; |
169 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 174 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
170 | input_report_abs(input_dev, ABS_HAT0X, (buf[8] << 8) | buf[9]); | 175 | snd_caiaq_input_report_abs(dev, ABS_HAT0X, buf, 4); |
171 | input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]); | 176 | snd_caiaq_input_report_abs(dev, ABS_HAT0Y, buf, 2); |
172 | input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]); | 177 | snd_caiaq_input_report_abs(dev, ABS_HAT1X, buf, 6); |
173 | input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]); | 178 | snd_caiaq_input_report_abs(dev, ABS_HAT1Y, buf, 1); |
174 | input_report_abs(input_dev, ABS_HAT2X, (buf[14] << 8) | buf[15]); | 179 | snd_caiaq_input_report_abs(dev, ABS_HAT2X, buf, 7); |
175 | input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]); | 180 | snd_caiaq_input_report_abs(dev, ABS_HAT2Y, buf, 0); |
176 | input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]); | 181 | snd_caiaq_input_report_abs(dev, ABS_HAT3X, buf, 5); |
177 | input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]); | 182 | snd_caiaq_input_report_abs(dev, ABS_HAT3Y, buf, 3); |
178 | input_sync(input_dev); | ||
179 | break; | 183 | break; |
180 | } | 184 | } |
185 | |||
186 | input_sync(input_dev); | ||
181 | } | 187 | } |
182 | 188 | ||
183 | static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, | 189 | static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, |
@@ -250,6 +256,150 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, | |||
250 | input_sync(input_dev); | 256 | input_sync(input_dev); |
251 | } | 257 | } |
252 | 258 | ||
259 | #define TKS4_MSGBLOCK_SIZE 16 | ||
260 | |||
261 | static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev, | ||
262 | const unsigned char *buf, | ||
263 | unsigned int len) | ||
264 | { | ||
265 | while (len) { | ||
266 | unsigned int i, block_id = (buf[0] << 8) | buf[1]; | ||
267 | |||
268 | switch (block_id) { | ||
269 | case 0: | ||
270 | /* buttons */ | ||
271 | for (i = 0; i < KONTROLS4_BUTTONS; i++) | ||
272 | input_report_key(dev->input_dev, KONTROLS4_BUTTON(i), | ||
273 | (buf[4 + (i / 8)] >> (i % 8)) & 1); | ||
274 | break; | ||
275 | |||
276 | case 1: | ||
277 | /* left wheel */ | ||
278 | input_report_abs(dev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8)); | ||
279 | /* right wheel */ | ||
280 | input_report_abs(dev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8)); | ||
281 | |||
282 | /* rotary encoders */ | ||
283 | input_report_abs(dev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf); | ||
284 | input_report_abs(dev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4); | ||
285 | input_report_abs(dev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf); | ||
286 | input_report_abs(dev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4); | ||
287 | input_report_abs(dev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf); | ||
288 | input_report_abs(dev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4); | ||
289 | input_report_abs(dev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf); | ||
290 | input_report_abs(dev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4); | ||
291 | input_report_abs(dev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf); | ||
292 | |||
293 | break; | ||
294 | case 2: | ||
295 | /* Volume Fader Channel D */ | ||
296 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(0), buf, 1); | ||
297 | /* Volume Fader Channel B */ | ||
298 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(1), buf, 2); | ||
299 | /* Volume Fader Channel A */ | ||
300 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(2), buf, 3); | ||
301 | /* Volume Fader Channel C */ | ||
302 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(3), buf, 4); | ||
303 | /* Loop Volume */ | ||
304 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(4), buf, 6); | ||
305 | /* Crossfader */ | ||
306 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(7), buf, 7); | ||
307 | |||
308 | break; | ||
309 | |||
310 | case 3: | ||
311 | /* Tempo Fader R */ | ||
312 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(6), buf, 3); | ||
313 | /* Tempo Fader L */ | ||
314 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(5), buf, 4); | ||
315 | /* Mic Volume */ | ||
316 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(8), buf, 6); | ||
317 | /* Cue Mix */ | ||
318 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(9), buf, 7); | ||
319 | |||
320 | break; | ||
321 | |||
322 | case 4: | ||
323 | /* Wheel distance sensor L */ | ||
324 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(10), buf, 1); | ||
325 | /* Wheel distance sensor R */ | ||
326 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(11), buf, 2); | ||
327 | /* Channel D EQ - Filter */ | ||
328 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(12), buf, 3); | ||
329 | /* Channel D EQ - Low */ | ||
330 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(13), buf, 4); | ||
331 | /* Channel D EQ - Mid */ | ||
332 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(14), buf, 5); | ||
333 | /* Channel D EQ - Hi */ | ||
334 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(15), buf, 6); | ||
335 | /* FX2 - dry/wet */ | ||
336 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(16), buf, 7); | ||
337 | |||
338 | break; | ||
339 | |||
340 | case 5: | ||
341 | /* FX2 - 1 */ | ||
342 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(17), buf, 1); | ||
343 | /* FX2 - 2 */ | ||
344 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(18), buf, 2); | ||
345 | /* FX2 - 3 */ | ||
346 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(19), buf, 3); | ||
347 | /* Channel B EQ - Filter */ | ||
348 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(20), buf, 4); | ||
349 | /* Channel B EQ - Low */ | ||
350 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(21), buf, 5); | ||
351 | /* Channel B EQ - Mid */ | ||
352 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(22), buf, 6); | ||
353 | /* Channel B EQ - Hi */ | ||
354 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(23), buf, 7); | ||
355 | |||
356 | break; | ||
357 | |||
358 | case 6: | ||
359 | /* Channel A EQ - Filter */ | ||
360 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(24), buf, 1); | ||
361 | /* Channel A EQ - Low */ | ||
362 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(25), buf, 2); | ||
363 | /* Channel A EQ - Mid */ | ||
364 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(26), buf, 3); | ||
365 | /* Channel A EQ - Hi */ | ||
366 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(27), buf, 4); | ||
367 | /* Channel C EQ - Filter */ | ||
368 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(28), buf, 5); | ||
369 | /* Channel C EQ - Low */ | ||
370 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(29), buf, 6); | ||
371 | /* Channel C EQ - Mid */ | ||
372 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(30), buf, 7); | ||
373 | |||
374 | break; | ||
375 | |||
376 | case 7: | ||
377 | /* Channel C EQ - Hi */ | ||
378 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(31), buf, 1); | ||
379 | /* FX1 - wet/dry */ | ||
380 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(32), buf, 2); | ||
381 | /* FX1 - 1 */ | ||
382 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(33), buf, 3); | ||
383 | /* FX1 - 2 */ | ||
384 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(34), buf, 4); | ||
385 | /* FX1 - 3 */ | ||
386 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(35), buf, 5); | ||
387 | |||
388 | break; | ||
389 | |||
390 | default: | ||
391 | debug("%s(): bogus block (id %d)\n", | ||
392 | __func__, block_id); | ||
393 | return; | ||
394 | } | ||
395 | |||
396 | len -= TKS4_MSGBLOCK_SIZE; | ||
397 | buf += TKS4_MSGBLOCK_SIZE; | ||
398 | } | ||
399 | |||
400 | input_sync(dev->input_dev); | ||
401 | } | ||
402 | |||
253 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | 403 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) |
254 | { | 404 | { |
255 | struct snd_usb_caiaqdev *dev = urb->context; | 405 | struct snd_usb_caiaqdev *dev = urb->context; |
@@ -259,11 +409,11 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | |||
259 | if (urb->status || !dev || urb != dev->ep4_in_urb) | 409 | if (urb->status || !dev || urb != dev->ep4_in_urb) |
260 | return; | 410 | return; |
261 | 411 | ||
262 | if (urb->actual_length < 24) | ||
263 | goto requeue; | ||
264 | |||
265 | switch (dev->chip.usb_id) { | 412 | switch (dev->chip.usb_id) { |
266 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 413 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
414 | if (urb->actual_length < 24) | ||
415 | goto requeue; | ||
416 | |||
267 | if (buf[0] & 0x3) | 417 | if (buf[0] & 0x3) |
268 | snd_caiaq_input_read_io(dev, buf + 1, 7); | 418 | snd_caiaq_input_read_io(dev, buf + 1, 7); |
269 | 419 | ||
@@ -271,6 +421,10 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | |||
271 | snd_caiaq_input_read_analog(dev, buf + 8, 16); | 421 | snd_caiaq_input_read_analog(dev, buf + 8, 16); |
272 | 422 | ||
273 | break; | 423 | break; |
424 | |||
425 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | ||
426 | snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length); | ||
427 | break; | ||
274 | } | 428 | } |
275 | 429 | ||
276 | requeue: | 430 | requeue: |
@@ -289,6 +443,7 @@ static int snd_usb_caiaq_input_open(struct input_dev *idev) | |||
289 | 443 | ||
290 | switch (dev->chip.usb_id) { | 444 | switch (dev->chip.usb_id) { |
291 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 445 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
446 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | ||
292 | if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) | 447 | if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) |
293 | return -EIO; | 448 | return -EIO; |
294 | break; | 449 | break; |
@@ -306,6 +461,7 @@ static void snd_usb_caiaq_input_close(struct input_dev *idev) | |||
306 | 461 | ||
307 | switch (dev->chip.usb_id) { | 462 | switch (dev->chip.usb_id) { |
308 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 463 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
464 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | ||
309 | usb_kill_urb(dev->ep4_in_urb); | 465 | usb_kill_urb(dev->ep4_in_urb); |
310 | break; | 466 | break; |
311 | } | 467 | } |
@@ -456,6 +612,46 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
456 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | 612 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); |
457 | 613 | ||
458 | break; | 614 | break; |
615 | |||
616 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | ||
617 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
618 | BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLS4_BUTTONS); | ||
619 | for (i = 0; i < KONTROLS4_BUTTONS; i++) | ||
620 | dev->keycode[i] = KONTROLS4_BUTTON(i); | ||
621 | input->keycodemax = KONTROLS4_BUTTONS; | ||
622 | |||
623 | for (i = 0; i < KONTROLS4_AXIS; i++) { | ||
624 | int axis = KONTROLS4_ABS(i); | ||
625 | input->absbit[BIT_WORD(axis)] |= BIT_MASK(axis); | ||
626 | } | ||
627 | |||
628 | /* 36 analog potentiometers and faders */ | ||
629 | for (i = 0; i < 36; i++) | ||
630 | input_set_abs_params(input, KONTROLS4_ABS(i), 0, 0xfff, 0, 10); | ||
631 | |||
632 | /* 2 encoder wheels */ | ||
633 | input_set_abs_params(input, KONTROLS4_ABS(36), 0, 0x3ff, 0, 1); | ||
634 | input_set_abs_params(input, KONTROLS4_ABS(37), 0, 0x3ff, 0, 1); | ||
635 | |||
636 | /* 9 rotary encoders */ | ||
637 | for (i = 0; i < 9; i++) | ||
638 | input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1); | ||
639 | |||
640 | dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
641 | if (!dev->ep4_in_urb) { | ||
642 | ret = -ENOMEM; | ||
643 | goto exit_free_idev; | ||
644 | } | ||
645 | |||
646 | usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev, | ||
647 | usb_rcvbulkpipe(usb_dev, 0x4), | ||
648 | dev->ep4_in_buf, EP4_BUFSIZE, | ||
649 | snd_usb_caiaq_ep4_reply_dispatch, dev); | ||
650 | |||
651 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | ||
652 | |||
653 | break; | ||
654 | |||
459 | default: | 655 | default: |
460 | /* no input methods supported on this device */ | 656 | /* no input methods supported on this device */ |
461 | goto exit_free_idev; | 657 | goto exit_free_idev; |