Commit 523f1dce37434a9a6623bf46e7893e2b4b10ac3c

Authored by Daniel Mack
Committed by Jaroslav Kysela
1 parent e24a121aa1

[ALSA] Add Native Instrument usb audio device support

Add snd-usb-caiaq driver to support caiaq usb-audio devices from
Native Instrument:
	* Native Instruments RigKontrol2
	* Native Instruments Kore Controller
	* Native Instruments Audio Kontrol 1
	* Native Instruments Audio 8 DJ

Signed-off-by: Daniel Mack <daniel@caiaq.org>
Signed-off-by: Karsten Wiese <fzu@wemgehoertderstaat.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>

Showing 12 changed files with 1747 additions and 1 deletions Side-by-side Diff

Documentation/sound/alsa/ALSA-Configuration.txt
... ... @@ -1697,6 +1697,17 @@
1697 1697  
1698 1698 This module supports multiple devices, autoprobe and hotplugging.
1699 1699  
  1700 + Module snd-usb-caiaq
  1701 + --------------------
  1702 +
  1703 + Module for caiaq UB audio interfaces,
  1704 + * Native Instruments RigKontrol2
  1705 + * Native Instruments Kore Controller
  1706 + * Native Instruments Audio Kontrol 1
  1707 + * Native Instruments Audio 8 DJ
  1708 +
  1709 + This module supports multiple devices, autoprobe and hotplugging.
  1710 +
1700 1711 Module snd-usb-usx2y
1701 1712 --------------------
1702 1713  
... ... @@ -29,5 +29,33 @@
29 29 To compile this driver as a module, choose M here: the module
30 30 will be called snd-usb-usx2y.
31 31  
  32 +config SND_USB_CAIAQ
  33 + tristate "Native Instruments USB audio devices"
  34 + depends on SND && USB
  35 + select SND_HWDEP
  36 + select SND_RAWMIDI
  37 + select SND_PCM
  38 + help
  39 + Say Y here to include support for caiaq USB audio interfaces,
  40 + namely:
  41 +
  42 + * Native Instruments RigKontrol2
  43 + * Native Instruments Kore Controller
  44 + * Native Instruments Audio Kontrol 1
  45 + * Native Instruments Audio 8 DJ
  46 +
  47 + To compile this driver as a module, choose M here: the module
  48 + will be called snd-usb-caiaq.
  49 +
  50 +config SND_USB_CAIAQ_INPUT
  51 + bool "enable input device for controllers"
  52 + depends on SND_USB_CAIAQ
  53 + help
  54 + Say Y here to support input controllers like buttons, knobs,
  55 + alpha dials and analog pedals on the following products:
  56 +
  57 + * Native Instruments RigKontrol2
  58 + * Native Instruments Audio Kontrol 1
  59 +
32 60 endmenu
... ... @@ -9,5 +9,5 @@
9 9 obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o
10 10 obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o
11 11  
12   -obj-$(CONFIG_SND) += usx2y/
  12 +obj-$(CONFIG_SND) += usx2y/ caiaq/
sound/usb/caiaq/Makefile
  1 +snd-usb-caiaq-objs := caiaq-device.o caiaq-audio.o caiaq-midi.o caiaq-input.o
  2 +
  3 +obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o
sound/usb/caiaq/caiaq-audio.c
  1 +/*
  2 + * Copyright (c) 2006,2007 Daniel Mack, Karsten Wiese
  3 + *
  4 + * This program is free software; you can redistribute it and/or modify
  5 + * it under the terms of the GNU General Public License as published by
  6 + * the Free Software Foundation; either version 2 of the License, or
  7 + * (at your option) any later version.
  8 + *
  9 + * This program is distributed in the hope that it will be useful,
  10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 + * GNU General Public License for more details.
  13 + *
  14 + * You should have received a copy of the GNU General Public License
  15 + * along with this program; if not, write to the Free Software
  16 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17 +*/
  18 +
  19 +#include <sound/driver.h>
  20 +#include <linux/init.h>
  21 +#include <linux/module.h>
  22 +#include <linux/moduleparam.h>
  23 +#include <linux/interrupt.h>
  24 +#include <linux/usb.h>
  25 +#include <linux/spinlock.h>
  26 +#include <sound/core.h>
  27 +#include <sound/initval.h>
  28 +#include <sound/pcm.h>
  29 +#include <sound/rawmidi.h>
  30 +#ifdef CONFIG_SND_USB_CAIAQ_INPUT
  31 +#include <linux/input.h>
  32 +#endif
  33 +
  34 +#include "caiaq-device.h"
  35 +#include "caiaq-audio.h"
  36 +
  37 +#define N_URBS 32
  38 +#define CLOCK_DRIFT_TOLERANCE 5
  39 +#define FRAMES_PER_URB 8
  40 +#define BYTES_PER_FRAME 512
  41 +#define CHANNELS_PER_STREAM 2
  42 +#define BYTES_PER_SAMPLE 3
  43 +#define BYTES_PER_SAMPLE_USB 4
  44 +#define MAX_BUFFER_SIZE (128*1024)
  45 +
  46 +#define ENDPOINT_CAPTURE 2
  47 +#define ENDPOINT_PLAYBACK 6
  48 +
  49 +#define MAKE_CHECKBYTE(dev,stream,i) \
  50 + (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1)
  51 +
  52 +static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = {
  53 + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
  54 + SNDRV_PCM_INFO_BLOCK_TRANSFER),
  55 + .formats = SNDRV_PCM_FMTBIT_S24_3BE,
  56 + .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
  57 + SNDRV_PCM_RATE_96000),
  58 + .rate_min = 44100,
  59 + .rate_max = 0, /* will overwrite later */
  60 + .channels_min = CHANNELS_PER_STREAM,
  61 + .channels_max = CHANNELS_PER_STREAM,
  62 + .buffer_bytes_max = MAX_BUFFER_SIZE,
  63 + .period_bytes_min = 4096,
  64 + .period_bytes_max = MAX_BUFFER_SIZE,
  65 + .periods_min = 1,
  66 + .periods_max = 1024,
  67 +};
  68 +
  69 +static void
  70 +activate_substream(struct snd_usb_caiaqdev *dev,
  71 + struct snd_pcm_substream *sub)
  72 +{
  73 + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
  74 + dev->sub_playback[sub->number] = sub;
  75 + else
  76 + dev->sub_capture[sub->number] = sub;
  77 +}
  78 +
  79 +static void
  80 +deactivate_substream(struct snd_usb_caiaqdev *dev,
  81 + struct snd_pcm_substream *sub)
  82 +{
  83 + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
  84 + dev->sub_playback[sub->number] = NULL;
  85 + else
  86 + dev->sub_capture[sub->number] = NULL;
  87 +}
  88 +
  89 +static int
  90 +all_substreams_zero(struct snd_pcm_substream **subs)
  91 +{
  92 + int i;
  93 + for (i = 0; i < MAX_STREAMS; i++)
  94 + if (subs[i] != NULL)
  95 + return 0;
  96 + return 1;
  97 +}
  98 +
  99 +static int stream_start(struct snd_usb_caiaqdev *dev)
  100 +{
  101 + int i, ret;
  102 +
  103 + debug("stream_start(%p)\n", dev);
  104 + spin_lock_irq(&dev->spinlock);
  105 + if (dev->streaming) {
  106 + spin_unlock_irq(&dev->spinlock);
  107 + return -EINVAL;
  108 + }
  109 +
  110 + dev->input_panic = 0;
  111 + dev->output_panic = 0;
  112 + dev->first_packet = 1;
  113 + dev->streaming = 1;
  114 +
  115 + for (i = 0; i < N_URBS; i++) {
  116 + ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC);
  117 + if (ret) {
  118 + log("unable to trigger initial read #%d! (ret = %d)\n",
  119 + i, ret);
  120 + dev->streaming = 0;
  121 + spin_unlock_irq(&dev->spinlock);
  122 + return -EPIPE;
  123 + }
  124 + }
  125 +
  126 + spin_unlock_irq(&dev->spinlock);
  127 + return 0;
  128 +}
  129 +
  130 +static void stream_stop(struct snd_usb_caiaqdev *dev)
  131 +{
  132 + int i;
  133 +
  134 + debug("stream_stop(%p)\n", dev);
  135 + if (!dev->streaming)
  136 + return;
  137 +
  138 + dev->streaming = 0;
  139 + for (i = 0; i < N_URBS; i++) {
  140 + usb_unlink_urb(dev->data_urbs_in[i]);
  141 + usb_unlink_urb(dev->data_urbs_out[i]);
  142 + }
  143 +}
  144 +
  145 +static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream)
  146 +{
  147 + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
  148 + debug("snd_usb_caiaq_substream_open(%p)\n", substream);
  149 + substream->runtime->hw = dev->pcm_info;
  150 + snd_pcm_limit_hw_rates(substream->runtime);
  151 + return 0;
  152 +}
  153 +
  154 +static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
  155 +{
  156 + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
  157 +
  158 + debug("snd_usb_caiaq_substream_close(%p)\n", substream);
  159 + if (all_substreams_zero(dev->sub_playback) &&
  160 + all_substreams_zero(dev->sub_capture)) {
  161 + /* when the last client has stopped streaming,
  162 + * all sample rates are allowed again */
  163 + stream_stop(dev);
  164 + dev->pcm_info.rates = dev->samplerates;
  165 + }
  166 +
  167 + return 0;
  168 +}
  169 +
  170 +static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub,
  171 + struct snd_pcm_hw_params *hw_params)
  172 +{
  173 + debug("snd_usb_caiaq_pcm_hw_params(%p)\n", sub);
  174 + return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params));
  175 +}
  176 +
  177 +static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
  178 +{
  179 + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
  180 + debug("snd_usb_caiaq_pcm_hw_free(%p)\n", sub);
  181 + spin_lock_irq(&dev->spinlock);
  182 + deactivate_substream(dev, sub);
  183 + spin_unlock_irq(&dev->spinlock);
  184 + return snd_pcm_lib_free_pages(sub);
  185 +}
  186 +
  187 +/* this should probably go upstream */
  188 +#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
  189 +#error "Change this table"
  190 +#endif
  191 +
  192 +static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
  193 + 48000, 64000, 88200, 96000, 176400, 192000 };
  194 +
  195 +static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
  196 +{
  197 + int bytes_per_sample, bpp, ret, i;
  198 + int index = substream->number;
  199 + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
  200 + struct snd_pcm_runtime *runtime = substream->runtime;
  201 +
  202 + debug("snd_usb_caiaq_pcm_prepare(%p)\n", substream);
  203 +
  204 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  205 + dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1;
  206 + else
  207 + dev->audio_in_buf_pos[index] = 0;
  208 +
  209 + if (dev->streaming)
  210 + return 0;
  211 +
  212 + /* the first client that opens a stream defines the sample rate
  213 + * setting for all subsequent calls, until the last client closed. */
  214 + for (i=0; i < ARRAY_SIZE(rates); i++)
  215 + if (runtime->rate == rates[i])
  216 + dev->pcm_info.rates = 1 << i;
  217 +
  218 + snd_pcm_limit_hw_rates(runtime);
  219 +
  220 + bytes_per_sample = BYTES_PER_SAMPLE;
  221 + if (dev->spec.data_alignment == 2)
  222 + bytes_per_sample++;
  223 +
  224 + bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE)
  225 + * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams;
  226 +
  227 + ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate,
  228 + runtime->sample_bits, bpp);
  229 + if (ret)
  230 + return ret;
  231 +
  232 + ret = stream_start(dev);
  233 + if (ret)
  234 + return ret;
  235 +
  236 + dev->output_running = 0;
  237 + wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ);
  238 + if (!dev->output_running) {
  239 + stream_stop(dev);
  240 + return -EPIPE;
  241 + }
  242 +
  243 + return 0;
  244 +}
  245 +
  246 +static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd)
  247 +{
  248 + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
  249 +
  250 + switch (cmd) {
  251 + case SNDRV_PCM_TRIGGER_START:
  252 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  253 + spin_lock(&dev->spinlock);
  254 + activate_substream(dev, sub);
  255 + spin_unlock(&dev->spinlock);
  256 + break;
  257 + case SNDRV_PCM_TRIGGER_STOP:
  258 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  259 + spin_lock(&dev->spinlock);
  260 + deactivate_substream(dev, sub);
  261 + spin_unlock(&dev->spinlock);
  262 + break;
  263 + default:
  264 + return -EINVAL;
  265 + }
  266 +
  267 + return 0;
  268 +}
  269 +
  270 +static snd_pcm_uframes_t
  271 +snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
  272 +{
  273 + int index = sub->number;
  274 + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
  275 +
  276 + if (dev->input_panic || dev->output_panic)
  277 + return SNDRV_PCM_POS_XRUN;
  278 +
  279 + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
  280 + return bytes_to_frames(sub->runtime,
  281 + dev->audio_out_buf_pos[index]);
  282 + else
  283 + return bytes_to_frames(sub->runtime,
  284 + dev->audio_in_buf_pos[index]);
  285 +}
  286 +
  287 +/* operators for both playback and capture */
  288 +static struct snd_pcm_ops snd_usb_caiaq_ops = {
  289 + .open = snd_usb_caiaq_substream_open,
  290 + .close = snd_usb_caiaq_substream_close,
  291 + .ioctl = snd_pcm_lib_ioctl,
  292 + .hw_params = snd_usb_caiaq_pcm_hw_params,
  293 + .hw_free = snd_usb_caiaq_pcm_hw_free,
  294 + .prepare = snd_usb_caiaq_pcm_prepare,
  295 + .trigger = snd_usb_caiaq_pcm_trigger,
  296 + .pointer = snd_usb_caiaq_pcm_pointer
  297 +};
  298 +
  299 +static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev,
  300 + struct snd_pcm_substream **subs)
  301 +{
  302 + int stream, pb, *cnt;
  303 + struct snd_pcm_substream *sub;
  304 +
  305 + for (stream = 0; stream < dev->n_streams; stream++) {
  306 + sub = subs[stream];
  307 + if (!sub)
  308 + continue;
  309 +
  310 + pb = frames_to_bytes(sub->runtime,
  311 + sub->runtime->period_size);
  312 + cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  313 + &dev->period_out_count[stream] :
  314 + &dev->period_in_count[stream];
  315 +
  316 + if (*cnt >= pb) {
  317 + snd_pcm_period_elapsed(sub);
  318 + *cnt %= pb;
  319 + }
  320 + }
  321 +}
  322 +
  323 +static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev,
  324 + const struct urb *urb,
  325 + const struct usb_iso_packet_descriptor *iso)
  326 +{
  327 + unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
  328 + struct snd_pcm_substream *sub;
  329 + int stream, i;
  330 +
  331 + if (all_substreams_zero(dev->sub_capture))
  332 + return;
  333 +
  334 + spin_lock(&dev->spinlock);
  335 +
  336 + for (i = 0; i < iso->actual_length;) {
  337 + for (stream = 0; stream < dev->n_streams; stream++, i++) {
  338 + sub = dev->sub_capture[stream];
  339 + if (sub) {
  340 + struct snd_pcm_runtime *rt = sub->runtime;
  341 + char *audio_buf = rt->dma_area;
  342 + int sz = frames_to_bytes(rt, rt->buffer_size);
  343 + audio_buf[dev->audio_in_buf_pos[stream]++]
  344 + = usb_buf[i];
  345 + dev->period_in_count[stream]++;
  346 + if (dev->audio_in_buf_pos[stream] == sz)
  347 + dev->audio_in_buf_pos[stream] = 0;
  348 + }
  349 + }
  350 + }
  351 +
  352 + spin_unlock(&dev->spinlock);
  353 +}
  354 +
  355 +static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev,
  356 + const struct urb *urb,
  357 + const struct usb_iso_packet_descriptor *iso)
  358 +{
  359 + unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
  360 + unsigned char check_byte;
  361 + struct snd_pcm_substream *sub;
  362 + int stream, i;
  363 +
  364 + spin_lock(&dev->spinlock);
  365 +
  366 + for (i = 0; i < iso->actual_length;) {
  367 + if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) {
  368 + for (stream = 0;
  369 + stream < dev->n_streams;
  370 + stream++, i++) {
  371 + if (dev->first_packet)
  372 + continue;
  373 +
  374 + check_byte = MAKE_CHECKBYTE(dev, stream, i);
  375 +
  376 + if ((usb_buf[i] & 0x3f) != check_byte)
  377 + dev->input_panic = 1;
  378 +
  379 + if (usb_buf[i] & 0x80)
  380 + dev->output_panic = 1;
  381 + }
  382 + }
  383 + dev->first_packet = 0;
  384 +
  385 + for (stream = 0; stream < dev->n_streams; stream++, i++) {
  386 + sub = dev->sub_capture[stream];
  387 + if (sub) {
  388 + struct snd_pcm_runtime *rt = sub->runtime;
  389 + char *audio_buf = rt->dma_area;
  390 + int sz = frames_to_bytes(rt, rt->buffer_size);
  391 + audio_buf[dev->audio_in_buf_pos[stream]++]
  392 + = usb_buf[i];
  393 + dev->period_in_count[stream]++;
  394 + if (dev->audio_in_buf_pos[stream] == sz)
  395 + dev->audio_in_buf_pos[stream] = 0;
  396 + }
  397 + }
  398 + }
  399 +
  400 + spin_unlock(&dev->spinlock);
  401 +}
  402 +
  403 +static void read_in_urb(struct snd_usb_caiaqdev *dev,
  404 + const struct urb *urb,
  405 + const struct usb_iso_packet_descriptor *iso)
  406 +{
  407 + if (!dev->streaming)
  408 + return;
  409 +
  410 + switch (dev->spec.data_alignment) {
  411 + case 0:
  412 + read_in_urb_mode0(dev, urb, iso);
  413 + break;
  414 + case 2:
  415 + read_in_urb_mode2(dev, urb, iso);
  416 + break;
  417 + }
  418 +
  419 + if (dev->input_panic || dev->output_panic) {
  420 + debug("streaming error detected %s %s\n",
  421 + dev->input_panic ? "(input)" : "",
  422 + dev->output_panic ? "(output)" : "");
  423 + }
  424 +
  425 + check_for_elapsed_periods(dev, dev->sub_capture);
  426 +}
  427 +
  428 +static void fill_out_urb(struct snd_usb_caiaqdev *dev,
  429 + struct urb *urb,
  430 + const struct usb_iso_packet_descriptor *iso)
  431 +{
  432 + unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
  433 + struct snd_pcm_substream *sub;
  434 + int stream, i;
  435 +
  436 + spin_lock(&dev->spinlock);
  437 +
  438 + for (i = 0; i < iso->length;) {
  439 + for (stream = 0; stream < dev->n_streams; stream++) {
  440 + sub = dev->sub_playback[stream];
  441 + if (sub) {
  442 + struct snd_pcm_runtime *rt = sub->runtime;
  443 + char *audio_buf = rt->dma_area;
  444 + int sz = frames_to_bytes(rt, rt->buffer_size);
  445 + usb_buf[i++]
  446 + = audio_buf[dev->audio_out_buf_pos[stream]++];
  447 + dev->audio_out_buf_pos[stream]++;
  448 + if (dev->audio_out_buf_pos[stream] == sz)
  449 + dev->audio_out_buf_pos[stream] = 0;
  450 + } else
  451 + usb_buf[i++] = 0;
  452 +
  453 + /* fill in the check bytes */
  454 + if (dev->spec.data_alignment == 2 &&
  455 + i % (dev->n_streams * BYTES_PER_SAMPLE_USB) ==
  456 + (dev->n_streams * CHANNELS_PER_STREAM))
  457 + for (stream = 0; stream < dev->n_streams; stream++, i++)
  458 + usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i);
  459 + }
  460 + }
  461 +
  462 + spin_unlock(&dev->spinlock);
  463 + check_for_elapsed_periods(dev, dev->sub_playback);
  464 +}
  465 +
  466 +static void read_completed(struct urb *urb)
  467 +{
  468 + struct snd_usb_caiaq_cb_info *info = urb->context;
  469 + struct snd_usb_caiaqdev *dev;
  470 + struct urb *out;
  471 + int frame, len, send_it = 0, outframe = 0;
  472 +
  473 + if (urb->status || !info)
  474 + return;
  475 +
  476 + dev = info->dev;
  477 + if (!dev->streaming)
  478 + return;
  479 +
  480 + out = dev->data_urbs_out[info->index];
  481 +
  482 + /* read the recently received packet and send back one which has
  483 + * the same layout */
  484 + for (frame = 0; frame < FRAMES_PER_URB; frame++) {
  485 + if (urb->iso_frame_desc[frame].status)
  486 + continue;
  487 +
  488 + len = urb->iso_frame_desc[outframe].actual_length;
  489 + out->iso_frame_desc[outframe].length = len;
  490 + out->iso_frame_desc[outframe].actual_length = 0;
  491 + out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame;
  492 +
  493 + if (len > 0) {
  494 + fill_out_urb(dev, out, &out->iso_frame_desc[outframe]);
  495 + read_in_urb(dev, urb, &urb->iso_frame_desc[frame]);
  496 + send_it = 1;
  497 + }
  498 +
  499 + outframe++;
  500 + }
  501 +
  502 + if (send_it) {
  503 + out->number_of_packets = FRAMES_PER_URB;
  504 + out->transfer_flags = URB_ISO_ASAP;
  505 + usb_submit_urb(out, GFP_ATOMIC);
  506 + }
  507 +
  508 + /* re-submit inbound urb */
  509 + for (frame = 0; frame < FRAMES_PER_URB; frame++) {
  510 + urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame;
  511 + urb->iso_frame_desc[frame].length = BYTES_PER_FRAME;
  512 + urb->iso_frame_desc[frame].actual_length = 0;
  513 + }
  514 +
  515 + urb->number_of_packets = FRAMES_PER_URB;
  516 + urb->transfer_flags = URB_ISO_ASAP;
  517 + usb_submit_urb(urb, GFP_ATOMIC);
  518 +}
  519 +
  520 +static void write_completed(struct urb *urb)
  521 +{
  522 + struct snd_usb_caiaq_cb_info *info = urb->context;
  523 + struct snd_usb_caiaqdev *dev = info->dev;
  524 +
  525 + if (!dev->output_running) {
  526 + dev->output_running = 1;
  527 + wake_up(&dev->prepare_wait_queue);
  528 + }
  529 +}
  530 +
  531 +static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
  532 +{
  533 + int i, frame;
  534 + struct urb **urbs;
  535 + struct usb_device *usb_dev = dev->chip.dev;
  536 + unsigned int pipe;
  537 +
  538 + pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ?
  539 + usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) :
  540 + usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE);
  541 +
  542 + urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL);
  543 + if (!urbs) {
  544 + log("unable to kmalloc() urbs, OOM!?\n");
  545 + *ret = -ENOMEM;
  546 + return NULL;
  547 + }
  548 +
  549 + for (i = 0; i < N_URBS; i++) {
  550 + urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL);
  551 + if (!urbs[i]) {
  552 + log("unable to usb_alloc_urb(), OOM!?\n");
  553 + *ret = -ENOMEM;
  554 + return urbs;
  555 + }
  556 +
  557 + urbs[i]->transfer_buffer =
  558 + kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
  559 + if (!urbs[i]->transfer_buffer) {
  560 + log("unable to kmalloc() transfer buffer, OOM!?\n");
  561 + *ret = -ENOMEM;
  562 + return urbs;
  563 + }
  564 +
  565 + for (frame = 0; frame < FRAMES_PER_URB; frame++) {
  566 + struct usb_iso_packet_descriptor *iso =
  567 + &urbs[i]->iso_frame_desc[frame];
  568 +
  569 + iso->offset = BYTES_PER_FRAME * frame;
  570 + iso->length = BYTES_PER_FRAME;
  571 + }
  572 +
  573 + urbs[i]->dev = usb_dev;
  574 + urbs[i]->pipe = pipe;
  575 + urbs[i]->transfer_buffer_length = FRAMES_PER_URB
  576 + * BYTES_PER_FRAME;
  577 + urbs[i]->context = &dev->data_cb_info[i];
  578 + urbs[i]->interval = 1;
  579 + urbs[i]->transfer_flags = URB_ISO_ASAP;
  580 + urbs[i]->number_of_packets = FRAMES_PER_URB;
  581 + urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ?
  582 + read_completed : write_completed;
  583 + }
  584 +
  585 + *ret = 0;
  586 + return urbs;
  587 +}
  588 +
  589 +static void free_urbs(struct urb **urbs)
  590 +{
  591 + int i;
  592 +
  593 + if (!urbs)
  594 + return;
  595 +
  596 + for (i = 0; i < N_URBS; i++) {
  597 + if (!urbs[i])
  598 + continue;
  599 +
  600 + usb_kill_urb(urbs[i]);
  601 + kfree(urbs[i]->transfer_buffer);
  602 + usb_free_urb(urbs[i]);
  603 + }
  604 +
  605 + kfree(urbs);
  606 +}
  607 +
  608 +int __devinit snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
  609 +{
  610 + int i, ret;
  611 +
  612 + dev->n_audio_in = max(dev->spec.num_analog_audio_in,
  613 + dev->spec.num_digital_audio_in) /
  614 + CHANNELS_PER_STREAM;
  615 + dev->n_audio_out = max(dev->spec.num_analog_audio_out,
  616 + dev->spec.num_digital_audio_out) /
  617 + CHANNELS_PER_STREAM;
  618 + dev->n_streams = max(dev->n_audio_in, dev->n_audio_out);
  619 +
  620 + debug("dev->n_audio_in = %d\n", dev->n_audio_in);
  621 + debug("dev->n_audio_out = %d\n", dev->n_audio_out);
  622 + debug("dev->n_streams = %d\n", dev->n_streams);
  623 +
  624 + if (dev->n_streams > MAX_STREAMS) {
  625 + log("unable to initialize device, too many streams.\n");
  626 + return -EINVAL;
  627 + }
  628 +
  629 + ret = snd_pcm_new(dev->chip.card, dev->product_name, 0,
  630 + dev->n_audio_out, dev->n_audio_in, &dev->pcm);
  631 +
  632 + if (ret < 0) {
  633 + log("snd_pcm_new() returned %d\n", ret);
  634 + return ret;
  635 + }
  636 +
  637 + dev->pcm->private_data = dev;
  638 + strcpy(dev->pcm->name, dev->product_name);
  639 +
  640 + memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
  641 + memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
  642 +
  643 + memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware,
  644 + sizeof(snd_usb_caiaq_pcm_hardware));
  645 +
  646 + /* setup samplerates */
  647 + dev->samplerates = dev->pcm_info.rates;
  648 + switch (dev->chip.usb_id) {
  649 + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
  650 + dev->samplerates |= SNDRV_PCM_RATE_88200;
  651 + dev->samplerates |= SNDRV_PCM_RATE_192000;
  652 + break;
  653 + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
  654 + dev->samplerates |= SNDRV_PCM_RATE_88200;
  655 + break;
  656 + }
  657 +
  658 + snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
  659 + &snd_usb_caiaq_ops);
  660 + snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
  661 + &snd_usb_caiaq_ops);
  662 +
  663 + snd_pcm_lib_preallocate_pages_for_all(dev->pcm,
  664 + SNDRV_DMA_TYPE_CONTINUOUS,
  665 + snd_dma_continuous_data(GFP_KERNEL),
  666 + MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
  667 +
  668 + dev->data_cb_info =
  669 + kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS,
  670 + GFP_KERNEL);
  671 +
  672 + if (!dev->data_cb_info)
  673 + return -ENOMEM;
  674 +
  675 + for (i = 0; i < N_URBS; i++) {
  676 + dev->data_cb_info[i].dev = dev;
  677 + dev->data_cb_info[i].index = i;
  678 + }
  679 +
  680 + dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret);
  681 + if (ret < 0) {
  682 + kfree(dev->data_cb_info);
  683 + free_urbs(dev->data_urbs_in);
  684 + return ret;
  685 + }
  686 +
  687 + dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret);
  688 + if (ret < 0) {
  689 + kfree(dev->data_cb_info);
  690 + free_urbs(dev->data_urbs_in);
  691 + free_urbs(dev->data_urbs_out);
  692 + return ret;
  693 + }
  694 +
  695 + return 0;
  696 +}
  697 +
  698 +void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev)
  699 +{
  700 + debug("snd_usb_caiaq_audio_free (%p)\n", dev);
  701 + stream_stop(dev);
  702 + free_urbs(dev->data_urbs_in);
  703 + free_urbs(dev->data_urbs_out);
  704 + kfree(dev->data_cb_info);
  705 +}
sound/usb/caiaq/caiaq-audio.h
  1 +#ifndef CAIAQ_AUDIO_H
  2 +#define CAIAQ_AUDIO_H
  3 +
  4 +int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev);
  5 +void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev);
  6 +
  7 +#endif /* CAIAQ_AUDIO_H */
sound/usb/caiaq/caiaq-device.c
  1 +/*
  2 + * caiaq.c: ALSA driver for caiaq/NativeInstruments devices
  3 + *
  4 + * Copyright (c) 2007 Daniel Mack <daniel@caiaq.de>
  5 + * Karsten Wiese <fzu@wemgehoertderstaat.de>
  6 + *
  7 + * This program is free software; you can redistribute it and/or modify
  8 + * it under the terms of the GNU General Public License as published by
  9 + * the Free Software Foundation; either version 2 of the License, or
  10 + * (at your option) any later version.
  11 + *
  12 + * This program is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + * GNU General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU General Public License
  18 + * along with this program; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20 +*/
  21 +
  22 +#include <linux/init.h>
  23 +#include <linux/module.h>
  24 +#include <linux/moduleparam.h>
  25 +#include <linux/interrupt.h>
  26 +#include <linux/usb.h>
  27 +#include <linux/input.h>
  28 +#include <linux/spinlock.h>
  29 +#include <sound/driver.h>
  30 +#include <sound/core.h>
  31 +#include <sound/initval.h>
  32 +#include <sound/pcm.h>
  33 +#include <sound/rawmidi.h>
  34 +
  35 +#include "caiaq-device.h"
  36 +#include "caiaq-audio.h"
  37 +#include "caiaq-midi.h"
  38 +
  39 +#ifdef CONFIG_SND_USB_CAIAQ_INPUT
  40 +#include "caiaq-input.h"
  41 +#endif
  42 +
  43 +MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
  44 +MODULE_DESCRIPTION("caiaq USB audio, version 1.1.0");
  45 +MODULE_LICENSE("GPL");
  46 +MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
  47 + "{Native Instruments, Kore Controller},"
  48 + "{Native Instruments, Audio Kontrol 1}"
  49 + "{Native Instruments, Audio 8 DJ}}");
  50 +
  51 +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
  52 +static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
  53 +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
  54 +static int snd_card_used[SNDRV_CARDS];
  55 +
  56 +module_param_array(index, int, NULL, 0444);
  57 +MODULE_PARM_DESC(index, "Index value for the caiaq sound device");
  58 +module_param_array(id, charp, NULL, 0444);
  59 +MODULE_PARM_DESC(id, "ID string for the caiaq soundcard.");
  60 +module_param_array(enable, bool, NULL, 0444);
  61 +MODULE_PARM_DESC(enable, "Enable the caiaq soundcard.");
  62 +
  63 +enum {
  64 + SAMPLERATE_44100 = 0,
  65 + SAMPLERATE_48000 = 1,
  66 + SAMPLERATE_96000 = 2,
  67 + SAMPLERATE_192000 = 3,
  68 + SAMPLERATE_88200 = 4,
  69 + SAMPLERATE_INVALID = 0xff
  70 +};
  71 +
  72 +enum {
  73 + DEPTH_NONE = 0,
  74 + DEPTH_16 = 1,
  75 + DEPTH_24 = 2,
  76 + DEPTH_32 = 3
  77 +};
  78 +
  79 +static struct usb_device_id snd_usb_id_table[] = {
  80 + {
  81 + .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
  82 + .idVendor = USB_VID_NATIVEINSTRUMENTS,
  83 + .idProduct = USB_PID_RIGKONTROL2
  84 + },
  85 + {
  86 + .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
  87 + .idVendor = USB_VID_NATIVEINSTRUMENTS,
  88 + .idProduct = USB_PID_KORECONTROLLER
  89 + },
  90 + {
  91 + .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
  92 + .idVendor = USB_VID_NATIVEINSTRUMENTS,
  93 + .idProduct = USB_PID_AK1
  94 + },
  95 + {
  96 + .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
  97 + .idVendor = USB_VID_NATIVEINSTRUMENTS,
  98 + .idProduct = USB_PID_AUDIO8DJ
  99 + },
  100 + { /* terminator */ }
  101 +};
  102 +
  103 +static void usb_ep1_command_reply_dispatch (struct urb* urb)
  104 +{
  105 + int ret;
  106 + struct snd_usb_caiaqdev *dev = urb->context;
  107 + unsigned char *buf = urb->transfer_buffer;
  108 +
  109 + if (urb->status || !dev) {
  110 + log("received EP1 urb->status = %i\n", urb->status);
  111 + return;
  112 + }
  113 +
  114 + switch(buf[0]) {
  115 + case EP1_CMD_GET_DEVICE_INFO:
  116 + memcpy(&dev->spec, buf+1, sizeof(struct caiaq_device_spec));
  117 + dev->spec.fw_version = le16_to_cpu(dev->spec.fw_version);
  118 + debug("device spec (firmware %d): audio: %d in, %d out, "
  119 + "MIDI: %d in, %d out, data alignment %d\n",
  120 + dev->spec.fw_version,
  121 + dev->spec.num_analog_audio_in,
  122 + dev->spec.num_analog_audio_out,
  123 + dev->spec.num_midi_in,
  124 + dev->spec.num_midi_out,
  125 + dev->spec.data_alignment);
  126 +
  127 + dev->spec_received++;
  128 + wake_up(&dev->ep1_wait_queue);
  129 + break;
  130 + case EP1_CMD_AUDIO_PARAMS:
  131 + dev->audio_parm_answer = buf[1];
  132 + wake_up(&dev->ep1_wait_queue);
  133 + break;
  134 + case EP1_CMD_MIDI_READ:
  135 + snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]);
  136 + break;
  137 +
  138 +#ifdef CONFIG_SND_USB_CAIAQ_INPUT
  139 + case EP1_CMD_READ_ERP:
  140 + case EP1_CMD_READ_ANALOG:
  141 + case EP1_CMD_READ_IO:
  142 + snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length);
  143 + break;
  144 +#endif
  145 + }
  146 +
  147 + dev->ep1_in_urb.actual_length = 0;
  148 + ret = usb_submit_urb(&dev->ep1_in_urb, GFP_ATOMIC);
  149 + if (ret < 0)
  150 + log("unable to submit urb. OOM!?\n");
  151 +}
  152 +
  153 +static int send_command (struct snd_usb_caiaqdev *dev,
  154 + unsigned char command,
  155 + const unsigned char *buffer,
  156 + int len)
  157 +{
  158 + int actual_len;
  159 + struct usb_device *usb_dev = dev->chip.dev;
  160 +
  161 + if (!usb_dev)
  162 + return -EIO;
  163 +
  164 + if (len > EP1_BUFSIZE - 1)
  165 + len = EP1_BUFSIZE - 1;
  166 +
  167 + if (buffer && len > 0)
  168 + memcpy(dev->ep1_out_buf+1, buffer, len);
  169 +
  170 + dev->ep1_out_buf[0] = command;
  171 + return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1),
  172 + dev->ep1_out_buf, len+1, &actual_len, 200);
  173 +}
  174 +
  175 +int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev,
  176 + int rate, int depth, int bpp)
  177 +{
  178 + int ret;
  179 + char tmp[5];
  180 +
  181 + switch (rate) {
  182 + case 44100: tmp[0] = SAMPLERATE_44100; break;
  183 + case 48000: tmp[0] = SAMPLERATE_48000; break;
  184 + case 88200: tmp[0] = SAMPLERATE_88200; break;
  185 + case 96000: tmp[0] = SAMPLERATE_96000; break;
  186 + case 192000: tmp[0] = SAMPLERATE_192000; break;
  187 + default: return -EINVAL;
  188 + }
  189 +
  190 + switch (depth) {
  191 + case 16: tmp[1] = DEPTH_16; break;
  192 + case 24: tmp[1] = DEPTH_24; break;
  193 + default: return -EINVAL;
  194 + }
  195 +
  196 + tmp[2] = bpp & 0xff;
  197 + tmp[3] = bpp >> 8;
  198 + tmp[4] = 1; /* packets per microframe */
  199 +
  200 + debug("setting audio params: %d Hz, %d bits, %d bpp\n",
  201 + rate, depth, bpp);
  202 +
  203 + dev->audio_parm_answer = -1;
  204 + ret = send_command(dev, EP1_CMD_AUDIO_PARAMS, tmp, sizeof(tmp));
  205 +
  206 + if (ret)
  207 + return ret;
  208 +
  209 + if (!wait_event_timeout(dev->ep1_wait_queue,
  210 + dev->audio_parm_answer >= 0, HZ))
  211 + return -EPIPE;
  212 +
  213 + if (dev->audio_parm_answer != 1)
  214 + debug("unable to set the device's audio params\n");
  215 +
  216 + return dev->audio_parm_answer == 1 ? 0 : -EINVAL;
  217 +}
  218 +
  219 +int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev,
  220 + int digital, int analog, int erp)
  221 +{
  222 + char tmp[3] = { digital, analog, erp };
  223 + return send_command(dev, EP1_CMD_AUTO_MSG, tmp, sizeof(tmp));
  224 +}
  225 +
  226 +static void setup_card(struct snd_usb_caiaqdev *dev)
  227 +{
  228 + int ret;
  229 + char val[3];
  230 +
  231 + /* device-specific startup specials */
  232 + switch (dev->chip.usb_id) {
  233 + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
  234 + /* RigKontrol2 - display centered dash ('-') */
  235 + val[0] = 0x00;
  236 + val[1] = 0x00;
  237 + val[2] = 0x01;
  238 + send_command(dev, EP1_CMD_WRITE_IO, val, 3);
  239 + break;
  240 + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
  241 + /* Audio Kontrol 1 - make USB-LED stop blinking */
  242 + val[0] = 0x00;
  243 + send_command(dev, EP1_CMD_WRITE_IO, val, 1);
  244 + break;
  245 + }
  246 +
  247 + ret = snd_usb_caiaq_audio_init(dev);
  248 + if (ret < 0)
  249 + log("Unable to set up audio system (ret=%d)\n", ret);
  250 +
  251 + ret = snd_usb_caiaq_midi_init(dev);
  252 + if (ret < 0)
  253 + log("Unable to set up MIDI system (ret=%d)\n", ret);
  254 +
  255 +#ifdef CONFIG_SND_USB_CAIAQ_INPUT
  256 + ret = snd_usb_caiaq_input_init(dev);
  257 + if (ret < 0)
  258 + log("Unable to set up input system (ret=%d)\n", ret);
  259 +#endif
  260 +
  261 + /* finally, register the card and all its sub-instances */
  262 + ret = snd_card_register(dev->chip.card);
  263 + if (ret < 0) {
  264 + log("snd_card_register() returned %d\n", ret);
  265 + snd_card_free(dev->chip.card);
  266 + }
  267 +}
  268 +
  269 +static struct snd_card* create_card(struct usb_device* usb_dev)
  270 +{
  271 + int devnum;
  272 + struct snd_card *card;
  273 + struct snd_usb_caiaqdev *dev;
  274 +
  275 + for (devnum = 0; devnum < SNDRV_CARDS; devnum++)
  276 + if (enable[devnum] && !snd_card_used[devnum])
  277 + break;
  278 +
  279 + if (devnum >= SNDRV_CARDS)
  280 + return NULL;
  281 +
  282 + card = snd_card_new(index[devnum], id[devnum], THIS_MODULE,
  283 + sizeof(struct snd_usb_caiaqdev));
  284 + if (!card)
  285 + return NULL;
  286 +
  287 + dev = caiaqdev(card);
  288 + dev->chip.dev = usb_dev;
  289 + dev->chip.card = card;
  290 + dev->chip.usb_id = USB_ID(usb_dev->descriptor.idVendor,
  291 + usb_dev->descriptor.idProduct);
  292 + spin_lock_init(&dev->spinlock);
  293 + snd_card_set_dev(card, &usb_dev->dev);
  294 +
  295 + return card;
  296 +}
  297 +
  298 +static int init_card(struct snd_usb_caiaqdev *dev)
  299 +{
  300 + char *c;
  301 + struct usb_device *usb_dev = dev->chip.dev;
  302 + struct snd_card *card = dev->chip.card;
  303 + int err, len;
  304 +
  305 + if (usb_set_interface(usb_dev, 0, 1) != 0) {
  306 + log("can't set alt interface.\n");
  307 + return -EIO;
  308 + }
  309 +
  310 + usb_init_urb(&dev->ep1_in_urb);
  311 + usb_init_urb(&dev->midi_out_urb);
  312 +
  313 + usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev,
  314 + usb_rcvbulkpipe(usb_dev, 0x1),
  315 + dev->ep1_in_buf, EP1_BUFSIZE,
  316 + usb_ep1_command_reply_dispatch, dev);
  317 +
  318 + usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev,
  319 + usb_sndbulkpipe(usb_dev, 0x1),
  320 + dev->midi_out_buf, EP1_BUFSIZE,
  321 + snd_usb_caiaq_midi_output_done, dev);
  322 +
  323 + init_waitqueue_head(&dev->ep1_wait_queue);
  324 + init_waitqueue_head(&dev->prepare_wait_queue);
  325 +
  326 + if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0)
  327 + return -EIO;
  328 +
  329 + err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
  330 + if (err)
  331 + return err;
  332 +
  333 + if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ))
  334 + return -ENODEV;
  335 +
  336 + usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
  337 + dev->vendor_name, CAIAQ_USB_STR_LEN);
  338 +
  339 + usb_string(usb_dev, usb_dev->descriptor.iProduct,
  340 + dev->product_name, CAIAQ_USB_STR_LEN);
  341 +
  342 + usb_string(usb_dev, usb_dev->descriptor.iSerialNumber,
  343 + dev->serial, CAIAQ_USB_STR_LEN);
  344 +
  345 + /* terminate serial string at first white space occurence */
  346 + c = strchr(dev->serial, ' ');
  347 + if (c)
  348 + *c = '\0';
  349 +
  350 + strcpy(card->driver, MODNAME);
  351 + strcpy(card->shortname, dev->product_name);
  352 +
  353 + len = snprintf(card->longname, sizeof(card->longname),
  354 + "%s %s (serial %s, ",
  355 + dev->vendor_name, dev->product_name, dev->serial);
  356 +
  357 + if (len < sizeof(card->longname) - 2)
  358 + len += usb_make_path(usb_dev, card->longname + len,
  359 + sizeof(card->longname) - len);
  360 +
  361 + card->longname[len++] = ')';
  362 + card->longname[len] = '\0';
  363 + setup_card(dev);
  364 + return 0;
  365 +}
  366 +
  367 +static int snd_probe(struct usb_interface *intf,
  368 + const struct usb_device_id *id)
  369 +{
  370 + int ret;
  371 + struct snd_card *card;
  372 + struct usb_device *device = interface_to_usbdev(intf);
  373 +
  374 + card = create_card(device);
  375 +
  376 + if (!card)
  377 + return -ENOMEM;
  378 +
  379 + dev_set_drvdata(&intf->dev, card);
  380 + ret = init_card(caiaqdev(card));
  381 + if (ret < 0) {
  382 + log("unable to init card! (ret=%d)\n", ret);
  383 + snd_card_free(card);
  384 + return ret;
  385 + }
  386 +
  387 + return 0;
  388 +}
  389 +
  390 +static void snd_disconnect(struct usb_interface *intf)
  391 +{
  392 + struct snd_usb_caiaqdev *dev;
  393 + struct snd_card *card = dev_get_drvdata(&intf->dev);
  394 +
  395 + debug("snd_disconnect(%p)\n", intf);
  396 +
  397 + if (!card)
  398 + return;
  399 +
  400 + dev = caiaqdev(card);
  401 + snd_card_disconnect(card);
  402 +
  403 +#ifdef CONFIG_SND_USB_CAIAQ_INPUT
  404 + snd_usb_caiaq_input_free(dev);
  405 +#endif
  406 + snd_usb_caiaq_audio_free(dev);
  407 +
  408 + usb_kill_urb(&dev->ep1_in_urb);
  409 + usb_kill_urb(&dev->midi_out_urb);
  410 +
  411 + snd_card_free(card);
  412 + usb_reset_device(interface_to_usbdev(intf));
  413 +}
  414 +
  415 +
  416 +MODULE_DEVICE_TABLE(usb, snd_usb_id_table);
  417 +static struct usb_driver snd_usb_driver = {
  418 + .name = MODNAME,
  419 + .probe = snd_probe,
  420 + .disconnect = snd_disconnect,
  421 + .id_table = snd_usb_id_table,
  422 +};
  423 +
  424 +static int __init snd_module_init(void)
  425 +{
  426 + return usb_register(&snd_usb_driver);
  427 +}
  428 +
  429 +static void __exit snd_module_exit(void)
  430 +{
  431 + usb_deregister(&snd_usb_driver);
  432 +}
  433 +
  434 +module_init(snd_module_init)
  435 +module_exit(snd_module_exit)
sound/usb/caiaq/caiaq-device.h
  1 +#ifndef CAIAQ_DEVICE_H
  2 +#define CAIAQ_DEVICE_H
  3 +
  4 +#include "../usbaudio.h"
  5 +
  6 +#define USB_VID_NATIVEINSTRUMENTS 0x17cc
  7 +
  8 +#define USB_PID_RIGKONTROL2 0x1969
  9 +#define USB_PID_KORECONTROLLER 0x4711
  10 +#define USB_PID_AK1 0x0815
  11 +#define USB_PID_AUDIO8DJ 0x1978
  12 +
  13 +#define EP1_BUFSIZE 64
  14 +#define CAIAQ_USB_STR_LEN 0xff
  15 +#define MAX_STREAMS 32
  16 +
  17 +//#define SND_USB_CAIAQ_DEBUG
  18 +
  19 +#define MODNAME "snd-usb-caiaq"
  20 +#define log(x...) snd_printk(KERN_WARNING MODNAME" log: " x)
  21 +
  22 +#ifdef SND_USB_CAIAQ_DEBUG
  23 +#define debug(x...) snd_printk(KERN_WARNING MODNAME " debug: " x)
  24 +#else
  25 +#define debug(x...) do { } while(0)
  26 +#endif
  27 +
  28 +#define EP1_CMD_GET_DEVICE_INFO 0x1
  29 +#define EP1_CMD_READ_ERP 0x2
  30 +#define EP1_CMD_READ_ANALOG 0x3
  31 +#define EP1_CMD_READ_IO 0x4
  32 +#define EP1_CMD_WRITE_IO 0x5
  33 +#define EP1_CMD_MIDI_READ 0x6
  34 +#define EP1_CMD_MIDI_WRITE 0x7
  35 +#define EP1_CMD_AUDIO_PARAMS 0x9
  36 +#define EP1_CMD_AUTO_MSG 0xb
  37 +
  38 +struct caiaq_device_spec {
  39 + unsigned short fw_version;
  40 + unsigned char hw_subtype;
  41 + unsigned char num_erp;
  42 + unsigned char num_analog_in;
  43 + unsigned char num_digital_in;
  44 + unsigned char num_digital_out;
  45 + unsigned char num_analog_audio_out;
  46 + unsigned char num_analog_audio_in;
  47 + unsigned char num_digital_audio_out;
  48 + unsigned char num_digital_audio_in;
  49 + unsigned char num_midi_out;
  50 + unsigned char num_midi_in;
  51 + unsigned char data_alignment;
  52 +} __attribute__ ((packed));
  53 +
  54 +struct snd_usb_caiaq_cb_info;
  55 +
  56 +struct snd_usb_caiaqdev {
  57 + struct snd_usb_audio chip;
  58 +
  59 + struct urb ep1_in_urb;
  60 + struct urb midi_out_urb;
  61 + struct urb **data_urbs_in;
  62 + struct urb **data_urbs_out;
  63 + struct snd_usb_caiaq_cb_info *data_cb_info;
  64 +
  65 + unsigned char ep1_in_buf[EP1_BUFSIZE];
  66 + unsigned char ep1_out_buf[EP1_BUFSIZE];
  67 + unsigned char midi_out_buf[EP1_BUFSIZE];
  68 +
  69 + struct caiaq_device_spec spec;
  70 + spinlock_t spinlock;
  71 + wait_queue_head_t ep1_wait_queue;
  72 + wait_queue_head_t prepare_wait_queue;
  73 + int spec_received, audio_parm_answer;
  74 +
  75 + char vendor_name[CAIAQ_USB_STR_LEN];
  76 + char product_name[CAIAQ_USB_STR_LEN];
  77 + char serial[CAIAQ_USB_STR_LEN];
  78 +
  79 + int n_streams, n_audio_in, n_audio_out;
  80 + int streaming, first_packet, output_running;
  81 + int audio_in_buf_pos[MAX_STREAMS];
  82 + int audio_out_buf_pos[MAX_STREAMS];
  83 + int period_in_count[MAX_STREAMS];
  84 + int period_out_count[MAX_STREAMS];
  85 + int input_panic, output_panic;
  86 + char *audio_in_buf, *audio_out_buf;
  87 + unsigned int samplerates;
  88 +
  89 + struct snd_pcm_substream *sub_playback[MAX_STREAMS];
  90 + struct snd_pcm_substream *sub_capture[MAX_STREAMS];
  91 +
  92 + /* Linux input */
  93 +#ifdef CONFIG_SND_USB_CAIAQ_INPUT
  94 + struct input_dev *input_dev;
  95 +#endif
  96 +
  97 + /* ALSA */
  98 + struct snd_pcm *pcm;
  99 + struct snd_pcm_hardware pcm_info;
  100 + struct snd_rawmidi *rmidi;
  101 + struct snd_rawmidi_substream *midi_receive_substream;
  102 + struct snd_rawmidi_substream *midi_out_substream;
  103 +};
  104 +
  105 +struct snd_usb_caiaq_cb_info {
  106 + struct snd_usb_caiaqdev *dev;
  107 + int index;
  108 +};
  109 +
  110 +#define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data)
  111 +
  112 +int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp);
  113 +int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp);
  114 +
  115 +
  116 +#endif /* CAIAQ_DEVICE_H */
sound/usb/caiaq/caiaq-input.c
  1 +/*
  2 + * Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz
  3 + *
  4 + * This program is free software; you can redistribute it and/or modify
  5 + * it under the terms of the GNU General Public License as published by
  6 + * the Free Software Foundation; either version 2 of the License, or
  7 + * (at your option) any later version.
  8 + *
  9 + * This program is distributed in the hope that it will be useful,
  10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 + * GNU General Public License for more details.
  13 + *
  14 + * You should have received a copy of the GNU General Public License
  15 + * along with this program; if not, write to the Free Software
  16 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17 +*/
  18 +
  19 +#include <linux/init.h>
  20 +#include <linux/module.h>
  21 +#include <linux/moduleparam.h>
  22 +#include <linux/input.h>
  23 +#include <linux/usb.h>
  24 +#include <linux/spinlock.h>
  25 +#include <sound/driver.h>
  26 +#include <sound/core.h>
  27 +#include <sound/rawmidi.h>
  28 +#include <sound/pcm.h>
  29 +#include "caiaq-device.h"
  30 +#include "caiaq-input.h"
  31 +
  32 +#ifdef CONFIG_SND_USB_CAIAQ_INPUT
  33 +
  34 +static unsigned char keycode_ak1[] = { KEY_C, KEY_B, KEY_A };
  35 +static unsigned char keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4,
  36 + KEY_5, KEY_6, KEY_7 };
  37 +
  38 +#define DEG90 (range/2)
  39 +#define DEG180 (range)
  40 +#define DEG270 (DEG90 + DEG180)
  41 +#define DEG360 (DEG180 * 2)
  42 +#define HIGH_PEAK (268)
  43 +#define LOW_PEAK (-7)
  44 +
  45 +/* some of these devices have endless rotation potentiometers
  46 + * built in which use two tapers, 90 degrees phase shifted.
  47 + * this algorithm decodes them to one single value, ranging
  48 + * from 0 to 999 */
  49 +static unsigned int decode_erp(unsigned char a, unsigned char b)
  50 +{
  51 + int weight_a, weight_b;
  52 + int pos_a, pos_b;
  53 + int ret;
  54 + int range = HIGH_PEAK - LOW_PEAK;
  55 + int mid_value = (HIGH_PEAK + LOW_PEAK) / 2;
  56 +
  57 + weight_b = abs(mid_value-a) - (range/2 - 100)/2;
  58 +
  59 + if (weight_b < 0)
  60 + weight_b = 0;
  61 +
  62 + if (weight_b > 100)
  63 + weight_b = 100;
  64 +
  65 + weight_a = 100 - weight_b;
  66 +
  67 + if (a < mid_value) {
  68 + /* 0..90 and 270..360 degrees */
  69 + pos_b = b - LOW_PEAK + DEG270;
  70 + if (pos_b >= DEG360)
  71 + pos_b -= DEG360;
  72 + } else
  73 + /* 90..270 degrees */
  74 + pos_b = HIGH_PEAK - b + DEG90;
  75 +
  76 +
  77 + if (b > mid_value)
  78 + /* 0..180 degrees */
  79 + pos_a = a - LOW_PEAK;
  80 + else
  81 + /* 180..360 degrees */
  82 + pos_a = HIGH_PEAK - a + DEG180;
  83 +
  84 + /* interpolate both slider values, depending on weight factors */
  85 + /* 0..99 x DEG360 */
  86 + ret = pos_a * weight_a + pos_b * weight_b;
  87 +
  88 + /* normalize to 0..999 */
  89 + ret *= 10;
  90 + ret /= DEG360;
  91 +
  92 + if (ret < 0)
  93 + ret += 1000;
  94 +
  95 + if (ret >= 1000)
  96 + ret -= 1000;
  97 +
  98 + return ret;
  99 +}
  100 +
  101 +#undef DEG90
  102 +#undef DEG180
  103 +#undef DEG270
  104 +#undef DEG360
  105 +#undef HIGH_PEAK
  106 +#undef LOW_PEAK
  107 +
  108 +
  109 +static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
  110 + const char *buf, unsigned int len)
  111 +{
  112 + switch(dev->input_dev->id.product) {
  113 + case USB_PID_RIGKONTROL2:
  114 + input_report_abs(dev->input_dev, ABS_X, (buf[4] << 8) |buf[5]);
  115 + input_report_abs(dev->input_dev, ABS_Y, (buf[0] << 8) |buf[1]);
  116 + input_report_abs(dev->input_dev, ABS_Z, (buf[2] << 8) |buf[3]);
  117 + input_sync(dev->input_dev);
  118 + break;
  119 + }
  120 +}
  121 +
  122 +static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
  123 + const char *buf, unsigned int len)
  124 +{
  125 + int i;
  126 +
  127 + switch(dev->input_dev->id.product) {
  128 + case USB_PID_AK1:
  129 + i = decode_erp(buf[0], buf[1]);
  130 + input_report_abs(dev->input_dev, ABS_X, i);
  131 + input_sync(dev->input_dev);
  132 + break;
  133 + }
  134 +}
  135 +
  136 +static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
  137 + char *buf, unsigned int len)
  138 +{
  139 + int i;
  140 + unsigned char *keycode = dev->input_dev->keycode;
  141 +
  142 + if (!keycode)
  143 + return;
  144 +
  145 + if (dev->input_dev->id.product == USB_PID_RIGKONTROL2)
  146 + for (i=0; i<len; i++)
  147 + buf[i] = ~buf[i];
  148 +
  149 + for (i=0; (i<dev->input_dev->keycodemax) && (i < len); i++)
  150 + input_report_key(dev->input_dev, keycode[i],
  151 + buf[i/8] & (1 << (i%8)));
  152 +
  153 + input_sync(dev->input_dev);
  154 +}
  155 +
  156 +void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev,
  157 + char *buf,
  158 + unsigned int len)
  159 +{
  160 + if (!dev->input_dev || (len < 1))
  161 + return;
  162 +
  163 + switch (buf[0]) {
  164 + case EP1_CMD_READ_ANALOG:
  165 + snd_caiaq_input_read_analog(dev, buf+1, len-1);
  166 + break;
  167 + case EP1_CMD_READ_ERP:
  168 + snd_caiaq_input_read_erp(dev, buf+1, len-1);
  169 + break;
  170 + case EP1_CMD_READ_IO:
  171 + snd_caiaq_input_read_io(dev, buf+1, len-1);
  172 + break;
  173 + }
  174 +}
  175 +
  176 +int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
  177 +{
  178 + struct usb_device *usb_dev = dev->chip.dev;
  179 + struct input_dev *input;
  180 + int i, ret;
  181 +
  182 + input = input_allocate_device();
  183 + if (!input)
  184 + return -ENOMEM;
  185 +
  186 + input->name = dev->product_name;
  187 + input->id.bustype = BUS_USB;
  188 + input->id.vendor = usb_dev->descriptor.idVendor;
  189 + input->id.product = usb_dev->descriptor.idProduct;
  190 + input->id.version = usb_dev->descriptor.bcdDevice;
  191 +
  192 + switch (dev->chip.usb_id) {
  193 + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
  194 + input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
  195 + input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);
  196 + input->keycode = keycode_rk2;
  197 + input->keycodesize = sizeof(char);
  198 + input->keycodemax = ARRAY_SIZE(keycode_rk2);
  199 + for (i=0; i<ARRAY_SIZE(keycode_rk2); i++)
  200 + set_bit(keycode_rk2[i], input->keybit);
  201 +
  202 + input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
  203 + input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
  204 + input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
  205 + snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
  206 + break;
  207 + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
  208 + input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
  209 + input->absbit[0] = BIT(ABS_X);
  210 + input->keycode = keycode_ak1;
  211 + input->keycodesize = sizeof(char);
  212 + input->keycodemax = ARRAY_SIZE(keycode_ak1);
  213 + for (i=0; i<ARRAY_SIZE(keycode_ak1); i++)
  214 + set_bit(keycode_ak1[i], input->keybit);
  215 +
  216 + input_set_abs_params(input, ABS_X, 0, 999, 0, 10);
  217 + snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5);
  218 + break;
  219 + default:
  220 + /* no input methods supported on this device */
  221 + input_free_device(input);
  222 + return 0;
  223 + }
  224 +
  225 + ret = input_register_device(input);
  226 + if (ret < 0) {
  227 + input_free_device(input);
  228 + return ret;
  229 + }
  230 +
  231 + dev->input_dev = input;
  232 + return 0;
  233 +}
  234 +
  235 +void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
  236 +{
  237 + if (!dev || !dev->input_dev)
  238 + return;
  239 +
  240 + input_unregister_device(dev->input_dev);
  241 + input_free_device(dev->input_dev);
  242 + dev->input_dev = NULL;
  243 +}
  244 +
  245 +#endif /* CONFIG_SND_USB_CAIAQ_INPUT */
sound/usb/caiaq/caiaq-input.h
  1 +#ifndef CAIAQ_INPUT_H
  2 +#define CAIAQ_INPUT_H
  3 +
  4 +void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len);
  5 +int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev);
  6 +void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev);
  7 +
  8 +#endif
sound/usb/caiaq/caiaq-midi.c
  1 +/*
  2 + * Copyright (c) 2006,2007 Daniel Mack
  3 + *
  4 + * This program is free software; you can redistribute it and/or modify
  5 + * it under the terms of the GNU General Public License as published by
  6 + * the Free Software Foundation; either version 2 of the License, or
  7 + * (at your option) any later version.
  8 + *
  9 + * This program is distributed in the hope that it will be useful,
  10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 + * GNU General Public License for more details.
  13 + *
  14 + * You should have received a copy of the GNU General Public License
  15 + * along with this program; if not, write to the Free Software
  16 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17 +*/
  18 +
  19 +#include <linux/init.h>
  20 +#include <linux/module.h>
  21 +#include <linux/moduleparam.h>
  22 +#include <linux/interrupt.h>
  23 +#include <linux/usb.h>
  24 +#include <linux/input.h>
  25 +#include <linux/spinlock.h>
  26 +#include <sound/driver.h>
  27 +#include <sound/core.h>
  28 +#include <sound/rawmidi.h>
  29 +#include <sound/pcm.h>
  30 +
  31 +#include "caiaq-device.h"
  32 +#include "caiaq-midi.h"
  33 +
  34 +
  35 +static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream)
  36 +{
  37 + return 0;
  38 +}
  39 +
  40 +static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream)
  41 +{
  42 + return 0;
  43 +}
  44 +
  45 +static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
  46 +{
  47 + struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
  48 +
  49 + if (!dev)
  50 + return;
  51 +
  52 + dev->midi_receive_substream = up ? substream : NULL;
  53 +}
  54 +
  55 +
  56 +static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream)
  57 +{
  58 + return 0;
  59 +}
  60 +
  61 +static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream)
  62 +{
  63 + return 0;
  64 +}
  65 +
  66 +static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
  67 + struct snd_rawmidi_substream *substream)
  68 +{
  69 + int len, ret;
  70 +
  71 + dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
  72 + dev->midi_out_buf[1] = 0; /* port */
  73 + len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3);
  74 +
  75 + if (len <= 0)
  76 + return;
  77 +
  78 + dev->midi_out_buf[2] = len;
  79 + dev->midi_out_urb.transfer_buffer_length = len+3;
  80 +
  81 + ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC);
  82 + if (ret < 0)
  83 + log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n",
  84 + substream, ret);
  85 +}
  86 +
  87 +static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
  88 +{
  89 + struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
  90 +
  91 + if (dev->midi_out_substream != NULL)
  92 + return;
  93 +
  94 + if (!up) {
  95 + dev->midi_out_substream = NULL;
  96 + return;
  97 + }
  98 +
  99 + dev->midi_out_substream = substream;
  100 + snd_usb_caiaq_midi_send(dev, substream);
  101 +}
  102 +
  103 +
  104 +static struct snd_rawmidi_ops snd_usb_caiaq_midi_output =
  105 +{
  106 + .open = snd_usb_caiaq_midi_output_open,
  107 + .close = snd_usb_caiaq_midi_output_close,
  108 + .trigger = snd_usb_caiaq_midi_output_trigger,
  109 +};
  110 +
  111 +static struct snd_rawmidi_ops snd_usb_caiaq_midi_input =
  112 +{
  113 + .open = snd_usb_caiaq_midi_input_open,
  114 + .close = snd_usb_caiaq_midi_input_close,
  115 + .trigger = snd_usb_caiaq_midi_input_trigger,
  116 +};
  117 +
  118 +void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev,
  119 + int port, const char *buf, int len)
  120 +{
  121 + if (!dev->midi_receive_substream)
  122 + return;
  123 +
  124 + snd_rawmidi_receive(dev->midi_receive_substream, buf, len);
  125 +}
  126 +
  127 +int __devinit snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
  128 +{
  129 + int ret;
  130 + struct snd_rawmidi *rmidi;
  131 +
  132 + ret = snd_rawmidi_new(device->chip.card, device->product_name, 0,
  133 + device->spec.num_midi_out,
  134 + device->spec.num_midi_in,
  135 + &rmidi);
  136 +
  137 + if (ret < 0)
  138 + return ret;
  139 +
  140 + strcpy(rmidi->name, device->product_name);
  141 +
  142 + rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX;
  143 + rmidi->private_data = device;
  144 +
  145 + if (device->spec.num_midi_out > 0) {
  146 + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
  147 + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
  148 + &snd_usb_caiaq_midi_output);
  149 + }
  150 +
  151 + if (device->spec.num_midi_in > 0) {
  152 + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
  153 + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
  154 + &snd_usb_caiaq_midi_input);
  155 + }
  156 +
  157 + device->rmidi = rmidi;
  158 +
  159 + return 0;
  160 +}
  161 +
  162 +void snd_usb_caiaq_midi_output_done(struct urb* urb)
  163 +{
  164 + struct snd_usb_caiaqdev *dev = urb->context;
  165 + char *buf = urb->transfer_buffer;
  166 +
  167 + if (urb->status != 0)
  168 + return;
  169 +
  170 + if (!dev->midi_out_substream)
  171 + return;
  172 +
  173 + snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]);
  174 + dev->midi_out_substream = NULL;
  175 + snd_usb_caiaq_midi_send(dev, dev->midi_out_substream);
  176 +}
sound/usb/caiaq/caiaq-midi.h
  1 +#ifndef CAIAQ_MIDI_H
  2 +#define CAIAQ_MIDI_H
  3 +
  4 +int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev);
  5 +void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len);
  6 +void snd_usb_caiaq_midi_output_done(struct urb* urb);
  7 +
  8 +#endif /* CAIAQ_MIDI_H */