X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=sound%2Fusb%2Fusbaudio.c;h=8298c462c291c2a529cecf04f0cb18a0aa213a52;hb=a5c96cab8f3c4ca9b2177dceb5de5a0edb31418e;hp=da1fe0f0bca0e2d602643550828da2b428705be6;hpb=c3f9329716df9965cbaf74ce313a12fe889c1a62;p=powerpc.git diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index da1fe0f0bc..8298c462c2 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -98,7 +98,7 @@ MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); #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; @@ -153,6 +153,7 @@ struct snd_usb_substream { unsigned int format; /* USB data format */ unsigned int datapipe; /* the data i/o pipe */ unsigned int syncpipe; /* 1 - async out or adaptive in */ + unsigned int datainterval; /* log_2 of data packet interval */ unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */ unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */ @@ -212,7 +213,7 @@ static snd_usb_audio_t *usb_chip[SNDRV_CARDS]; * convert a sampling rate into our full speed format (fs/1000 in Q16.16) * this will overflow at approx 524 kHz */ -inline static unsigned get_usb_full_speed_rate(unsigned int rate) +static inline unsigned get_usb_full_speed_rate(unsigned int rate) { return ((rate << 13) + 62) / 125; } @@ -221,19 +222,19 @@ inline static unsigned get_usb_full_speed_rate(unsigned int rate) * convert a sampling rate into USB high speed format (fs/8000 in Q16.16) * this will overflow at approx 4 MHz */ -inline static unsigned get_usb_high_speed_rate(unsigned int rate) +static inline unsigned get_usb_high_speed_rate(unsigned int rate) { return ((rate << 10) + 62) / 125; } /* convert our full speed USB rate into sampling rate in Hz */ -inline static unsigned get_full_speed_hz(unsigned int usb_rate) +static inline unsigned get_full_speed_hz(unsigned int usb_rate) { return (usb_rate * 125 + (1 << 12)) >> 13; } /* convert our high speed USB rate into sampling rate in Hz */ -inline static unsigned get_high_speed_hz(unsigned int usb_rate) +static inline unsigned get_high_speed_hz(unsigned int usb_rate) { return (usb_rate * 125 + (1 << 9)) >> 10; } @@ -452,17 +453,11 @@ static int retire_playback_sync_urb(snd_usb_substream_t *subs, 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; @@ -484,9 +479,11 @@ static int retire_playback_sync_urb_hs(snd_usb_substream_t *subs, 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; @@ -522,7 +519,8 @@ static int prepare_playback_urb(snd_usb_substream_t *subs, if (subs->fill_max) counts = subs->maxframesize; /* fixed */ else { - subs->phase = (subs->phase & 0xffff) + subs->freqm; + subs->phase = (subs->phase & 0xffff) + + (subs->freqm << subs->datainterval); counts = subs->phase >> 16; if (counts > subs->maxframesize) counts = subs->maxframesize; @@ -569,6 +567,8 @@ static int prepare_playback_urb(snd_usb_substream_t *subs, /* 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; @@ -792,7 +792,7 @@ static int start_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) */ static int wait_clear_urbs(snd_usb_substream_t *subs) { - int timeout = HZ; + unsigned long end_time = jiffies + msecs_to_jiffies(1000); unsigned int i; int alive; @@ -812,7 +812,7 @@ static int wait_clear_urbs(snd_usb_substream_t *subs) break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); - } while (--timeout > 0); + } while (time_before(jiffies, end_time)); if (alive) snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); return 0; @@ -861,10 +861,8 @@ static void release_urb_ctx(snd_urb_ctx_t *u) usb_free_urb(u->urb); u->urb = NULL; } - if (u->buf) { - kfree(u->buf); - u->buf = NULL; - } + kfree(u->buf); + u->buf = NULL; } /* @@ -882,10 +880,8 @@ static void release_substream_urbs(snd_usb_substream_t *subs, int force) 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; } @@ -905,16 +901,19 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by else subs->freqn = get_usb_high_speed_rate(rate); subs->freqm = subs->freqn; - subs->freqmax = subs->freqn + (subs->freqn >> 2); /* max. allowed frequency */ - subs->phase = 0; - - /* calculate the max. size of packet */ - maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3)) >> 16; - if (subs->maxpacksize && maxsize > subs->maxpacksize) { - //snd_printd(KERN_DEBUG "maxsize %d is greater than defined size %d\n", - // maxsize, subs->maxpacksize); + /* calculate max. frequency */ + if (subs->maxpacksize) { + /* whatever fits into a max. size packet */ maxsize = subs->maxpacksize; + subs->freqmax = (maxsize / (frame_bits >> 3)) + << (16 - subs->datainterval); + } else { + /* no max. packet size: just take 25% higher than nominal */ + subs->freqmax = subs->freqn + (subs->freqn >> 2); + maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3)) + >> (16 - subs->datainterval); } + subs->phase = 0; if (subs->fill_max) subs->curpacksize = subs->maxpacksize; @@ -924,7 +923,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) urb_packs = nrpacks; else - urb_packs = nrpacks * 8; + urb_packs = (nrpacks * 8) >> subs->datainterval; /* allocate a temporary buffer for playback */ if (is_playback) { @@ -997,7 +996,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by u->urb->pipe = subs->datapipe; u->urb->transfer_flags = URB_ISO_ASAP; u->urb->number_of_packets = u->packets; - u->urb->interval = 1; + u->urb->interval = 1 << subs->datainterval; u->urb->context = u; u->urb->complete = snd_usb_complete_callback(snd_complete_urb); } @@ -1201,6 +1200,12 @@ static int set_format(snd_usb_substream_t *subs, struct audioformat *fmt) subs->datapipe = usb_sndisocpipe(dev, ep); else subs->datapipe = usb_rcvisocpipe(dev, ep); + if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH && + get_endpoint(alts, 0)->bInterval >= 1 && + get_endpoint(alts, 0)->bInterval <= 4) + subs->datainterval = get_endpoint(alts, 0)->bInterval - 1; + else + subs->datainterval = 0; subs->syncpipe = subs->syncinterval = 0; subs->maxpacksize = fmt->maxpacksize; subs->fill_max = 0; @@ -1242,8 +1247,13 @@ static int set_format(snd_usb_substream_t *subs, struct audioformat *fmt) 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 */ @@ -2398,10 +2408,9 @@ static int parse_audio_format(snd_usb_audio_t *chip, struct audioformat *fp, if (chip->usb_id == USB_ID(0x041e, 0x3000) || chip->usb_id == USB_ID(0x041e, 0x3020)) { if (fmt[3] == USB_FORMAT_TYPE_I && - stream == SNDRV_PCM_STREAM_PLAYBACK && fp->rates != SNDRV_PCM_RATE_48000 && fp->rates != SNDRV_PCM_RATE_96000) - return -1; /* use 48k only */ + return -1; } #endif return 0; @@ -2493,8 +2502,10 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no) fp->altset_idx = i; fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; - /* FIXME: decode wMaxPacketSize of high bandwith endpoints */ fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); + if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) + fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) + * (fp->maxpacksize & 0x7ff); fp->attributes = csep[3]; /* some quirks for attributes here */ @@ -2724,7 +2735,8 @@ static int create_standard_interface_quirk(snd_usb_audio_t *chip, * to detect the sample rate is by looking at wMaxPacketSize. */ static int create_ua700_ua25_quirk(snd_usb_audio_t *chip, - struct usb_interface *iface) + struct usb_interface *iface, + const snd_usb_audio_quirk_t *quirk) { static const struct audioformat ua_format = { .format = SNDRV_PCM_FORMAT_S24_3LE, @@ -2815,7 +2827,9 @@ static int create_ua700_ua25_quirk(snd_usb_audio_t *chip, /* * Create a stream for an Edirol UA-1000 interface. */ -static int create_ua1000_quirk(snd_usb_audio_t *chip, struct usb_interface *iface) +static int create_ua1000_quirk(snd_usb_audio_t *chip, + struct usb_interface *iface, + const snd_usb_audio_quirk_t *quirk) { static const struct audioformat ua1000_format = { .format = SNDRV_PCM_FORMAT_S32_LE, @@ -2892,6 +2906,13 @@ static int create_composite_quirk(snd_usb_audio_t *chip, return 0; } +static int ignore_interface_quirk(snd_usb_audio_t *chip, + struct usb_interface *iface, + const snd_usb_audio_quirk_t *quirk) +{ + return 0; +} + /* * boot quirks @@ -2925,6 +2946,22 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac return 0; } +static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) +{ + 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; + } + return 0; +} + /* * audio-interface quirks @@ -2938,28 +2975,28 @@ static int snd_usb_create_quirk(snd_usb_audio_t *chip, struct usb_interface *iface, const snd_usb_audio_quirk_t *quirk) { - switch (quirk->type) { - case QUIRK_MIDI_FIXED_ENDPOINT: - case QUIRK_MIDI_YAMAHA: - case QUIRK_MIDI_MIDIMAN: - case QUIRK_MIDI_NOVATION: - case QUIRK_MIDI_MOTU: - case QUIRK_MIDI_EMAGIC: - return snd_usb_create_midi_interface(chip, iface, quirk); - case QUIRK_COMPOSITE: - return create_composite_quirk(chip, iface, quirk); - case QUIRK_AUDIO_FIXED_ENDPOINT: - return create_fixed_stream_quirk(chip, iface, quirk); - case QUIRK_AUDIO_STANDARD_INTERFACE: - case QUIRK_MIDI_STANDARD_INTERFACE: - return create_standard_interface_quirk(chip, iface, quirk); - case QUIRK_AUDIO_EDIROL_UA700_UA25: - return create_ua700_ua25_quirk(chip, iface); - case QUIRK_AUDIO_EDIROL_UA1000: - return create_ua1000_quirk(chip, iface); - case QUIRK_IGNORE_INTERFACE: - return 0; - default: + typedef int (*quirk_func_t)(snd_usb_audio_t *, struct usb_interface *, + const snd_usb_audio_quirk_t *); + static const quirk_func_t quirk_funcs[] = { + [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk, + [QUIRK_COMPOSITE] = create_composite_quirk, + [QUIRK_MIDI_STANDARD_INTERFACE] = snd_usb_create_midi_interface, + [QUIRK_MIDI_FIXED_ENDPOINT] = snd_usb_create_midi_interface, + [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface, + [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface, + [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, + [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, + [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, + [QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface, + [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_interface_quirk, + [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, + [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, + [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, + }; + + if (quirk->type < QUIRK_TYPE_COUNT) { + return quirk_funcs[quirk->type](chip, iface, quirk); + } else { snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); return -ENXIO; } @@ -3110,8 +3147,6 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, snd_usb_audio_create_proc(chip); - snd_card_set_dev(card, &dev->dev); - *rchip = chip; return 0; } @@ -3154,6 +3189,11 @@ static void *snd_usb_audio_probe(struct usb_device *dev, 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 @@ -3188,6 +3228,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev, if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) { goto __error; } + snd_card_set_dev(chip->card, &intf->dev); break; } if (! chip) {