aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Fay <mail@bfay.de>2007-02-05 06:27:21 -0500
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:03:53 -0500
commitd0b0fac14edf81dc62615cd757e7c73d2059152c (patch)
treefa42567910d6993eac52ce601012a598249cec85
parentf32610edab47f36946d23b883aeae91e15986121 (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.c53
-rw-r--r--sound/usb/usbaudio.h1
-rw-r--r--sound/usb/usbquirks.h32
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 */
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) {
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),