#define MAX_PACKS 10
#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
#define MAX_URBS 5 /* max. 20ms long packets */
-#define SYNC_URBS 2 /* always two urbs for sync */
+#define SYNC_URBS 4 /* always four urbs for sync */
#define MIN_PACKS_URB 1 /* minimum 1 packet per urb */
typedef struct snd_usb_substream snd_usb_substream_t;
if (urb->iso_frame_desc[0].status == 0 &&
urb->iso_frame_desc[0].actual_length == 3) {
f = combine_triple((u8*)urb->transfer_buffer) << 2;
-#if 0
- if (f < subs->freqn - (subs->freqn>>3) || f > subs->freqmax) {
- snd_printd(KERN_WARNING "requested frequency %d (%u,%03uHz) out of range (current nominal %d (%u,%03uHz))\n",
- f, f >> 14, (f & ((1 << 14) - 1) * 1000) / ((1 << 14) - 1),
- subs->freqn, subs->freqn >> 14, (subs->freqn & ((1 << 14) - 1) * 1000) / ((1 << 14) - 1));
- continue;
+ if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
+ spin_lock_irqsave(&subs->lock, flags);
+ subs->freqm = f;
+ spin_unlock_irqrestore(&subs->lock, flags);
}
-#endif
- spin_lock_irqsave(&subs->lock, flags);
- subs->freqm = f;
- spin_unlock_irqrestore(&subs->lock, flags);
}
return 0;
if (urb->iso_frame_desc[0].status == 0 &&
urb->iso_frame_desc[0].actual_length == 4) {
f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
- spin_lock_irqsave(&subs->lock, flags);
- subs->freqm = f;
- spin_unlock_irqrestore(&subs->lock, flags);
+ if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
+ spin_lock_irqsave(&subs->lock, flags);
+ subs->freqm = f;
+ spin_unlock_irqrestore(&subs->lock, flags);
+ }
}
return 0;
/* set the buffer pointer */
urb->transfer_buffer = runtime->dma_area + subs->hwptr * stride;
subs->hwptr += offs;
+ if (subs->hwptr == runtime->buffer_size)
+ subs->hwptr = 0;
}
spin_unlock_irqrestore(&subs->lock, flags);
urb->transfer_buffer_length = offs * stride;
usb_free_urb(u->urb);
u->urb = NULL;
}
- if (u->buf) {
- kfree(u->buf);
- u->buf = NULL;
- }
+ kfree(u->buf);
+ u->buf = NULL;
}
/*
release_urb_ctx(&subs->dataurb[i]);
for (i = 0; i < SYNC_URBS; i++)
release_urb_ctx(&subs->syncurb[i]);
- if (subs->tmpbuf) {
- kfree(subs->tmpbuf);
- subs->tmpbuf = NULL;
- }
+ kfree(subs->tmpbuf);
+ subs->tmpbuf = NULL;
subs->nurbs = 0;
}
get_endpoint(alts, 1)->bRefresh >= 1 &&
get_endpoint(alts, 1)->bRefresh <= 9)
subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
- else
+ else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
subs->syncinterval = 1;
+ else if (get_endpoint(alts, 1)->bInterval >= 1 &&
+ get_endpoint(alts, 1)->bInterval <= 16)
+ subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
+ else
+ subs->syncinterval = 3;
}
/* always fill max packet size */
return 0;
}
+static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
+{
+#if 0
+ /* TODO: enable this when high speed synchronization actually works */
+ u8 buf = 1;
+
+ snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+ 0, 0, &buf, 1, 1000);
+ if (buf == 0) {
+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+ 1, 2000, NULL, 0, 1000);
+ return -ENODEV;
+ }
+#endif
+ return 0;
+}
+
/*
* audio-interface quirks
snd_usb_audio_create_proc(chip);
- snd_card_set_dev(card, &dev->dev);
-
*rchip = chip;
return 0;
}
goto __err_val;
config = dev->actconfig;
}
+ /* SB Audigy 2 NX needs its own boot-up magic, too */
+ if (id == USB_ID(0x041e, 0x3020)) {
+ if (snd_usb_audigy2nx_boot_quirk(dev) < 0)
+ goto __err_val;
+ }
/*
* found a config. now register to ALSA
if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
goto __error;
}
+ snd_card_set_dev(chip->card, &intf->dev);
break;
}
if (! chip) {