diff options
Diffstat (limited to 'sound/usb/caiaq/audio.c')
-rw-r--r-- | sound/usb/caiaq/audio.c | 462 |
1 files changed, 238 insertions, 224 deletions
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index fde9a7a29cb..c1916184e2e 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/device.h> #include <linux/spinlock.h> #include <linux/slab.h> #include <linux/init.h> @@ -39,8 +40,8 @@ #define ENDPOINT_CAPTURE 2 #define ENDPOINT_PLAYBACK 6 -#define MAKE_CHECKBYTE(dev,stream,i) \ - (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) +#define MAKE_CHECKBYTE(cdev,stream,i) \ + (stream << 1) | (~(i / (cdev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -60,32 +61,32 @@ static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { }; static void -activate_substream(struct snd_usb_caiaqdev *dev, +activate_substream(struct snd_usb_caiaqdev *cdev, struct snd_pcm_substream *sub) { - spin_lock(&dev->spinlock); + spin_lock(&cdev->spinlock); if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) - dev->sub_playback[sub->number] = sub; + cdev->sub_playback[sub->number] = sub; else - dev->sub_capture[sub->number] = sub; + cdev->sub_capture[sub->number] = sub; - spin_unlock(&dev->spinlock); + spin_unlock(&cdev->spinlock); } static void -deactivate_substream(struct snd_usb_caiaqdev *dev, +deactivate_substream(struct snd_usb_caiaqdev *cdev, struct snd_pcm_substream *sub) { unsigned long flags; - spin_lock_irqsave(&dev->spinlock, flags); + spin_lock_irqsave(&cdev->spinlock, flags); if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) - dev->sub_playback[sub->number] = NULL; + cdev->sub_playback[sub->number] = NULL; else - dev->sub_capture[sub->number] = NULL; + cdev->sub_capture[sub->number] = NULL; - spin_unlock_irqrestore(&dev->spinlock, flags); + spin_unlock_irqrestore(&cdev->spinlock, flags); } static int @@ -98,28 +99,30 @@ all_substreams_zero(struct snd_pcm_substream **subs) return 1; } -static int stream_start(struct snd_usb_caiaqdev *dev) +static int stream_start(struct snd_usb_caiaqdev *cdev) { int i, ret; + struct device *dev = caiaqdev_to_dev(cdev); - debug("%s(%p)\n", __func__, dev); + dev_dbg(dev, "%s(%p)\n", __func__, cdev); - if (dev->streaming) + if (cdev->streaming) return -EINVAL; - memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); - memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); - dev->input_panic = 0; - dev->output_panic = 0; - dev->first_packet = 4; - dev->streaming = 1; - dev->warned = 0; + memset(cdev->sub_playback, 0, sizeof(cdev->sub_playback)); + memset(cdev->sub_capture, 0, sizeof(cdev->sub_capture)); + cdev->input_panic = 0; + cdev->output_panic = 0; + cdev->first_packet = 4; + cdev->streaming = 1; + cdev->warned = 0; for (i = 0; i < N_URBS; i++) { - ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC); + ret = usb_submit_urb(cdev->data_urbs_in[i], GFP_ATOMIC); if (ret) { - log("unable to trigger read #%d! (ret %d)\n", i, ret); - dev->streaming = 0; + dev_err(dev, "unable to trigger read #%d! (ret %d)\n", + i, ret); + cdev->streaming = 0; return -EPIPE; } } @@ -127,46 +130,51 @@ static int stream_start(struct snd_usb_caiaqdev *dev) return 0; } -static void stream_stop(struct snd_usb_caiaqdev *dev) +static void stream_stop(struct snd_usb_caiaqdev *cdev) { int i; + struct device *dev = caiaqdev_to_dev(cdev); - debug("%s(%p)\n", __func__, dev); - if (!dev->streaming) + dev_dbg(dev, "%s(%p)\n", __func__, cdev); + if (!cdev->streaming) return; - dev->streaming = 0; + cdev->streaming = 0; for (i = 0; i < N_URBS; i++) { - usb_kill_urb(dev->data_urbs_in[i]); + usb_kill_urb(cdev->data_urbs_in[i]); - if (test_bit(i, &dev->outurb_active_mask)) - usb_kill_urb(dev->data_urbs_out[i]); + if (test_bit(i, &cdev->outurb_active_mask)) + usb_kill_urb(cdev->data_urbs_out[i]); } - dev->outurb_active_mask = 0; + cdev->outurb_active_mask = 0; } static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) { - struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); - debug("%s(%p)\n", __func__, substream); - substream->runtime->hw = dev->pcm_info; + struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream); + struct device *dev = caiaqdev_to_dev(cdev); + + dev_dbg(dev, "%s(%p)\n", __func__, substream); + substream->runtime->hw = cdev->pcm_info; snd_pcm_limit_hw_rates(substream->runtime); + return 0; } static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) { - struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); + struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream); + struct device *dev = caiaqdev_to_dev(cdev); - debug("%s(%p)\n", __func__, substream); - if (all_substreams_zero(dev->sub_playback) && - all_substreams_zero(dev->sub_capture)) { + dev_dbg(dev, "%s(%p)\n", __func__, substream); + if (all_substreams_zero(cdev->sub_playback) && + all_substreams_zero(cdev->sub_capture)) { /* when the last client has stopped streaming, * all sample rates are allowed again */ - stream_stop(dev); - dev->pcm_info.rates = dev->samplerates; + stream_stop(cdev); + cdev->pcm_info.rates = cdev->samplerates; } return 0; @@ -175,15 +183,13 @@ static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, struct snd_pcm_hw_params *hw_params) { - debug("%s(%p)\n", __func__, sub); return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); } static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub) { - struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); - debug("%s(%p)\n", __func__, sub); - deactivate_substream(dev, sub); + struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); + deactivate_substream(cdev, sub); return snd_pcm_lib_free_pages(sub); } @@ -199,15 +205,16 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) { int bytes_per_sample, bpp, ret, i; int index = substream->number; - struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); + struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; + struct device *dev = caiaqdev_to_dev(cdev); - debug("%s(%p)\n", __func__, substream); + dev_dbg(dev, "%s(%p)\n", __func__, substream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { int out_pos; - switch (dev->spec.data_alignment) { + switch (cdev->spec.data_alignment) { case 0: case 2: out_pos = BYTES_PER_SAMPLE + 1; @@ -218,12 +225,12 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) break; } - dev->period_out_count[index] = out_pos; - dev->audio_out_buf_pos[index] = out_pos; + cdev->period_out_count[index] = out_pos; + cdev->audio_out_buf_pos[index] = out_pos; } else { int in_pos; - switch (dev->spec.data_alignment) { + switch (cdev->spec.data_alignment) { case 0: in_pos = BYTES_PER_SAMPLE + 2; break; @@ -236,44 +243,44 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) break; } - dev->period_in_count[index] = in_pos; - dev->audio_in_buf_pos[index] = in_pos; + cdev->period_in_count[index] = in_pos; + cdev->audio_in_buf_pos[index] = in_pos; } - if (dev->streaming) + if (cdev->streaming) return 0; /* the first client that opens a stream defines the sample rate * setting for all subsequent calls, until the last client closed. */ for (i=0; i < ARRAY_SIZE(rates); i++) if (runtime->rate == rates[i]) - dev->pcm_info.rates = 1 << i; + cdev->pcm_info.rates = 1 << i; snd_pcm_limit_hw_rates(runtime); bytes_per_sample = BYTES_PER_SAMPLE; - if (dev->spec.data_alignment >= 2) + if (cdev->spec.data_alignment >= 2) bytes_per_sample++; bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) - * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams; + * bytes_per_sample * CHANNELS_PER_STREAM * cdev->n_streams; if (bpp > MAX_ENDPOINT_SIZE) bpp = MAX_ENDPOINT_SIZE; - ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate, + ret = snd_usb_caiaq_set_audio_params(cdev, runtime->rate, runtime->sample_bits, bpp); if (ret) return ret; - ret = stream_start(dev); + ret = stream_start(cdev); if (ret) return ret; - dev->output_running = 0; - wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ); - if (!dev->output_running) { - stream_stop(dev); + cdev->output_running = 0; + wait_event_timeout(cdev->prepare_wait_queue, cdev->output_running, HZ); + if (!cdev->output_running) { + stream_stop(cdev); return -EPIPE; } @@ -282,18 +289,19 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd) { - struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); + struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); + struct device *dev = caiaqdev_to_dev(cdev); - debug("%s(%p) cmd %d\n", __func__, sub, cmd); + dev_dbg(dev, "%s(%p) cmd %d\n", __func__, sub, cmd); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - activate_substream(dev, sub); + activate_substream(cdev, sub); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - deactivate_substream(dev, sub); + deactivate_substream(cdev, sub); break; default: return -EINVAL; @@ -306,25 +314,25 @@ static snd_pcm_uframes_t snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) { int index = sub->number; - struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); + struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); snd_pcm_uframes_t ptr; - spin_lock(&dev->spinlock); + spin_lock(&cdev->spinlock); - if (dev->input_panic || dev->output_panic) { + if (cdev->input_panic || cdev->output_panic) { ptr = SNDRV_PCM_POS_XRUN; goto unlock; } if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ptr = bytes_to_frames(sub->runtime, - dev->audio_out_buf_pos[index]); + cdev->audio_out_buf_pos[index]); else ptr = bytes_to_frames(sub->runtime, - dev->audio_in_buf_pos[index]); + cdev->audio_in_buf_pos[index]); unlock: - spin_unlock(&dev->spinlock); + spin_unlock(&cdev->spinlock); return ptr; } @@ -340,21 +348,21 @@ static struct snd_pcm_ops snd_usb_caiaq_ops = { .pointer = snd_usb_caiaq_pcm_pointer }; -static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, +static void check_for_elapsed_periods(struct snd_usb_caiaqdev *cdev, struct snd_pcm_substream **subs) { int stream, pb, *cnt; struct snd_pcm_substream *sub; - for (stream = 0; stream < dev->n_streams; stream++) { + for (stream = 0; stream < cdev->n_streams; stream++) { sub = subs[stream]; if (!sub) continue; pb = snd_pcm_lib_period_bytes(sub); cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - &dev->period_out_count[stream] : - &dev->period_in_count[stream]; + &cdev->period_out_count[stream] : + &cdev->period_in_count[stream]; if (*cnt >= pb) { snd_pcm_period_elapsed(sub); @@ -363,7 +371,7 @@ static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, } } -static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev, +static void read_in_urb_mode0(struct snd_usb_caiaqdev *cdev, const struct urb *urb, const struct usb_iso_packet_descriptor *iso) { @@ -371,27 +379,27 @@ static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev, struct snd_pcm_substream *sub; int stream, i; - if (all_substreams_zero(dev->sub_capture)) + if (all_substreams_zero(cdev->sub_capture)) return; for (i = 0; i < iso->actual_length;) { - for (stream = 0; stream < dev->n_streams; stream++, i++) { - sub = dev->sub_capture[stream]; + for (stream = 0; stream < cdev->n_streams; stream++, i++) { + sub = cdev->sub_capture[stream]; if (sub) { struct snd_pcm_runtime *rt = sub->runtime; char *audio_buf = rt->dma_area; int sz = frames_to_bytes(rt, rt->buffer_size); - audio_buf[dev->audio_in_buf_pos[stream]++] + audio_buf[cdev->audio_in_buf_pos[stream]++] = usb_buf[i]; - dev->period_in_count[stream]++; - if (dev->audio_in_buf_pos[stream] == sz) - dev->audio_in_buf_pos[stream] = 0; + cdev->period_in_count[stream]++; + if (cdev->audio_in_buf_pos[stream] == sz) + cdev->audio_in_buf_pos[stream] = 0; } } } } -static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, +static void read_in_urb_mode2(struct snd_usb_caiaqdev *cdev, const struct urb *urb, const struct usb_iso_packet_descriptor *iso) { @@ -401,48 +409,49 @@ static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, int stream, i; for (i = 0; i < iso->actual_length;) { - if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { + if (i % (cdev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { for (stream = 0; - stream < dev->n_streams; + stream < cdev->n_streams; stream++, i++) { - if (dev->first_packet) + if (cdev->first_packet) continue; - check_byte = MAKE_CHECKBYTE(dev, stream, i); + check_byte = MAKE_CHECKBYTE(cdev, stream, i); if ((usb_buf[i] & 0x3f) != check_byte) - dev->input_panic = 1; + cdev->input_panic = 1; if (usb_buf[i] & 0x80) - dev->output_panic = 1; + cdev->output_panic = 1; } } - dev->first_packet = 0; + cdev->first_packet = 0; - for (stream = 0; stream < dev->n_streams; stream++, i++) { - sub = dev->sub_capture[stream]; - if (dev->input_panic) + for (stream = 0; stream < cdev->n_streams; stream++, i++) { + sub = cdev->sub_capture[stream]; + if (cdev->input_panic) usb_buf[i] = 0; if (sub) { struct snd_pcm_runtime *rt = sub->runtime; char *audio_buf = rt->dma_area; int sz = frames_to_bytes(rt, rt->buffer_size); - audio_buf[dev->audio_in_buf_pos[stream]++] = + audio_buf[cdev->audio_in_buf_pos[stream]++] = usb_buf[i]; - dev->period_in_count[stream]++; - if (dev->audio_in_buf_pos[stream] == sz) - dev->audio_in_buf_pos[stream] = 0; + cdev->period_in_count[stream]++; + if (cdev->audio_in_buf_pos[stream] == sz) + cdev->audio_in_buf_pos[stream] = 0; } } } } -static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev, +static void read_in_urb_mode3(struct snd_usb_caiaqdev *cdev, const struct urb *urb, const struct usb_iso_packet_descriptor *iso) { unsigned char *usb_buf = urb->transfer_buffer + iso->offset; + struct device *dev = caiaqdev_to_dev(cdev); int stream, i; /* paranoia check */ @@ -450,12 +459,12 @@ static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev, return; for (i = 0; i < iso->actual_length;) { - for (stream = 0; stream < dev->n_streams; stream++) { - struct snd_pcm_substream *sub = dev->sub_capture[stream]; + for (stream = 0; stream < cdev->n_streams; stream++) { + struct snd_pcm_substream *sub = cdev->sub_capture[stream]; char *audio_buf = NULL; int c, n, sz = 0; - if (sub && !dev->input_panic) { + if (sub && !cdev->input_panic) { struct snd_pcm_runtime *rt = sub->runtime; audio_buf = rt->dma_area; sz = frames_to_bytes(rt, rt->buffer_size); @@ -465,23 +474,23 @@ static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev, /* 3 audio data bytes, followed by 1 check byte */ if (audio_buf) { for (n = 0; n < BYTES_PER_SAMPLE; n++) { - audio_buf[dev->audio_in_buf_pos[stream]++] = usb_buf[i+n]; + audio_buf[cdev->audio_in_buf_pos[stream]++] = usb_buf[i+n]; - if (dev->audio_in_buf_pos[stream] == sz) - dev->audio_in_buf_pos[stream] = 0; + if (cdev->audio_in_buf_pos[stream] == sz) + cdev->audio_in_buf_pos[stream] = 0; } - dev->period_in_count[stream] += BYTES_PER_SAMPLE; + cdev->period_in_count[stream] += BYTES_PER_SAMPLE; } i += BYTES_PER_SAMPLE; if (usb_buf[i] != ((stream << 1) | c) && - !dev->first_packet) { - if (!dev->input_panic) - printk(" EXPECTED: %02x got %02x, c %d, stream %d, i %d\n", - ((stream << 1) | c), usb_buf[i], c, stream, i); - dev->input_panic = 1; + !cdev->first_packet) { + if (!cdev->input_panic) + dev_warn(dev, " EXPECTED: %02x got %02x, c %d, stream %d, i %d\n", + ((stream << 1) | c), usb_buf[i], c, stream, i); + cdev->input_panic = 1; } i++; @@ -489,41 +498,43 @@ static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev, } } - if (dev->first_packet > 0) - dev->first_packet--; + if (cdev->first_packet > 0) + cdev->first_packet--; } -static void read_in_urb(struct snd_usb_caiaqdev *dev, +static void read_in_urb(struct snd_usb_caiaqdev *cdev, const struct urb *urb, const struct usb_iso_packet_descriptor *iso) { - if (!dev->streaming) + struct device *dev = caiaqdev_to_dev(cdev); + + if (!cdev->streaming) return; - if (iso->actual_length < dev->bpp) + if (iso->actual_length < cdev->bpp) return; - switch (dev->spec.data_alignment) { + switch (cdev->spec.data_alignment) { case 0: - read_in_urb_mode0(dev, urb, iso); + read_in_urb_mode0(cdev, urb, iso); break; case 2: - read_in_urb_mode2(dev, urb, iso); + read_in_urb_mode2(cdev, urb, iso); break; case 3: - read_in_urb_mode3(dev, urb, iso); + read_in_urb_mode3(cdev, urb, iso); break; } - if ((dev->input_panic || dev->output_panic) && !dev->warned) { - debug("streaming error detected %s %s\n", - dev->input_panic ? "(input)" : "", - dev->output_panic ? "(output)" : ""); - dev->warned = 1; + if ((cdev->input_panic || cdev->output_panic) && !cdev->warned) { + dev_warn(dev, "streaming error detected %s %s\n", + cdev->input_panic ? "(input)" : "", + cdev->output_panic ? "(output)" : ""); + cdev->warned = 1; } } -static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev, +static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *cdev, struct urb *urb, const struct usb_iso_packet_descriptor *iso) { @@ -532,32 +543,32 @@ static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev, int stream, i; for (i = 0; i < iso->length;) { - for (stream = 0; stream < dev->n_streams; stream++, i++) { - sub = dev->sub_playback[stream]; + for (stream = 0; stream < cdev->n_streams; stream++, i++) { + sub = cdev->sub_playback[stream]; if (sub) { struct snd_pcm_runtime *rt = sub->runtime; char *audio_buf = rt->dma_area; int sz = frames_to_bytes(rt, rt->buffer_size); usb_buf[i] = - audio_buf[dev->audio_out_buf_pos[stream]]; - dev->period_out_count[stream]++; - dev->audio_out_buf_pos[stream]++; - if (dev->audio_out_buf_pos[stream] == sz) - dev->audio_out_buf_pos[stream] = 0; + audio_buf[cdev->audio_out_buf_pos[stream]]; + cdev->period_out_count[stream]++; + cdev->audio_out_buf_pos[stream]++; + if (cdev->audio_out_buf_pos[stream] == sz) + cdev->audio_out_buf_pos[stream] = 0; } else usb_buf[i] = 0; } /* fill in the check bytes */ - if (dev->spec.data_alignment == 2 && - i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == - (dev->n_streams * CHANNELS_PER_STREAM)) - for (stream = 0; stream < dev->n_streams; stream++, i++) - usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); + if (cdev->spec.data_alignment == 2 && + i % (cdev->n_streams * BYTES_PER_SAMPLE_USB) == + (cdev->n_streams * CHANNELS_PER_STREAM)) + for (stream = 0; stream < cdev->n_streams; stream++, i++) + usb_buf[i] = MAKE_CHECKBYTE(cdev, stream, i); } } -static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev, +static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *cdev, struct urb *urb, const struct usb_iso_packet_descriptor *iso) { @@ -565,8 +576,8 @@ static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev, int stream, i; for (i = 0; i < iso->length;) { - for (stream = 0; stream < dev->n_streams; stream++) { - struct snd_pcm_substream *sub = dev->sub_playback[stream]; + for (stream = 0; stream < cdev->n_streams; stream++) { + struct snd_pcm_substream *sub = cdev->sub_playback[stream]; char *audio_buf = NULL; int c, n, sz = 0; @@ -579,17 +590,17 @@ static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev, for (c = 0; c < CHANNELS_PER_STREAM; c++) { for (n = 0; n < BYTES_PER_SAMPLE; n++) { if (audio_buf) { - usb_buf[i+n] = audio_buf[dev->audio_out_buf_pos[stream]++]; + usb_buf[i+n] = audio_buf[cdev->audio_out_buf_pos[stream]++]; - if (dev->audio_out_buf_pos[stream] == sz) - dev->audio_out_buf_pos[stream] = 0; + if (cdev->audio_out_buf_pos[stream] == sz) + cdev->audio_out_buf_pos[stream] = 0; } else { usb_buf[i+n] = 0; } } if (audio_buf) - dev->period_out_count[stream] += BYTES_PER_SAMPLE; + cdev->period_out_count[stream] += BYTES_PER_SAMPLE; i += BYTES_PER_SAMPLE; @@ -600,17 +611,17 @@ static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev, } } -static inline void fill_out_urb(struct snd_usb_caiaqdev *dev, +static inline void fill_out_urb(struct snd_usb_caiaqdev *cdev, struct urb *urb, const struct usb_iso_packet_descriptor *iso) { - switch (dev->spec.data_alignment) { + switch (cdev->spec.data_alignment) { case 0: case 2: - fill_out_urb_mode_0(dev, urb, iso); + fill_out_urb_mode_0(cdev, urb, iso); break; case 3: - fill_out_urb_mode_3(dev, urb, iso); + fill_out_urb_mode_3(cdev, urb, iso); break; } } @@ -618,7 +629,8 @@ static inline void fill_out_urb(struct snd_usb_caiaqdev *dev, static void read_completed(struct urb *urb) { struct snd_usb_caiaq_cb_info *info = urb->context; - struct snd_usb_caiaqdev *dev; + struct snd_usb_caiaqdev *cdev; + struct device *dev; struct urb *out = NULL; int i, frame, len, send_it = 0, outframe = 0; size_t offset = 0; @@ -626,20 +638,21 @@ static void read_completed(struct urb *urb) if (urb->status || !info) return; - dev = info->dev; + cdev = info->cdev; + dev = caiaqdev_to_dev(cdev); - if (!dev->streaming) + if (!cdev->streaming) return; /* find an unused output urb that is unused */ for (i = 0; i < N_URBS; i++) - if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) { - out = dev->data_urbs_out[i]; + if (test_and_set_bit(i, &cdev->outurb_active_mask) == 0) { + out = cdev->data_urbs_out[i]; break; } if (!out) { - log("Unable to find an output urb to use\n"); + dev_err(dev, "Unable to find an output urb to use\n"); goto requeue; } @@ -656,12 +669,12 @@ static void read_completed(struct urb *urb) offset += len; if (len > 0) { - spin_lock(&dev->spinlock); - fill_out_urb(dev, out, &out->iso_frame_desc[outframe]); - read_in_urb(dev, urb, &urb->iso_frame_desc[frame]); - spin_unlock(&dev->spinlock); - check_for_elapsed_periods(dev, dev->sub_playback); - check_for_elapsed_periods(dev, dev->sub_capture); + spin_lock(&cdev->spinlock); + fill_out_urb(cdev, out, &out->iso_frame_desc[outframe]); + read_in_urb(cdev, urb, &urb->iso_frame_desc[frame]); + spin_unlock(&cdev->spinlock); + check_for_elapsed_periods(cdev, cdev->sub_playback); + check_for_elapsed_periods(cdev, cdev->sub_capture); send_it = 1; } @@ -670,11 +683,10 @@ static void read_completed(struct urb *urb) if (send_it) { out->number_of_packets = outframe; - out->transfer_flags = URB_ISO_ASAP; usb_submit_urb(out, GFP_ATOMIC); } else { struct snd_usb_caiaq_cb_info *oinfo = out->context; - clear_bit(oinfo->index, &dev->outurb_active_mask); + clear_bit(oinfo->index, &cdev->outurb_active_mask); } requeue: @@ -686,28 +698,28 @@ requeue: } urb->number_of_packets = FRAMES_PER_URB; - urb->transfer_flags = URB_ISO_ASAP; usb_submit_urb(urb, GFP_ATOMIC); } static void write_completed(struct urb *urb) { struct snd_usb_caiaq_cb_info *info = urb->context; - struct snd_usb_caiaqdev *dev = info->dev; + struct snd_usb_caiaqdev *cdev = info->cdev; - if (!dev->output_running) { - dev->output_running = 1; - wake_up(&dev->prepare_wait_queue); + if (!cdev->output_running) { + cdev->output_running = 1; + wake_up(&cdev->prepare_wait_queue); } - clear_bit(info->index, &dev->outurb_active_mask); + clear_bit(info->index, &cdev->outurb_active_mask); } -static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) +static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) { int i, frame; struct urb **urbs; - struct usb_device *usb_dev = dev->chip.dev; + struct usb_device *usb_dev = cdev->chip.dev; + struct device *dev = caiaqdev_to_dev(cdev); unsigned int pipe; pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? @@ -716,7 +728,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); if (!urbs) { - log("unable to kmalloc() urbs, OOM!?\n"); + dev_err(dev, "unable to kmalloc() urbs, OOM!?\n"); *ret = -ENOMEM; return NULL; } @@ -724,7 +736,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) for (i = 0; i < N_URBS; i++) { urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); if (!urbs[i]) { - log("unable to usb_alloc_urb(), OOM!?\n"); + dev_err(dev, "unable to usb_alloc_urb(), OOM!?\n"); *ret = -ENOMEM; return urbs; } @@ -732,7 +744,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) urbs[i]->transfer_buffer = kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); if (!urbs[i]->transfer_buffer) { - log("unable to kmalloc() transfer buffer, OOM!?\n"); + dev_err(dev, "unable to kmalloc() transfer buffer, OOM!?\n"); *ret = -ENOMEM; return urbs; } @@ -749,9 +761,8 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) urbs[i]->pipe = pipe; urbs[i]->transfer_buffer_length = FRAMES_PER_URB * BYTES_PER_FRAME; - urbs[i]->context = &dev->data_cb_info[i]; + urbs[i]->context = &cdev->data_cb_info[i]; urbs[i]->interval = 1; - urbs[i]->transfer_flags = URB_ISO_ASAP; urbs[i]->number_of_packets = FRAMES_PER_URB; urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ? read_completed : write_completed; @@ -780,110 +791,113 @@ static void free_urbs(struct urb **urbs) kfree(urbs); } -int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) +int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev) { int i, ret; + struct device *dev = caiaqdev_to_dev(cdev); - dev->n_audio_in = max(dev->spec.num_analog_audio_in, - dev->spec.num_digital_audio_in) / + cdev->n_audio_in = max(cdev->spec.num_analog_audio_in, + cdev->spec.num_digital_audio_in) / CHANNELS_PER_STREAM; - dev->n_audio_out = max(dev->spec.num_analog_audio_out, - dev->spec.num_digital_audio_out) / + cdev->n_audio_out = max(cdev->spec.num_analog_audio_out, + cdev->spec.num_digital_audio_out) / CHANNELS_PER_STREAM; - dev->n_streams = max(dev->n_audio_in, dev->n_audio_out); + cdev->n_streams = max(cdev->n_audio_in, cdev->n_audio_out); - debug("dev->n_audio_in = %d\n", dev->n_audio_in); - debug("dev->n_audio_out = %d\n", dev->n_audio_out); - debug("dev->n_streams = %d\n", dev->n_streams); + dev_dbg(dev, "cdev->n_audio_in = %d\n", cdev->n_audio_in); + dev_dbg(dev, "cdev->n_audio_out = %d\n", cdev->n_audio_out); + dev_dbg(dev, "cdev->n_streams = %d\n", cdev->n_streams); - if (dev->n_streams > MAX_STREAMS) { - log("unable to initialize device, too many streams.\n"); + if (cdev->n_streams > MAX_STREAMS) { + dev_err(dev, "unable to initialize device, too many streams.\n"); return -EINVAL; } - ret = snd_pcm_new(dev->chip.card, dev->product_name, 0, - dev->n_audio_out, dev->n_audio_in, &dev->pcm); + ret = snd_pcm_new(cdev->chip.card, cdev->product_name, 0, + cdev->n_audio_out, cdev->n_audio_in, &cdev->pcm); if (ret < 0) { - log("snd_pcm_new() returned %d\n", ret); + dev_err(dev, "snd_pcm_new() returned %d\n", ret); return ret; } - dev->pcm->private_data = dev; - strlcpy(dev->pcm->name, dev->product_name, sizeof(dev->pcm->name)); + cdev->pcm->private_data = cdev; + strlcpy(cdev->pcm->name, cdev->product_name, sizeof(cdev->pcm->name)); - memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); - memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); + memset(cdev->sub_playback, 0, sizeof(cdev->sub_playback)); + memset(cdev->sub_capture, 0, sizeof(cdev->sub_capture)); - memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware, + memcpy(&cdev->pcm_info, &snd_usb_caiaq_pcm_hardware, sizeof(snd_usb_caiaq_pcm_hardware)); /* setup samplerates */ - dev->samplerates = dev->pcm_info.rates; - switch (dev->chip.usb_id) { + cdev->samplerates = cdev->pcm_info.rates; + switch (cdev->chip.usb_id) { case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE): - dev->samplerates |= SNDRV_PCM_RATE_192000; + cdev->samplerates |= SNDRV_PCM_RATE_192000; /* fall thru */ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORAUDIO2): - dev->samplerates |= SNDRV_PCM_RATE_88200; + cdev->samplerates |= SNDRV_PCM_RATE_88200; break; } - snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, + snd_pcm_set_ops(cdev->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usb_caiaq_ops); - snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, + snd_pcm_set_ops(cdev->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usb_caiaq_ops); - snd_pcm_lib_preallocate_pages_for_all(dev->pcm, + snd_pcm_lib_preallocate_pages_for_all(cdev->pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data(GFP_KERNEL), MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); - dev->data_cb_info = + cdev->data_cb_info = kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, GFP_KERNEL); - if (!dev->data_cb_info) + if (!cdev->data_cb_info) return -ENOMEM; - dev->outurb_active_mask = 0; - BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8)); + cdev->outurb_active_mask = 0; + BUILD_BUG_ON(N_URBS > (sizeof(cdev->outurb_active_mask) * 8)); for (i = 0; i < N_URBS; i++) { - dev->data_cb_info[i].dev = dev; - dev->data_cb_info[i].index = i; + cdev->data_cb_info[i].cdev = cdev; + cdev->data_cb_info[i].index = i; } - dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret); + cdev->data_urbs_in = alloc_urbs(cdev, SNDRV_PCM_STREAM_CAPTURE, &ret); if (ret < 0) { - kfree(dev->data_cb_info); - free_urbs(dev->data_urbs_in); + kfree(cdev->data_cb_info); + free_urbs(cdev->data_urbs_in); return ret; } - dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret); + cdev->data_urbs_out = alloc_urbs(cdev, SNDRV_PCM_STREAM_PLAYBACK, &ret); if (ret < 0) { - kfree(dev->data_cb_info); - free_urbs(dev->data_urbs_in); - free_urbs(dev->data_urbs_out); + kfree(cdev->data_cb_info); + free_urbs(cdev->data_urbs_in); + free_urbs(cdev->data_urbs_out); return ret; } return 0; } -void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev) +void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev) { - debug("%s(%p)\n", __func__, dev); - stream_stop(dev); - free_urbs(dev->data_urbs_in); - free_urbs(dev->data_urbs_out); - kfree(dev->data_cb_info); + struct device *dev = caiaqdev_to_dev(cdev); + + dev_dbg(dev, "%s(%p)\n", __func__, cdev); + stream_stop(cdev); + free_urbs(cdev->data_urbs_in); + free_urbs(cdev->data_urbs_out); + kfree(cdev->data_cb_info); } |