From 9568f461e50c023e45ec702027bb1a5f60e443dc Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 12 Jan 2006 08:19:21 +0100 Subject: [ALSA] usb-audio: factor out packet size calculation code Modules: USB generic driver Move the common packet size calculation code from prepare_startup_playback_urb() and prepare_playback_urb() to a new function. Signed-off-by: Clemens Ladisch --- sound/usb/usbaudio.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'sound/usb/usbaudio.c') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index d5013383fad7..f5aadb001986 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -475,6 +475,18 @@ 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. * @@ -492,16 +504,7 @@ 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) { - /* 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; - } + counts = snd_usb_audio_next_packet_size(subs); urb->iso_frame_desc[i].offset = offs * stride; urb->iso_frame_desc[i].length = counts * stride; offs += counts; @@ -538,16 +541,7 @@ 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++) { - /* 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; - } + counts = snd_usb_audio_next_packet_size(subs); /* set up descriptor */ urb->iso_frame_desc[i].offset = offs * stride; urb->iso_frame_desc[i].length = counts * stride; -- cgit v1.2.2 From 21a3479a0b606d36fe24093f70a1c27328cec286 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 13 Jan 2006 09:12:11 +0100 Subject: [ALSA] PCM midlevel & PCM OSS - make procfs & OSS plugin code optional Modules: ALSA Core,PCM Midlevel,ALSA<-OSS emulation,USB generic driver 1) The verbose procfs code for the PCM midlevel and usb audio can be removed now (more patches will follow). CONFIG_SND_VERBOSE_PROCFS 2) The PCM OSS plugin system can be also compiled optionaly. CONFIG_SND_PCM_OSS_PLUGINS Signed-off-by: Jaroslav Kysela --- sound/usb/usbaudio.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'sound/usb/usbaudio.c') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index f5aadb001986..c9476c237c42 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -1384,8 +1384,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 = %s, rate = %d, channels = %d\n", - snd_pcm_format_name(format), rate, channels); + snd_printd(KERN_DEBUG "cannot set format: format = 0x%x, rate = %d, channels = %d\n", + format, rate, channels); return -EINVAL; } @@ -2011,6 +2011,8 @@ static struct usb_driver usb_audio_driver = { }; +#if defined(CONFIG_PROCFS) && defined(CONFIG_SND_VERBOSE_PROCFS) + /* * proc interface for list the supported pcm formats */ @@ -2101,6 +2103,13 @@ static void proc_pcm_format_add(struct snd_usb_stream *stream) snd_info_set_text_ops(entry, stream, 1024, proc_pcm_format_read); } +#else + +static inline void proc_pcm_format_add(struct snd_usb_stream *stream) +{ +} + +#endif /* * initialize the substream instance. -- cgit v1.2.2 From 12aa757905d09b1dc2c1c3d0de3fa8f4c9726f2b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 16 Jan 2006 16:36:05 +0100 Subject: [ALSA] semaphore -> mutex (Archs, misc buses) Semaphore to mutex conversion. The conversion was generated via scripts, and the result was validated automatically via a script as well. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/usb/usbaudio.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'sound/usb/usbaudio.c') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index c9476c237c42..53009bb642f6 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -202,7 +203,7 @@ struct snd_usb_stream { * the all interfaces on the same card as one sound device. */ -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); static struct snd_usb_audio *usb_chip[SNDRV_CARDS]; @@ -3285,7 +3286,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev, /* check whether it's already registered */ chip = NULL; - down(®ister_mutex); + mutex_lock(®ister_mutex); for (i = 0; i < SNDRV_CARDS; i++) { if (usb_chip[i] && usb_chip[i]->dev == dev) { if (usb_chip[i]->shutdown) { @@ -3338,13 +3339,13 @@ static void *snd_usb_audio_probe(struct usb_device *dev, usb_chip[chip->index] = chip; chip->num_interfaces++; - up(®ister_mutex); + mutex_unlock(®ister_mutex); return chip; __error: if (chip && !chip->num_interfaces) snd_card_free(chip->card); - up(®ister_mutex); + mutex_unlock(®ister_mutex); __err_val: return NULL; } @@ -3364,7 +3365,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) chip = ptr; card = chip->card; - down(®ister_mutex); + mutex_lock(®ister_mutex); chip->shutdown = 1; chip->num_interfaces--; if (chip->num_interfaces <= 0) { @@ -3382,10 +3383,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) snd_usb_mixer_disconnect(p); } usb_chip[chip->index] = NULL; - up(®ister_mutex); + mutex_unlock(®ister_mutex); snd_card_free(card); } else { - up(®ister_mutex); + mutex_unlock(®ister_mutex); } } -- cgit v1.2.2 From 3f72a30ccfd5054c01fc3bb0d37241df5380a54c Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 18 Jan 2006 11:50:40 +0100 Subject: [ALSA] snd_pcm_format_name() is no longer exported Modules: PCM Midlevel,USB generic driver Because snd_pcm_format_name() function is used only for informational purposes, it is no longer exported from the PCM midlevel to reduce space and dependency. usbaudio module shows only numeric value for format. Signed-off-by: Jaroslav Kysela --- sound/usb/usbaudio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/usb/usbaudio.c') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 53009bb642f6..51a862637f20 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -2029,7 +2029,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: %s\n", snd_pcm_format_name(fp->format)); + snd_iprintf(buffer, " Format: 0x%x\n", fp->format); snd_iprintf(buffer, " Channels: %d\n", fp->channels); snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", fp->endpoint & USB_ENDPOINT_NUMBER_MASK, -- cgit v1.2.2 From cc7a59bd8dcee9b01e0c9ab21380071f0ae6ef0d Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 7 Feb 2006 17:11:06 +0100 Subject: [ALSA] usb-audio: rename QUIRK_MIDI_MIDITECH to QUIRK_MIDI_CME Modules: USB generic driver Rename QUIRK_MIDI_MIDITECH to QUIRK_MIDI_CME because Miditech keyboards are built by CME and use the same protocol, and don't force a Miditech product name for the USB ID used by both Miditech and CME UF-x keyboards. Signed-off-by: Clemens Ladisch --- sound/usb/usbaudio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/usb/usbaudio.c') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 51a862637f20..7b1b9f29f377 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -3074,7 +3074,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_MIDITECH] = snd_usb_create_midi_interface, + [QUIRK_MIDI_CME] = 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, -- cgit v1.2.2 From 9c4be3d334808d1dedea7db0ae84759bfac8e18e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 9 Feb 2006 20:04:16 +0100 Subject: [ALSA] no need to check pointers passed to vfree() for NULL Modules: Digigram VX core,USB generic driver There's no need to check pointers passed to vfree() for NULL. Signed-off-by: Jesper Juhl Signed-off-by: Takashi Iwai --- sound/usb/usbaudio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sound/usb/usbaudio.c') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 7b1b9f29f377..039f27dc1f08 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -720,10 +720,9 @@ 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; - if (runtime->dma_area) { - vfree(runtime->dma_area); - runtime->dma_area = NULL; - } + + vfree(runtime->dma_area); + runtime->dma_area = NULL; return 0; } -- cgit v1.2.2 From 32e19e882c722b41f37e90956bf12eacdaba6f2b Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 9 Mar 2006 07:58:39 +0100 Subject: [ALSA] usb-audio: show USB error descriptions Modules: USB generic driver When usb_submit_urb() fails, show an error description instead of just the error code. Signed-off-by: Clemens Ladisch --- sound/usb/usbaudio.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'sound/usb/usbaudio.c') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 039f27dc1f08..45157d3cf789 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -773,6 +773,31 @@ 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"; + case -EINVAL: + case -EAGAIN: + case -EFBIG: + case -EMSGSIZE: + return "internal error"; + default: + return "unknown error"; + } +} + /* * set up and start data/sync urbs */ @@ -805,16 +830,22 @@ 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++) { - 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); + 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)); goto __error; } set_bit(i, &subs->active_mask); } if (subs->syncpipe) { for (i = 0; i < SYNC_URBS; i++) { - 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); + 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)); goto __error; } set_bit(i + 16, &subs->active_mask); -- cgit v1.2.2 From 3e964432f56f05a8ef639902796e476456b230ad Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 14 Mar 2006 08:06:12 +0100 Subject: [ALSA] usb-audio: add error message about missing split iso support Modules: USB generic driver Add an error message for -ENOSYS for situations when split iso support is needed but not enabled. Signed-off-by: Clemens Ladisch --- sound/usb/usbaudio.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/usb/usbaudio.c') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 45157d3cf789..6fad2c40c77c 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -788,6 +788,10 @@ static const char *usb_error_string(int err) 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: -- cgit v1.2.2 From e311334ee6bdd173d53be52f4fdffa5f39652e26 Mon Sep 17 00:00:00 2001 From: Thibault LE MEUR Date: Tue, 14 Mar 2006 11:44:53 +0100 Subject: [ALSA] Fixes audiophile usb analog capture with the new device_setup parameter Modules: Documentation,USB generic driver The patch adds the 'device_setup' module parameter and a specific quirk to correctly initialize the audiophile usb device: this fixes the distorted sound bug on the Analog capture port. Backward compatibility is achieved by simply omitting the new parameter. Signed-off-by: Thibault LE MEUR Signed-off-by: Takashi Iwai --- sound/usb/usbaudio.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'sound/usb/usbaudio.c') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 6fad2c40c77c..4e614ac39f21 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -70,6 +70,7 @@ 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."); @@ -85,6 +86,8 @@ 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)."); /* @@ -2547,6 +2550,8 @@ 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; @@ -2581,6 +2586,12 @@ 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); @@ -2675,7 +2686,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, i, fp->endpoint); + snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, altno, fp->endpoint); err = add_audio_endpoint(chip, stream, fp); if (err < 0) { kfree(fp->rate_table); @@ -3083,6 +3094,45 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) return 0; } +/* + * 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 -- cgit v1.2.2