X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fusb%2Fusbaudio.c;fp=sound%2Fusb%2Fusbaudio.c;h=d5013383fad71dec63557b5207cc38f08ba0578c;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=1b7f499c549da7f2457bbff3f7c3e1ab63cf7e40;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 1b7f499c5..d5013383f 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include @@ -70,7 +69,6 @@ static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor ID for 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 device_setup[SNDRV_CARDS]; /* device parameter for this card*/ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); @@ -86,8 +84,6 @@ module_param(nrpacks, int, 0644); MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); module_param(async_unlink, bool, 0444); MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); -module_param_array(device_setup, int, NULL, 0444); -MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); /* @@ -206,7 +202,7 @@ struct snd_usb_stream { * the all interfaces on the same card as one sound device. */ -static DEFINE_MUTEX(register_mutex); +static DECLARE_MUTEX(register_mutex); static struct snd_usb_audio *usb_chip[SNDRV_CARDS]; @@ -479,18 +475,6 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, return 0; } -/* determine the number of frames in the next packet */ -static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) -{ - if (subs->fill_max) - return subs->maxframesize; - else { - subs->phase = (subs->phase & 0xffff) - + (subs->freqm << subs->datainterval); - return min(subs->phase >> 16, subs->maxframesize); - } -} - /* * Prepare urb for streaming before playback starts. * @@ -508,7 +492,16 @@ static int prepare_startup_playback_urb(struct snd_usb_substream *subs, urb->dev = ctx->subs->dev; urb->number_of_packets = subs->packs_per_ms; for (i = 0; i < subs->packs_per_ms; ++i) { - counts = snd_usb_audio_next_packet_size(subs); + /* calculate the size of a packet */ + if (subs->fill_max) + counts = subs->maxframesize; /* fixed */ + else { + subs->phase = (subs->phase & 0xffff) + + (subs->freqm << subs->datainterval); + counts = subs->phase >> 16; + if (counts > subs->maxframesize) + counts = subs->maxframesize; + } urb->iso_frame_desc[i].offset = offs * stride; urb->iso_frame_desc[i].length = counts * stride; offs += counts; @@ -545,7 +538,16 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, urb->number_of_packets = 0; spin_lock_irqsave(&subs->lock, flags); for (i = 0; i < ctx->packets; i++) { - counts = snd_usb_audio_next_packet_size(subs); + /* calculate the size of a packet */ + if (subs->fill_max) + counts = subs->maxframesize; /* fixed */ + else { + subs->phase = (subs->phase & 0xffff) + + (subs->freqm << subs->datainterval); + counts = subs->phase >> 16; + if (counts > subs->maxframesize) + counts = subs->maxframesize; + } /* set up descriptor */ urb->iso_frame_desc[i].offset = offs * stride; urb->iso_frame_desc[i].length = counts * stride; @@ -723,9 +725,10 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) { struct snd_pcm_runtime *runtime = subs->runtime; - - vfree(runtime->dma_area); - runtime->dma_area = NULL; + if (runtime->dma_area) { + vfree(runtime->dma_area); + runtime->dma_area = NULL; + } return 0; } @@ -776,35 +779,6 @@ static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sl } -static const char *usb_error_string(int err) -{ - switch (err) { - case -ENODEV: - return "no device"; - case -ENOENT: - return "endpoint not enabled"; - case -EPIPE: - return "endpoint stalled"; - case -ENOSPC: - return "not enough bandwidth"; - case -ESHUTDOWN: - return "device disabled"; - case -EHOSTUNREACH: - return "device suspended"; -#ifndef CONFIG_USB_EHCI_SPLIT_ISO - case -ENOSYS: - return "enable CONFIG_USB_EHCI_SPLIT_ISO to play through a hub"; -#endif - case -EINVAL: - case -EAGAIN: - case -EFBIG: - case -EMSGSIZE: - return "internal error"; - default: - return "unknown error"; - } -} - /* * set up and start data/sync urbs */ @@ -837,22 +811,16 @@ static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *ru subs->unlink_mask = 0; subs->running = 1; for (i = 0; i < subs->nurbs; i++) { - err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC); - if (err < 0) { - snd_printk(KERN_ERR "cannot submit datapipe " - "for urb %d, error %d: %s\n", - i, err, usb_error_string(err)); + if ((err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC)) < 0) { + snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); goto __error; } set_bit(i, &subs->active_mask); } if (subs->syncpipe) { for (i = 0; i < SYNC_URBS; i++) { - err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC); - if (err < 0) { - snd_printk(KERN_ERR "cannot submit syncpipe " - "for urb %d, error %d: %s\n", - i, err, usb_error_string(err)); + if ((err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC)) < 0) { + snd_printk(KERN_ERR "cannot submit syncpipe for urb %d, err = %d\n", i, err); goto __error; } set_bit(i + 16, &subs->active_mask); @@ -1422,8 +1390,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, channels = params_channels(hw_params); fmt = find_format(subs, format, rate, channels); if (! fmt) { - snd_printd(KERN_DEBUG "cannot set format: format = 0x%x, rate = %d, channels = %d\n", - format, rate, channels); + snd_printd(KERN_DEBUG "cannot set format: format = %s, rate = %d, channels = %d\n", + snd_pcm_format_name(format), rate, channels); return -EINVAL; } @@ -2049,8 +2017,6 @@ static struct usb_driver usb_audio_driver = { }; -#if defined(CONFIG_PROCFS) && defined(CONFIG_SND_VERBOSE_PROCFS) - /* * proc interface for list the supported pcm formats */ @@ -2066,7 +2032,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s fp = list_entry(p, struct audioformat, list); snd_iprintf(buffer, " Interface %d\n", fp->iface); snd_iprintf(buffer, " Altset %d\n", fp->altsetting); - snd_iprintf(buffer, " Format: 0x%x\n", fp->format); + snd_iprintf(buffer, " Format: %s\n", snd_pcm_format_name(fp->format)); snd_iprintf(buffer, " Channels: %d\n", fp->channels); snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", fp->endpoint & USB_ENDPOINT_NUMBER_MASK, @@ -2138,16 +2104,9 @@ static void proc_pcm_format_add(struct snd_usb_stream *stream) sprintf(name, "stream%d", stream->pcm_index); if (! snd_card_proc_new(card, name, &entry)) - snd_info_set_text_ops(entry, stream, proc_pcm_format_read); -} - -#else - -static inline void proc_pcm_format_add(struct snd_usb_stream *stream) -{ + snd_info_set_text_ops(entry, stream, 1024, proc_pcm_format_read); } -#endif /* * initialize the substream instance. @@ -2260,9 +2219,10 @@ static int add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct aud } /* create a new pcm */ - as = kzalloc(sizeof(*as), GFP_KERNEL); + as = kmalloc(sizeof(*as), GFP_KERNEL); if (! as) return -ENOMEM; + memset(as, 0, sizeof(*as)); as->pcm_index = chip->pcm_devs; as->chip = chip; as->fmt_type = fp->fmt_type; @@ -2549,8 +2509,6 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp return 0; } -static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, - int iface, int altno); static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) { struct usb_device *dev; @@ -2585,12 +2543,6 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; altno = altsd->bAlternateSetting; - - /* audiophile usb: skip altsets incompatible with device_setup - */ - if (chip->usb_id == USB_ID(0x0763, 0x2003) && - audiophile_skip_setting_quirk(chip, iface_no, altno)) - continue; /* get audio formats */ fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); @@ -2626,18 +2578,18 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) if (!csep && altsd->bNumEndpoints >= 2) csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) { - snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" - " class specific endpoint descriptor\n", + snd_printk(KERN_ERR "%d:%u:%d : no or invalid class specific endpoint descriptor\n", dev->devnum, iface_no, altno); - csep = NULL; + continue; } - fp = kzalloc(sizeof(*fp), GFP_KERNEL); + fp = kmalloc(sizeof(*fp), GFP_KERNEL); if (! fp) { snd_printk(KERN_ERR "cannot malloc\n"); return -ENOMEM; } + memset(fp, 0, sizeof(*fp)); fp->iface = iface_no; fp->altsetting = altno; fp->altset_idx = i; @@ -2647,7 +2599,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) * (fp->maxpacksize & 0x7ff); - fp->attributes = csep ? csep[3] : 0; + fp->attributes = csep[3]; /* some quirks for attributes here */ @@ -2685,7 +2637,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) continue; } - snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, altno, fp->endpoint); + snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, i, fp->endpoint); err = add_audio_endpoint(chip, stream, fp); if (err < 0) { kfree(fp->rate_table); @@ -2979,7 +2931,7 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip, return -ENXIO; alts = &iface->altsetting[1]; altsd = get_iface_desc(alts); - if (alts->extralen != 11 || alts->extra[1] != USB_DT_CS_INTERFACE || + if (alts->extralen != 11 || alts->extra[1] != CS_AUDIO_INTERFACE || altsd->bNumEndpoints != 1) return -ENXIO; @@ -3093,71 +3045,6 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) return 0; } -/* - * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely - * documented in the device's data sheet. - */ -static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value) -{ - u8 buf[4]; - buf[0] = 0x20; - buf[1] = value & 0xff; - buf[2] = (value >> 8) & 0xff; - buf[3] = reg; - return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, - 0, 0, &buf, 4, 1000); -} - -static int snd_usb_cm106_boot_quirk(struct usb_device *dev) -{ - /* - * Enable line-out driver mode, set headphone source to front - * channels, enable stereo mic. - */ - return snd_usb_cm106_write_int_reg(dev, 2, 0x8004); -} - - -/* - * Setup quirks - */ -#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ -#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */ -#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */ -#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */ -#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */ -#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */ -#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */ -#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */ -#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */ -#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */ - -static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, - int iface, int altno) -{ - if (device_setup[chip->index] & AUDIOPHILE_SET) { - if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS) - && altno != 6) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_96K) - && altno != 1) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == - AUDIOPHILE_SET_24B_48K_DI && altno != 2) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == - AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == - AUDIOPHILE_SET_16B_48K_DI && altno != 4) - return 1; /* skip this altsetting */ - if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == - AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5) - return 1; /* skip this altsetting */ - } - return 0; /* keep this altsetting */ -} /* * audio-interface quirks @@ -3183,7 +3070,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, [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_CME] = snd_usb_create_midi_interface, + [QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface, [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, @@ -3222,9 +3109,9 @@ static void snd_usb_audio_create_proc(struct snd_usb_audio *chip) { struct snd_info_entry *entry; if (! snd_card_proc_new(chip->card, "usbbus", &entry)) - snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read); + snd_info_set_text_ops(entry, chip, 1024, proc_audio_usbbus_read); if (! snd_card_proc_new(chip->card, "usbid", &entry)) - snd_info_set_text_ops(entry, chip, proc_audio_usbid_read); + snd_info_set_text_ops(entry, chip, 1024, proc_audio_usbid_read); } /* @@ -3389,19 +3276,13 @@ static void *snd_usb_audio_probe(struct usb_device *dev, goto __err_val; } - /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */ - if (id == USB_ID(0x10f5, 0x0200)) { - if (snd_usb_cm106_boot_quirk(dev) < 0) - goto __err_val; - } - /* * found a config. now register to ALSA */ /* check whether it's already registered */ chip = NULL; - mutex_lock(®ister_mutex); + down(®ister_mutex); for (i = 0; i < SNDRV_CARDS; i++) { if (usb_chip[i] && usb_chip[i]->dev == dev) { if (usb_chip[i]->shutdown) { @@ -3454,13 +3335,13 @@ static void *snd_usb_audio_probe(struct usb_device *dev, usb_chip[chip->index] = chip; chip->num_interfaces++; - mutex_unlock(®ister_mutex); + up(®ister_mutex); return chip; __error: if (chip && !chip->num_interfaces) snd_card_free(chip->card); - mutex_unlock(®ister_mutex); + up(®ister_mutex); __err_val: return NULL; } @@ -3480,7 +3361,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) chip = ptr; card = chip->card; - mutex_lock(®ister_mutex); + down(®ister_mutex); chip->shutdown = 1; chip->num_interfaces--; if (chip->num_interfaces <= 0) { @@ -3498,10 +3379,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) snd_usb_mixer_disconnect(p); } usb_chip[chip->index] = NULL; - mutex_unlock(®ister_mutex); + up(®ister_mutex); snd_card_free(card); } else { - mutex_unlock(®ister_mutex); + up(®ister_mutex); } }