Commit edcd3633 authored by Daniel Mack's avatar Daniel Mack Committed by Takashi Iwai

ALSA: snd-usb: switch over to new endpoint streaming logic

With the previous commit that added the new streaming model, all
endpoint and streaming related code is now in endpoint.c, and pcm.c
only acts as a wrapper for handling the packet's payload.
Signed-off-by: default avatarDaniel Mack <zonque@gmail.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 8fdff6a3
...@@ -131,8 +131,9 @@ static void snd_usb_stream_disconnect(struct list_head *head) ...@@ -131,8 +131,9 @@ static void snd_usb_stream_disconnect(struct list_head *head)
subs = &as->substream[idx]; subs = &as->substream[idx];
if (!subs->num_formats) if (!subs->num_formats)
continue; continue;
snd_usb_release_substream_urbs(subs, 1);
subs->interface = -1; subs->interface = -1;
subs->data_endpoint = NULL;
subs->sync_endpoint = NULL;
} }
} }
...@@ -350,6 +351,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, ...@@ -350,6 +351,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct)); le16_to_cpu(dev->descriptor.idProduct));
INIT_LIST_HEAD(&chip->pcm_list); INIT_LIST_HEAD(&chip->pcm_list);
INIT_LIST_HEAD(&chip->ep_list);
INIT_LIST_HEAD(&chip->midi_list); INIT_LIST_HEAD(&chip->midi_list);
INIT_LIST_HEAD(&chip->mixer_list); INIT_LIST_HEAD(&chip->mixer_list);
...@@ -567,6 +569,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, ...@@ -567,6 +569,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
list_for_each(p, &chip->pcm_list) { list_for_each(p, &chip->pcm_list) {
snd_usb_stream_disconnect(p); snd_usb_stream_disconnect(p);
} }
/* release the endpoint resources */
list_for_each(p, &chip->ep_list) {
snd_usb_endpoint_free(p);
}
/* release the midi resources */ /* release the midi resources */
list_for_each(p, &chip->midi_list) { list_for_each(p, &chip->midi_list) {
snd_usbmidi_disconnect(p); snd_usbmidi_disconnect(p);
......
...@@ -145,6 +145,10 @@ struct snd_usb_substream { ...@@ -145,6 +145,10 @@ struct snd_usb_substream {
struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */ struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */
char *syncbuf; /* sync buffer for all sync URBs */ char *syncbuf; /* sync buffer for all sync URBs */
dma_addr_t sync_dma; /* DMA address of syncbuf */ dma_addr_t sync_dma; /* DMA address of syncbuf */
/* data and sync endpoints for this stream */
struct snd_usb_endpoint *data_endpoint;
struct snd_usb_endpoint *sync_endpoint;
unsigned long flags;
u64 formats; /* format bitmasks (all or'ed) */ u64 formats; /* format bitmasks (all or'ed) */
unsigned int num_formats; /* number of supported audio formats (list) */ unsigned int num_formats; /* number of supported audio formats (list) */
......
...@@ -912,46 +912,6 @@ void snd_usb_init_substream(struct snd_usb_stream *as, ...@@ -912,46 +912,6 @@ void snd_usb_init_substream(struct snd_usb_stream *as,
subs->fmt_type = fp->fmt_type; subs->fmt_type = fp->fmt_type;
} }
int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_usb_substream *subs = substream->runtime->private_data;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
subs->ops.prepare = prepare_playback_urb;
return 0;
case SNDRV_PCM_TRIGGER_STOP:
return deactivate_urbs_old(subs, 0, 0);
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
subs->ops.prepare = prepare_nodata_playback_urb;
return 0;
}
return -EINVAL;
}
int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_usb_substream *subs = substream->runtime->private_data;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
subs->ops.retire = retire_capture_urb;
return start_urbs(subs, substream->runtime);
case SNDRV_PCM_TRIGGER_STOP:
return deactivate_urbs_old(subs, 0, 0);
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
subs->ops.retire = retire_paused_capture_urb;
return 0;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
subs->ops.retire = retire_capture_urb;
return 0;
}
return -EINVAL;
}
int snd_usb_substream_prepare(struct snd_usb_substream *subs, int snd_usb_substream_prepare(struct snd_usb_substream *subs,
struct snd_pcm_runtime *runtime) struct snd_pcm_runtime *runtime)
{ {
......
...@@ -15,9 +15,6 @@ void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force); ...@@ -15,9 +15,6 @@ void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force);
int snd_usb_substream_prepare(struct snd_usb_substream *subs, int snd_usb_substream_prepare(struct snd_usb_substream *subs,
struct snd_pcm_runtime *runtime); struct snd_pcm_runtime *runtime);
int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd);
int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd);
#define SND_USB_ENDPOINT_TYPE_DATA 0 #define SND_USB_ENDPOINT_TYPE_DATA 0
#define SND_USB_ENDPOINT_TYPE_SYNC 1 #define SND_USB_ENDPOINT_TYPE_SYNC 1
......
This diff is collapsed.
...@@ -73,6 +73,31 @@ static void snd_usb_audio_pcm_free(struct snd_pcm *pcm) ...@@ -73,6 +73,31 @@ static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
} }
} }
/*
* initialize the substream instance.
*/
static void snd_usb_init_substream(struct snd_usb_stream *as,
int stream,
struct audioformat *fp)
{
struct snd_usb_substream *subs = &as->substream[stream];
INIT_LIST_HEAD(&subs->fmt_list);
spin_lock_init(&subs->lock);
subs->stream = as;
subs->direction = stream;
subs->dev = as->chip->dev;
subs->txfr_quirk = as->chip->txfr_quirk;
snd_usb_set_pcm_ops(as->pcm, stream);
list_add_tail(&fp->list, &subs->fmt_list);
subs->formats |= fp->formats;
subs->num_formats++;
subs->fmt_type = fp->fmt_type;
}
/* /*
* add this endpoint to the chip instance. * add this endpoint to the chip instance.
...@@ -94,9 +119,9 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, ...@@ -94,9 +119,9 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
if (as->fmt_type != fp->fmt_type) if (as->fmt_type != fp->fmt_type)
continue; continue;
subs = &as->substream[stream]; subs = &as->substream[stream];
if (!subs->endpoint) if (!subs->data_endpoint)
continue; continue;
if (subs->endpoint == fp->endpoint) { if (subs->data_endpoint->ep_num == fp->endpoint) {
list_add_tail(&fp->list, &subs->fmt_list); list_add_tail(&fp->list, &subs->fmt_list);
subs->num_formats++; subs->num_formats++;
subs->formats |= fp->formats; subs->formats |= fp->formats;
...@@ -109,7 +134,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, ...@@ -109,7 +134,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
if (as->fmt_type != fp->fmt_type) if (as->fmt_type != fp->fmt_type)
continue; continue;
subs = &as->substream[stream]; subs = &as->substream[stream];
if (subs->endpoint) if (subs->data_endpoint)
continue; continue;
err = snd_pcm_new_stream(as->pcm, stream, 1); err = snd_pcm_new_stream(as->pcm, stream, 1);
if (err < 0) if (err < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment