aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usbaudio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r--sound/usb/usbaudio.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 8fd37596e3a1..4dfb91d4398a 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -3077,6 +3077,58 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip,
3077 return 0; 3077 return 0;
3078} 3078}
3079 3079
3080/*
3081 * Create a stream for an Edirol UA-101 interface.
3082 * Copy, paste and modify from Edirol UA-1000
3083 */
3084static int create_ua101_quirk(struct snd_usb_audio *chip,
3085 struct usb_interface *iface,
3086 const struct snd_usb_audio_quirk *quirk)
3087{
3088 static const struct audioformat ua101_format = {
3089 .format = SNDRV_PCM_FORMAT_S32_LE,
3090 .fmt_type = USB_FORMAT_TYPE_I,
3091 .altsetting = 1,
3092 .altset_idx = 1,
3093 .attributes = 0,
3094 .rates = SNDRV_PCM_RATE_CONTINUOUS,
3095 };
3096 struct usb_host_interface *alts;
3097 struct usb_interface_descriptor *altsd;
3098 struct audioformat *fp;
3099 int stream, err;
3100
3101 if (iface->num_altsetting != 2)
3102 return -ENXIO;
3103 alts = &iface->altsetting[1];
3104 altsd = get_iface_desc(alts);
3105 if (alts->extralen != 18 || alts->extra[1] != USB_DT_CS_INTERFACE ||
3106 altsd->bNumEndpoints != 1)
3107 return -ENXIO;
3108
3109 fp = kmemdup(&ua101_format, sizeof(*fp), GFP_KERNEL);
3110 if (!fp)
3111 return -ENOMEM;
3112
3113 fp->channels = alts->extra[11];
3114 fp->iface = altsd->bInterfaceNumber;
3115 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
3116 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
3117 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3118 fp->rate_max = fp->rate_min = combine_triple(&alts->extra[15]);
3119
3120 stream = (fp->endpoint & USB_DIR_IN)
3121 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3122 err = add_audio_endpoint(chip, stream, fp);
3123 if (err < 0) {
3124 kfree(fp);
3125 return err;
3126 }
3127 /* FIXME: playback must be synchronized to capture */
3128 usb_set_interface(chip->dev, fp->iface, 0);
3129 return 0;
3130}
3131
3080static int snd_usb_create_quirk(struct snd_usb_audio *chip, 3132static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3081 struct usb_interface *iface, 3133 struct usb_interface *iface,
3082 const struct snd_usb_audio_quirk *quirk); 3134 const struct snd_usb_audio_quirk *quirk);
@@ -3258,6 +3310,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3258 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, 3310 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3259 [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, 3311 [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk,
3260 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, 3312 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
3313 [QUIRK_AUDIO_EDIROL_UA101] = create_ua101_quirk,
3261 }; 3314 };
3262 3315
3263 if (quirk->type < QUIRK_TYPE_COUNT) { 3316 if (quirk->type < QUIRK_TYPE_COUNT) {