static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */
static int nrpacks = 4; /* max. number of packets per urb */
static int async_unlink = 1;
-static int boot_devs;
-module_param_array(index, int, boot_devs, 0444);
+module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
-module_param_array(id, charp, boot_devs, 0444);
+module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
-module_param_array(enable, bool, boot_devs, 0444);
+module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
-module_param_array(vid, int, boot_devs, 0444);
+module_param_array(vid, int, NULL, 0444);
MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
-module_param_array(pid, int, boot_devs, 0444);
+module_param_array(pid, int, NULL, 0444);
MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
module_param(nrpacks, int, 0444);
MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
subs->running = 0;
if (!force && subs->stream->chip->shutdown) /* to be sure... */
- return 0;
+ return -EBADFD;
async = !can_sleep && async_unlink;
if (test_bit(i, &subs->active_mask)) {
if (! test_and_set_bit(i, &subs->unlink_mask)) {
struct urb *u = subs->dataurb[i].urb;
- if (async)
+ if (async) {
u->transfer_flags |= URB_ASYNC_UNLINK;
- else
- u->transfer_flags &= ~URB_ASYNC_UNLINK;
- usb_unlink_urb(u);
+ usb_unlink_urb(u);
+ } else
+ usb_kill_urb(u);
}
}
}
if (test_bit(i+16, &subs->active_mask)) {
if (! test_and_set_bit(i+16, &subs->unlink_mask)) {
struct urb *u = subs->syncurb[i].urb;
- if (async)
+ if (async) {
u->transfer_flags |= URB_ASYNC_UNLINK;
- else
- u->transfer_flags &= ~URB_ASYNC_UNLINK;
- usb_unlink_urb(u);
+ usb_unlink_urb(u);
+ } else
+ usb_kill_urb(u);
}
}
}
unsigned int i;
int err;
+ if (subs->stream->chip->shutdown)
+ return -EBADFD;
+
for (i = 0; i < subs->nurbs; i++) {
snd_assert(subs->dataurb[i].urb, return -EINVAL);
if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
}
/*
- * Create a stream for an Edirol UA-700 interface. The only way
+ * Create a stream for an Edirol UA-700/UA-25 interface. The only way
* to detect the sample rate is by looking at wMaxPacketSize.
*/
-static int create_ua700_quirk(snd_usb_audio_t *chip, struct usb_interface *iface)
+static int create_ua700_ua25_quirk(snd_usb_audio_t *chip,
+ struct usb_interface *iface)
{
- static const struct audioformat ua700_format = {
+ static const struct audioformat ua_format = {
.format = SNDRV_PCM_FORMAT_S24_3LE,
.channels = 2,
.fmt_type = USB_FORMAT_TYPE_I,
altsd = get_iface_desc(alts);
if (altsd->bNumEndpoints == 2) {
- static const snd_usb_midi_endpoint_info_t ep = {
+ static const snd_usb_midi_endpoint_info_t ua700_ep = {
.out_cables = 0x0003,
.in_cables = 0x0003
};
- static const snd_usb_audio_quirk_t quirk = {
+ static const snd_usb_audio_quirk_t ua700_quirk = {
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = &ua700_ep
+ };
+ static const snd_usb_midi_endpoint_info_t ua25_ep = {
+ .out_cables = 0x0001,
+ .in_cables = 0x0001
+ };
+ static const snd_usb_audio_quirk_t ua25_quirk = {
.type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &ep
+ .data = &ua25_ep
};
- return snd_usb_create_midi_interface(chip, iface, &quirk);
+ if (chip->dev->descriptor.idProduct == 0x002b)
+ return snd_usb_create_midi_interface(chip, iface,
+ &ua700_quirk);
+ else
+ return snd_usb_create_midi_interface(chip, iface,
+ &ua25_quirk);
}
if (altsd->bNumEndpoints != 1)
fp = kmalloc(sizeof(*fp), GFP_KERNEL);
if (!fp)
return -ENOMEM;
- memcpy(fp, &ua700_format, sizeof(*fp));
+ memcpy(fp, &ua_format, sizeof(*fp));
fp->iface = altsd->bInterfaceNumber;
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
fp->rate_max = fp->rate_min = 44100;
break;
case 0x138:
+ case 0x140:
fp->rate_max = fp->rate_min = 48000;
break;
case 0x258:
+ case 0x260:
fp->rate_max = fp->rate_min = 96000;
break;
default:
return 0;
}
+/*
+ * Create a stream for an Edirol UA-1000 interface.
+ */
+static int create_ua1000_quirk(snd_usb_audio_t *chip, struct usb_interface *iface)
+{
+ static const struct audioformat ua1000_format = {
+ .format = SNDRV_PCM_FORMAT_S32_LE,
+ .fmt_type = USB_FORMAT_TYPE_I,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .attributes = 0,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ };
+ struct usb_host_interface *alts;
+ struct usb_interface_descriptor *altsd;
+ struct audioformat *fp;
+ int stream, err;
+
+ if (iface->num_altsetting != 2)
+ return -ENXIO;
+ alts = &iface->altsetting[1];
+ altsd = get_iface_desc(alts);
+ if (alts->extralen != 11 || alts->extra[1] != CS_AUDIO_INTERFACE ||
+ altsd->bNumEndpoints != 1)
+ return -ENXIO;
+
+ fp = kmalloc(sizeof(*fp), GFP_KERNEL);
+ if (!fp)
+ return -ENOMEM;
+ memcpy(fp, &ua1000_format, sizeof(*fp));
+
+ fp->channels = alts->extra[4];
+ fp->iface = altsd->bInterfaceNumber;
+ fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
+ fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
+ fp->maxpacksize = get_endpoint(alts, 0)->wMaxPacketSize;
+ fp->rate_max = fp->rate_min = combine_triple(&alts->extra[8]);
+
+ stream = (fp->endpoint & USB_DIR_IN)
+ ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
+ err = add_audio_endpoint(chip, stream, fp);
+ if (err < 0) {
+ kfree(fp);
+ return err;
+ }
+ /* FIXME: playback must be synchronized to capture */
+ usb_set_interface(chip->dev, fp->iface, 0);
+ return 0;
+}
+
static int snd_usb_create_quirk(snd_usb_audio_t *chip,
struct usb_interface *iface,
const snd_usb_audio_quirk_t *quirk);
case QUIRK_AUDIO_STANDARD_INTERFACE:
case QUIRK_MIDI_STANDARD_INTERFACE:
return create_standard_interface_quirk(chip, iface, quirk);
- case QUIRK_AUDIO_EDIROL_UA700:
- return create_ua700_quirk(chip, iface);
+ case QUIRK_AUDIO_EDIROL_UA700_UA25:
+ return create_ua700_ua25_quirk(chip, iface);
+ case QUIRK_AUDIO_EDIROL_UA1000:
+ return create_ua1000_quirk(chip, iface);
default:
snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
return -ENXIO;