diff options
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r-- | sound/usb/usbaudio.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index b8cfb7c2276..bbd70d5814a 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -71,6 +71,7 @@ static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; | |||
71 | static int nrpacks = 8; /* max. number of packets per urb */ | 71 | static int nrpacks = 8; /* max. number of packets per urb */ |
72 | static int async_unlink = 1; | 72 | static int async_unlink = 1; |
73 | static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/ | 73 | static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/ |
74 | static int ignore_ctl_error; | ||
74 | 75 | ||
75 | module_param_array(index, int, NULL, 0444); | 76 | module_param_array(index, int, NULL, 0444); |
76 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); | 77 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); |
@@ -88,7 +89,9 @@ module_param(async_unlink, bool, 0444); | |||
88 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); | 89 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); |
89 | module_param_array(device_setup, int, NULL, 0444); | 90 | module_param_array(device_setup, int, NULL, 0444); |
90 | MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); | 91 | MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); |
91 | 92 | module_param(ignore_ctl_error, bool, 0444); | |
93 | MODULE_PARM_DESC(ignore_ctl_error, | ||
94 | "Ignore errors from USB controller for mixer interfaces."); | ||
92 | 95 | ||
93 | /* | 96 | /* |
94 | * debug the h/w constraints | 97 | * debug the h/w constraints |
@@ -481,7 +484,7 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, | |||
481 | } | 484 | } |
482 | 485 | ||
483 | /* | 486 | /* |
484 | * process after E-Mu 0202/0404 high speed playback sync complete | 487 | * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete |
485 | * | 488 | * |
486 | * These devices return the number of samples per packet instead of the number | 489 | * These devices return the number of samples per packet instead of the number |
487 | * of samples per microframe. | 490 | * of samples per microframe. |
@@ -841,7 +844,8 @@ static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *ru | |||
841 | return -EBADFD; | 844 | return -EBADFD; |
842 | 845 | ||
843 | for (i = 0; i < subs->nurbs; i++) { | 846 | for (i = 0; i < subs->nurbs; i++) { |
844 | snd_assert(subs->dataurb[i].urb, return -EINVAL); | 847 | if (snd_BUG_ON(!subs->dataurb[i].urb)) |
848 | return -EINVAL; | ||
845 | if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) { | 849 | if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) { |
846 | snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i); | 850 | snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i); |
847 | goto __error; | 851 | goto __error; |
@@ -849,7 +853,8 @@ static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *ru | |||
849 | } | 853 | } |
850 | if (subs->syncpipe) { | 854 | if (subs->syncpipe) { |
851 | for (i = 0; i < SYNC_URBS; i++) { | 855 | for (i = 0; i < SYNC_URBS; i++) { |
852 | snd_assert(subs->syncurb[i].urb, return -EINVAL); | 856 | if (snd_BUG_ON(!subs->syncurb[i].urb)) |
857 | return -EINVAL; | ||
853 | if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) { | 858 | if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) { |
854 | snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i); | 859 | snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i); |
855 | goto __error; | 860 | goto __error; |
@@ -1321,10 +1326,12 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
1321 | int err; | 1326 | int err; |
1322 | 1327 | ||
1323 | iface = usb_ifnum_to_if(dev, fmt->iface); | 1328 | iface = usb_ifnum_to_if(dev, fmt->iface); |
1324 | snd_assert(iface, return -EINVAL); | 1329 | if (WARN_ON(!iface)) |
1330 | return -EINVAL; | ||
1325 | alts = &iface->altsetting[fmt->altset_idx]; | 1331 | alts = &iface->altsetting[fmt->altset_idx]; |
1326 | altsd = get_iface_desc(alts); | 1332 | altsd = get_iface_desc(alts); |
1327 | snd_assert(altsd->bAlternateSetting == fmt->altsetting, return -EINVAL); | 1333 | if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting)) |
1334 | return -EINVAL; | ||
1328 | 1335 | ||
1329 | if (fmt == subs->cur_audiofmt) | 1336 | if (fmt == subs->cur_audiofmt) |
1330 | return 0; | 1337 | return 0; |
@@ -2257,6 +2264,7 @@ static void init_substream(struct snd_usb_stream *as, int stream, struct audiofo | |||
2257 | switch (as->chip->usb_id) { | 2264 | switch (as->chip->usb_id) { |
2258 | case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */ | 2265 | case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */ |
2259 | case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */ | 2266 | case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */ |
2267 | case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */ | ||
2260 | subs->ops.retire_sync = retire_playback_sync_urb_hs_emu; | 2268 | subs->ops.retire_sync = retire_playback_sync_urb_hs_emu; |
2261 | break; | 2269 | break; |
2262 | } | 2270 | } |
@@ -2989,12 +2997,12 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip, | |||
2989 | } | 2997 | } |
2990 | 2998 | ||
2991 | /* | 2999 | /* |
2992 | * Create a stream for an Edirol UA-700/UA-25 interface. The only way | 3000 | * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface. |
2993 | * to detect the sample rate is by looking at wMaxPacketSize. | 3001 | * The only way to detect the sample rate is by looking at wMaxPacketSize. |
2994 | */ | 3002 | */ |
2995 | static int create_ua700_ua25_quirk(struct snd_usb_audio *chip, | 3003 | static int create_uaxx_quirk(struct snd_usb_audio *chip, |
2996 | struct usb_interface *iface, | 3004 | struct usb_interface *iface, |
2997 | const struct snd_usb_audio_quirk *quirk) | 3005 | const struct snd_usb_audio_quirk *quirk) |
2998 | { | 3006 | { |
2999 | static const struct audioformat ua_format = { | 3007 | static const struct audioformat ua_format = { |
3000 | .format = SNDRV_PCM_FORMAT_S24_3LE, | 3008 | .format = SNDRV_PCM_FORMAT_S24_3LE, |
@@ -3009,8 +3017,8 @@ static int create_ua700_ua25_quirk(struct snd_usb_audio *chip, | |||
3009 | struct audioformat *fp; | 3017 | struct audioformat *fp; |
3010 | int stream, err; | 3018 | int stream, err; |
3011 | 3019 | ||
3012 | /* both PCM and MIDI interfaces have 2 altsettings */ | 3020 | /* both PCM and MIDI interfaces have 2 or more altsettings */ |
3013 | if (iface->num_altsetting != 2) | 3021 | if (iface->num_altsetting < 2) |
3014 | return -ENXIO; | 3022 | return -ENXIO; |
3015 | alts = &iface->altsetting[1]; | 3023 | alts = &iface->altsetting[1]; |
3016 | altsd = get_iface_desc(alts); | 3024 | altsd = get_iface_desc(alts); |
@@ -3024,20 +3032,20 @@ static int create_ua700_ua25_quirk(struct snd_usb_audio *chip, | |||
3024 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | 3032 | .type = QUIRK_MIDI_FIXED_ENDPOINT, |
3025 | .data = &ua700_ep | 3033 | .data = &ua700_ep |
3026 | }; | 3034 | }; |
3027 | static const struct snd_usb_midi_endpoint_info ua25_ep = { | 3035 | static const struct snd_usb_midi_endpoint_info uaxx_ep = { |
3028 | .out_cables = 0x0001, | 3036 | .out_cables = 0x0001, |
3029 | .in_cables = 0x0001 | 3037 | .in_cables = 0x0001 |
3030 | }; | 3038 | }; |
3031 | static const struct snd_usb_audio_quirk ua25_quirk = { | 3039 | static const struct snd_usb_audio_quirk uaxx_quirk = { |
3032 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | 3040 | .type = QUIRK_MIDI_FIXED_ENDPOINT, |
3033 | .data = &ua25_ep | 3041 | .data = &uaxx_ep |
3034 | }; | 3042 | }; |
3035 | if (chip->usb_id == USB_ID(0x0582, 0x002b)) | 3043 | if (chip->usb_id == USB_ID(0x0582, 0x002b)) |
3036 | return snd_usb_create_midi_interface(chip, iface, | 3044 | return snd_usb_create_midi_interface(chip, iface, |
3037 | &ua700_quirk); | 3045 | &ua700_quirk); |
3038 | else | 3046 | else |
3039 | return snd_usb_create_midi_interface(chip, iface, | 3047 | return snd_usb_create_midi_interface(chip, iface, |
3040 | &ua25_quirk); | 3048 | &uaxx_quirk); |
3041 | } | 3049 | } |
3042 | 3050 | ||
3043 | if (altsd->bNumEndpoints != 1) | 3051 | if (altsd->bNumEndpoints != 1) |
@@ -3369,9 +3377,9 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
3369 | [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, | 3377 | [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, |
3370 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 3378 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
3371 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 3379 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
3372 | [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, | ||
3373 | [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, | 3380 | [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, |
3374 | [QUIRK_AUDIO_EDIROL_UA101] = create_ua101_quirk, | 3381 | [QUIRK_AUDIO_EDIROL_UA101] = create_ua101_quirk, |
3382 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk | ||
3375 | }; | 3383 | }; |
3376 | 3384 | ||
3377 | if (quirk->type < QUIRK_TYPE_COUNT) { | 3385 | if (quirk->type < QUIRK_TYPE_COUNT) { |
@@ -3629,7 +3637,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
3629 | if (err > 0) { | 3637 | if (err > 0) { |
3630 | /* create normal USB audio interfaces */ | 3638 | /* create normal USB audio interfaces */ |
3631 | if (snd_usb_create_streams(chip, ifnum) < 0 || | 3639 | if (snd_usb_create_streams(chip, ifnum) < 0 || |
3632 | snd_usb_create_mixer(chip, ifnum) < 0) { | 3640 | snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) { |
3633 | goto __error; | 3641 | goto __error; |
3634 | } | 3642 | } |
3635 | } | 3643 | } |