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> 13ccddbe4aSTakashi Iwai #include <linux/export.h> 1461864d84STakashi Iwai #include <sound/core.h> 1561864d84STakashi Iwai #include <sound/control.h> 1661864d84STakashi Iwai #include <sound/pcm.h> 1761864d84STakashi Iwai #include <sound/pcm_params.h> 1861864d84STakashi Iwai 1961864d84STakashi Iwai #include "capture.h" 2061864d84STakashi Iwai #include "driver.h" 2161864d84STakashi Iwai #include "playback.h" 2261864d84STakashi Iwai 23075587b7STakashi Iwai /* impulse response volume controls */ 24075587b7STakashi Iwai static int snd_line6_impulse_volume_info(struct snd_kcontrol *kcontrol, 25075587b7STakashi Iwai struct snd_ctl_elem_info *uinfo) 2661864d84STakashi Iwai { 27075587b7STakashi Iwai uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 28075587b7STakashi Iwai uinfo->count = 1; 29075587b7STakashi Iwai uinfo->value.integer.min = 0; 30075587b7STakashi Iwai uinfo->value.integer.max = 255; 31075587b7STakashi Iwai return 0; 3261864d84STakashi Iwai } 3361864d84STakashi Iwai 34075587b7STakashi Iwai static int snd_line6_impulse_volume_get(struct snd_kcontrol *kcontrol, 35075587b7STakashi Iwai struct snd_ctl_elem_value *ucontrol) 3661864d84STakashi Iwai { 37075587b7STakashi Iwai struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 38075587b7STakashi Iwai 39075587b7STakashi Iwai ucontrol->value.integer.value[0] = line6pcm->impulse_volume; 40075587b7STakashi Iwai return 0; 4161864d84STakashi Iwai } 4261864d84STakashi Iwai 43075587b7STakashi Iwai static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol, 44075587b7STakashi Iwai struct snd_ctl_elem_value *ucontrol) 4561864d84STakashi Iwai { 46075587b7STakashi Iwai struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 47075587b7STakashi Iwai int value = ucontrol->value.integer.value[0]; 4861864d84STakashi Iwai 49075587b7STakashi Iwai if (line6pcm->impulse_volume == value) 50075587b7STakashi Iwai return 0; 5161864d84STakashi Iwai 5261864d84STakashi Iwai line6pcm->impulse_volume = value; 5361864d84STakashi Iwai if (value > 0) 5461864d84STakashi Iwai line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE); 5561864d84STakashi Iwai else 5661864d84STakashi Iwai line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE); 57075587b7STakashi Iwai return 1; 5861864d84STakashi Iwai } 5961864d84STakashi Iwai 60075587b7STakashi Iwai /* impulse response period controls */ 61075587b7STakashi Iwai static int snd_line6_impulse_period_info(struct snd_kcontrol *kcontrol, 62075587b7STakashi Iwai struct snd_ctl_elem_info *uinfo) 6361864d84STakashi Iwai { 64075587b7STakashi Iwai uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 65075587b7STakashi Iwai uinfo->count = 1; 66075587b7STakashi Iwai uinfo->value.integer.min = 0; 67075587b7STakashi Iwai uinfo->value.integer.max = 2000; 68075587b7STakashi Iwai return 0; 6961864d84STakashi Iwai } 7061864d84STakashi Iwai 71075587b7STakashi Iwai static int snd_line6_impulse_period_get(struct snd_kcontrol *kcontrol, 72075587b7STakashi Iwai struct snd_ctl_elem_value *ucontrol) 7361864d84STakashi Iwai { 74075587b7STakashi Iwai struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 7561864d84STakashi Iwai 76075587b7STakashi Iwai ucontrol->value.integer.value[0] = line6pcm->impulse_period; 77075587b7STakashi Iwai return 0; 7861864d84STakashi Iwai } 7961864d84STakashi Iwai 80075587b7STakashi Iwai static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol, 81075587b7STakashi Iwai struct snd_ctl_elem_value *ucontrol) 82075587b7STakashi Iwai { 83075587b7STakashi Iwai struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 84075587b7STakashi Iwai int value = ucontrol->value.integer.value[0]; 85075587b7STakashi Iwai 86075587b7STakashi Iwai if (line6pcm->impulse_period == value) 87075587b7STakashi Iwai return 0; 88075587b7STakashi Iwai 89075587b7STakashi Iwai line6pcm->impulse_period = value; 90075587b7STakashi Iwai return 1; 91075587b7STakashi Iwai } 9261864d84STakashi Iwai 93d8131e67STakashi Iwai /* 94d8131e67STakashi Iwai Unlink all currently active URBs. 95d8131e67STakashi Iwai */ 96d8131e67STakashi Iwai static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm, 97d8131e67STakashi Iwai struct line6_pcm_stream *pcms) 98d8131e67STakashi Iwai { 99d8131e67STakashi Iwai int i; 100d8131e67STakashi Iwai 101d8131e67STakashi Iwai for (i = 0; i < LINE6_ISO_BUFFERS; i++) { 102d8131e67STakashi Iwai if (test_bit(i, &pcms->active_urbs)) { 103d8131e67STakashi Iwai if (!test_and_set_bit(i, &pcms->unlink_urbs)) 104d8131e67STakashi Iwai usb_unlink_urb(pcms->urbs[i]); 105d8131e67STakashi Iwai } 106d8131e67STakashi Iwai } 107d8131e67STakashi Iwai } 108d8131e67STakashi Iwai 109d8131e67STakashi Iwai /* 110d8131e67STakashi Iwai Wait until unlinking of all currently active URBs has been finished. 111d8131e67STakashi Iwai */ 112d8131e67STakashi Iwai static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm, 113d8131e67STakashi Iwai struct line6_pcm_stream *pcms) 114d8131e67STakashi Iwai { 115d8131e67STakashi Iwai int timeout = HZ; 116d8131e67STakashi Iwai int i; 117d8131e67STakashi Iwai int alive; 118d8131e67STakashi Iwai 119d8131e67STakashi Iwai do { 120d8131e67STakashi Iwai alive = 0; 121d8131e67STakashi Iwai for (i = 0; i < LINE6_ISO_BUFFERS; i++) { 122d8131e67STakashi Iwai if (test_bit(i, &pcms->active_urbs)) 123d8131e67STakashi Iwai alive++; 124d8131e67STakashi Iwai } 125d8131e67STakashi Iwai if (!alive) 126d8131e67STakashi Iwai break; 127d8131e67STakashi Iwai set_current_state(TASK_UNINTERRUPTIBLE); 128d8131e67STakashi Iwai schedule_timeout(1); 129d8131e67STakashi Iwai } while (--timeout > 0); 130d8131e67STakashi Iwai if (alive) 131ccaac9edSTakashi Iwai dev_err(line6pcm->line6->ifcdev, 132ccaac9edSTakashi Iwai "timeout: still %d active urbs..\n", alive); 133d8131e67STakashi Iwai } 134d8131e67STakashi Iwai 135*e90576c5STakashi Iwai static int line6_alloc_stream_buffer(struct snd_line6_pcm *line6pcm, 136*e90576c5STakashi Iwai struct line6_pcm_stream *pcms) 137*e90576c5STakashi Iwai { 138*e90576c5STakashi Iwai /* Invoked multiple times in a row so allocate once only */ 139*e90576c5STakashi Iwai if (pcms->buffer) 140*e90576c5STakashi Iwai return 0; 141*e90576c5STakashi Iwai 142*e90576c5STakashi Iwai pcms->buffer = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * 143*e90576c5STakashi Iwai line6pcm->max_packet_size, GFP_KERNEL); 144*e90576c5STakashi Iwai if (!pcms->buffer) 145*e90576c5STakashi Iwai return -ENOMEM; 146*e90576c5STakashi Iwai return 0; 147*e90576c5STakashi Iwai } 148*e90576c5STakashi Iwai 149*e90576c5STakashi Iwai static void line6_free_stream_buffer(struct snd_line6_pcm *line6pcm, 150*e90576c5STakashi Iwai struct line6_pcm_stream *pcms) 151*e90576c5STakashi Iwai { 152*e90576c5STakashi Iwai kfree(pcms->buffer); 153*e90576c5STakashi Iwai pcms->buffer = NULL; 154*e90576c5STakashi Iwai } 155*e90576c5STakashi Iwai 15661864d84STakashi Iwai static bool test_flags(unsigned long flags0, unsigned long flags1, 15761864d84STakashi Iwai unsigned long mask) 15861864d84STakashi Iwai { 15961864d84STakashi Iwai return ((flags0 & mask) == 0) && ((flags1 & mask) != 0); 16061864d84STakashi Iwai } 16161864d84STakashi Iwai 16261864d84STakashi Iwai int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) 16361864d84STakashi Iwai { 16461864d84STakashi Iwai unsigned long flags_old, flags_new, flags_final; 16561864d84STakashi Iwai int err; 16661864d84STakashi Iwai 16761864d84STakashi Iwai do { 16861864d84STakashi Iwai flags_old = ACCESS_ONCE(line6pcm->flags); 16961864d84STakashi Iwai flags_new = flags_old | channels; 17061864d84STakashi Iwai } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); 17161864d84STakashi Iwai 1725343ecf4STakashi Iwai flags_final = 0; 17361864d84STakashi Iwai 17461864d84STakashi Iwai line6pcm->prev_fbuf = NULL; 17561864d84STakashi Iwai 17661864d84STakashi Iwai if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { 177*e90576c5STakashi Iwai err = line6_alloc_stream_buffer(line6pcm, &line6pcm->in); 178*e90576c5STakashi Iwai if (err < 0) 17961864d84STakashi Iwai goto pcm_acquire_error; 18061864d84STakashi Iwai flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER; 18161864d84STakashi Iwai } 18261864d84STakashi Iwai 18361864d84STakashi Iwai if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) { 18461864d84STakashi Iwai /* 18561864d84STakashi Iwai Waiting for completion of active URBs in the stop handler is 18661864d84STakashi Iwai a bug, we therefore report an error if capturing is restarted 18761864d84STakashi Iwai too soon. 18861864d84STakashi Iwai */ 189ad0119abSTakashi Iwai if (line6pcm->in.active_urbs || line6pcm->in.unlink_urbs) { 19061864d84STakashi Iwai dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); 191eab22e40STakashi Iwai err = -EBUSY; 192eab22e40STakashi Iwai goto pcm_acquire_error; 19361864d84STakashi Iwai } 19461864d84STakashi Iwai 195ad0119abSTakashi Iwai line6pcm->in.count = 0; 19661864d84STakashi Iwai line6pcm->prev_fsize = 0; 19761864d84STakashi Iwai err = line6_submit_audio_in_all_urbs(line6pcm); 19861864d84STakashi Iwai 19961864d84STakashi Iwai if (err < 0) 20061864d84STakashi Iwai goto pcm_acquire_error; 20161864d84STakashi Iwai 20261864d84STakashi Iwai flags_final |= channels & LINE6_BITS_CAPTURE_STREAM; 20361864d84STakashi Iwai } 20461864d84STakashi Iwai 20561864d84STakashi Iwai if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) { 206*e90576c5STakashi Iwai err = line6_alloc_stream_buffer(line6pcm, &line6pcm->out); 207*e90576c5STakashi Iwai if (err < 0) 20861864d84STakashi Iwai goto pcm_acquire_error; 20961864d84STakashi Iwai flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER; 21061864d84STakashi Iwai } 21161864d84STakashi Iwai 21261864d84STakashi Iwai if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) { 21361864d84STakashi Iwai /* 21461864d84STakashi Iwai See comment above regarding PCM restart. 21561864d84STakashi Iwai */ 216ad0119abSTakashi Iwai if (line6pcm->out.active_urbs || line6pcm->out.unlink_urbs) { 21761864d84STakashi Iwai dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); 21861864d84STakashi Iwai return -EBUSY; 21961864d84STakashi Iwai } 22061864d84STakashi Iwai 221ad0119abSTakashi Iwai line6pcm->out.count = 0; 22261864d84STakashi Iwai err = line6_submit_audio_out_all_urbs(line6pcm); 22361864d84STakashi Iwai 22461864d84STakashi Iwai if (err < 0) 22561864d84STakashi Iwai goto pcm_acquire_error; 22661864d84STakashi Iwai 22761864d84STakashi Iwai flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM; 22861864d84STakashi Iwai } 22961864d84STakashi Iwai 23061864d84STakashi Iwai return 0; 23161864d84STakashi Iwai 23261864d84STakashi Iwai pcm_acquire_error: 23361864d84STakashi Iwai /* 23461864d84STakashi Iwai If not all requested resources/streams could be obtained, release 23561864d84STakashi Iwai those which were successfully obtained (if any). 23661864d84STakashi Iwai */ 2375343ecf4STakashi Iwai line6_pcm_release(line6pcm, flags_final); 23861864d84STakashi Iwai return err; 23961864d84STakashi Iwai } 240ccddbe4aSTakashi Iwai EXPORT_SYMBOL_GPL(line6_pcm_acquire); 24161864d84STakashi Iwai 24261864d84STakashi Iwai int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels) 24361864d84STakashi Iwai { 24461864d84STakashi Iwai unsigned long flags_old, flags_new; 24561864d84STakashi Iwai 24661864d84STakashi Iwai do { 24761864d84STakashi Iwai flags_old = ACCESS_ONCE(line6pcm->flags); 24861864d84STakashi Iwai flags_new = flags_old & ~channels; 24961864d84STakashi Iwai } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); 25061864d84STakashi Iwai 25161864d84STakashi Iwai if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM)) 252d8131e67STakashi Iwai line6_unlink_audio_urbs(line6pcm, &line6pcm->in); 25361864d84STakashi Iwai 25461864d84STakashi Iwai if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) { 255d8131e67STakashi Iwai line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in); 256*e90576c5STakashi Iwai line6_free_stream_buffer(line6pcm, &line6pcm->in); 25761864d84STakashi Iwai } 25861864d84STakashi Iwai 25961864d84STakashi Iwai if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM)) 260d8131e67STakashi Iwai line6_unlink_audio_urbs(line6pcm, &line6pcm->out); 26161864d84STakashi Iwai 26261864d84STakashi Iwai if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) { 263d8131e67STakashi Iwai line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out); 264*e90576c5STakashi Iwai line6_free_stream_buffer(line6pcm, &line6pcm->out); 26561864d84STakashi Iwai } 26661864d84STakashi Iwai 26761864d84STakashi Iwai return 0; 26861864d84STakashi Iwai } 269ccddbe4aSTakashi Iwai EXPORT_SYMBOL_GPL(line6_pcm_release); 27061864d84STakashi Iwai 27161864d84STakashi Iwai /* trigger callback */ 27261864d84STakashi Iwai int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) 27361864d84STakashi Iwai { 27461864d84STakashi Iwai struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 27561864d84STakashi Iwai struct snd_pcm_substream *s; 276f2a76225STakashi Iwai int err = 0; 27761864d84STakashi Iwai 27861864d84STakashi Iwai clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags); 27961864d84STakashi Iwai 28061864d84STakashi Iwai snd_pcm_group_for_each_entry(s, substream) { 2817d70c81cSTakashi Iwai if (s->pcm->card != substream->pcm->card) 2827d70c81cSTakashi Iwai continue; 28361864d84STakashi Iwai switch (s->stream) { 28461864d84STakashi Iwai case SNDRV_PCM_STREAM_PLAYBACK: 28561864d84STakashi Iwai err = snd_line6_playback_trigger(line6pcm, cmd); 28661864d84STakashi Iwai break; 28761864d84STakashi Iwai 28861864d84STakashi Iwai case SNDRV_PCM_STREAM_CAPTURE: 28961864d84STakashi Iwai err = snd_line6_capture_trigger(line6pcm, cmd); 29061864d84STakashi Iwai break; 29161864d84STakashi Iwai 29261864d84STakashi Iwai default: 29361864d84STakashi Iwai dev_err(line6pcm->line6->ifcdev, 29461864d84STakashi Iwai "Unknown stream direction %d\n", s->stream); 295f2a76225STakashi Iwai err = -EINVAL; 296f2a76225STakashi Iwai break; 29761864d84STakashi Iwai } 298f2a76225STakashi Iwai if (err < 0) 299f2a76225STakashi Iwai break; 30061864d84STakashi Iwai } 30161864d84STakashi Iwai 302f2a76225STakashi Iwai return err; 30361864d84STakashi Iwai } 30461864d84STakashi Iwai 30561864d84STakashi Iwai /* control info callback */ 30661864d84STakashi Iwai static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol, 30761864d84STakashi Iwai struct snd_ctl_elem_info *uinfo) 30861864d84STakashi Iwai { 30961864d84STakashi Iwai uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 31061864d84STakashi Iwai uinfo->count = 2; 31161864d84STakashi Iwai uinfo->value.integer.min = 0; 31261864d84STakashi Iwai uinfo->value.integer.max = 256; 31361864d84STakashi Iwai return 0; 31461864d84STakashi Iwai } 31561864d84STakashi Iwai 31661864d84STakashi Iwai /* control get callback */ 31761864d84STakashi Iwai static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol, 31861864d84STakashi Iwai struct snd_ctl_elem_value *ucontrol) 31961864d84STakashi Iwai { 32061864d84STakashi Iwai int i; 32161864d84STakashi Iwai struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 32261864d84STakashi Iwai 3239fb754b7STakashi Iwai for (i = 0; i < 2; i++) 32461864d84STakashi Iwai ucontrol->value.integer.value[i] = line6pcm->volume_playback[i]; 32561864d84STakashi Iwai 32661864d84STakashi Iwai return 0; 32761864d84STakashi Iwai } 32861864d84STakashi Iwai 32961864d84STakashi Iwai /* control put callback */ 33061864d84STakashi Iwai static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol, 33161864d84STakashi Iwai struct snd_ctl_elem_value *ucontrol) 33261864d84STakashi Iwai { 33361864d84STakashi Iwai int i, changed = 0; 33461864d84STakashi Iwai struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 33561864d84STakashi Iwai 3369fb754b7STakashi Iwai for (i = 0; i < 2; i++) 33761864d84STakashi Iwai if (line6pcm->volume_playback[i] != 33861864d84STakashi Iwai ucontrol->value.integer.value[i]) { 33961864d84STakashi Iwai line6pcm->volume_playback[i] = 34061864d84STakashi Iwai ucontrol->value.integer.value[i]; 34161864d84STakashi Iwai changed = 1; 34261864d84STakashi Iwai } 34361864d84STakashi Iwai 34461864d84STakashi Iwai return changed; 34561864d84STakashi Iwai } 34661864d84STakashi Iwai 34761864d84STakashi Iwai /* control definition */ 348075587b7STakashi Iwai static struct snd_kcontrol_new line6_controls[] = { 349075587b7STakashi Iwai { 35061864d84STakashi Iwai .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 35161864d84STakashi Iwai .name = "PCM Playback Volume", 35261864d84STakashi Iwai .info = snd_line6_control_playback_info, 35361864d84STakashi Iwai .get = snd_line6_control_playback_get, 35461864d84STakashi Iwai .put = snd_line6_control_playback_put 355075587b7STakashi Iwai }, 356075587b7STakashi Iwai { 357075587b7STakashi Iwai .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 358075587b7STakashi Iwai .name = "Impulse Response Volume", 359075587b7STakashi Iwai .info = snd_line6_impulse_volume_info, 360075587b7STakashi Iwai .get = snd_line6_impulse_volume_get, 361075587b7STakashi Iwai .put = snd_line6_impulse_volume_put 362075587b7STakashi Iwai }, 363075587b7STakashi Iwai { 364075587b7STakashi Iwai .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 365075587b7STakashi Iwai .name = "Impulse Response Period", 366075587b7STakashi Iwai .info = snd_line6_impulse_period_info, 367075587b7STakashi Iwai .get = snd_line6_impulse_period_get, 368075587b7STakashi Iwai .put = snd_line6_impulse_period_put 369075587b7STakashi Iwai }, 37061864d84STakashi Iwai }; 37161864d84STakashi Iwai 37261864d84STakashi Iwai /* 37361864d84STakashi Iwai Cleanup the PCM device. 37461864d84STakashi Iwai */ 375d8131e67STakashi Iwai static void cleanup_urbs(struct line6_pcm_stream *pcms) 37661864d84STakashi Iwai { 37761864d84STakashi Iwai int i; 37861864d84STakashi Iwai 3799fb754b7STakashi Iwai for (i = 0; i < LINE6_ISO_BUFFERS; i++) { 380d8131e67STakashi Iwai if (pcms->urbs[i]) { 381d8131e67STakashi Iwai usb_kill_urb(pcms->urbs[i]); 382d8131e67STakashi Iwai usb_free_urb(pcms->urbs[i]); 38361864d84STakashi Iwai } 38461864d84STakashi Iwai } 385d8131e67STakashi Iwai } 386d8131e67STakashi Iwai 387d8131e67STakashi Iwai static void line6_cleanup_pcm(struct snd_pcm *pcm) 388d8131e67STakashi Iwai { 389d8131e67STakashi Iwai struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm); 390d8131e67STakashi Iwai 391d8131e67STakashi Iwai cleanup_urbs(&line6pcm->out); 392d8131e67STakashi Iwai cleanup_urbs(&line6pcm->in); 393b45a7c56STakashi Iwai kfree(line6pcm); 39461864d84STakashi Iwai } 39561864d84STakashi Iwai 39661864d84STakashi Iwai /* create a PCM device */ 397b45a7c56STakashi Iwai static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret) 39861864d84STakashi Iwai { 39961864d84STakashi Iwai struct snd_pcm *pcm; 40061864d84STakashi Iwai int err; 40161864d84STakashi Iwai 402b45a7c56STakashi Iwai err = snd_pcm_new(line6->card, (char *)line6->properties->name, 403b45a7c56STakashi Iwai 0, 1, 1, pcm_ret); 40461864d84STakashi Iwai if (err < 0) 40561864d84STakashi Iwai return err; 406b45a7c56STakashi Iwai pcm = *pcm_ret; 407b45a7c56STakashi Iwai strcpy(pcm->name, line6->properties->name); 40861864d84STakashi Iwai 40961864d84STakashi Iwai /* set operators */ 41061864d84STakashi Iwai snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 41161864d84STakashi Iwai &snd_line6_playback_ops); 41261864d84STakashi Iwai snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops); 41361864d84STakashi Iwai 41461864d84STakashi Iwai /* pre-allocation of buffers */ 41561864d84STakashi Iwai snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, 41661864d84STakashi Iwai snd_dma_continuous_data 41761864d84STakashi Iwai (GFP_KERNEL), 64 * 1024, 41861864d84STakashi Iwai 128 * 1024); 41961864d84STakashi Iwai return 0; 42061864d84STakashi Iwai } 42161864d84STakashi Iwai 42261864d84STakashi Iwai /* 4235a475311STakashi Iwai Sync with PCM stream stops. 42461864d84STakashi Iwai */ 42561864d84STakashi Iwai void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm) 42661864d84STakashi Iwai { 427d8131e67STakashi Iwai line6_unlink_audio_urbs(line6pcm, &line6pcm->out); 428d8131e67STakashi Iwai line6_unlink_audio_urbs(line6pcm, &line6pcm->in); 429d8131e67STakashi Iwai line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out); 430d8131e67STakashi Iwai line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in); 43161864d84STakashi Iwai } 43261864d84STakashi Iwai 43361864d84STakashi Iwai /* 43461864d84STakashi Iwai Create and register the PCM device and mixer entries. 43561864d84STakashi Iwai Create URBs for playback and capture. 43661864d84STakashi Iwai */ 43761864d84STakashi Iwai int line6_init_pcm(struct usb_line6 *line6, 43861864d84STakashi Iwai struct line6_pcm_properties *properties) 43961864d84STakashi Iwai { 440075587b7STakashi Iwai int i, err; 44161864d84STakashi Iwai unsigned ep_read = line6->properties->ep_audio_r; 44261864d84STakashi Iwai unsigned ep_write = line6->properties->ep_audio_w; 443b45a7c56STakashi Iwai struct snd_pcm *pcm; 44461864d84STakashi Iwai struct snd_line6_pcm *line6pcm; 44561864d84STakashi Iwai 44661864d84STakashi Iwai if (!(line6->properties->capabilities & LINE6_CAP_PCM)) 44761864d84STakashi Iwai return 0; /* skip PCM initialization and report success */ 44861864d84STakashi Iwai 449b45a7c56STakashi Iwai err = snd_line6_new_pcm(line6, &pcm); 450b45a7c56STakashi Iwai if (err < 0) 451b45a7c56STakashi Iwai return err; 45261864d84STakashi Iwai 453b45a7c56STakashi Iwai line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL); 454b45a7c56STakashi Iwai if (!line6pcm) 45561864d84STakashi Iwai return -ENOMEM; 45661864d84STakashi Iwai 457b45a7c56STakashi Iwai line6pcm->pcm = pcm; 458b45a7c56STakashi Iwai line6pcm->properties = properties; 45961864d84STakashi Iwai line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255; 46061864d84STakashi Iwai line6pcm->volume_monitor = 255; 46161864d84STakashi Iwai line6pcm->line6 = line6; 46261864d84STakashi Iwai 46361864d84STakashi Iwai /* Read and write buffers are sized identically, so choose minimum */ 46461864d84STakashi Iwai line6pcm->max_packet_size = min( 46561864d84STakashi Iwai usb_maxpacket(line6->usbdev, 46661864d84STakashi Iwai usb_rcvisocpipe(line6->usbdev, ep_read), 0), 46761864d84STakashi Iwai usb_maxpacket(line6->usbdev, 46861864d84STakashi Iwai usb_sndisocpipe(line6->usbdev, ep_write), 1)); 46961864d84STakashi Iwai 470ad0119abSTakashi Iwai spin_lock_init(&line6pcm->out.lock); 471ad0119abSTakashi Iwai spin_lock_init(&line6pcm->in.lock); 472075587b7STakashi Iwai line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; 47361864d84STakashi Iwai 474b45a7c56STakashi Iwai line6->line6pcm = line6pcm; 475b45a7c56STakashi Iwai 476b45a7c56STakashi Iwai pcm->private_data = line6pcm; 477b45a7c56STakashi Iwai pcm->private_free = line6_cleanup_pcm; 478b45a7c56STakashi Iwai 47961864d84STakashi Iwai err = line6_create_audio_out_urbs(line6pcm); 48061864d84STakashi Iwai if (err < 0) 48161864d84STakashi Iwai return err; 48261864d84STakashi Iwai 48361864d84STakashi Iwai err = line6_create_audio_in_urbs(line6pcm); 48461864d84STakashi Iwai if (err < 0) 48561864d84STakashi Iwai return err; 48661864d84STakashi Iwai 48761864d84STakashi Iwai /* mixer: */ 488075587b7STakashi Iwai for (i = 0; i < ARRAY_SIZE(line6_controls); i++) { 489075587b7STakashi Iwai err = snd_ctl_add(line6->card, 490075587b7STakashi Iwai snd_ctl_new1(&line6_controls[i], line6pcm)); 49161864d84STakashi Iwai if (err < 0) 49261864d84STakashi Iwai return err; 493075587b7STakashi Iwai } 49461864d84STakashi Iwai 49561864d84STakashi Iwai return 0; 49661864d84STakashi Iwai } 497ccddbe4aSTakashi Iwai EXPORT_SYMBOL_GPL(line6_init_pcm); 49861864d84STakashi Iwai 49961864d84STakashi Iwai /* prepare pcm callback */ 50061864d84STakashi Iwai int snd_line6_prepare(struct snd_pcm_substream *substream) 50161864d84STakashi Iwai { 50261864d84STakashi Iwai struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 50361864d84STakashi Iwai 50461864d84STakashi Iwai switch (substream->stream) { 50561864d84STakashi Iwai case SNDRV_PCM_STREAM_PLAYBACK: 506d8131e67STakashi Iwai if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0) { 507d8131e67STakashi Iwai line6_unlink_audio_urbs(line6pcm, &line6pcm->out); 508d8131e67STakashi Iwai line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out); 509d8131e67STakashi Iwai } 51061864d84STakashi Iwai break; 51161864d84STakashi Iwai 51261864d84STakashi Iwai case SNDRV_PCM_STREAM_CAPTURE: 513d8131e67STakashi Iwai if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0) { 514d8131e67STakashi Iwai line6_unlink_audio_urbs(line6pcm, &line6pcm->in); 515d8131e67STakashi Iwai line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in); 516d8131e67STakashi Iwai } 51761864d84STakashi Iwai break; 51861864d84STakashi Iwai } 51961864d84STakashi Iwai 52061864d84STakashi Iwai if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) { 521ad0119abSTakashi Iwai line6pcm->out.count = 0; 522ad0119abSTakashi Iwai line6pcm->out.pos = 0; 523ad0119abSTakashi Iwai line6pcm->out.pos_done = 0; 524ad0119abSTakashi Iwai line6pcm->out.bytes = 0; 525ad0119abSTakashi Iwai line6pcm->in.count = 0; 526ad0119abSTakashi Iwai line6pcm->in.pos_done = 0; 527ad0119abSTakashi Iwai line6pcm->in.bytes = 0; 52861864d84STakashi Iwai } 52961864d84STakashi Iwai 53061864d84STakashi Iwai return 0; 53161864d84STakashi Iwai } 532