diff options
| author | Bjoern Fay <mail@bfay.de> | 2007-02-05 06:27:21 -0500 |
|---|---|---|
| committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:03:53 -0500 |
| commit | d0b0fac14edf81dc62615cd757e7c73d2059152c (patch) | |
| tree | fa42567910d6993eac52ce601012a598249cec85 | |
| parent | f32610edab47f36946d23b883aeae91e15986121 (diff) | |
[ALSA] usbaudio - Add support for Edirol UA-101
Added support for the Edirol UA-101 (only in high-speed mode) by taking
the quirks for the UA-1000 and change them accordingly. Changes were
made in 'usbaudio.c', 'usbaudio.h', and 'usbquirks.h'
MIDI and recording seem to work perfectly (with JACK), but playback
gives some few glitches. I think that's the mentioned
synchronizing-problem in the UA-1000 quirk ('FIXME: playback must be
synchronized to capture'), so I didn't change that.
ToDo: Adding Mixer-Support for the built-in
control-panel/patch-bay/router.
Signed-off-by: Bjoern Fay <mail@bfay.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
| -rw-r--r-- | sound/usb/usbaudio.c | 53 | ||||
| -rw-r--r-- | sound/usb/usbaudio.h | 1 | ||||
| -rw-r--r-- | sound/usb/usbquirks.h | 32 |
3 files changed, 85 insertions, 1 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) { |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 0f4b2b8541d6..2272f45a1867 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
| @@ -159,6 +159,7 @@ enum quirk_type { | |||
| 159 | QUIRK_AUDIO_FIXED_ENDPOINT, | 159 | QUIRK_AUDIO_FIXED_ENDPOINT, |
| 160 | QUIRK_AUDIO_EDIROL_UA700_UA25, | 160 | QUIRK_AUDIO_EDIROL_UA700_UA25, |
| 161 | QUIRK_AUDIO_EDIROL_UA1000, | 161 | QUIRK_AUDIO_EDIROL_UA1000, |
| 162 | QUIRK_AUDIO_EDIROL_UA101, | ||
| 162 | 163 | ||
| 163 | QUIRK_TYPE_COUNT | 164 | QUIRK_TYPE_COUNT |
| 164 | }; | 165 | }; |
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index a7e9563a01df..25b4ab4f61e7 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h | |||
| @@ -1098,7 +1098,37 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
| 1098 | } | 1098 | } |
| 1099 | } | 1099 | } |
| 1100 | }, | 1100 | }, |
| 1101 | /* TODO: add Edirol UA-101 support */ | 1101 | /* Roland UA-101 in High-Speed Mode only */ |
| 1102 | { | ||
| 1103 | USB_DEVICE(0x0582, 0x007d), | ||
| 1104 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
| 1105 | .vendor_name = "Roland", | ||
| 1106 | .product_name = "UA-101", | ||
| 1107 | .ifnum = QUIRK_ANY_INTERFACE, | ||
| 1108 | .type = QUIRK_COMPOSITE, | ||
| 1109 | .data = (const struct snd_usb_audio_quirk[]) { | ||
| 1110 | { | ||
| 1111 | .ifnum = 0, | ||
| 1112 | .type = QUIRK_AUDIO_EDIROL_UA101 | ||
| 1113 | }, | ||
| 1114 | { | ||
| 1115 | .ifnum = 1, | ||
| 1116 | .type = QUIRK_AUDIO_EDIROL_UA101 | ||
| 1117 | }, | ||
| 1118 | { | ||
| 1119 | .ifnum = 2, | ||
| 1120 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
| 1121 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
| 1122 | .out_cables = 0x0001, | ||
| 1123 | .in_cables = 0x0001 | ||
| 1124 | } | ||
| 1125 | }, | ||
| 1126 | { | ||
| 1127 | .ifnum = -1 | ||
| 1128 | } | ||
| 1129 | } | ||
| 1130 | } | ||
| 1131 | }, | ||
| 1102 | { | 1132 | { |
| 1103 | /* has ID 0x0081 when not in "Advanced Driver" mode */ | 1133 | /* has ID 0x0081 when not in "Advanced Driver" mode */ |
| 1104 | USB_DEVICE(0x0582, 0x0080), | 1134 | USB_DEVICE(0x0582, 0x0080), |
