diff options
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r-- | sound/usb/usbaudio.c | 53 |
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 | */ | ||
3084 | static 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 | |||
3080 | static int snd_usb_create_quirk(struct snd_usb_audio *chip, | 3132 | static 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) { |