aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorEldad Zack <eldad@fogrefinery.com>2013-08-03 04:50:17 -0400
committerTakashi Iwai <tiwai@suse.de>2013-08-06 04:48:34 -0400
commit71bb64c56d787a221752b1de034fe8c07c737f5c (patch)
tree6af50222ade08ed53c6245e1d18091ecc6397503 /sound/usb
parentd133f2c22e9cb7b6afd170437cf0ef1e8a1571b6 (diff)
ALSA: usb-audio: separate sync endpoint setting from set_format
Setting the sync endpoint currently takes up about half of set_format(). Move it to a dedicated function. No functional change. Signed-off-by: Eldad Zack <eldad@fogrefinery.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/pcm.c128
1 files changed, 73 insertions, 55 deletions
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index be5c7c2219ea..e24ce7d58d83 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -327,64 +327,17 @@ static int search_roland_implicit_fb(struct usb_device *dev, int ifnum,
327 return 0; 327 return 0;
328} 328}
329 329
330/* 330
331 * find a matching format and set up the interface 331static int set_sync_endpoint(struct snd_usb_substream *subs,
332 */ 332 struct audioformat *fmt,
333static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) 333 struct usb_device *dev,
334 struct usb_host_interface *alts,
335 struct usb_interface_descriptor *altsd)
334{ 336{
335 struct usb_device *dev = subs->dev;
336 struct usb_host_interface *alts;
337 struct usb_interface_descriptor *altsd;
338 struct usb_interface *iface; 337 struct usb_interface *iface;
339 unsigned int ep, attr;
340 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; 338 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
341 int err, implicit_fb = 0; 339 unsigned int ep, attr;
342 340 int implicit_fb = 0;
343 iface = usb_ifnum_to_if(dev, fmt->iface);
344 if (WARN_ON(!iface))
345 return -EINVAL;
346 alts = &iface->altsetting[fmt->altset_idx];
347 altsd = get_iface_desc(alts);
348 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
349 return -EINVAL;
350
351 if (fmt == subs->cur_audiofmt)
352 return 0;
353
354 /* close the old interface */
355 if (subs->interface >= 0 && subs->interface != fmt->iface) {
356 err = usb_set_interface(subs->dev, subs->interface, 0);
357 if (err < 0) {
358 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed (%d)\n",
359 dev->devnum, fmt->iface, fmt->altsetting, err);
360 return -EIO;
361 }
362 subs->interface = -1;
363 subs->altset_idx = 0;
364 }
365
366 /* set interface */
367 if (subs->interface != fmt->iface ||
368 subs->altset_idx != fmt->altset_idx) {
369 err = usb_set_interface(dev, fmt->iface, fmt->altsetting);
370 if (err < 0) {
371 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed (%d)\n",
372 dev->devnum, fmt->iface, fmt->altsetting, err);
373 return -EIO;
374 }
375 snd_printdd(KERN_INFO "setting usb interface %d:%d\n",
376 fmt->iface, fmt->altsetting);
377 subs->interface = fmt->iface;
378 subs->altset_idx = fmt->altset_idx;
379
380 snd_usb_set_interface_quirk(dev);
381 }
382
383 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip,
384 alts, fmt->endpoint, subs->direction,
385 SND_USB_ENDPOINT_TYPE_DATA);
386 if (!subs->data_endpoint)
387 return -EINVAL;
388 341
389 /* we need a sync pipe in async OUT or adaptive IN mode */ 342 /* we need a sync pipe in async OUT or adaptive IN mode */
390 /* check the number of EP, since some devices have broken 343 /* check the number of EP, since some devices have broken
@@ -479,6 +432,71 @@ add_sync_ep:
479 subs->data_endpoint->sync_master = subs->sync_endpoint; 432 subs->data_endpoint->sync_master = subs->sync_endpoint;
480 } 433 }
481 434
435 return 0;
436}
437
438/*
439 * find a matching format and set up the interface
440 */
441static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
442{
443 struct usb_device *dev = subs->dev;
444 struct usb_host_interface *alts;
445 struct usb_interface_descriptor *altsd;
446 struct usb_interface *iface;
447 int err;
448
449 iface = usb_ifnum_to_if(dev, fmt->iface);
450 if (WARN_ON(!iface))
451 return -EINVAL;
452 alts = &iface->altsetting[fmt->altset_idx];
453 altsd = get_iface_desc(alts);
454 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
455 return -EINVAL;
456
457 if (fmt == subs->cur_audiofmt)
458 return 0;
459
460 /* close the old interface */
461 if (subs->interface >= 0 && subs->interface != fmt->iface) {
462 err = usb_set_interface(subs->dev, subs->interface, 0);
463 if (err < 0) {
464 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed (%d)\n",
465 dev->devnum, fmt->iface, fmt->altsetting, err);
466 return -EIO;
467 }
468 subs->interface = -1;
469 subs->altset_idx = 0;
470 }
471
472 /* set interface */
473 if (subs->interface != fmt->iface ||
474 subs->altset_idx != fmt->altset_idx) {
475 err = usb_set_interface(dev, fmt->iface, fmt->altsetting);
476 if (err < 0) {
477 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed (%d)\n",
478 dev->devnum, fmt->iface, fmt->altsetting, err);
479 return -EIO;
480 }
481 snd_printdd(KERN_INFO "setting usb interface %d:%d\n",
482 fmt->iface, fmt->altsetting);
483 subs->interface = fmt->iface;
484 subs->altset_idx = fmt->altset_idx;
485
486 snd_usb_set_interface_quirk(dev);
487 }
488
489 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip,
490 alts, fmt->endpoint, subs->direction,
491 SND_USB_ENDPOINT_TYPE_DATA);
492
493 if (!subs->data_endpoint)
494 return -EINVAL;
495
496 err = set_sync_endpoint(subs, fmt, dev, alts, altsd);
497 if (err < 0)
498 return err;
499
482 err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt); 500 err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt);
483 if (err < 0) 501 if (err < 0)
484 return err; 502 return err;