161864d84STakashi Iwai /* 2c078a4aaSChris Rorvick * Line 6 Linux USB driver 361864d84STakashi Iwai * 461864d84STakashi Iwai * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 561864d84STakashi Iwai * 661864d84STakashi Iwai * This program is free software; you can redistribute it and/or 761864d84STakashi Iwai * modify it under the terms of the GNU General Public License as 861864d84STakashi Iwai * published by the Free Software Foundation, version 2. 961864d84STakashi Iwai * 1061864d84STakashi Iwai */ 1161864d84STakashi Iwai 1261864d84STakashi Iwai #include <linux/slab.h> 1361864d84STakashi Iwai #include <sound/core.h> 1461864d84STakashi Iwai #include <sound/pcm.h> 1561864d84STakashi Iwai #include <sound/pcm_params.h> 1661864d84STakashi Iwai 1761864d84STakashi Iwai #include "capture.h" 1861864d84STakashi Iwai #include "driver.h" 1961864d84STakashi Iwai #include "pcm.h" 2061864d84STakashi Iwai #include "playback.h" 2161864d84STakashi Iwai 2261864d84STakashi Iwai /* 2361864d84STakashi Iwai Software stereo volume control. 2461864d84STakashi Iwai */ 2561864d84STakashi Iwai static void change_volume(struct urb *urb_out, int volume[], 2661864d84STakashi Iwai int bytes_per_frame) 2761864d84STakashi Iwai { 2861864d84STakashi Iwai int chn = 0; 2961864d84STakashi Iwai 3061864d84STakashi Iwai if (volume[0] == 256 && volume[1] == 256) 3161864d84STakashi Iwai return; /* maximum volume - no change */ 3261864d84STakashi Iwai 3361864d84STakashi Iwai if (bytes_per_frame == 4) { 340416980dSTakashi Iwai __le16 *p, *buf_end; 3561864d84STakashi Iwai 360416980dSTakashi Iwai p = (__le16 *)urb_out->transfer_buffer; 3761864d84STakashi Iwai buf_end = p + urb_out->transfer_buffer_length / sizeof(*p); 3861864d84STakashi Iwai 3961864d84STakashi Iwai for (; p < buf_end; ++p) { 400416980dSTakashi Iwai short pv = le16_to_cpu(*p); 410416980dSTakashi Iwai int val = (pv * volume[chn & 1]) >> 8; 420416980dSTakashi Iwai pv = clamp(val, 0x7fff, -0x8000); 430416980dSTakashi Iwai *p = cpu_to_le16(pv); 4461864d84STakashi Iwai ++chn; 4561864d84STakashi Iwai } 4661864d84STakashi Iwai } else if (bytes_per_frame == 6) { 4761864d84STakashi Iwai unsigned char *p, *buf_end; 4861864d84STakashi Iwai 4961864d84STakashi Iwai p = (unsigned char *)urb_out->transfer_buffer; 5061864d84STakashi Iwai buf_end = p + urb_out->transfer_buffer_length; 5161864d84STakashi Iwai 5261864d84STakashi Iwai for (; p < buf_end; p += 3) { 5361864d84STakashi Iwai int val; 5461864d84STakashi Iwai 5561864d84STakashi Iwai val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16); 5661864d84STakashi Iwai val = (val * volume[chn & 1]) >> 8; 57c8491535STakashi Iwai val = clamp(val, 0x7fffff, -0x800000); 5861864d84STakashi Iwai p[0] = val; 5961864d84STakashi Iwai p[1] = val >> 8; 6061864d84STakashi Iwai p[2] = val >> 16; 6161864d84STakashi Iwai ++chn; 6261864d84STakashi Iwai } 6361864d84STakashi Iwai } 6461864d84STakashi Iwai } 6561864d84STakashi Iwai 6661864d84STakashi Iwai /* 6761864d84STakashi Iwai Create signal for impulse response test. 6861864d84STakashi Iwai */ 6961864d84STakashi Iwai static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm, 7061864d84STakashi Iwai struct urb *urb_out, int bytes_per_frame) 7161864d84STakashi Iwai { 7261864d84STakashi Iwai int frames = urb_out->transfer_buffer_length / bytes_per_frame; 7361864d84STakashi Iwai 7461864d84STakashi Iwai if (bytes_per_frame == 4) { 7561864d84STakashi Iwai int i; 7661864d84STakashi Iwai short *pi = (short *)line6pcm->prev_fbuf; 7761864d84STakashi Iwai short *po = (short *)urb_out->transfer_buffer; 7861864d84STakashi Iwai 7961864d84STakashi Iwai for (i = 0; i < frames; ++i) { 8061864d84STakashi Iwai po[0] = pi[0]; 8161864d84STakashi Iwai po[1] = 0; 8261864d84STakashi Iwai pi += 2; 8361864d84STakashi Iwai po += 2; 8461864d84STakashi Iwai } 8561864d84STakashi Iwai } else if (bytes_per_frame == 6) { 8661864d84STakashi Iwai int i, j; 8761864d84STakashi Iwai unsigned char *pi = line6pcm->prev_fbuf; 8861864d84STakashi Iwai unsigned char *po = urb_out->transfer_buffer; 8961864d84STakashi Iwai 9061864d84STakashi Iwai for (i = 0; i < frames; ++i) { 9161864d84STakashi Iwai for (j = 0; j < bytes_per_frame / 2; ++j) 9261864d84STakashi Iwai po[j] = pi[j]; 9361864d84STakashi Iwai 9461864d84STakashi Iwai for (; j < bytes_per_frame; ++j) 9561864d84STakashi Iwai po[j] = 0; 9661864d84STakashi Iwai 9761864d84STakashi Iwai pi += bytes_per_frame; 9861864d84STakashi Iwai po += bytes_per_frame; 9961864d84STakashi Iwai } 10061864d84STakashi Iwai } 10161864d84STakashi Iwai if (--line6pcm->impulse_count <= 0) { 10261864d84STakashi Iwai ((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame - 10361864d84STakashi Iwai 1] = 10461864d84STakashi Iwai line6pcm->impulse_volume; 10561864d84STakashi Iwai line6pcm->impulse_count = line6pcm->impulse_period; 10661864d84STakashi Iwai } 10761864d84STakashi Iwai } 10861864d84STakashi Iwai 10961864d84STakashi Iwai /* 11061864d84STakashi Iwai Add signal to buffer for software monitoring. 11161864d84STakashi Iwai */ 11261864d84STakashi Iwai static void add_monitor_signal(struct urb *urb_out, unsigned char *signal, 11361864d84STakashi Iwai int volume, int bytes_per_frame) 11461864d84STakashi Iwai { 11561864d84STakashi Iwai if (volume == 0) 11661864d84STakashi Iwai return; /* zero volume - no change */ 11761864d84STakashi Iwai 11861864d84STakashi Iwai if (bytes_per_frame == 4) { 1190416980dSTakashi Iwai __le16 *pi, *po, *buf_end; 12061864d84STakashi Iwai 1210416980dSTakashi Iwai pi = (__le16 *)signal; 1220416980dSTakashi Iwai po = (__le16 *)urb_out->transfer_buffer; 12361864d84STakashi Iwai buf_end = po + urb_out->transfer_buffer_length / sizeof(*po); 12461864d84STakashi Iwai 125c8491535STakashi Iwai for (; po < buf_end; ++pi, ++po) { 1260416980dSTakashi Iwai short pov = le16_to_cpu(*po); 1270416980dSTakashi Iwai short piv = le16_to_cpu(*pi); 1280416980dSTakashi Iwai int val = pov + ((piv * volume) >> 8); 1290416980dSTakashi Iwai pov = clamp(val, 0x7fff, -0x8000); 1300416980dSTakashi Iwai *po = cpu_to_le16(pov); 131c8491535STakashi Iwai } 13261864d84STakashi Iwai } 13361864d84STakashi Iwai 13461864d84STakashi Iwai /* 13561864d84STakashi Iwai We don't need to handle devices with 6 bytes per frame here 13661864d84STakashi Iwai since they all support hardware monitoring. 13761864d84STakashi Iwai */ 13861864d84STakashi Iwai } 13961864d84STakashi Iwai 14061864d84STakashi Iwai /* 14161864d84STakashi Iwai Find a free URB, prepare audio data, and submit URB. 1423d3ae445STakashi Iwai must be called in line6pcm->out.lock context 14361864d84STakashi Iwai */ 14461864d84STakashi Iwai static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) 14561864d84STakashi Iwai { 14661864d84STakashi Iwai int index; 14761864d84STakashi Iwai int i, urb_size, urb_frames; 14861864d84STakashi Iwai int ret; 14961864d84STakashi Iwai const int bytes_per_frame = line6pcm->properties->bytes_per_frame; 15061864d84STakashi Iwai const int frame_increment = 151*1263f611STakashi Iwai line6pcm->properties->rates.rats[0].num_min; 15261864d84STakashi Iwai const int frame_factor = 153*1263f611STakashi Iwai line6pcm->properties->rates.rats[0].den * 15461864d84STakashi Iwai (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL); 15561864d84STakashi Iwai struct urb *urb_out; 15661864d84STakashi Iwai 15761864d84STakashi Iwai index = 158ad0119abSTakashi Iwai find_first_zero_bit(&line6pcm->out.active_urbs, LINE6_ISO_BUFFERS); 15961864d84STakashi Iwai 16061864d84STakashi Iwai if (index < 0 || index >= LINE6_ISO_BUFFERS) { 16161864d84STakashi Iwai dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); 16261864d84STakashi Iwai return -EINVAL; 16361864d84STakashi Iwai } 16461864d84STakashi Iwai 165ad0119abSTakashi Iwai urb_out = line6pcm->out.urbs[index]; 16661864d84STakashi Iwai urb_size = 0; 16761864d84STakashi Iwai 16861864d84STakashi Iwai for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 16961864d84STakashi Iwai /* compute frame size for given sampling rate */ 17061864d84STakashi Iwai int fsize = 0; 17161864d84STakashi Iwai struct usb_iso_packet_descriptor *fout = 17261864d84STakashi Iwai &urb_out->iso_frame_desc[i]; 17361864d84STakashi Iwai 17461864d84STakashi Iwai fsize = line6pcm->prev_fsize; 17561864d84STakashi Iwai if (fsize == 0) { 17661864d84STakashi Iwai int n; 17761864d84STakashi Iwai 178ad0119abSTakashi Iwai line6pcm->out.count += frame_increment; 179ad0119abSTakashi Iwai n = line6pcm->out.count / frame_factor; 180ad0119abSTakashi Iwai line6pcm->out.count -= n * frame_factor; 18161864d84STakashi Iwai fsize = n * bytes_per_frame; 18261864d84STakashi Iwai } 18361864d84STakashi Iwai 18461864d84STakashi Iwai fout->offset = urb_size; 18561864d84STakashi Iwai fout->length = fsize; 18661864d84STakashi Iwai urb_size += fsize; 18761864d84STakashi Iwai } 18861864d84STakashi Iwai 18961864d84STakashi Iwai if (urb_size == 0) { 19061864d84STakashi Iwai /* can't determine URB size */ 19161864d84STakashi Iwai dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); 19261864d84STakashi Iwai return -EINVAL; 19361864d84STakashi Iwai } 19461864d84STakashi Iwai 19561864d84STakashi Iwai urb_frames = urb_size / bytes_per_frame; 19661864d84STakashi Iwai urb_out->transfer_buffer = 197ad0119abSTakashi Iwai line6pcm->out.buffer + 19861864d84STakashi Iwai index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; 19961864d84STakashi Iwai urb_out->transfer_buffer_length = urb_size; 20061864d84STakashi Iwai urb_out->context = line6pcm; 20161864d84STakashi Iwai 20263e20df1STakashi Iwai if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running) && 20363e20df1STakashi Iwai !test_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags)) { 20461864d84STakashi Iwai struct snd_pcm_runtime *runtime = 20561864d84STakashi Iwai get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; 20661864d84STakashi Iwai 207ad0119abSTakashi Iwai if (line6pcm->out.pos + urb_frames > runtime->buffer_size) { 20861864d84STakashi Iwai /* 20961864d84STakashi Iwai The transferred area goes over buffer boundary, 21061864d84STakashi Iwai copy the data to the temp buffer. 21161864d84STakashi Iwai */ 21261864d84STakashi Iwai int len; 21361864d84STakashi Iwai 214ad0119abSTakashi Iwai len = runtime->buffer_size - line6pcm->out.pos; 21561864d84STakashi Iwai 21661864d84STakashi Iwai if (len > 0) { 21761864d84STakashi Iwai memcpy(urb_out->transfer_buffer, 21861864d84STakashi Iwai runtime->dma_area + 219ad0119abSTakashi Iwai line6pcm->out.pos * bytes_per_frame, 22061864d84STakashi Iwai len * bytes_per_frame); 22161864d84STakashi Iwai memcpy(urb_out->transfer_buffer + 22261864d84STakashi Iwai len * bytes_per_frame, runtime->dma_area, 22361864d84STakashi Iwai (urb_frames - len) * bytes_per_frame); 22461864d84STakashi Iwai } else 22561864d84STakashi Iwai dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", 22661864d84STakashi Iwai len); 22761864d84STakashi Iwai } else { 22861864d84STakashi Iwai memcpy(urb_out->transfer_buffer, 22961864d84STakashi Iwai runtime->dma_area + 230ad0119abSTakashi Iwai line6pcm->out.pos * bytes_per_frame, 23161864d84STakashi Iwai urb_out->transfer_buffer_length); 23261864d84STakashi Iwai } 23361864d84STakashi Iwai 234ad0119abSTakashi Iwai line6pcm->out.pos += urb_frames; 235ad0119abSTakashi Iwai if (line6pcm->out.pos >= runtime->buffer_size) 236ad0119abSTakashi Iwai line6pcm->out.pos -= runtime->buffer_size; 23762a109d9STakashi Iwai 23862a109d9STakashi Iwai change_volume(urb_out, line6pcm->volume_playback, 23962a109d9STakashi Iwai bytes_per_frame); 24061864d84STakashi Iwai } else { 24161864d84STakashi Iwai memset(urb_out->transfer_buffer, 0, 24261864d84STakashi Iwai urb_out->transfer_buffer_length); 24361864d84STakashi Iwai } 24461864d84STakashi Iwai 2453d3ae445STakashi Iwai spin_lock_nested(&line6pcm->in.lock, SINGLE_DEPTH_NESTING); 2463d3ae445STakashi Iwai if (line6pcm->prev_fbuf) { 24763e20df1STakashi Iwai if (test_bit(LINE6_STREAM_IMPULSE, &line6pcm->out.running)) { 24861864d84STakashi Iwai create_impulse_test_signal(line6pcm, urb_out, 24961864d84STakashi Iwai bytes_per_frame); 25063e20df1STakashi Iwai if (test_bit(LINE6_STREAM_PCM, &line6pcm->in.running)) { 25161864d84STakashi Iwai line6_capture_copy(line6pcm, 25261864d84STakashi Iwai urb_out->transfer_buffer, 25361864d84STakashi Iwai urb_out-> 25461864d84STakashi Iwai transfer_buffer_length); 25561864d84STakashi Iwai line6_capture_check_period(line6pcm, 25661864d84STakashi Iwai urb_out->transfer_buffer_length); 25761864d84STakashi Iwai } 25861864d84STakashi Iwai } else { 25963e20df1STakashi Iwai if (!(line6pcm->line6->properties->capabilities & LINE6_CAP_HWMON) 26063e20df1STakashi Iwai && line6pcm->out.running && line6pcm->in.running) 26161864d84STakashi Iwai add_monitor_signal(urb_out, line6pcm->prev_fbuf, 26261864d84STakashi Iwai line6pcm->volume_monitor, 26361864d84STakashi Iwai bytes_per_frame); 26461864d84STakashi Iwai } 265f2bb614bSTakashi Iwai line6pcm->prev_fbuf = NULL; 266f2bb614bSTakashi Iwai line6pcm->prev_fsize = 0; 26761864d84STakashi Iwai } 2683d3ae445STakashi Iwai spin_unlock(&line6pcm->in.lock); 26961864d84STakashi Iwai 27061864d84STakashi Iwai ret = usb_submit_urb(urb_out, GFP_ATOMIC); 27161864d84STakashi Iwai 27261864d84STakashi Iwai if (ret == 0) 273ad0119abSTakashi Iwai set_bit(index, &line6pcm->out.active_urbs); 27461864d84STakashi Iwai else 27561864d84STakashi Iwai dev_err(line6pcm->line6->ifcdev, 27661864d84STakashi Iwai "URB out #%d submission failed (%d)\n", index, ret); 27761864d84STakashi Iwai 27861864d84STakashi Iwai return 0; 27961864d84STakashi Iwai } 28061864d84STakashi Iwai 28161864d84STakashi Iwai /* 28261864d84STakashi Iwai Submit all currently available playback URBs. 28363e20df1STakashi Iwai must be called in line6pcm->out.lock context 28461864d84STakashi Iwai */ 28561864d84STakashi Iwai int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm) 28661864d84STakashi Iwai { 2873d3ae445STakashi Iwai int ret = 0, i; 28861864d84STakashi Iwai 28961864d84STakashi Iwai for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 29061864d84STakashi Iwai ret = submit_audio_out_urb(line6pcm); 29161864d84STakashi Iwai if (ret < 0) 2923d3ae445STakashi Iwai break; 29361864d84STakashi Iwai } 29461864d84STakashi Iwai 2953d3ae445STakashi Iwai return ret; 29661864d84STakashi Iwai } 29761864d84STakashi Iwai 29861864d84STakashi Iwai /* 29961864d84STakashi Iwai Callback for completed playback URB. 30061864d84STakashi Iwai */ 30161864d84STakashi Iwai static void audio_out_callback(struct urb *urb) 30261864d84STakashi Iwai { 30361864d84STakashi Iwai int i, index, length = 0, shutdown = 0; 30461864d84STakashi Iwai unsigned long flags; 30561864d84STakashi Iwai struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; 30661864d84STakashi Iwai struct snd_pcm_substream *substream = 30761864d84STakashi Iwai get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK); 30861864d84STakashi Iwai 30961864d84STakashi Iwai #if USE_CLEAR_BUFFER_WORKAROUND 31061864d84STakashi Iwai memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); 31161864d84STakashi Iwai #endif 31261864d84STakashi Iwai 313ad0119abSTakashi Iwai line6pcm->out.last_frame = urb->start_frame; 31461864d84STakashi Iwai 31561864d84STakashi Iwai /* find index of URB */ 3169fb754b7STakashi Iwai for (index = 0; index < LINE6_ISO_BUFFERS; index++) 317ad0119abSTakashi Iwai if (urb == line6pcm->out.urbs[index]) 31861864d84STakashi Iwai break; 31961864d84STakashi Iwai 3209fb754b7STakashi Iwai if (index >= LINE6_ISO_BUFFERS) 32161864d84STakashi Iwai return; /* URB has been unlinked asynchronously */ 32261864d84STakashi Iwai 3239fb754b7STakashi Iwai for (i = 0; i < LINE6_ISO_PACKETS; i++) 32461864d84STakashi Iwai length += urb->iso_frame_desc[i].length; 32561864d84STakashi Iwai 326ad0119abSTakashi Iwai spin_lock_irqsave(&line6pcm->out.lock, flags); 32761864d84STakashi Iwai 32863e20df1STakashi Iwai if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) { 32961864d84STakashi Iwai struct snd_pcm_runtime *runtime = substream->runtime; 33061864d84STakashi Iwai 331ad0119abSTakashi Iwai line6pcm->out.pos_done += 33261864d84STakashi Iwai length / line6pcm->properties->bytes_per_frame; 33361864d84STakashi Iwai 334ad0119abSTakashi Iwai if (line6pcm->out.pos_done >= runtime->buffer_size) 335ad0119abSTakashi Iwai line6pcm->out.pos_done -= runtime->buffer_size; 33661864d84STakashi Iwai } 33761864d84STakashi Iwai 338ad0119abSTakashi Iwai clear_bit(index, &line6pcm->out.active_urbs); 33961864d84STakashi Iwai 3409fb754b7STakashi Iwai for (i = 0; i < LINE6_ISO_PACKETS; i++) 34161864d84STakashi Iwai if (urb->iso_frame_desc[i].status == -EXDEV) { 34261864d84STakashi Iwai shutdown = 1; 34361864d84STakashi Iwai break; 34461864d84STakashi Iwai } 34561864d84STakashi Iwai 346ad0119abSTakashi Iwai if (test_and_clear_bit(index, &line6pcm->out.unlink_urbs)) 34761864d84STakashi Iwai shutdown = 1; 34861864d84STakashi Iwai 34961864d84STakashi Iwai if (!shutdown) { 35061864d84STakashi Iwai submit_audio_out_urb(line6pcm); 35161864d84STakashi Iwai 35263e20df1STakashi Iwai if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) { 353ad0119abSTakashi Iwai line6pcm->out.bytes += length; 354ad0119abSTakashi Iwai if (line6pcm->out.bytes >= line6pcm->out.period) { 355ad0119abSTakashi Iwai line6pcm->out.bytes %= line6pcm->out.period; 3563d3ae445STakashi Iwai spin_unlock(&line6pcm->out.lock); 35761864d84STakashi Iwai snd_pcm_period_elapsed(substream); 3583d3ae445STakashi Iwai spin_lock(&line6pcm->out.lock); 35961864d84STakashi Iwai } 36061864d84STakashi Iwai } 36161864d84STakashi Iwai } 3623d3ae445STakashi Iwai spin_unlock_irqrestore(&line6pcm->out.lock, flags); 36361864d84STakashi Iwai } 36461864d84STakashi Iwai 36561864d84STakashi Iwai /* open playback callback */ 36661864d84STakashi Iwai static int snd_line6_playback_open(struct snd_pcm_substream *substream) 36761864d84STakashi Iwai { 36861864d84STakashi Iwai int err; 36961864d84STakashi Iwai struct snd_pcm_runtime *runtime = substream->runtime; 37061864d84STakashi Iwai struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 37161864d84STakashi Iwai 37261864d84STakashi Iwai err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 373*1263f611STakashi Iwai &line6pcm->properties->rates); 37461864d84STakashi Iwai if (err < 0) 37561864d84STakashi Iwai return err; 37661864d84STakashi Iwai 377*1263f611STakashi Iwai runtime->hw = line6pcm->properties->playback_hw; 37861864d84STakashi Iwai return 0; 37961864d84STakashi Iwai } 38061864d84STakashi Iwai 38161864d84STakashi Iwai /* close playback callback */ 38261864d84STakashi Iwai static int snd_line6_playback_close(struct snd_pcm_substream *substream) 38361864d84STakashi Iwai { 38461864d84STakashi Iwai return 0; 38561864d84STakashi Iwai } 38661864d84STakashi Iwai 38761864d84STakashi Iwai /* playback operators */ 38861864d84STakashi Iwai struct snd_pcm_ops snd_line6_playback_ops = { 38961864d84STakashi Iwai .open = snd_line6_playback_open, 39061864d84STakashi Iwai .close = snd_line6_playback_close, 39161864d84STakashi Iwai .ioctl = snd_pcm_lib_ioctl, 39263e20df1STakashi Iwai .hw_params = snd_line6_hw_params, 39363e20df1STakashi Iwai .hw_free = snd_line6_hw_free, 39461864d84STakashi Iwai .prepare = snd_line6_prepare, 39561864d84STakashi Iwai .trigger = snd_line6_trigger, 3962954f914STakashi Iwai .pointer = snd_line6_pointer, 39761864d84STakashi Iwai }; 39861864d84STakashi Iwai 39961864d84STakashi Iwai int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) 40061864d84STakashi Iwai { 40161864d84STakashi Iwai struct usb_line6 *line6 = line6pcm->line6; 40261864d84STakashi Iwai int i; 40361864d84STakashi Iwai 40461864d84STakashi Iwai /* create audio URBs and fill in constant values: */ 40561864d84STakashi Iwai for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 40661864d84STakashi Iwai struct urb *urb; 40761864d84STakashi Iwai 40861864d84STakashi Iwai /* URB for audio out: */ 409ad0119abSTakashi Iwai urb = line6pcm->out.urbs[i] = 41061864d84STakashi Iwai usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); 41161864d84STakashi Iwai 412a019f5e8STakashi Iwai if (urb == NULL) 41361864d84STakashi Iwai return -ENOMEM; 41461864d84STakashi Iwai 41561864d84STakashi Iwai urb->dev = line6->usbdev; 41661864d84STakashi Iwai urb->pipe = 41761864d84STakashi Iwai usb_sndisocpipe(line6->usbdev, 41861864d84STakashi Iwai line6->properties->ep_audio_w & 41961864d84STakashi Iwai USB_ENDPOINT_NUMBER_MASK); 42061864d84STakashi Iwai urb->transfer_flags = URB_ISO_ASAP; 42161864d84STakashi Iwai urb->start_frame = -1; 42261864d84STakashi Iwai urb->number_of_packets = LINE6_ISO_PACKETS; 42361864d84STakashi Iwai urb->interval = LINE6_ISO_INTERVAL; 42461864d84STakashi Iwai urb->error_count = 0; 42561864d84STakashi Iwai urb->complete = audio_out_callback; 42661864d84STakashi Iwai } 42761864d84STakashi Iwai 42861864d84STakashi Iwai return 0; 42961864d84STakashi Iwai } 430