diff options
Diffstat (limited to 'sound/usb')
38 files changed, 1885 insertions, 857 deletions
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c index c39c7797846..dcddfc354ba 100644 --- a/sound/usb/6fire/chip.c +++ b/sound/usb/6fire/chip.c @@ -101,12 +101,12 @@ static int usb6fire_chip_probe(struct usb_interface *intf,  			usb_set_intfdata(intf, chips[i]);  			mutex_unlock(®ister_mutex);  			return 0; -		} else if (regidx < 0) +		} else if (!devices[i] && regidx < 0)  			regidx = i;  	}  	if (regidx < 0) {  		mutex_unlock(®ister_mutex); -		snd_printk(KERN_ERR PREFIX "too many cards registered.\n"); +		dev_err(&intf->dev, "too many cards registered.\n");  		return -ENODEV;  	}  	devices[regidx] = device; @@ -121,20 +121,19 @@ static int usb6fire_chip_probe(struct usb_interface *intf,  	/* if we are here, card can be registered in alsa. */  	if (usb_set_interface(device, 0, 0) != 0) { -		snd_printk(KERN_ERR PREFIX "can't set first interface.\n"); +		dev_err(&intf->dev, "can't set first interface.\n");  		return -EIO;  	} -	ret = snd_card_create(index[regidx], id[regidx], THIS_MODULE, -			sizeof(struct sfire_chip), &card); +	ret = snd_card_new(&intf->dev, index[regidx], id[regidx], +			   THIS_MODULE, sizeof(struct sfire_chip), &card);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "cannot create alsa card.\n"); +		dev_err(&intf->dev, "cannot create alsa card.\n");  		return ret;  	}  	strcpy(card->driver, "6FireUSB");  	strcpy(card->shortname, "TerraTec DMX6FireUSB");  	sprintf(card->longname, "%s at %d:%d", card->shortname,  			device->bus->busnum, device->devnum); -	snd_card_set_dev(card, &intf->dev);  	chip = card->private_data;  	chips[regidx] = chip; @@ -169,7 +168,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf,  	ret = snd_card_register(card);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "cannot register card."); +		dev_err(&intf->dev, "cannot register card.");  		usb6fire_chip_destroy(chip);  		return ret;  	} diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c index 23452ee617e..161215d78d9 100644 --- a/sound/usb/6fire/comm.c +++ b/sound/usb/6fire/comm.c @@ -51,7 +51,7 @@ static void usb6fire_comm_receiver_handler(struct urb *urb)  		urb->status = 0;  		urb->actual_length = 0;  		if (usb_submit_urb(urb, GFP_ATOMIC) < 0) -			snd_printk(KERN_WARNING PREFIX +			dev_warn(&urb->dev->dev,  					"comm data receiver aborted.\n");  	}  } @@ -179,7 +179,7 @@ int usb6fire_comm_init(struct sfire_chip *chip)  	if (ret < 0) {  		kfree(rt->receiver_buffer);  		kfree(rt); -		snd_printk(KERN_ERR PREFIX "cannot create comm data receiver."); +		dev_err(&chip->dev->dev, "cannot create comm data receiver.");  		return ret;  	}  	chip->comm = rt; diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c index f6434c24572..184e3987ac2 100644 --- a/sound/usb/6fire/control.c +++ b/sound/usb/6fire/control.c @@ -194,7 +194,8 @@ static int usb6fire_control_output_vol_put(struct snd_kcontrol *kcontrol,  	int changed = 0;  	if (ch > 4) { -		snd_printk(KERN_ERR PREFIX "Invalid channel in volume control."); +		dev_err(&rt->chip->dev->dev, +			"Invalid channel in volume control.");  		return -EINVAL;  	} @@ -222,7 +223,8 @@ static int usb6fire_control_output_vol_get(struct snd_kcontrol *kcontrol,  	unsigned int ch = kcontrol->private_value;  	if (ch > 4) { -		snd_printk(KERN_ERR PREFIX "Invalid channel in volume control."); +		dev_err(&rt->chip->dev->dev, +			"Invalid channel in volume control.");  		return -EINVAL;  	} @@ -240,7 +242,8 @@ static int usb6fire_control_output_mute_put(struct snd_kcontrol *kcontrol,  	u8 value = 0;  	if (ch > 4) { -		snd_printk(KERN_ERR PREFIX "Invalid channel in volume control."); +		dev_err(&rt->chip->dev->dev, +			"Invalid channel in volume control.");  		return -EINVAL;  	} @@ -265,7 +268,8 @@ static int usb6fire_control_output_mute_get(struct snd_kcontrol *kcontrol,  	u8 value = rt->output_mute >> ch;  	if (ch > 4) { -		snd_printk(KERN_ERR PREFIX "Invalid channel in volume control."); +		dev_err(&rt->chip->dev->dev, +			"Invalid channel in volume control.");  		return -EINVAL;  	} @@ -594,14 +598,14 @@ int usb6fire_control_init(struct sfire_chip *chip)  	ret = usb6fire_control_add_virtual(rt, chip->card,  		"Master Playback Volume", vol_elements);  	if (ret) { -		snd_printk(KERN_ERR PREFIX "cannot add control.\n"); +		dev_err(&chip->dev->dev, "cannot add control.\n");  		kfree(rt);  		return ret;  	}  	ret = usb6fire_control_add_virtual(rt, chip->card,  		"Master Playback Switch", mute_elements);  	if (ret) { -		snd_printk(KERN_ERR PREFIX "cannot add control.\n"); +		dev_err(&chip->dev->dev, "cannot add control.\n");  		kfree(rt);  		return ret;  	} @@ -611,7 +615,7 @@ int usb6fire_control_init(struct sfire_chip *chip)  		ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt));  		if (ret < 0) {  			kfree(rt); -			snd_printk(KERN_ERR PREFIX "cannot add control.\n"); +			dev_err(&chip->dev->dev, "cannot add control.\n");  			return ret;  		}  		i++; diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 780bf3f62d2..3b02e54b8f6 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -219,16 +219,16 @@ static int usb6fire_fw_ezusb_upload(  	ret = request_firmware(&fw, fwname, &device->dev);  	if (ret < 0) {  		kfree(rec); -		snd_printk(KERN_ERR PREFIX "error requesting ezusb " -				"firmware %s.\n", fwname); +		dev_err(&intf->dev, +			"error requesting ezusb firmware %s.\n", fwname);  		return ret;  	}  	ret = usb6fire_fw_ihex_init(fw, rec);  	if (ret < 0) {  		kfree(rec);  		release_firmware(fw); -		snd_printk(KERN_ERR PREFIX "error validating ezusb " -				"firmware %s.\n", fwname); +		dev_err(&intf->dev, +			"error validating ezusb firmware %s.\n", fwname);  		return ret;  	}  	/* upload firmware image */ @@ -237,8 +237,9 @@ static int usb6fire_fw_ezusb_upload(  	if (ret < 0) {  		kfree(rec);  		release_firmware(fw); -		snd_printk(KERN_ERR PREFIX "unable to upload ezusb " -				"firmware %s: begin message.\n", fwname); +		dev_err(&intf->dev, +			"unable to upload ezusb firmware %s: begin message.\n", +			fwname);  		return ret;  	} @@ -248,8 +249,9 @@ static int usb6fire_fw_ezusb_upload(  		if (ret < 0) {  			kfree(rec);  			release_firmware(fw); -			snd_printk(KERN_ERR PREFIX "unable to upload ezusb " -					"firmware %s: data urb.\n", fwname); +			dev_err(&intf->dev, +				"unable to upload ezusb firmware %s: data urb.\n", +				fwname);  			return ret;  		}  	} @@ -260,8 +262,9 @@ static int usb6fire_fw_ezusb_upload(  		ret = usb6fire_fw_ezusb_write(device, 0xa0, postaddr,  				postdata, postlen);  		if (ret < 0) { -			snd_printk(KERN_ERR PREFIX "unable to upload ezusb " -					"firmware %s: post urb.\n", fwname); +			dev_err(&intf->dev, +				"unable to upload ezusb firmware %s: post urb.\n", +				fwname);  			return ret;  		}  	} @@ -269,8 +272,9 @@ static int usb6fire_fw_ezusb_upload(  	data = 0x00; /* resume ezusb cpu */  	ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "unable to upload ezusb " -				"firmware %s: end message.\n", fwname); +		dev_err(&intf->dev, +			"unable to upload ezusb firmware %s: end message.\n", +			fwname);  		return ret;  	}  	return 0; @@ -292,7 +296,7 @@ static int usb6fire_fw_fpga_upload(  	ret = request_firmware(&fw, fwname, &device->dev);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "unable to get fpga firmware %s.\n", +		dev_err(&intf->dev, "unable to get fpga firmware %s.\n",  				fwname);  		kfree(buffer);  		return -EIO; @@ -305,8 +309,8 @@ static int usb6fire_fw_fpga_upload(  	if (ret < 0) {  		kfree(buffer);  		release_firmware(fw); -		snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: " -				"begin urb.\n"); +		dev_err(&intf->dev, +			"unable to upload fpga firmware: begin urb.\n");  		return ret;  	} @@ -318,8 +322,8 @@ static int usb6fire_fw_fpga_upload(  		if (ret < 0) {  			release_firmware(fw);  			kfree(buffer); -			snd_printk(KERN_ERR PREFIX "unable to upload fpga " -					"firmware: fw urb.\n"); +			dev_err(&intf->dev, +				"unable to upload fpga firmware: fw urb.\n");  			return ret;  		}  	} @@ -328,8 +332,8 @@ static int usb6fire_fw_fpga_upload(  	ret = usb6fire_fw_ezusb_write(device, 9, 0, NULL, 0);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: " -				"end urb.\n"); +		dev_err(&intf->dev, +			"unable to upload fpga firmware: end urb.\n");  		return ret;  	}  	return 0; @@ -338,7 +342,7 @@ static int usb6fire_fw_fpga_upload(  /* check, if the firmware version the devices has currently loaded   * is known by this driver. 'version' needs to have 4 bytes version   * info data. */ -static int usb6fire_fw_check(u8 *version) +static int usb6fire_fw_check(struct usb_interface *intf, const u8 *version)  {  	int i; @@ -346,7 +350,7 @@ static int usb6fire_fw_check(u8 *version)  		if (!memcmp(version, known_fw_versions + i, 2))  			return 0; -	snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %4ph. " +	dev_err(&intf->dev, "invalid fimware version in device: %4ph. "  			"please reconnect to power. if this failure "  			"still happens, check your firmware installation.",  			version); @@ -364,16 +368,16 @@ int usb6fire_fw_init(struct usb_interface *intf)  	ret = usb6fire_fw_ezusb_read(device, 1, 0, buffer, 8);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "unable to receive device " -				"firmware state.\n"); +		dev_err(&intf->dev, +			"unable to receive device firmware state.\n");  		return ret;  	}  	if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) { -		snd_printk(KERN_ERR PREFIX "unknown device firmware state " -				"received from device: "); +		dev_err(&intf->dev, +			"unknown device firmware state received from device:");  		for (i = 0; i < 8; i++) -			snd_printk("%02x ", buffer[i]); -		snd_printk("\n"); +			printk(KERN_CONT "%02x ", buffer[i]); +		printk(KERN_CONT "\n");  		return -EIO;  	}  	/* do we need fpga loader ezusb firmware? */ @@ -386,7 +390,7 @@ int usb6fire_fw_init(struct usb_interface *intf)  	}  	/* do we need fpga firmware and application ezusb firmware? */  	else if (buffer[3] == 0x02) { -		ret = usb6fire_fw_check(buffer + 4); +		ret = usb6fire_fw_check(intf, buffer + 4);  		if (ret < 0)  			return ret;  		ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); @@ -402,14 +406,14 @@ int usb6fire_fw_init(struct usb_interface *intf)  	}  	/* all fw loaded? */  	else if (buffer[3] == 0x03) -		return usb6fire_fw_check(buffer + 4); +		return usb6fire_fw_check(intf, buffer + 4);  	/* unknown data? */  	else { -		snd_printk(KERN_ERR PREFIX "unknown device firmware state " -				"received from device: "); +		dev_err(&intf->dev, +			"unknown device firmware state received from device: ");  		for (i = 0; i < 8; i++) -			snd_printk("%02x ", buffer[i]); -		snd_printk("\n"); +			printk(KERN_CONT "%02x ", buffer[i]); +		printk(KERN_CONT "\n");  		return -EIO;  	}  	return 0; diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c index f3dd7266c39..3d410969553 100644 --- a/sound/usb/6fire/midi.c +++ b/sound/usb/6fire/midi.c @@ -41,8 +41,9 @@ static void usb6fire_midi_out_handler(struct urb *urb)  			ret = usb_submit_urb(urb, GFP_ATOMIC);  			if (ret < 0) -				snd_printk(KERN_ERR PREFIX "midi out urb " -						"submit failed: %d\n", ret); +				dev_err(&urb->dev->dev, +					"midi out urb submit failed: %d\n", +					ret);  		} else /* no more data to transmit */  			rt->out = NULL;  	} @@ -94,8 +95,9 @@ static void usb6fire_midi_out_trigger(  			ret = usb_submit_urb(urb, GFP_ATOMIC);  			if (ret < 0) -				snd_printk(KERN_ERR PREFIX "midi out urb " -						"submit failed: %d\n", ret); +				dev_err(&urb->dev->dev, +					"midi out urb submit failed: %d\n", +					ret);  			else  				rt->out = alsa_sub;  		} @@ -181,7 +183,7 @@ int usb6fire_midi_init(struct sfire_chip *chip)  	if (ret < 0) {  		kfree(rt->out_buffer);  		kfree(rt); -		snd_printk(KERN_ERR PREFIX "unable to create midi.\n"); +		dev_err(&chip->dev->dev, "unable to create midi.\n");  		return ret;  	}  	rt->instance->private_data = rt; diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index b5eb97fdc84..ba40489b2de 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -79,32 +79,35 @@ static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)  	ctrl_rt->usb_streaming = false;  	ret = ctrl_rt->update_streaming(ctrl_rt);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "error stopping streaming while " -				"setting samplerate %d.\n", rates[rt->rate]); +		dev_err(&rt->chip->dev->dev, +			"error stopping streaming while setting samplerate %d.\n", +			rates[rt->rate]);  		return ret;  	}  	ret = ctrl_rt->set_rate(ctrl_rt, rt->rate);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n", -				rates[rt->rate]); +		dev_err(&rt->chip->dev->dev, +			"error setting samplerate %d.\n", +			rates[rt->rate]);  		return ret;  	}  	ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS,  			false, false);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "error initializing channels " -				"while setting samplerate %d.\n", -				rates[rt->rate]); +		dev_err(&rt->chip->dev->dev, +			"error initializing channels while setting samplerate %d.\n", +			rates[rt->rate]);  		return ret;  	}  	ctrl_rt->usb_streaming = true;  	ret = ctrl_rt->update_streaming(ctrl_rt);  	if (ret < 0) { -		snd_printk(KERN_ERR PREFIX "error starting streaming while " -				"setting samplerate %d.\n", rates[rt->rate]); +		dev_err(&rt->chip->dev->dev, +			"error starting streaming while setting samplerate %d.\n", +			rates[rt->rate]);  		return ret;  	} @@ -124,7 +127,7 @@ static struct pcm_substream *usb6fire_pcm_get_substream(  		return &rt->playback;  	else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE)  		return &rt->capture; -	snd_printk(KERN_ERR PREFIX "error getting pcm substream slot.\n"); +	dev_err(&rt->chip->dev->dev, "error getting pcm substream slot.\n");  	return NULL;  } @@ -257,7 +260,7 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub,  	else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)  		dest = (u32 *) (urb->buffer);  	else { -		snd_printk(KERN_ERR PREFIX "Unknown sample format."); +		dev_err(&rt->chip->dev->dev, "Unknown sample format.");  		return;  	} @@ -307,8 +310,8 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)  		}  	if (rt->stream_state == STREAM_DISABLED) { -		snd_printk(KERN_ERR PREFIX "internal error: " -				"stream disabled in in-urb handler.\n"); +		dev_err(&rt->chip->dev->dev, +			"internal error: stream disabled in in-urb handler.\n");  		return;  	} @@ -410,7 +413,7 @@ static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)  	if (!sub) {  		mutex_unlock(&rt->stream_mutex); -		snd_printk(KERN_ERR PREFIX "invalid stream type.\n"); +		dev_err(&rt->chip->dev->dev, "invalid stream type.\n");  		return -EINVAL;  	} @@ -481,8 +484,9 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)  				break;  		if (rt->rate == ARRAY_SIZE(rates)) {  			mutex_unlock(&rt->stream_mutex); -			snd_printk("invalid rate %d in prepare.\n", -					alsa_rt->rate); +			dev_err(&rt->chip->dev->dev, +				"invalid rate %d in prepare.\n", +				alsa_rt->rate);  			return -EINVAL;  		} @@ -494,8 +498,8 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)  		ret = usb6fire_pcm_stream_start(rt);  		if (ret) {  			mutex_unlock(&rt->stream_mutex); -			snd_printk(KERN_ERR PREFIX -					"could not start pcm stream.\n"); +			dev_err(&rt->chip->dev->dev, +				"could not start pcm stream.\n");  			return ret;  		}  	} @@ -650,7 +654,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip)  	if (ret < 0) {  		usb6fire_pcm_buffers_destroy(rt);  		kfree(rt); -		snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n"); +		dev_err(&chip->dev->dev, "cannot create pcm instance.\n");  		return ret;  	} @@ -662,8 +666,8 @@ int usb6fire_pcm_init(struct sfire_chip *chip)  	if (ret) {  		usb6fire_pcm_buffers_destroy(rt);  		kfree(rt); -		snd_printk(KERN_ERR PREFIX -				"error preallocating pcm buffers.\n"); +		dev_err(&chip->dev->dev, +			"error preallocating pcm buffers.\n");  		return ret;  	}  	rt->instance = pcm; diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index de9408b83f7..d393153c474 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig @@ -14,6 +14,7 @@ config SND_USB_AUDIO  	select SND_HWDEP  	select SND_RAWMIDI  	select SND_PCM +	select BITREVERSE  	help  	  Say Y here to include support for USB audio and USB MIDI  	  devices. @@ -146,5 +147,18 @@ config SND_USB_HIFACE  	  To compile this driver as a module, choose M here: the module  	  will be called snd-usb-hiface. +config SND_BCD2000 +	tristate "Behringer BCD2000 MIDI driver" +	select SND_RAWMIDI +	help +	  Say Y here to include MIDI support for the Behringer BCD2000 DJ +	  controller. + +	  Audio support is still work-in-progress at +	  https://github.com/anyc/snd-usb-bcd2000 + +	  To compile this driver as a module, choose M here: the module +	  will be called snd-bcd2000. +  endif	# SND_USB diff --git a/sound/usb/Makefile b/sound/usb/Makefile index abe668f660d..2b92f0dcbc4 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile @@ -23,4 +23,4 @@ obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o  obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o  obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o -obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ +obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/ diff --git a/sound/usb/bcd2000/Makefile b/sound/usb/bcd2000/Makefile new file mode 100644 index 00000000000..f09ccc0af6f --- /dev/null +++ b/sound/usb/bcd2000/Makefile @@ -0,0 +1,3 @@ +snd-bcd2000-y := bcd2000.o + +obj-$(CONFIG_SND_BCD2000) += snd-bcd2000.o
\ No newline at end of file diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c new file mode 100644 index 00000000000..820d6ca8c45 --- /dev/null +++ b/sound/usb/bcd2000/bcd2000.c @@ -0,0 +1,461 @@ +/* + * Behringer BCD2000 driver + * + *   Copyright (C) 2014 Mario Kicherer (dev@kicherer.org) + * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of the GNU General Public License as published by + *   the Free Software Foundation; either version 2 of the License, or + *   (at your option) any later version. + * + *   This program is distributed in the hope that it will be useful, + *   but WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *   GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/bitmap.h> +#include <linux/usb.h> +#include <linux/usb/audio.h> +#include <sound/core.h> +#include <sound/initval.h> +#include <sound/rawmidi.h> + +#define PREFIX "snd-bcd2000: " +#define BUFSIZE 64 + +static struct usb_device_id id_table[] = { +	{ USB_DEVICE(0x1397, 0x00bd) }, +	{ }, +}; + +static unsigned char device_cmd_prefix[] = {0x03, 0x00}; + +static unsigned char bcd2000_init_sequence[] = { +	0x07, 0x00, 0x00, 0x00, 0x78, 0x48, 0x1c, 0x81, +	0xc4, 0x00, 0x00, 0x00, 0x5e, 0x53, 0x4a, 0xf7, +	0x18, 0xfa, 0x11, 0xff, 0x6c, 0xf3, 0x90, 0xff, +	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +	0x18, 0xfa, 0x11, 0xff, 0x14, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0xf2, 0x34, 0x4a, 0xf7, +	0x18, 0xfa, 0x11, 0xff +}; + +struct bcd2000 { +	struct usb_device *dev; +	struct snd_card *card; +	struct usb_interface *intf; +	int card_index; + +	int midi_out_active; +	struct snd_rawmidi *rmidi; +	struct snd_rawmidi_substream *midi_receive_substream; +	struct snd_rawmidi_substream *midi_out_substream; + +	unsigned char midi_in_buf[BUFSIZE]; +	unsigned char midi_out_buf[BUFSIZE]; + +	struct urb *midi_out_urb; +	struct urb *midi_in_urb; + +	struct usb_anchor anchor; +}; + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; + +static DEFINE_MUTEX(devices_mutex); +DECLARE_BITMAP(devices_used, SNDRV_CARDS); +static struct usb_driver bcd2000_driver; + +#ifdef CONFIG_SND_DEBUG +static void bcd2000_dump_buffer(const char *prefix, const char *buf, int len) +{ +	print_hex_dump(KERN_DEBUG, prefix, +			DUMP_PREFIX_NONE, 16, 1, +			buf, len, false); +} +#else +static void bcd2000_dump_buffer(const char *prefix, const char *buf, int len) {} +#endif + +static int bcd2000_midi_input_open(struct snd_rawmidi_substream *substream) +{ +	return 0; +} + +static int bcd2000_midi_input_close(struct snd_rawmidi_substream *substream) +{ +	return 0; +} + +/* (de)register midi substream from client */ +static void bcd2000_midi_input_trigger(struct snd_rawmidi_substream *substream, +						int up) +{ +	struct bcd2000 *bcd2k = substream->rmidi->private_data; +	bcd2k->midi_receive_substream = up ? substream : NULL; +} + +static void bcd2000_midi_handle_input(struct bcd2000 *bcd2k, +				const unsigned char *buf, unsigned int buf_len) +{ +	unsigned int payload_length, tocopy; +	struct snd_rawmidi_substream *midi_receive_substream; + +	midi_receive_substream = ACCESS_ONCE(bcd2k->midi_receive_substream); +	if (!midi_receive_substream) +		return; + +	bcd2000_dump_buffer(PREFIX "received from device: ", buf, buf_len); + +	if (buf_len < 2) +		return; + +	payload_length = buf[0]; + +	/* ignore packets without payload */ +	if (payload_length == 0) +		return; + +	tocopy = min(payload_length, buf_len-1); + +	bcd2000_dump_buffer(PREFIX "sending to userspace: ", +					&buf[1], tocopy); + +	snd_rawmidi_receive(midi_receive_substream, +					&buf[1], tocopy); +} + +static void bcd2000_midi_send(struct bcd2000 *bcd2k) +{ +	int len, ret; +	struct snd_rawmidi_substream *midi_out_substream; + +	BUILD_BUG_ON(sizeof(device_cmd_prefix) >= BUFSIZE); + +	midi_out_substream = ACCESS_ONCE(bcd2k->midi_out_substream); +	if (!midi_out_substream) +		return; + +	/* copy command prefix bytes */ +	memcpy(bcd2k->midi_out_buf, device_cmd_prefix, +		sizeof(device_cmd_prefix)); + +	/* +	 * get MIDI packet and leave space for command prefix +	 * and payload length +	 */ +	len = snd_rawmidi_transmit(midi_out_substream, +				bcd2k->midi_out_buf + 3, BUFSIZE - 3); + +	if (len < 0) +		dev_err(&bcd2k->dev->dev, "%s: snd_rawmidi_transmit error %d\n", +				__func__, len); + +	if (len <= 0) +		return; + +	/* set payload length */ +	bcd2k->midi_out_buf[2] = len; +	bcd2k->midi_out_urb->transfer_buffer_length = BUFSIZE; + +	bcd2000_dump_buffer(PREFIX "sending to device: ", +			bcd2k->midi_out_buf, len+3); + +	/* send packet to the BCD2000 */ +	ret = usb_submit_urb(bcd2k->midi_out_urb, GFP_ATOMIC); +	if (ret < 0) +		dev_err(&bcd2k->dev->dev, PREFIX +			"%s (%p): usb_submit_urb() failed, ret=%d, len=%d\n", +			__func__, midi_out_substream, ret, len); +	else +		bcd2k->midi_out_active = 1; +} + +static int bcd2000_midi_output_open(struct snd_rawmidi_substream *substream) +{ +	return 0; +} + +static int bcd2000_midi_output_close(struct snd_rawmidi_substream *substream) +{ +	struct bcd2000 *bcd2k = substream->rmidi->private_data; + +	if (bcd2k->midi_out_active) { +		usb_kill_urb(bcd2k->midi_out_urb); +		bcd2k->midi_out_active = 0; +	} + +	return 0; +} + +/* (de)register midi substream from client */ +static void bcd2000_midi_output_trigger(struct snd_rawmidi_substream *substream, +						int up) +{ +	struct bcd2000 *bcd2k = substream->rmidi->private_data; + +	if (up) { +		bcd2k->midi_out_substream = substream; +		/* check if there is data userspace wants to send */ +		if (!bcd2k->midi_out_active) +			bcd2000_midi_send(bcd2k); +	} else { +		bcd2k->midi_out_substream = NULL; +	} +} + +static void bcd2000_output_complete(struct urb *urb) +{ +	struct bcd2000 *bcd2k = urb->context; + +	bcd2k->midi_out_active = 0; + +	if (urb->status) +		dev_warn(&urb->dev->dev, +			PREFIX "output urb->status: %d\n", urb->status); + +	if (urb->status == -ESHUTDOWN) +		return; + +	/* check if there is more data userspace wants to send */ +	bcd2000_midi_send(bcd2k); +} + +static void bcd2000_input_complete(struct urb *urb) +{ +	int ret; +	struct bcd2000 *bcd2k = urb->context; + +	if (urb->status) +		dev_warn(&urb->dev->dev, +			PREFIX "input urb->status: %i\n", urb->status); + +	if (!bcd2k || urb->status == -ESHUTDOWN) +		return; + +	if (urb->actual_length > 0) +		bcd2000_midi_handle_input(bcd2k, urb->transfer_buffer, +					urb->actual_length); + +	/* return URB to device */ +	ret = usb_submit_urb(bcd2k->midi_in_urb, GFP_ATOMIC); +	if (ret < 0) +		dev_err(&bcd2k->dev->dev, PREFIX +			"%s: usb_submit_urb() failed, ret=%d\n", +			__func__, ret); +} + +static struct snd_rawmidi_ops bcd2000_midi_output = { +	.open =    bcd2000_midi_output_open, +	.close =   bcd2000_midi_output_close, +	.trigger = bcd2000_midi_output_trigger, +}; + +static struct snd_rawmidi_ops bcd2000_midi_input = { +	.open =    bcd2000_midi_input_open, +	.close =   bcd2000_midi_input_close, +	.trigger = bcd2000_midi_input_trigger, +}; + +static void bcd2000_init_device(struct bcd2000 *bcd2k) +{ +	int ret; + +	init_usb_anchor(&bcd2k->anchor); +	usb_anchor_urb(bcd2k->midi_out_urb, &bcd2k->anchor); +	usb_anchor_urb(bcd2k->midi_in_urb, &bcd2k->anchor); + +	/* copy init sequence into buffer */ +	memcpy(bcd2k->midi_out_buf, bcd2000_init_sequence, 52); +	bcd2k->midi_out_urb->transfer_buffer_length = 52; + +	/* submit sequence */ +	ret = usb_submit_urb(bcd2k->midi_out_urb, GFP_KERNEL); +	if (ret < 0) +		dev_err(&bcd2k->dev->dev, PREFIX +			"%s: usb_submit_urb() out failed, ret=%d: ", +			__func__, ret); +	else +		bcd2k->midi_out_active = 1; + +	/* pass URB to device to enable button and controller events */ +	ret = usb_submit_urb(bcd2k->midi_in_urb, GFP_KERNEL); +	if (ret < 0) +		dev_err(&bcd2k->dev->dev, PREFIX +			"%s: usb_submit_urb() in failed, ret=%d: ", +			__func__, ret); + +	/* ensure initialization is finished */ +	usb_wait_anchor_empty_timeout(&bcd2k->anchor, 1000); +} + +static int bcd2000_init_midi(struct bcd2000 *bcd2k) +{ +	int ret; +	struct snd_rawmidi *rmidi; + +	ret = snd_rawmidi_new(bcd2k->card, bcd2k->card->shortname, 0, +					1, /* output */ +					1, /* input */ +					&rmidi); + +	if (ret < 0) +		return ret; + +	strlcpy(rmidi->name, bcd2k->card->shortname, sizeof(rmidi->name)); + +	rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX; +	rmidi->private_data = bcd2k; + +	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; +	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, +					&bcd2000_midi_output); + +	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; +	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, +					&bcd2000_midi_input); + +	bcd2k->rmidi = rmidi; + +	bcd2k->midi_in_urb = usb_alloc_urb(0, GFP_KERNEL); +	bcd2k->midi_out_urb = usb_alloc_urb(0, GFP_KERNEL); + +	if (!bcd2k->midi_in_urb || !bcd2k->midi_out_urb) { +		dev_err(&bcd2k->dev->dev, PREFIX "usb_alloc_urb failed\n"); +		return -ENOMEM; +	} + +	usb_fill_int_urb(bcd2k->midi_in_urb, bcd2k->dev, +				usb_rcvintpipe(bcd2k->dev, 0x81), +				bcd2k->midi_in_buf, BUFSIZE, +				bcd2000_input_complete, bcd2k, 1); + +	usb_fill_int_urb(bcd2k->midi_out_urb, bcd2k->dev, +				usb_sndintpipe(bcd2k->dev, 0x1), +				bcd2k->midi_out_buf, BUFSIZE, +				bcd2000_output_complete, bcd2k, 1); + +	bcd2000_init_device(bcd2k); + +	return 0; +} + +static void bcd2000_free_usb_related_resources(struct bcd2000 *bcd2k, +						struct usb_interface *interface) +{ +	/* usb_kill_urb not necessary, urb is aborted automatically */ + +	usb_free_urb(bcd2k->midi_out_urb); +	usb_free_urb(bcd2k->midi_in_urb); + +	if (bcd2k->intf) { +		usb_set_intfdata(bcd2k->intf, NULL); +		bcd2k->intf = NULL; +	} +} + +static int bcd2000_probe(struct usb_interface *interface, +				const struct usb_device_id *usb_id) +{ +	struct snd_card *card; +	struct bcd2000 *bcd2k; +	unsigned int card_index; +	char usb_path[32]; +	int err; + +	mutex_lock(&devices_mutex); + +	for (card_index = 0; card_index < SNDRV_CARDS; ++card_index) +		if (!test_bit(card_index, devices_used)) +			break; + +	if (card_index >= SNDRV_CARDS) { +		mutex_unlock(&devices_mutex); +		return -ENOENT; +	} + +	err = snd_card_new(&interface->dev, index[card_index], id[card_index], +			THIS_MODULE, sizeof(*bcd2k), &card); +	if (err < 0) { +		mutex_unlock(&devices_mutex); +		return err; +	} + +	bcd2k = card->private_data; +	bcd2k->dev = interface_to_usbdev(interface); +	bcd2k->card = card; +	bcd2k->card_index = card_index; +	bcd2k->intf = interface; + +	snd_card_set_dev(card, &interface->dev); + +	strncpy(card->driver, "snd-bcd2000", sizeof(card->driver)); +	strncpy(card->shortname, "BCD2000", sizeof(card->shortname)); +	usb_make_path(bcd2k->dev, usb_path, sizeof(usb_path)); +	snprintf(bcd2k->card->longname, sizeof(bcd2k->card->longname), +		    "Behringer BCD2000 at %s", +			usb_path); + +	err = bcd2000_init_midi(bcd2k); +	if (err < 0) +		goto probe_error; + +	err = snd_card_register(card); +	if (err < 0) +		goto probe_error; + +	usb_set_intfdata(interface, bcd2k); +	set_bit(card_index, devices_used); + +	mutex_unlock(&devices_mutex); +	return 0; + +probe_error: +	dev_info(&bcd2k->dev->dev, PREFIX "error during probing"); +	bcd2000_free_usb_related_resources(bcd2k, interface); +	snd_card_free(card); +	mutex_unlock(&devices_mutex); +	return err; +} + +static void bcd2000_disconnect(struct usb_interface *interface) +{ +	struct bcd2000 *bcd2k = usb_get_intfdata(interface); + +	if (!bcd2k) +		return; + +	mutex_lock(&devices_mutex); + +	/* make sure that userspace cannot create new requests */ +	snd_card_disconnect(bcd2k->card); + +	bcd2000_free_usb_related_resources(bcd2k, interface); + +	clear_bit(bcd2k->card_index, devices_used); + +	snd_card_free_when_closed(bcd2k->card); + +	mutex_unlock(&devices_mutex); +} + +static struct usb_driver bcd2000_driver = { +	.name =		"snd-bcd2000", +	.probe =	bcd2000_probe, +	.disconnect =	bcd2000_disconnect, +	.id_table =	id_table, +}; + +module_usb_driver(bcd2000_driver); + +MODULE_DEVICE_TABLE(usb, id_table); +MODULE_AUTHOR("Mario Kicherer, dev@kicherer.org"); +MODULE_DESCRIPTION("Behringer BCD2000 driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c index ae6b50f9ed5..f65fc0987cf 100644 --- a/sound/usb/caiaq/control.c +++ b/sound/usb/caiaq/control.c @@ -28,6 +28,7 @@  #include "control.h"  #define CNT_INTVAL 0x10000 +#define MASCHINE_BANK_SIZE 32  static int control_info(struct snd_kcontrol *kcontrol,  			struct snd_ctl_elem_info *uinfo) @@ -105,6 +106,10 @@ static int control_put(struct snd_kcontrol *kcontrol,  		USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1))  		cmd = EP1_CMD_DIMM_LEDS; +	if (cdev->chip.usb_id == +		USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER)) +		cmd = EP1_CMD_DIMM_LEDS; +  	if (pos & CNT_INTVAL) {  		int i = pos & ~CNT_INTVAL; @@ -121,6 +126,20 @@ static int control_put(struct snd_kcontrol *kcontrol,  				     usb_sndbulkpipe(cdev->chip.dev, 8),  				     cdev->ep8_out_buf, sizeof(cdev->ep8_out_buf),  				     &actual_len, 200); +		} else if (cdev->chip.usb_id == +			USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER)) { + +			int bank = 0; +			int offset = 0; + +			if (i >= MASCHINE_BANK_SIZE) { +				bank = 0x1e; +				offset = MASCHINE_BANK_SIZE; +			} + +			snd_usb_caiaq_send_command_bank(cdev, cmd, bank, +					cdev->control_state + offset, +					MASCHINE_BANK_SIZE);  		} else {  			snd_usb_caiaq_send_command(cdev, cmd,  					cdev->control_state, sizeof(cdev->control_state)); @@ -490,6 +509,74 @@ static struct caiaq_controller kontrols4_controller[] = {  	{ "LED: FX2: Mode",			133 | CNT_INTVAL },  }; +static struct caiaq_controller maschine_controller[] = { +	{ "LED: Pad 1",				3  | CNT_INTVAL }, +	{ "LED: Pad 2",				2  | CNT_INTVAL }, +	{ "LED: Pad 3",				1  | CNT_INTVAL }, +	{ "LED: Pad 4",				0  | CNT_INTVAL }, +	{ "LED: Pad 5",				7  | CNT_INTVAL }, +	{ "LED: Pad 6",				6  | CNT_INTVAL }, +	{ "LED: Pad 7",				5  | CNT_INTVAL }, +	{ "LED: Pad 8",				4  | CNT_INTVAL }, +	{ "LED: Pad 9",				11 | CNT_INTVAL }, +	{ "LED: Pad 10",			10 | CNT_INTVAL }, +	{ "LED: Pad 11",			9  | CNT_INTVAL }, +	{ "LED: Pad 12",			8  | CNT_INTVAL }, +	{ "LED: Pad 13",			15 | CNT_INTVAL }, +	{ "LED: Pad 14",			14 | CNT_INTVAL }, +	{ "LED: Pad 15",			13 | CNT_INTVAL }, +	{ "LED: Pad 16",			12 | CNT_INTVAL }, + +	{ "LED: Mute",				16 | CNT_INTVAL }, +	{ "LED: Solo",				17 | CNT_INTVAL }, +	{ "LED: Select",			18 | CNT_INTVAL }, +	{ "LED: Duplicate",			19 | CNT_INTVAL }, +	{ "LED: Navigate",			20 | CNT_INTVAL }, +	{ "LED: Pad Mode",			21 | CNT_INTVAL }, +	{ "LED: Pattern",			22 | CNT_INTVAL }, +	{ "LED: Scene",				23 | CNT_INTVAL }, + +	{ "LED: Shift",				24 | CNT_INTVAL }, +	{ "LED: Erase",				25 | CNT_INTVAL }, +	{ "LED: Grid",				26 | CNT_INTVAL }, +	{ "LED: Right Bottom",			27 | CNT_INTVAL }, +	{ "LED: Rec",				28 | CNT_INTVAL }, +	{ "LED: Play",				29 | CNT_INTVAL }, +	{ "LED: Left Bottom",			32 | CNT_INTVAL }, +	{ "LED: Restart",			33 | CNT_INTVAL }, + +	{ "LED: Group A",			41 | CNT_INTVAL }, +	{ "LED: Group B",			40 | CNT_INTVAL }, +	{ "LED: Group C",			37 | CNT_INTVAL }, +	{ "LED: Group D",			36 | CNT_INTVAL }, +	{ "LED: Group E",			39 | CNT_INTVAL }, +	{ "LED: Group F",			38 | CNT_INTVAL }, +	{ "LED: Group G",			35 | CNT_INTVAL }, +	{ "LED: Group H",			34 | CNT_INTVAL }, + +	{ "LED: Auto Write",			42 | CNT_INTVAL }, +	{ "LED: Snap",				43 | CNT_INTVAL }, +	{ "LED: Right Top",			44 | CNT_INTVAL }, +	{ "LED: Left Top",			45 | CNT_INTVAL }, +	{ "LED: Sampling",			46 | CNT_INTVAL }, +	{ "LED: Browse",			47 | CNT_INTVAL }, +	{ "LED: Step",				48 | CNT_INTVAL }, +	{ "LED: Control",			49 | CNT_INTVAL }, + +	{ "LED: Top Button 1",			57 | CNT_INTVAL }, +	{ "LED: Top Button 2",			56 | CNT_INTVAL }, +	{ "LED: Top Button 3",			55 | CNT_INTVAL }, +	{ "LED: Top Button 4",			54 | CNT_INTVAL }, +	{ "LED: Top Button 5",			53 | CNT_INTVAL }, +	{ "LED: Top Button 6",			52 | CNT_INTVAL }, +	{ "LED: Top Button 7",			51 | CNT_INTVAL }, +	{ "LED: Top Button 8",			50 | CNT_INTVAL }, + +	{ "LED: Note Repeat",			58 | CNT_INTVAL }, + +	{ "Backlight Display",			59 | CNT_INTVAL } +}; +  static int add_controls(struct caiaq_controller *c, int num,  			struct snd_usb_caiaqdev *cdev)  { @@ -553,6 +640,11 @@ int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *cdev)  		ret = add_controls(kontrols4_controller,  			ARRAY_SIZE(kontrols4_controller), cdev);  		break; + +	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): +		ret = add_controls(maschine_controller, +			ARRAY_SIZE(maschine_controller), cdev); +		break;  	}  	return ret; diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 1a61dd12fe3..b871ba407e4 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -235,6 +235,31 @@ int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *cdev,  			   cdev->ep1_out_buf, len+1, &actual_len, 200);  } +int snd_usb_caiaq_send_command_bank(struct snd_usb_caiaqdev *cdev, +			       unsigned char command, +			       unsigned char bank, +			       const unsigned char *buffer, +			       int len) +{ +	int actual_len; +	struct usb_device *usb_dev = cdev->chip.dev; + +	if (!usb_dev) +		return -EIO; + +	if (len > EP1_BUFSIZE - 2) +		len = EP1_BUFSIZE - 2; + +	if (buffer && len > 0) +		memcpy(cdev->ep1_out_buf+2, buffer, len); + +	cdev->ep1_out_buf[0] = command; +	cdev->ep1_out_buf[1] = bank; + +	return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), +			   cdev->ep1_out_buf, len+2, &actual_len, 200); +} +  int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *cdev,  		   		    int rate, int depth, int bpp)  { @@ -393,8 +418,9 @@ static int create_card(struct usb_device *usb_dev,  	if (devnum >= SNDRV_CARDS)  		return -ENODEV; -	err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, -			      sizeof(struct snd_usb_caiaqdev), &card); +	err = snd_card_new(&intf->dev, +			   index[devnum], id[devnum], THIS_MODULE, +			   sizeof(struct snd_usb_caiaqdev), &card);  	if (err < 0)  		return err; @@ -404,7 +430,6 @@ static int create_card(struct usb_device *usb_dev,  	cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor),  				  le16_to_cpu(usb_dev->descriptor.idProduct));  	spin_lock_init(&cdev->spinlock); -	snd_card_set_dev(card, &intf->dev);  	*cardp = card;  	return 0; diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index ad102fac694..ab0f7520a99 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h @@ -128,5 +128,10 @@ int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *cdev,  			       unsigned char command,  			       const unsigned char *buffer,  			       int len); +int snd_usb_caiaq_send_command_bank(struct snd_usb_caiaqdev *cdev, +			       unsigned char command, +			       unsigned char bank, +			       const unsigned char *buffer, +			       int len);  #endif /* CAIAQ_DEVICE_H */ diff --git a/sound/usb/card.c b/sound/usb/card.c index 64952e2d3ed..a09e5f3519e 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -79,7 +79,6 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card *  /* Vendor/product IDs for this card */  static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };  static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; -static int nrpacks = 8;		/* max. number of packets per urb */  static int device_setup[SNDRV_CARDS]; /* device parameter for this card */  static bool ignore_ctl_error;  static bool autoclock = true; @@ -94,8 +93,6 @@ module_param_array(vid, int, NULL, 0444);  MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");  module_param_array(pid, int, NULL, 0444);  MODULE_PARM_DESC(pid, "Product ID for the USB audio device."); -module_param(nrpacks, int, 0644); -MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");  module_param_array(device_setup, int, NULL, 0444);  MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");  module_param(ignore_ctl_error, bool, 0444); @@ -142,8 +139,8 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int  	struct usb_interface *iface = usb_ifnum_to_if(dev, interface);  	if (!iface) { -		snd_printk(KERN_ERR "%d:%u:%d : does not exist\n", -			   dev->devnum, ctrlif, interface); +		dev_err(&dev->dev, "%u:%d : does not exist\n", +			ctrlif, interface);  		return -EINVAL;  	} @@ -168,8 +165,8 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int  	}  	if (usb_interface_claimed(iface)) { -		snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", -						dev->devnum, ctrlif, interface); +		dev_dbg(&dev->dev, "%d:%d: skipping, already claimed\n", +			ctrlif, interface);  		return -EINVAL;  	} @@ -179,8 +176,9 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int  		int err = snd_usbmidi_create(chip->card, iface,  					     &chip->midi_list, NULL);  		if (err < 0) { -			snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", -						dev->devnum, ctrlif, interface); +			dev_err(&dev->dev, +				"%u:%d: cannot create sequencer device\n", +				ctrlif, interface);  			return -EINVAL;  		}  		usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); @@ -191,14 +189,15 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int  	if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&  	     altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||  	    altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) { -		snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", -					dev->devnum, ctrlif, interface, altsd->bInterfaceClass); +		dev_dbg(&dev->dev, +			"%u:%d: skipping non-supported interface %d\n", +			ctrlif, interface, altsd->bInterfaceClass);  		/* skip non-supported classes */  		return -EINVAL;  	}  	if (snd_usb_get_speed(dev) == USB_SPEED_LOW) { -		snd_printk(KERN_ERR "low speed audio streaming not supported\n"); +		dev_err(&dev->dev, "low speed audio streaming not supported\n");  		return -EINVAL;  	} @@ -231,26 +230,27 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)  	protocol = altsd->bInterfaceProtocol;  	if (!control_header) { -		snd_printk(KERN_ERR "cannot find UAC_HEADER\n"); +		dev_err(&dev->dev, "cannot find UAC_HEADER\n");  		return -EINVAL;  	}  	switch (protocol) {  	default: -		snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1\n", -			    protocol); +		dev_warn(&dev->dev, +			 "unknown interface protocol %#02x, assuming v1\n", +			 protocol);  		/* fall through */  	case UAC_VERSION_1: {  		struct uac1_ac_header_descriptor *h1 = control_header;  		if (!h1->bInCollection) { -			snd_printk(KERN_INFO "skipping empty audio interface (v1)\n"); +			dev_info(&dev->dev, "skipping empty audio interface (v1)\n");  			return -EINVAL;  		}  		if (h1->bLength < sizeof(*h1) + h1->bInCollection) { -			snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n"); +			dev_err(&dev->dev, "invalid UAC_HEADER (v1)\n");  			return -EINVAL;  		} @@ -280,7 +280,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)  		}  		if (!assoc) { -			snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n"); +			dev_err(&dev->dev, "Audio class v2 interfaces need an interface association\n");  			return -EINVAL;  		} @@ -307,6 +307,11 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)  static int snd_usb_audio_free(struct snd_usb_audio *chip)  { +	struct list_head *p, *n; + +	list_for_each_safe(p, n, &chip->ep_list) +		snd_usb_endpoint_free(p); +  	mutex_destroy(&chip->mutex);  	kfree(chip);  	return 0; @@ -331,7 +336,8 @@ static void remove_trailing_spaces(char *str)  /*   * create a chip instance and set its names.   */ -static int snd_usb_audio_create(struct usb_device *dev, int idx, +static int snd_usb_audio_create(struct usb_interface *intf, +				struct usb_device *dev, int idx,  				const struct snd_usb_audio_quirk *quirk,  				struct snd_usb_audio **rchip)  { @@ -349,16 +355,18 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,  	case USB_SPEED_LOW:  	case USB_SPEED_FULL:  	case USB_SPEED_HIGH: +	case USB_SPEED_WIRELESS:  	case USB_SPEED_SUPER:  		break;  	default: -		snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev)); +		dev_err(&dev->dev, "unknown device speed %d\n", snd_usb_get_speed(dev));  		return -ENXIO;  	} -	err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card); +	err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE, +			   0, &card);  	if (err < 0) { -		snd_printk(KERN_ERR "cannot create card instance %d\n", idx); +		dev_err(&dev->dev, "cannot create card instance %d\n", idx);  		return err;  	} @@ -374,7 +382,6 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,  	chip->dev = dev;  	chip->card = card;  	chip->setup = device_setup[idx]; -	chip->nrpacks = nrpacks;  	chip->autoclock = autoclock;  	chip->probing = 1; @@ -500,7 +507,7 @@ snd_usb_audio_probe(struct usb_device *dev,  	for (i = 0; i < SNDRV_CARDS; i++) {  		if (usb_chip[i] && usb_chip[i]->dev == dev) {  			if (usb_chip[i]->shutdown) { -				snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n"); +				dev_err(&dev->dev, "USB device is in the shutdown state, cannot create a card instance\n");  				goto __error;  			}  			chip = usb_chip[i]; @@ -516,15 +523,15 @@ snd_usb_audio_probe(struct usb_device *dev,  			if (enable[i] && ! usb_chip[i] &&  			    (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&  			    (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { -				if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) { +				if (snd_usb_audio_create(intf, dev, i, quirk, +							 &chip) < 0) {  					goto __error;  				} -				snd_card_set_dev(chip->card, &intf->dev);  				chip->pm_intf = intf;  				break;  			}  		if (!chip) { -			printk(KERN_ERR "no available usb audio device\n"); +			dev_err(&dev->dev, "no available usb audio device\n");  			goto __error;  		}  	} @@ -583,7 +590,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,  				     struct snd_usb_audio *chip)  {  	struct snd_card *card; -	struct list_head *p, *n; +	struct list_head *p;  	if (chip == (void *)-1L)  		return; @@ -596,14 +603,16 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,  	mutex_lock(®ister_mutex);  	chip->num_interfaces--;  	if (chip->num_interfaces <= 0) { +		struct snd_usb_endpoint *ep; +  		snd_card_disconnect(card);  		/* release the pcm resources */  		list_for_each(p, &chip->pcm_list) {  			snd_usb_stream_disconnect(p);  		}  		/* release the endpoint resources */ -		list_for_each_safe(p, n, &chip->ep_list) { -			snd_usb_endpoint_free(p); +		list_for_each_entry(ep, &chip->ep_list, list) { +			snd_usb_endpoint_release(ep);  		}  		/* release the midi resources */  		list_for_each(p, &chip->midi_list) { @@ -649,7 +658,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)  	int err = -ENODEV;  	down_read(&chip->shutdown_rwsem); -	if (chip->probing) +	if (chip->probing && chip->in_pm)  		err = 0;  	else if (!chip->shutdown)  		err = usb_autopm_get_interface(chip->pm_intf); @@ -661,7 +670,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)  void snd_usb_autosuspend(struct snd_usb_audio *chip)  {  	down_read(&chip->shutdown_rwsem); -	if (!chip->shutdown && !chip->probing) +	if (!chip->shutdown && !chip->probing && !chip->in_pm)  		usb_autopm_put_interface(chip->pm_intf);  	up_read(&chip->shutdown_rwsem);  } @@ -693,13 +702,14 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)  			chip->autosuspended = 1;  	} -	list_for_each_entry(mixer, &chip->mixer_list, list) -		snd_usb_mixer_inactivate(mixer); +	if (chip->num_suspended_intf == 1) +		list_for_each_entry(mixer, &chip->mixer_list, list) +			snd_usb_mixer_suspend(mixer);  	return 0;  } -static int usb_audio_resume(struct usb_interface *intf) +static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)  {  	struct snd_usb_audio *chip = usb_get_intfdata(intf);  	struct usb_mixer_interface *mixer; @@ -709,12 +719,14 @@ static int usb_audio_resume(struct usb_interface *intf)  		return 0;  	if (--chip->num_suspended_intf)  		return 0; + +	chip->in_pm = 1;  	/*  	 * ALSA leaves material resumption to user space  	 * we just notify and restart the mixers  	 */  	list_for_each_entry(mixer, &chip->mixer_list, list) { -		err = snd_usb_mixer_activate(mixer); +		err = snd_usb_mixer_resume(mixer, reset_resume);  		if (err < 0)  			goto err_out;  	} @@ -724,11 +736,23 @@ static int usb_audio_resume(struct usb_interface *intf)  	chip->autosuspended = 0;  err_out: +	chip->in_pm = 0;  	return err;  } + +static int usb_audio_resume(struct usb_interface *intf) +{ +	return __usb_audio_resume(intf, false); +} + +static int usb_audio_reset_resume(struct usb_interface *intf) +{ +	return __usb_audio_resume(intf, true); +}  #else  #define usb_audio_suspend	NULL  #define usb_audio_resume	NULL +#define usb_audio_reset_resume	NULL  #endif		/* CONFIG_PM */  static struct usb_device_id usb_audio_ids [] = { @@ -750,23 +774,9 @@ static struct usb_driver usb_audio_driver = {  	.disconnect =	usb_audio_disconnect,  	.suspend =	usb_audio_suspend,  	.resume =	usb_audio_resume, +	.reset_resume =	usb_audio_reset_resume,  	.id_table =	usb_audio_ids,  	.supports_autosuspend = 1,  }; -static int __init snd_usb_audio_init(void) -{ -	if (nrpacks < 1 || nrpacks > MAX_PACKS) { -		printk(KERN_WARNING "invalid nrpacks value.\n"); -		return -EINVAL; -	} -	return usb_register(&usb_audio_driver); -} - -static void __exit snd_usb_audio_cleanup(void) -{ -	usb_deregister(&usb_audio_driver); -} - -module_init(snd_usb_audio_init); -module_exit(snd_usb_audio_cleanup); +module_usb_driver(usb_audio_driver); diff --git a/sound/usb/card.h b/sound/usb/card.h index 5ecacaa90b5..97acb906acc 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -2,11 +2,11 @@  #define __USBAUDIO_CARD_H  #define MAX_NR_RATES	1024 -#define MAX_PACKS	20 +#define MAX_PACKS	6		/* per URB */  #define MAX_PACKS_HS	(MAX_PACKS * 8)	/* in high speed mode */ -#define MAX_URBS	8 +#define MAX_URBS	12  #define SYNC_URBS	4	/* always four urbs for sync */ -#define MAX_QUEUE	24	/* try not to exceed this queue length, in ms */ +#define MAX_QUEUE	18	/* try not to exceed this queue length, in ms */  struct audioformat {  	struct list_head list; @@ -87,15 +87,17 @@ struct snd_usb_endpoint {  	unsigned int phase;		/* phase accumulator */  	unsigned int maxpacksize;	/* max packet size in bytes */  	unsigned int maxframesize;      /* max packet size in frames */ +	unsigned int max_urb_frames;	/* max URB size in frames */  	unsigned int curpacksize;	/* current packet size in bytes (for capture) */  	unsigned int curframesize;      /* current packet size in frames (for capture) */  	unsigned int syncmaxsize;	/* sync endpoint packet size */  	unsigned int fill_max:1;	/* fill max packet size always */ +	unsigned int udh01_fb_quirk:1;	/* corrupted feedback data */  	unsigned int datainterval;      /* log_2 of data packet interval */  	unsigned int syncinterval;	/* P for adaptive mode, 0 otherwise */  	unsigned char silence_value;  	unsigned int stride; -	int iface, alt_idx; +	int iface, altsetting;  	int skip_packets;		/* quirks for devices to ignore the first n packets  					   in a stream */ @@ -116,6 +118,8 @@ struct snd_usb_substream {  	unsigned int channels_max;	/* max channels in the all audiofmts */  	unsigned int cur_rate;		/* current rate (for hw_params callback) */  	unsigned int period_bytes;	/* current period bytes (for hw_params callback) */ +	unsigned int period_frames;	/* current frames per period */ +	unsigned int buffer_periods;	/* current periods per buffer */  	unsigned int altset_idx;     /* USB data format: index of alternate setting */  	unsigned int txfr_quirk:1;	/* allow sub-frame alignment */  	unsigned int fmt_type;		/* USB audio format type (1-3) */ @@ -125,6 +129,7 @@ struct snd_usb_substream {  	unsigned int hwptr_done;	/* processed byte position in the buffer */  	unsigned int transfer_done;		/* processed frames since last period update */ +	unsigned int frame_limit;	/* limits number of packets in URB */  	/* data and sync endpoints for this stream */  	unsigned int ep_num;		/* the endpoint number */ diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 86f80c60b21..03fed6611d9 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -115,9 +115,9 @@ static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_i  		return ret;  	if (ret != sizeof(pin)) { -		snd_printk(KERN_ERR -			"usb-audio:%d: setting selector (id %d) unexpected length %d\n", -			chip->dev->devnum, selector_id, ret); +		usb_audio_err(chip, +			"setting selector (id %d) unexpected length %d\n", +			selector_id, ret);  		return -EINVAL;  	} @@ -126,9 +126,9 @@ static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_i  		return ret;  	if (ret != pin) { -		snd_printk(KERN_ERR -			"usb-audio:%d: setting selector (id %d) to %x failed (current: %d)\n", -			chip->dev->devnum, selector_id, pin, ret); +		usb_audio_err(chip, +			"setting selector (id %d) to %x failed (current: %d)\n", +			selector_id, pin, ret);  		return -EINVAL;  	} @@ -158,7 +158,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)  			      &data, sizeof(data));  	if (err < 0) { -		snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", +		dev_warn(&dev->dev, +			 "%s(): cannot get clock validity for id %d\n",  			   __func__, source_id);  		return 0;  	} @@ -177,9 +178,9 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,  	entity_id &= 0xff;  	if (test_and_set_bit(entity_id, visited)) { -		snd_printk(KERN_WARNING -			"%s(): recursive clock topology detected, id %d.\n", -			__func__, entity_id); +		usb_audio_warn(chip, +			 "%s(): recursive clock topology detected, id %d.\n", +			 __func__, entity_id);  		return -EINVAL;  	} @@ -188,8 +189,9 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,  	if (source) {  		entity_id = source->bClockID;  		if (validate && !uac_clock_source_is_valid(chip, entity_id)) { -			snd_printk(KERN_ERR "usb-audio:%d: clock source %d is not valid, cannot use\n", -				   chip->dev->devnum, entity_id); +			usb_audio_err(chip, +				"clock source %d is not valid, cannot use\n", +				entity_id);  			return -ENXIO;  		}  		return entity_id; @@ -208,7 +210,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,  		/* Selector values are one-based */  		if (ret > selector->bNrInPins || ret < 1) { -			snd_printk(KERN_ERR +			usb_audio_err(chip,  				"%s(): selector reported illegal value, id %d, ret %d\n",  				__func__, selector->bClockID, ret); @@ -237,9 +239,9 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,  			if (err < 0)  				continue; -			snd_printk(KERN_INFO -				"usb-audio:%d: found and selected valid clock source %d\n", -				chip->dev->devnum, ret); +			usb_audio_info(chip, +				 "found and selected valid clock source %d\n", +				 ret);  			return ret;  		} @@ -296,8 +298,8 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,  				   USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,  				   UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,  				   data, sizeof(data))) < 0) { -		snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", -			   dev->devnum, iface, fmt->altsetting, rate, ep); +		dev_err(&dev->dev, "%d:%d: cannot set freq %d to ep %#x\n", +			iface, fmt->altsetting, rate, ep);  		return err;  	} @@ -305,14 +307,14 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,  				   USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,  				   UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,  				   data, sizeof(data))) < 0) { -		snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", -			   dev->devnum, iface, fmt->altsetting, ep); +		dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n", +			iface, fmt->altsetting, ep);  		return 0; /* some devices don't support reading */  	}  	crate = data[0] | (data[1] << 8) | (data[2] << 16);  	if (crate != rate) { -		snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); +		dev_warn(&dev->dev, "current rate %d is different from the runtime rate %d\n", crate, rate);  		// runtime->rate = crate;  	} @@ -332,8 +334,8 @@ static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface,  			      snd_usb_ctrl_intf(chip) | (clock << 8),  			      &data, sizeof(data));  	if (err < 0) { -		snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2): err %d\n", -			   dev->devnum, iface, altsetting, err); +		dev_warn(&dev->dev, "%d:%d: cannot get freq (v2): err %d\n", +			 iface, altsetting, err);  		return 0;  	} @@ -369,8 +371,9 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,  				      snd_usb_ctrl_intf(chip) | (clock << 8),  				      &data, sizeof(data));  		if (err < 0) { -			snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2): err %d\n", -				   dev->devnum, iface, fmt->altsetting, rate, err); +			usb_audio_err(chip, +				"%d:%d: cannot set freq %d (v2): err %d\n", +				iface, fmt->altsetting, rate, err);  			return err;  		} @@ -381,14 +384,14 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,  	if (cur_rate != rate) {  		if (!writeable) { -			snd_printk(KERN_WARNING -				   "%d:%d:%d: freq mismatch (RO clock): req %d, clock runs @%d\n", -				   dev->devnum, iface, fmt->altsetting, rate, cur_rate); +			usb_audio_warn(chip, +				 "%d:%d: freq mismatch (RO clock): req %d, clock runs @%d\n", +				 iface, fmt->altsetting, rate, cur_rate);  			return -ENXIO;  		} -		snd_printd(KERN_WARNING -			   "current rate %d is different from the runtime rate %d\n", -			   cur_rate, rate); +		usb_audio_dbg(chip, +			"current rate %d is different from the runtime rate %d\n", +			cur_rate, rate);  	}  	/* Some devices doesn't respond to sample rate changes while the diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 93e970f2b3c..114e3e7ff51 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -33,7 +33,6 @@  #include "pcm.h"  #include "quirks.h" -#define EP_FLAG_ACTIVATED	0  #define EP_FLAG_RUNNING		1  #define EP_FLAG_STOPPING	2 @@ -334,8 +333,9 @@ static void queue_pending_output_urbs(struct snd_usb_endpoint *ep)  		err = usb_submit_urb(ctx->urb, GFP_ATOMIC);  		if (err < 0) -			snd_printk(KERN_ERR "Unable to submit urb #%d: %d (urb %p)\n", -				   ctx->index, err, ctx->urb); +			usb_audio_err(ep->chip, +				"Unable to submit urb #%d: %d (urb %p)\n", +				ctx->index, err, ctx->urb);  		else  			set_bit(ctx->index, &ep->active_mask);  	} @@ -388,7 +388,7 @@ static void snd_complete_urb(struct urb *urb)  	if (err == 0)  		return; -	snd_printk(KERN_ERR "cannot submit urb (err = %d)\n", err); +	usb_audio_err(ep->chip, "cannot submit urb (err = %d)\n", err);  	//snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);  exit_clear: @@ -426,14 +426,15 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,  	list_for_each_entry(ep, &chip->ep_list, list) {  		if (ep->ep_num == ep_num &&  		    ep->iface == alts->desc.bInterfaceNumber && -		    ep->alt_idx == alts->desc.bAlternateSetting) { -			snd_printdd(KERN_DEBUG "Re-using EP %x in iface %d,%d @%p\n", -					ep_num, ep->iface, ep->alt_idx, ep); +		    ep->altsetting == alts->desc.bAlternateSetting) { +			usb_audio_dbg(ep->chip, +				      "Re-using EP %x in iface %d,%d @%p\n", +					ep_num, ep->iface, ep->altsetting, ep);  			goto __exit_unlock;  		}  	} -	snd_printdd(KERN_DEBUG "Creating new %s %s endpoint #%x\n", +	usb_audio_dbg(chip, "Creating new %s %s endpoint #%x\n",  		    is_playback ? "playback" : "capture",  		    type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync",  		    ep_num); @@ -447,7 +448,7 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,  	ep->type = type;  	ep->ep_num = ep_num;  	ep->iface = alts->desc.bInterfaceNumber; -	ep->alt_idx = alts->desc.bAlternateSetting; +	ep->altsetting = alts->desc.bAlternateSetting;  	INIT_LIST_HEAD(&ep->ready_playback_urbs);  	ep_num &= USB_ENDPOINT_NUMBER_MASK; @@ -470,6 +471,10 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,  			ep->syncinterval = 3;  		ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); + +		if (chip->usb_id == USB_ID(0x0644, 0x8038) /* TEAC UD-H01 */ && +		    ep->syncmaxsize == 4) +			ep->udh01_fb_quirk = 1;  	}  	list_add_tail(&ep->list, &chip->ep_list); @@ -497,8 +502,9 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep)  	} while (time_before(jiffies, end_time));  	if (alive) -		snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", -					alive, ep->ep_num); +		usb_audio_err(ep->chip, +			"timeout: still %d active urbs on EP #%x\n", +			alive, ep->ep_num);  	clear_bit(EP_FLAG_STOPPING, &ep->flags);  	return 0; @@ -574,11 +580,14 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,  			      snd_pcm_format_t pcm_format,  			      unsigned int channels,  			      unsigned int period_bytes, +			      unsigned int frames_per_period, +			      unsigned int periods_per_buffer,  			      struct audioformat *fmt,  			      struct snd_usb_endpoint *sync_ep)  { -	unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms; -	int is_playback = usb_pipeout(ep->pipe); +	unsigned int maxsize, minsize, packs_per_ms, max_packs_per_urb; +	unsigned int max_packs_per_period, urbs_per_period, urb_packs; +	unsigned int max_urbs, i;  	int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels;  	if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) { @@ -611,58 +620,81 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,  	else  		ep->curpacksize = maxsize; -	if (snd_usb_get_speed(ep->chip->dev) != USB_SPEED_FULL) +	if (snd_usb_get_speed(ep->chip->dev) != USB_SPEED_FULL) {  		packs_per_ms = 8 >> ep->datainterval; -	else -		packs_per_ms = 1; - -	if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { -		urb_packs = max(ep->chip->nrpacks, 1); -		urb_packs = min(urb_packs, (unsigned int) MAX_PACKS); +		max_packs_per_urb = MAX_PACKS_HS;  	} else { -		urb_packs = 1; +		packs_per_ms = 1; +		max_packs_per_urb = MAX_PACKS;  	} +	if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) +		max_packs_per_urb = min(max_packs_per_urb, +					1U << sync_ep->syncinterval); +	max_packs_per_urb = max(1u, max_packs_per_urb >> ep->datainterval); -	urb_packs *= packs_per_ms; +	/* +	 * Capture endpoints need to use small URBs because there's no way +	 * to tell in advance where the next period will end, and we don't +	 * want the next URB to complete much after the period ends. +	 * +	 * Playback endpoints with implicit sync much use the same parameters +	 * as their corresponding capture endpoint. +	 */ +	if (usb_pipein(ep->pipe) || +			snd_usb_endpoint_implicit_feedback_sink(ep)) { -	if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) -		urb_packs = min(urb_packs, 1U << sync_ep->syncinterval); +		urb_packs = packs_per_ms; +		/* +		 * Wireless devices can poll at a max rate of once per 4ms. +		 * For dataintervals less than 5, increase the packet count to +		 * allow the host controller to use bursting to fill in the +		 * gaps. +		 */ +		if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_WIRELESS) { +			int interval = ep->datainterval; +			while (interval < 5) { +				urb_packs <<= 1; +				++interval; +			} +		} +		/* make capture URBs <= 1 ms and smaller than a period */ +		urb_packs = min(max_packs_per_urb, urb_packs); +		while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) +			urb_packs >>= 1; +		ep->nurbs = MAX_URBS; -	/* decide how many packets to be used */ -	if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { -		unsigned int minsize, maxpacks; +	/* +	 * Playback endpoints without implicit sync are adjusted so that +	 * a period fits as evenly as possible in the smallest number of +	 * URBs.  The total number of URBs is adjusted to the size of the +	 * ALSA buffer, subject to the MAX_URBS and MAX_QUEUE limits. +	 */ +	} else {  		/* determine how small a packet can be */ -		minsize = (ep->freqn >> (16 - ep->datainterval)) -			  * (frame_bits >> 3); +		minsize = (ep->freqn >> (16 - ep->datainterval)) * +				(frame_bits >> 3);  		/* with sync from device, assume it can be 12% lower */  		if (sync_ep)  			minsize -= minsize >> 3;  		minsize = max(minsize, 1u); -		total_packs = (period_bytes + minsize - 1) / minsize; -		/* we need at least two URBs for queueing */ -		if (total_packs < 2) { -			total_packs = 2; -		} else { -			/* and we don't want too long a queue either */ -			maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2); -			total_packs = min(total_packs, maxpacks); -		} -	} else { -		while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) -			urb_packs >>= 1; -		total_packs = MAX_URBS * urb_packs; -	} -	ep->nurbs = (total_packs + urb_packs - 1) / urb_packs; -	if (ep->nurbs > MAX_URBS) { -		/* too much... */ -		ep->nurbs = MAX_URBS; -		total_packs = MAX_URBS * urb_packs; -	} else if (ep->nurbs < 2) { -		/* too little - we need at least two packets -		 * to ensure contiguous playback/capture -		 */ -		ep->nurbs = 2; +		/* how many packets will contain an entire ALSA period? */ +		max_packs_per_period = DIV_ROUND_UP(period_bytes, minsize); + +		/* how many URBs will contain a period? */ +		urbs_per_period = DIV_ROUND_UP(max_packs_per_period, +				max_packs_per_urb); +		/* how many packets are needed in each URB? */ +		urb_packs = DIV_ROUND_UP(max_packs_per_period, urbs_per_period); + +		/* limit the number of frames in a single URB */ +		ep->max_urb_frames = DIV_ROUND_UP(frames_per_period, +					urbs_per_period); + +		/* try to use enough URBs to contain an entire ALSA buffer */ +		max_urbs = min((unsigned) MAX_URBS, +				MAX_QUEUE * packs_per_ms / urb_packs); +		ep->nurbs = min(max_urbs, urbs_per_period * periods_per_buffer);  	}  	/* allocate and initialize data urbs */ @@ -670,8 +702,7 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,  		struct snd_urb_ctx *u = &ep->urb[i];  		u->index = i;  		u->ep = ep; -		u->packets = (i + 1) * total_packs / ep->nurbs -			- i * total_packs / ep->nurbs; +		u->packets = urb_packs;  		u->buffer_size = maxsize * u->packets;  		if (fmt->fmt_type == UAC_FORMAT_TYPE_II) @@ -703,8 +734,7 @@ out_of_memory:  /*   * configure a sync endpoint   */ -static int sync_ep_set_params(struct snd_usb_endpoint *ep, -			      struct audioformat *fmt) +static int sync_ep_set_params(struct snd_usb_endpoint *ep)  {  	int i; @@ -748,6 +778,8 @@ out_of_memory:   * @pcm_format: the audio fomat.   * @channels: the number of audio channels.   * @period_bytes: the number of bytes in one alsa period. + * @period_frames: the number of frames in one alsa period. + * @buffer_periods: the number of periods in one alsa buffer.   * @rate: the frame rate.   * @fmt: the USB audio format information   * @sync_ep: the sync endpoint to use, if any @@ -760,6 +792,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,  				snd_pcm_format_t pcm_format,  				unsigned int channels,  				unsigned int period_bytes, +				unsigned int period_frames, +				unsigned int buffer_periods,  				unsigned int rate,  				struct audioformat *fmt,  				struct snd_usb_endpoint *sync_ep) @@ -767,8 +801,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,  	int err;  	if (ep->use_count != 0) { -		snd_printk(KERN_WARNING "Unable to change format on ep #%x: already in use\n", -			   ep->ep_num); +		usb_audio_warn(ep->chip, +			 "Unable to change format on ep #%x: already in use\n", +			 ep->ep_num);  		return -EBUSY;  	} @@ -793,17 +828,19 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,  	switch (ep->type) {  	case  SND_USB_ENDPOINT_TYPE_DATA:  		err = data_ep_set_params(ep, pcm_format, channels, -					 period_bytes, fmt, sync_ep); +					 period_bytes, period_frames, +					 buffer_periods, fmt, sync_ep);  		break;  	case  SND_USB_ENDPOINT_TYPE_SYNC: -		err = sync_ep_set_params(ep, fmt); +		err = sync_ep_set_params(ep);  		break;  	default:  		err = -EINVAL;  	} -	snd_printdd(KERN_DEBUG "Setting params for ep #%x (type %d, %d urbs), ret=%d\n", -		   ep->ep_num, ep->type, ep->nurbs, err); +	usb_audio_dbg(ep->chip, +		"Setting params for ep #%x (type %d, %d urbs), ret=%d\n", +		ep->ep_num, ep->type, ep->nurbs, err);  	return err;  } @@ -878,8 +915,9 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep)  		err = usb_submit_urb(urb, GFP_ATOMIC);  		if (err < 0) { -			snd_printk(KERN_ERR "cannot submit urb %d, error %d: %s\n", -				   i, err, usb_error_string(err)); +			usb_audio_err(ep->chip, +				"cannot submit urb %d, error %d: %s\n", +				i, err, usb_error_string(err));  			goto __error;  		}  		set_bit(i, &ep->active_mask); @@ -931,28 +969,34 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep)   *   * @ep: the endpoint to deactivate   * - * If the endpoint is not currently in use, this functions will select the - * alternate interface setting 0 for the interface of this endpoint. + * If the endpoint is not currently in use, this functions will + * deactivate its associated URBs.   *   * In case of any active users, this functions does nothing. - * - * Returns an error if usb_set_interface() failed, 0 in all other - * cases.   */ -int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) +void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep)  {  	if (!ep) -		return -EINVAL; - -	deactivate_urbs(ep, true); -	wait_clear_urbs(ep); +		return;  	if (ep->use_count != 0) -		return 0; +		return; -	clear_bit(EP_FLAG_ACTIVATED, &ep->flags); +	deactivate_urbs(ep, true); +	wait_clear_urbs(ep); +} -	return 0; +/** + * snd_usb_endpoint_release: Tear down an snd_usb_endpoint + * + * @ep: the endpoint to release + * + * This function does not care for the endpoint's use count but will tear + * down all the streaming URBs immediately. + */ +void snd_usb_endpoint_release(struct snd_usb_endpoint *ep) +{ +	release_urbs(ep, 1);  }  /** @@ -960,15 +1004,13 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep)   *   * @ep: the list header of the endpoint to free   * - * This function does not care for the endpoint's use count but will tear - * down all the streaming URBs immediately and free all resources. + * This free all resources of the given ep.   */  void snd_usb_endpoint_free(struct list_head *head)  {  	struct snd_usb_endpoint *ep;  	ep = list_entry(head, struct snd_usb_endpoint, list); -	release_urbs(ep, 1);  	kfree(ep);  } @@ -1078,7 +1120,16 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,  	if (f == 0)  		return; -	if (unlikely(ep->freqshift == INT_MIN)) { +	if (unlikely(sender->udh01_fb_quirk)) { +		/* +		 * The TEAC UD-H01 firmware sometimes changes the feedback value +		 * by +/- 0x1.0000. +		 */ +		if (f < ep->freqn - 0x8000) +			f += 0x10000; +		else if (f > ep->freqn + 0x8000) +			f -= 0x10000; +	} else if (unlikely(ep->freqshift == INT_MIN)) {  		/*  		 * The first time we see a feedback value, determine its format  		 * by shifting it left or right until it matches the nominal diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 2287adf5ca5..e61ee5c356a 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h @@ -12,6 +12,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,  				snd_pcm_format_t pcm_format,  				unsigned int channels,  				unsigned int period_bytes, +				unsigned int period_frames, +				unsigned int buffer_periods,  				unsigned int rate,  				struct audioformat *fmt,  				struct snd_usb_endpoint *sync_ep); @@ -20,7 +22,8 @@ int  snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep);  void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep);  void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);  int  snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); -int  snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); +void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); +void snd_usb_endpoint_release(struct snd_usb_endpoint *ep);  void snd_usb_endpoint_free(struct list_head *head);  int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep); diff --git a/sound/usb/format.c b/sound/usb/format.c index 3525231c6b9..8bcc87cf566 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -74,8 +74,8 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,  	if ((pcm_formats == 0) &&  	    (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED))) {  		/* some devices don't define this correctly... */ -		snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", -			    chip->dev->devnum, fp->iface, fp->altsetting); +		usb_audio_info(chip, "%u:%d : format type 0 is detected, processed as PCM\n", +			fp->iface, fp->altsetting);  		format = 1 << UAC_FORMAT_TYPE_I_PCM;  	}  	if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) { @@ -83,9 +83,9 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,  		    sample_width == 24 && sample_bytes == 2)  			sample_bytes = 3;  		else if (sample_width > sample_bytes * 8) { -			snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n", -				   chip->dev->devnum, fp->iface, fp->altsetting, -				   sample_width, sample_bytes); +			usb_audio_info(chip, "%u:%d : sample bitwidth %d in over sample bytes %d\n", +				 fp->iface, fp->altsetting, +				 sample_width, sample_bytes);  		}  		/* check the format byte size */  		switch (sample_bytes) { @@ -108,9 +108,10 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,  			pcm_formats |= SNDRV_PCM_FMTBIT_S32_LE;  			break;  		default: -			snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n", -				   chip->dev->devnum, fp->iface, fp->altsetting, -				   sample_width, sample_bytes); +			usb_audio_info(chip, +				 "%u:%d : unsupported sample bitwidth %d in %d bytes\n", +				 fp->iface, fp->altsetting, +				 sample_width, sample_bytes);  			break;  		}  	} @@ -132,8 +133,9 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,  		pcm_formats |= SNDRV_PCM_FMTBIT_MU_LAW;  	}  	if (format & ~0x3f) { -		snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n", -			   chip->dev->devnum, fp->iface, fp->altsetting, format); +		usb_audio_info(chip, +			 "%u:%d : unsupported format bits %#x\n", +			 fp->iface, fp->altsetting, format);  	}  	pcm_formats |= snd_usb_interface_dsd_format_quirks(chip, fp, sample_bytes); @@ -158,8 +160,9 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof  	int nr_rates = fmt[offset];  	if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { -		snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", -				   chip->dev->devnum, fp->iface, fp->altsetting); +		usb_audio_err(chip, +			"%u:%d : invalid UAC_FORMAT_TYPE desc\n", +			fp->iface, fp->altsetting);  		return -EINVAL;  	} @@ -171,7 +174,7 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof  		fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);  		if (fp->rate_table == NULL) { -			snd_printk(KERN_ERR "cannot malloc\n"); +			usb_audio_err(chip, "cannot malloc\n");  			return -ENOMEM;  		} @@ -189,8 +192,10 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof  			     chip->usb_id == USB_ID(0x0ccd, 0x00b1)) &&  			    fp->altsetting == 5 && fp->maxpacksize == 392)  				rate = 96000; -			/* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */ -			if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068)) +			/* Creative VF0420/VF0470 Live Cams report 16 kHz instead of 8kHz */ +			if (rate == 16000 && +			    (chip->usb_id == USB_ID(0x041e, 0x4064) || +			     chip->usb_id == USB_ID(0x041e, 0x4068)))  				rate = 8000;  			fp->rate_table[fp->nr_rates] = rate; @@ -220,7 +225,8 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof   * get to know how many sample rates we have to expect.   * Then fp->rate_table can be allocated and filled.   */ -static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, +static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip, +					struct audioformat *fp, int nr_triplets,  					const unsigned char *data)  {  	int i, nr_rates = 0; @@ -259,7 +265,7 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,  			nr_rates++;  			if (nr_rates >= MAX_NR_RATES) { -				snd_printk(KERN_ERR "invalid uac2 rates\n"); +				usb_audio_err(chip, "invalid uac2 rates\n");  				break;  			} @@ -285,7 +291,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,  	int clock = snd_usb_clock_find_source(chip, fp->clock, false);  	if (clock < 0) { -		snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n", +		dev_err(&dev->dev, +			"%s(): unable to find clock source (clock %d)\n",  				__func__, clock);  		goto err;  	} @@ -298,7 +305,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,  			      tmp, sizeof(tmp));  	if (ret < 0) { -		snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n", +		dev_err(&dev->dev, +			"%s(): unable to retrieve number of sample rates (clock %d)\n",  				__func__, clock);  		goto err;  	} @@ -319,7 +327,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,  			      data, data_size);  	if (ret < 0) { -		snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n", +		dev_err(&dev->dev, +			"%s(): unable to retrieve sample rate range (clock %d)\n",  				__func__, clock);  		ret = -EINVAL;  		goto err_free; @@ -330,7 +339,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,  	 * will have to deal with. */  	kfree(fp->rate_table);  	fp->rate_table = NULL; -	fp->nr_rates = parse_uac2_sample_rate_range(fp, nr_triplets, data); +	fp->nr_rates = parse_uac2_sample_rate_range(chip, fp, nr_triplets, data);  	if (fp->nr_rates == 0) {  		/* SNDRV_PCM_RATE_CONTINUOUS */ @@ -346,7 +355,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,  	/* Call the triplet parser again, but this time, fp->rate_table is  	 * allocated, so the rates will be stored */ -	parse_uac2_sample_rate_range(fp, nr_triplets, data); +	parse_uac2_sample_rate_range(chip, fp, nr_triplets, data);  err_free:  	kfree(data); @@ -406,8 +415,9 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,  	}  	if (fp->channels < 1) { -		snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", -			   chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); +		usb_audio_err(chip, +			"%u:%d : invalid channels %d\n", +			fp->iface, fp->altsetting, fp->channels);  		return -EINVAL;  	} @@ -433,8 +443,9 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,  		fp->formats = SNDRV_PCM_FMTBIT_MPEG;  		break;  	default: -		snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected.  processed as MPEG.\n", -			   chip->dev->devnum, fp->iface, fp->altsetting, format); +		usb_audio_info(chip, +			 "%u:%d : unknown format tag %#x is detected.  processed as MPEG.\n", +			 fp->iface, fp->altsetting, format);  		fp->formats = SNDRV_PCM_FMTBIT_MPEG;  		break;  	} @@ -447,7 +458,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,  		struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;  		brate = le16_to_cpu(fmt->wMaxBitRate);  		framesize = le16_to_cpu(fmt->wSamplesPerFrame); -		snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); +		usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);  		fp->frame_size = framesize;  		ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */  		break; @@ -456,7 +467,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,  		struct uac_format_type_ii_ext_descriptor *fmt = _fmt;  		brate = le16_to_cpu(fmt->wMaxBitRate);  		framesize = le16_to_cpu(fmt->wSamplesPerFrame); -		snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); +		usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);  		fp->frame_size = framesize;  		ret = parse_audio_format_rates_v2(chip, fp);  		break; @@ -482,9 +493,10 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip,  		err = parse_audio_format_ii(chip, fp, format, fmt);  		break;  	default: -		snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", -			   chip->dev->devnum, fp->iface, fp->altsetting, -			   fmt->bFormatType); +		usb_audio_info(chip, +			 "%u:%d : format type %d is not supported yet\n", +			 fp->iface, fp->altsetting, +			 fmt->bFormatType);  		return -ENOTSUPP;  	}  	fp->fmt_type = fmt->bFormatType; diff --git a/sound/usb/helper.c b/sound/usb/helper.c index 620902463c6..51ed1ac825f 100644 --- a/sound/usb/helper.c +++ b/sound/usb/helper.c @@ -118,6 +118,7 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,  {  	switch (snd_usb_get_speed(chip->dev)) {  	case USB_SPEED_HIGH: +	case USB_SPEED_WIRELESS:  	case USB_SPEED_SUPER:  		if (get_endpoint(alts, 0)->bInterval >= 1 &&  		    get_endpoint(alts, 0)->bInterval <= 4) diff --git a/sound/usb/hiface/chip.c b/sound/usb/hiface/chip.c index b0dcb3924ce..2670d646bda 100644 --- a/sound/usb/hiface/chip.c +++ b/sound/usb/hiface/chip.c @@ -64,7 +64,8 @@ struct hiface_vendor_quirk {  	u8 extra_freq;  }; -static int hiface_chip_create(struct usb_device *device, int idx, +static int hiface_chip_create(struct usb_interface *intf, +			      struct usb_device *device, int idx,  			      const struct hiface_vendor_quirk *quirk,  			      struct hiface_chip **rchip)  { @@ -76,7 +77,8 @@ static int hiface_chip_create(struct usb_device *device, int idx,  	*rchip = NULL;  	/* if we are here, card can be registered in alsa. */ -	ret = snd_card_create(index[idx], id[idx], THIS_MODULE, sizeof(*chip), &card); +	ret = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE, +			   sizeof(*chip), &card);  	if (ret < 0) {  		dev_err(&device->dev, "cannot create alsa card.\n");  		return ret; @@ -132,12 +134,10 @@ static int hiface_chip_probe(struct usb_interface *intf,  		goto err;  	} -	ret = hiface_chip_create(device, i, quirk, &chip); +	ret = hiface_chip_create(intf, device, i, quirk, &chip);  	if (ret < 0)  		goto err; -	snd_card_set_dev(chip->card, &intf->dev); -  	ret = hiface_pcm_init(chip, quirk ? quirk->extra_freq : 0);  	if (ret < 0)  		goto err_chip_destroy; diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c index c21a3df9a0d..2c44139b404 100644 --- a/sound/usb/hiface/pcm.c +++ b/sound/usb/hiface/pcm.c @@ -110,7 +110,7 @@ static const struct snd_pcm_hardware pcm_hw = {  #define HIFACE_RATE_96000  0x4a  #define HIFACE_RATE_176400 0x40  #define HIFACE_RATE_192000 0x48 -#define HIFACE_RATE_352000 0x58 +#define HIFACE_RATE_352800 0x58  #define HIFACE_RATE_384000 0x68  static int hiface_pcm_set_rate(struct pcm_runtime *rt, unsigned int rate) @@ -141,8 +141,8 @@ static int hiface_pcm_set_rate(struct pcm_runtime *rt, unsigned int rate)  	case 192000:  		rate_value = HIFACE_RATE_192000;  		break; -	case 352000: -		rate_value = HIFACE_RATE_352000; +	case 352800: +		rate_value = HIFACE_RATE_352800;  		break;  	case 384000:  		rate_value = HIFACE_RATE_384000; diff --git a/sound/usb/midi.c b/sound/usb/midi.c index b901f468b67..9da74d2e8ee 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -191,16 +191,16 @@ static int snd_usbmidi_submit_urb(struct urb* urb, gfp_t flags)  {  	int err = usb_submit_urb(urb, flags);  	if (err < 0 && err != -ENODEV) -		snd_printk(KERN_ERR "usb_submit_urb: %d\n", err); +		dev_err(&urb->dev->dev, "usb_submit_urb: %d\n", err);  	return err;  }  /*   * Error handling for URB completion functions.   */ -static int snd_usbmidi_urb_error(int status) +static int snd_usbmidi_urb_error(const struct urb *urb)  { -	switch (status) { +	switch (urb->status) {  	/* manually unlinked, or device gone */  	case -ENOENT:  	case -ECONNRESET: @@ -213,7 +213,7 @@ static int snd_usbmidi_urb_error(int status)  	case -EILSEQ:  		return -EIO;  	default: -		snd_printk(KERN_ERR "urb status %d\n", status); +		dev_err(&urb->dev->dev, "urb status %d\n", urb->status);  		return 0; /* continue */  	}  } @@ -227,7 +227,7 @@ static void snd_usbmidi_input_data(struct snd_usb_midi_in_endpoint* ep, int port  	struct usbmidi_in_port* port = &ep->ports[portidx];  	if (!port->substream) { -		snd_printd("unexpected port %d!\n", portidx); +		dev_dbg(&ep->umidi->dev->dev, "unexpected port %d!\n", portidx);  		return;  	}  	if (!test_bit(port->substream->number, &ep->umidi->input_triggered)) @@ -259,7 +259,7 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb)  		ep->umidi->usb_protocol_ops->input(ep, urb->transfer_buffer,  						   urb->actual_length);  	} else { -		int err = snd_usbmidi_urb_error(urb->status); +		int err = snd_usbmidi_urb_error(urb);  		if (err < 0) {  			if (err != -ENODEV) {  				ep->error_resubmit = 1; @@ -289,7 +289,7 @@ static void snd_usbmidi_out_urb_complete(struct urb* urb)  	}  	spin_unlock(&ep->buffer_lock);  	if (urb->status < 0) { -		int err = snd_usbmidi_urb_error(urb->status); +		int err = snd_usbmidi_urb_error(urb);  		if (err < 0) {  			if (err != -ENODEV)  				mod_timer(&ep->umidi->error_timer, @@ -1668,7 +1668,7 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,  	struct snd_rawmidi_substream *substream = snd_usbmidi_find_substream(umidi, stream, number);  	if (!substream) { -		snd_printd(KERN_ERR "substream %d:%d not found\n", stream, number); +		dev_err(&umidi->dev->dev, "substream %d:%d not found\n", stream, number);  		return;  	} @@ -1717,7 +1717,7 @@ static int snd_usbmidi_create_endpoints(struct snd_usb_midi* umidi,  			}  		}  	} -	snd_printdd(KERN_INFO "created %d output and %d input ports\n", +	dev_dbg(&umidi->dev->dev, "created %d output and %d input ports\n",  		    out_ports, in_ports);  	return 0;  } @@ -1747,10 +1747,11 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,  	    ms_header->bLength >= 7 &&  	    ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&  	    ms_header->bDescriptorSubtype == UAC_HEADER) -		snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n", +		dev_dbg(&umidi->dev->dev, "MIDIStreaming version %02x.%02x\n",  			    ms_header->bcdMSC[1], ms_header->bcdMSC[0]);  	else -		snd_printk(KERN_WARNING "MIDIStreaming interface descriptor not found\n"); +		dev_warn(&umidi->dev->dev, +			 "MIDIStreaming interface descriptor not found\n");  	epidx = 0;  	for (i = 0; i < intfd->bNumEndpoints; ++i) { @@ -1767,7 +1768,8 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,  		if (usb_endpoint_dir_out(ep)) {  			if (endpoints[epidx].out_ep) {  				if (++epidx >= MIDI_MAX_ENDPOINTS) { -					snd_printk(KERN_WARNING "too many endpoints\n"); +					dev_warn(&umidi->dev->dev, +						 "too many endpoints\n");  					break;  				}  			} @@ -1782,12 +1784,13 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,  				 */  				endpoints[epidx].out_interval = 1;  			endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; -			snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", +			dev_dbg(&umidi->dev->dev, "EP %02X: %d jack(s)\n",  				    ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);  		} else {  			if (endpoints[epidx].in_ep) {  				if (++epidx >= MIDI_MAX_ENDPOINTS) { -					snd_printk(KERN_WARNING "too many endpoints\n"); +					dev_warn(&umidi->dev->dev, +						 "too many endpoints\n");  					break;  				}  			} @@ -1797,7 +1800,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,  			else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW)  				endpoints[epidx].in_interval = 1;  			endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; -			snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", +			dev_dbg(&umidi->dev->dev, "EP %02X: %d jack(s)\n",  				    ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);  		}  	} @@ -1865,7 +1868,7 @@ static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi)  	    (get_endpoint(hostif, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)  		return; -	snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n", +	dev_dbg(&umidi->dev->dev, "switching to altsetting %d with int ep\n",  		    intfd->bAlternateSetting);  	usb_set_interface(umidi->dev, intfd->bInterfaceNumber,  			  intfd->bAlternateSetting); @@ -2047,25 +2050,25 @@ static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi,  	 * input bulk endpoints (at indices 1 and 3) which aren't used.  	 */  	if (intfd->bNumEndpoints < (endpoint->out_cables > 0x0001 ? 5 : 3)) { -		snd_printdd(KERN_ERR "not enough endpoints\n"); +		dev_dbg(&umidi->dev->dev, "not enough endpoints\n");  		return -ENOENT;  	}  	epd = get_endpoint(hostif, 0);  	if (!usb_endpoint_dir_in(epd) || !usb_endpoint_xfer_int(epd)) { -		snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n"); +		dev_dbg(&umidi->dev->dev, "endpoint[0] isn't interrupt\n");  		return -ENXIO;  	}  	epd = get_endpoint(hostif, 2);  	if (!usb_endpoint_dir_out(epd) || !usb_endpoint_xfer_bulk(epd)) { -		snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n"); +		dev_dbg(&umidi->dev->dev, "endpoint[2] isn't bulk output\n");  		return -ENXIO;  	}  	if (endpoint->out_cables > 0x0001) {  		epd = get_endpoint(hostif, 4);  		if (!usb_endpoint_dir_out(epd) ||  		    !usb_endpoint_xfer_bulk(epd)) { -			snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n"); +			dev_dbg(&umidi->dev->dev, "endpoint[4] isn't bulk output\n");  			return -ENXIO;  		}  	} @@ -2289,7 +2292,7 @@ int snd_usbmidi_create(struct snd_card *card,  		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);  		break;  	default: -		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); +		dev_err(&umidi->dev->dev, "invalid quirk type %d\n", quirk->type);  		err = -ENXIO;  		break;  	} diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index 509315937f2..a1bab149df4 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c @@ -1243,8 +1243,9 @@ static int ua101_probe(struct usb_interface *interface,  		mutex_unlock(&devices_mutex);  		return -ENOENT;  	} -	err = snd_card_create(index[card_index], id[card_index], THIS_MODULE, -			      sizeof(*ua), &card); +	err = snd_card_new(&interface->dev, +			   index[card_index], id[card_index], THIS_MODULE, +			   sizeof(*ua), &card);  	if (err < 0) {  		mutex_unlock(&devices_mutex);  		return err; @@ -1283,8 +1284,6 @@ static int ua101_probe(struct usb_interface *interface,  		}  	} -	snd_card_set_dev(card, &interface->dev); -  	err = detect_usb_format(ua);  	if (err < 0)  		goto probe_error; diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 95558ef4a7a..0b728d886f0 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -162,7 +162,7 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,  {  	const struct usbmix_selector_map *p; -	if (! state->selector_map) +	if (!state->selector_map)  		return 0;  	for (p = state->selector_map; p->id; p++) {  		if (p->id == unitid && index < p->count) @@ -174,7 +174,8 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,  /*   * find an audio control unit with the given unit id   */ -static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit) +static void *find_audio_control_unit(struct mixer_build *state, +				     unsigned char unit)  {  	/* we just parse the header */  	struct uac_feature_unit_descriptor *hdr = NULL; @@ -194,7 +195,8 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un  /*   * copy a string with the given id   */ -static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen) +static int snd_usb_copy_string_desc(struct mixer_build *state, +				    int index, char *buf, int maxlen)  {  	int len = usb_string(state->chip->dev, index, buf, maxlen - 1);  	buf[len] = 0; @@ -253,7 +255,7 @@ static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)  static int get_relative_value(struct usb_mixer_elem_info *cval, int val)  { -	if (! cval->res) +	if (!cval->res)  		cval->res = 1;  	if (val < cval->min)  		return 0; @@ -267,7 +269,7 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)  {  	if (val < 0)  		return cval->min; -	if (! cval->res) +	if (!cval->res)  		cval->res = 1;  	val *= cval->res;  	val += cval->min; @@ -281,7 +283,8 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)   * retrieve a mixer value   */ -static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) +static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, +			    int validx, int *value_ret)  {  	struct snd_usb_audio *chip = cval->mixer->chip;  	unsigned char buf[2]; @@ -292,6 +295,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v  	err = snd_usb_autoresume(cval->mixer->chip);  	if (err < 0)  		return -EIO; +  	down_read(&chip->shutdown_rwsem);  	while (timeout-- > 0) {  		if (chip->shutdown) @@ -305,8 +309,9 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v  			goto out;  		}  	} -	snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", -		    request, validx, idx, cval->val_type); +	usb_audio_dbg(chip, +		"cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", +		request, validx, idx, cval->val_type);  	err = -EINVAL;   out: @@ -315,10 +320,11 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v  	return err;  } -static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) +static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, +			    int validx, int *value_ret)  {  	struct snd_usb_audio *chip = cval->mixer->chip; -	unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ +	unsigned char buf[2 + 3 * sizeof(__u16)]; /* enough space for one range */  	unsigned char *val;  	int idx = 0, ret, size;  	__u8 bRequest; @@ -338,9 +344,9 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v  		goto error;  	down_read(&chip->shutdown_rwsem); -	if (chip->shutdown) +	if (chip->shutdown) {  		ret = -ENODEV; -	else { +	} else {  		idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);  		ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,  			      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, @@ -351,8 +357,9 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v  	if (ret < 0) {  error: -		snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", -			   request, validx, idx, cval->val_type); +		usb_audio_err(chip, +			"cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", +			request, validx, idx, cval->val_type);  		return ret;  	} @@ -380,7 +387,8 @@ error:  	return 0;  } -static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) +static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, +			 int validx, int *value_ret)  {  	validx += cval->idx_off; @@ -389,7 +397,8 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali  		get_ctl_value_v2(cval, request, validx, value_ret);  } -static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value) +static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, +			     int validx, int *value)  {  	return get_ctl_value(cval, UAC_GET_CUR, validx, value);  } @@ -398,7 +407,9 @@ static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *  static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,  				  int channel, int *value)  { -	return get_ctl_value(cval, UAC_GET_CUR, (cval->control << 8) | channel, value); +	return get_ctl_value(cval, UAC_GET_CUR, +			     (cval->control << 8) | channel, +			     value);  }  static int get_cur_mix_value(struct usb_mixer_elem_info *cval, @@ -413,8 +424,9 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,  	err = get_cur_mix_raw(cval, channel, value);  	if (err < 0) {  		if (!cval->mixer->ignore_ctl_error) -			snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n", -				   cval->control, channel, err); +			usb_audio_dbg(cval->mixer->chip, +				"cannot get current value for control %d ch %d: err = %d\n", +				      cval->control, channel, err);  		return err;  	}  	cval->cached |= 1 << channel; @@ -422,7 +434,6 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,  	return 0;  } -  /*   * set a mixer value   */ @@ -444,7 +455,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,  		/* FIXME */  		if (request != UAC_SET_CUR) { -			snd_printdd(KERN_WARNING "RANGE setting not yet supported\n"); +			usb_audio_dbg(chip, "RANGE setting not yet supported\n");  			return -EINVAL;  		} @@ -470,8 +481,8 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,  			goto out;  		}  	} -	snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", -		    request, validx, idx, cval->val_type, buf[0], buf[1]); +	usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", +		      request, validx, idx, cval->val_type, buf[0], buf[1]);  	err = -EINVAL;   out: @@ -480,7 +491,8 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,  	return err;  } -static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) +static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, +			     int validx, int value)  {  	return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);  } @@ -494,13 +506,15 @@ static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,  		cval->ch_readonly & (1 << (channel - 1));  	if (read_only) { -		snd_printdd(KERN_INFO "%s(): channel %d of control %d is read_only\n", +		usb_audio_dbg(cval->mixer->chip, +			      "%s(): channel %d of control %d is read_only\n",  			    __func__, channel, cval->control);  		return 0;  	} -	err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel, -			    value); +	err = snd_usb_mixer_set_ctl_value(cval, +					  UAC_SET_CUR, (cval->control << 8) | channel, +					  value);  	if (err < 0)  		return err;  	cval->cached |= 1 << channel; @@ -537,13 +551,13 @@ static int parse_audio_unit(struct mixer_build *state, int unitid);   * check if the input/output channel routing is enabled on the given bitmap.   * used for mixer unit parser   */ -static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs) +static int check_matrix_bitmap(unsigned char *bmap, +			       int ich, int och, int num_outs)  {  	int idx = ich * num_outs + och;  	return bmap[idx >> 3] & (0x80 >> (idx & 7));  } -  /*   * add an alsa control element   * search and increment the index until an empty slot is found. @@ -560,7 +574,8 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,  	while (snd_ctl_find_id(mixer->chip->card, &kctl->id))  		kctl->id.index++;  	if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) { -		snd_printd(KERN_ERR "cannot add control (err = %d)\n", err); +		usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n", +			      err);  		return err;  	}  	cval->elem_id = &kctl->id; @@ -569,7 +584,6 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,  	return 0;  } -  /*   * get a terminal name string   */ @@ -623,7 +637,8 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm  	struct iterm_name_combo *names;  	if (iterm->name) -		return snd_usb_copy_string_desc(state, iterm->name, name, maxlen); +		return snd_usb_copy_string_desc(state, iterm->name, +						name, maxlen);  	/* virtual type - not a real terminal */  	if (iterm->type >> 16) { @@ -631,13 +646,17 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm  			return 0;  		switch (iterm->type >> 16) {  		case UAC_SELECTOR_UNIT: -			strcpy(name, "Selector"); return 8; +			strcpy(name, "Selector"); +			return 8;  		case UAC1_PROCESSING_UNIT: -			strcpy(name, "Process Unit"); return 12; +			strcpy(name, "Process Unit"); +			return 12;  		case UAC1_EXTENSION_UNIT: -			strcpy(name, "Ext Unit"); return 8; +			strcpy(name, "Ext Unit"); +			return 8;  		case UAC_MIXER_UNIT: -			strcpy(name, "Mixer"); return 5; +			strcpy(name, "Mixer"); +			return 5;  		default:  			return sprintf(name, "Unit %d", iterm->id);  		} @@ -645,29 +664,35 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm  	switch (iterm->type & 0xff00) {  	case 0x0100: -		strcpy(name, "PCM"); return 3; +		strcpy(name, "PCM"); +		return 3;  	case 0x0200: -		strcpy(name, "Mic"); return 3; +		strcpy(name, "Mic"); +		return 3;  	case 0x0400: -		strcpy(name, "Headset"); return 7; +		strcpy(name, "Headset"); +		return 7;  	case 0x0500: -		strcpy(name, "Phone"); return 5; +		strcpy(name, "Phone"); +		return 5;  	} -	for (names = iterm_names; names->type; names++) +	for (names = iterm_names; names->type; names++) {  		if (names->type == iterm->type) {  			strcpy(name, names->name);  			return strlen(names->name);  		} +	} +  	return 0;  } -  /*   * parse the source unit recursively until it reaches to a terminal   * or a branched unit.   */ -static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term) +static int check_input_term(struct mixer_build *state, int id, +			    struct usb_audio_term *term)  {  	int err;  	void *p1; @@ -762,7 +787,6 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_  	return -ENODEV;  } -  /*   * Feature Unit   */ @@ -790,7 +814,6 @@ static struct usb_feature_control_info audio_feature_info[] = {  	{ "Phase Inverter Control",	USB_MIXER_BOOLEAN },  }; -  /* private_free callback */  static void usb_mixer_elem_free(struct snd_kcontrol *kctl)  { @@ -798,7 +821,6 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)  	kctl->private_data = NULL;  } -  /*   * interface to ALSA control for feature/mixer units   */ @@ -807,7 +829,8 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)  static void volume_control_quirks(struct usb_mixer_elem_info *cval,  				  struct snd_kcontrol *kctl)  { -	switch (cval->mixer->chip->usb_id) { +	struct snd_usb_audio *chip = cval->mixer->chip; +	switch (chip->usb_id) {  	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */  	case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */  		if (strcmp(kctl->id.name, "Effect Duration") == 0) { @@ -839,8 +862,8 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,  	case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */  	case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */  		if (strcmp(kctl->id.name, "Effect Duration") == 0) { -			snd_printk(KERN_INFO -				"usb-audio: set quirk for FTU Effect Duration\n"); +			usb_audio_info(chip, +				       "set quirk for FTU Effect Duration\n");  			cval->min = 0x0000;  			cval->max = 0x7f00;  			cval->res = 0x0100; @@ -848,8 +871,8 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,  		}  		if (strcmp(kctl->id.name, "Effect Volume") == 0 ||  		    strcmp(kctl->id.name, "Effect Feedback Volume") == 0) { -			snd_printk(KERN_INFO -				"usb-audio: set quirks for FTU Effect Feedback/Volume\n"); +			usb_audio_info(chip, +				       "set quirks for FTU Effect Feedback/Volume\n");  			cval->min = 0x00;  			cval->max = 0x7f;  			break; @@ -867,7 +890,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,  	 */  		if (!strcmp(kctl->id.name, "PCM Playback Volume") &&  		    cval->min == -15616) { -			snd_printk(KERN_INFO +			usb_audio_info(chip,  				 "set volume quirk for UDA1321/N101 chip\n");  			cval->max = -256;  		} @@ -875,7 +898,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,  	case USB_ID(0x046d, 0x09a4):  		if (!strcmp(kctl->id.name, "Mic Capture Volume")) { -			snd_printk(KERN_INFO +			usb_audio_info(chip,  				"set volume quirk for QuickCam E3500\n");  			cval->min = 6080;  			cval->max = 8768; @@ -883,6 +906,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,  		}  		break; +	case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */  	case USB_ID(0x046d, 0x0808):  	case USB_ID(0x046d, 0x0809):  	case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ @@ -895,12 +919,11 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,  	 * Proboly there is some logitech magic behind this number --fishor  	 */  		if (!strcmp(kctl->id.name, "Mic Capture Volume")) { -			snd_printk(KERN_INFO +			usb_audio_info(chip,  				"set resolution quirk: cval->res = 384\n");  			cval->res = 384;  		}  		break; -  	}  } @@ -931,22 +954,28 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,  		}  		if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||  		    get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { -			snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", -				   cval->id, snd_usb_ctrl_intf(cval->mixer->chip), cval->control, cval->id); +			usb_audio_err(cval->mixer->chip, +				      "%d:%d: cannot get min/max values for control %d (id %d)\n", +				   cval->id, snd_usb_ctrl_intf(cval->mixer->chip), +							       cval->control, cval->id);  			return -EINVAL;  		} -		if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) { +		if (get_ctl_value(cval, UAC_GET_RES, +				  (cval->control << 8) | minchn, +				  &cval->res) < 0) {  			cval->res = 1;  		} else {  			int last_valid_res = cval->res;  			while (cval->res > 1) {  				if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES, -								(cval->control << 8) | minchn, cval->res / 2) < 0) +								(cval->control << 8) | minchn, +								cval->res / 2) < 0)  					break;  				cval->res /= 2;  			} -			if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) +			if (get_ctl_value(cval, UAC_GET_RES, +					  (cval->control << 8) | minchn, &cval->res) < 0)  				cval->res = last_valid_res;  		}  		if (cval->res == 0) @@ -1010,7 +1039,8 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,  #define get_min_max(cval, def)	get_min_max_with_quirks(cval, def, NULL)  /* get a feature/mixer unit info */ -static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_info *uinfo)  {  	struct usb_mixer_elem_info *cval = kcontrol->private_data; @@ -1044,7 +1074,8 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_  }  /* get the current value from feature/mixer unit */ -static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, +				 struct snd_ctl_elem_value *ucontrol)  {  	struct usb_mixer_elem_info *cval = kcontrol->private_data;  	int c, cnt, val, err; @@ -1075,7 +1106,8 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e  }  /* put the current value to feature/mixer unit */ -static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, +				 struct snd_ctl_elem_value *ucontrol)  {  	struct usb_mixer_elem_info *cval = kcontrol->private_data;  	int c, cnt, val, oval, err; @@ -1129,36 +1161,39 @@ static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {  	.put = NULL,  }; -/* This symbol is exported in order to allow the mixer quirks to - * hook up to the standard feature unit control mechanism */ +/* + * This symbol is exported in order to allow the mixer quirks to + * hook up to the standard feature unit control mechanism + */  struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl;  /*   * build a feature control   */ -  static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)  {  	return strlcat(kctl->id.name, str, sizeof(kctl->id.name));  } -/* A lot of headsets/headphones have a "Speaker" mixer. Make sure we -   rename it to "Headphone". We determine if something is a headphone -   similar to how udev determines form factor. */ +/* + * A lot of headsets/headphones have a "Speaker" mixer. Make sure we + * rename it to "Headphone". We determine if something is a headphone + * similar to how udev determines form factor. + */  static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,  					struct snd_card *card)  {  	const char *names_to_check[] = {  		"Headset", "headset", "Headphone", "headphone", NULL};  	const char **s; -	bool found = 0; +	bool found = false;  	if (strcmp("Speaker", kctl->id.name))  		return;  	for (s = names_to_check; *s; s++)  		if (strstr(card->shortname, *s)) { -			found = 1; +			found = true;  			break;  		} @@ -1194,10 +1229,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,  		return;  	cval = kzalloc(sizeof(*cval), GFP_KERNEL); -	if (! cval) { -		snd_printk(KERN_ERR "cannot malloc kcontrol\n"); +	if (!cval)  		return; -	}  	cval->mixer = state->mixer;  	cval->id = unitid;  	cval->control = control; @@ -1215,16 +1248,18 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,  		cval->ch_readonly = readonly_mask;  	} -	/* if all channels in the mask are marked read-only, make the control +	/* +	 * If all channels in the mask are marked read-only, make the control  	 * read-only. set_cur_mix_value() will check the mask again and won't -	 * issue write commands to read-only channels. */ +	 * issue write commands to read-only channels. +	 */  	if (cval->channels == readonly_mask)  		kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);  	else  		kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); -	if (! kctl) { -		snd_printk(KERN_ERR "cannot malloc kcontrol\n"); +	if (!kctl) { +		usb_audio_err(state->chip, "cannot malloc kcontrol\n");  		kfree(cval);  		return;  	} @@ -1232,48 +1267,53 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,  	len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));  	mapped_name = len != 0; -	if (! len && nameid) +	if (!len && nameid)  		len = snd_usb_copy_string_desc(state, nameid,  				kctl->id.name, sizeof(kctl->id.name));  	switch (control) {  	case UAC_FU_MUTE:  	case UAC_FU_VOLUME: -		/* determine the control name.  the rule is: +		/* +		 * determine the control name.  the rule is:  		 * - if a name id is given in descriptor, use it.  		 * - if the connected input can be determined, then use the name  		 *   of terminal type.  		 * - if the connected output can be determined, use it.  		 * - otherwise, anonymous name.  		 */ -		if (! len) { -			len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 1); -			if (! len) -				len = get_term_name(state, &state->oterm, kctl->id.name, sizeof(kctl->id.name), 1); -			if (! len) -				len = snprintf(kctl->id.name, sizeof(kctl->id.name), +		if (!len) { +			len = get_term_name(state, iterm, kctl->id.name, +					    sizeof(kctl->id.name), 1); +			if (!len) +				len = get_term_name(state, &state->oterm, +						    kctl->id.name, +						    sizeof(kctl->id.name), 1); +			if (!len) +				len = snprintf(kctl->id.name, +					       sizeof(kctl->id.name),  					       "Feature %d", unitid);  		}  		if (!mapped_name)  			check_no_speaker_on_headset(kctl, state->mixer->chip->card); -		/* determine the stream direction: +		/* +		 * determine the stream direction:  		 * if the connected output is USB stream, then it's likely a  		 * capture stream.  otherwise it should be playback (hopefully :)  		 */ -		if (! mapped_name && ! (state->oterm.type >> 16)) { -			if ((state->oterm.type & 0xff00) == 0x0100) { +		if (!mapped_name && !(state->oterm.type >> 16)) { +			if ((state->oterm.type & 0xff00) == 0x0100)  				len = append_ctl_name(kctl, " Capture"); -			} else { +			else  				len = append_ctl_name(kctl, " Playback"); -			}  		}  		append_ctl_name(kctl, control == UAC_FU_MUTE ?  				" Switch" : " Volume");  		break;  	default: -		if (! len) +		if (!len)  			strlcpy(kctl->id.name, audio_feature_info[control-1].name,  				sizeof(kctl->id.name));  		break; @@ -1293,33 +1333,35 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,  	}  	range = (cval->max - cval->min) / cval->res; -	/* Are there devices with volume range more than 255? I use a bit more +	/* +	 * Are there devices with volume range more than 255? I use a bit more  	 * to be sure. 384 is a resolution magic number found on Logitech  	 * devices. It will definitively catch all buggy Logitech devices.  	 */  	if (range > 384) { -		snd_printk(KERN_WARNING "usb_audio: Warning! Unlikely big " -			   "volume range (=%u), cval->res is probably wrong.", -			   range); -		snd_printk(KERN_WARNING "usb_audio: [%d] FU [%s] ch = %d, " -			   "val = %d/%d/%d", cval->id, -			   kctl->id.name, cval->channels, -			   cval->min, cval->max, cval->res); -	} - -	snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", -		    cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res); +		usb_audio_warn(state->chip, +			       "Warning! Unlikely big volume range (=%u), " +			       "cval->res is probably wrong.", +			       range); +		usb_audio_warn(state->chip, "[%d] FU [%s] ch = %d, " +			       "val = %d/%d/%d", cval->id, +			       kctl->id.name, cval->channels, +			       cval->min, cval->max, cval->res); +	} + +	usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", +		      cval->id, kctl->id.name, cval->channels, +		      cval->min, cval->max, cval->res);  	snd_usb_mixer_add_control(state->mixer, kctl);  } - -  /*   * parse a feature unit   *   * most of controls are defined here.   */ -static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr) +static int parse_audio_feature_unit(struct mixer_build *state, int unitid, +				    void *_ftr)  {  	int channels, i, j;  	struct usb_audio_term iterm; @@ -1331,16 +1373,17 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void  	if (state->mixer->protocol == UAC_VERSION_1) {  		csize = hdr->bControlSize;  		if (!csize) { -			snd_printdd(KERN_ERR "usbaudio: unit %u: " -				    "invalid bControlSize == 0\n", unitid); +			usb_audio_dbg(state->chip, +				      "unit %u: invalid bControlSize == 0\n", +				      unitid);  			return -EINVAL;  		}  		channels = (hdr->bLength - 7) / csize - 1;  		bmaControls = hdr->bmaControls;  		if (hdr->bLength < 7 + csize) { -			snd_printk(KERN_ERR "usbaudio: unit %u: " -				   "invalid UAC_FEATURE_UNIT descriptor\n", -				   unitid); +			usb_audio_err(state->chip, +				      "unit %u: invalid UAC_FEATURE_UNIT descriptor\n", +				      unitid);  			return -EINVAL;  		}  	} else { @@ -1349,9 +1392,9 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void  		channels = (hdr->bLength - 6) / 4 - 1;  		bmaControls = ftr->bmaControls;  		if (hdr->bLength < 6 + csize) { -			snd_printk(KERN_ERR "usbaudio: unit %u: " -				   "invalid UAC_FEATURE_UNIT descriptor\n", -				   unitid); +			usb_audio_err(state->chip, +				      "unit %u: invalid UAC_FEATURE_UNIT descriptor\n", +				      unitid);  			return -EINVAL;  		}  	} @@ -1369,14 +1412,14 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void  	/* master configuration quirks */  	switch (state->chip->usb_id) {  	case USB_ID(0x08bb, 0x2702): -		snd_printk(KERN_INFO -			   "usbmixer: master volume quirk for PCM2702 chip\n"); +		usb_audio_info(state->chip, +			       "usbmixer: master volume quirk for PCM2702 chip\n");  		/* disable non-functional volume control */  		master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME);  		break;  	case USB_ID(0x1130, 0xf211): -		snd_printk(KERN_INFO -			   "usbmixer: volume control quirk for Tenx TP6911 Audio Headset\n"); +		usb_audio_info(state->chip, +			       "usbmixer: volume control quirk for Tenx TP6911 Audio Headset\n");  		/* disable non-functional volume control */  		channels = 0;  		break; @@ -1392,15 +1435,25 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void  		for (i = 0; i < 10; i++) {  			unsigned int ch_bits = 0;  			for (j = 0; j < channels; j++) { -				unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize); +				unsigned int mask; + +				mask = snd_usb_combine_bytes(bmaControls + +							     csize * (j+1), csize);  				if (mask & (1 << i))  					ch_bits |= (1 << j);  			}  			/* audio class v1 controls are never read-only */ -			if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ -				build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0); + +			/* +			 * The first channel must be set +			 * (for ease of programming). +			 */ +			if (ch_bits & 1) +				build_feature_ctl(state, _ftr, ch_bits, i, +						  &iterm, unitid, 0);  			if (master_bits & (1 << i)) -				build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0); +				build_feature_ctl(state, _ftr, 0, i, &iterm, +						  unitid, 0);  		}  	} else { /* UAC_VERSION_2 */  		for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { @@ -1408,7 +1461,10 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void  			unsigned int ch_read_only = 0;  			for (j = 0; j < channels; j++) { -				unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize); +				unsigned int mask; + +				mask = snd_usb_combine_bytes(bmaControls + +							     csize * (j+1), csize);  				if (uac2_control_is_readable(mask, i)) {  					ch_bits |= (1 << j);  					if (!uac2_control_is_writeable(mask, i)) @@ -1416,12 +1472,22 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void  				}  			} -			/* NOTE: build_feature_ctl() will mark the control read-only if all channels -			 * are marked read-only in the descriptors. Otherwise, the control will be -			 * reported as writeable, but the driver will not actually issue a write -			 * command for read-only channels */ -			if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ -				build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only); +			/* +			 * NOTE: build_feature_ctl() will mark the control +			 * read-only if all channels are marked read-only in +			 * the descriptors. Otherwise, the control will be +			 * reported as writeable, but the driver will not +			 * actually issue a write command for read-only +			 * channels. +			 */ + +			/* +			 * The first channel must be set +			 * (for ease of programming). +			 */ +			if (ch_bits & 1) +				build_feature_ctl(state, _ftr, ch_bits, i, +						  &iterm, unitid, ch_read_only);  			if (uac2_control_is_readable(master_bits, i))  				build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,  						  !uac2_control_is_writeable(master_bits, i)); @@ -1431,7 +1497,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void  	return 0;  } -  /*   * Mixer Unit   */ @@ -1442,7 +1507,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void   * the callbacks are identical with feature unit.   * input channel number (zero based) is given in control field instead.   */ -  static void build_mixer_unit_ctl(struct mixer_build *state,  				 struct uac_mixer_unit_descriptor *desc,  				 int in_pin, int in_ch, int unitid, @@ -1459,7 +1523,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state,  		return;  	cval = kzalloc(sizeof(*cval), GFP_KERNEL); -	if (! cval) +	if (!cval)  		return;  	cval->mixer = state->mixer; @@ -1467,7 +1531,9 @@ static void build_mixer_unit_ctl(struct mixer_build *state,  	cval->control = in_ch + 1; /* based on 1 */  	cval->val_type = USB_MIXER_S16;  	for (i = 0; i < num_outs; i++) { -		if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) { +		__u8 *c = uac_mixer_unit_bmControls(desc, state->mixer->protocol); + +		if (check_matrix_bitmap(c, in_ch, i, num_outs)) {  			cval->cmask |= (1 << i);  			cval->channels++;  		} @@ -1477,43 +1543,48 @@ static void build_mixer_unit_ctl(struct mixer_build *state,  	get_min_max(cval, 0);  	kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); -	if (! kctl) { -		snd_printk(KERN_ERR "cannot malloc kcontrol\n"); +	if (!kctl) { +		usb_audio_err(state->chip, "cannot malloc kcontrol\n");  		kfree(cval);  		return;  	}  	kctl->private_free = usb_mixer_elem_free;  	len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); -	if (! len) -		len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0); -	if (! len) +	if (!len) +		len = get_term_name(state, iterm, kctl->id.name, +				    sizeof(kctl->id.name), 0); +	if (!len)  		len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);  	append_ctl_name(kctl, " Volume"); -	snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n", +	usb_audio_dbg(state->chip, "[%d] MU [%s] ch = %d, val = %d/%d\n",  		    cval->id, kctl->id.name, cval->channels, cval->min, cval->max);  	snd_usb_mixer_add_control(state->mixer, kctl);  } -  /*   * parse a mixer unit   */ -static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc) +static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, +				  void *raw_desc)  {  	struct uac_mixer_unit_descriptor *desc = raw_desc;  	struct usb_audio_term iterm;  	int input_pins, num_ins, num_outs;  	int pin, ich, err; -	if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) { -		snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid); +	if (desc->bLength < 11 || !(input_pins = desc->bNrInPins) || +	    !(num_outs = uac_mixer_unit_bNrChannels(desc))) { +		usb_audio_err(state->chip, +			      "invalid MIXER UNIT descriptor %d\n", +			      unitid);  		return -EINVAL;  	}  	/* no bmControls field (e.g. Maya44) -> ignore */  	if (desc->bLength <= 10 + input_pins) { -		snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid); +		usb_audio_dbg(state->chip, "MU %d has no bmControls field\n", +			      unitid);  		return 0;  	} @@ -1527,12 +1598,14 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *r  		if (err < 0)  			return err;  		num_ins += iterm.channels; -		for (; ich < num_ins; ++ich) { +		for (; ich < num_ins; ich++) {  			int och, ich_has_controls = 0; -			for (och = 0; och < num_outs; ++och) { -				if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), -							ich, och, num_outs)) { +			for (och = 0; och < num_outs; och++) { +				__u8 *c = uac_mixer_unit_bmControls(desc, +						state->mixer->protocol); + +				if (check_matrix_bitmap(c, ich, och, num_outs)) {  					ich_has_controls = 1;  					break;  				} @@ -1545,13 +1618,13 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *r  	return 0;  } -  /*   * Processing Unit / Extension Unit   */  /* get callback for processing/extension unit */ -static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol)  {  	struct usb_mixer_elem_info *cval = kcontrol->private_data;  	int err, val; @@ -1569,7 +1642,8 @@ static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_  }  /* put callback for processing/extension unit */ -static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol)  {  	struct usb_mixer_elem_info *cval = kcontrol->private_data;  	int val, oval, err; @@ -1598,7 +1672,6 @@ static struct snd_kcontrol_new mixer_procunit_ctl = {  	.put = mixer_ctl_procunit_put,  }; -  /*   * predefined data for processing units   */ @@ -1689,10 +1762,13 @@ static struct procunit_info extunits[] = {  	{ USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },  	{ 0 }  }; +  /*   * build a processing/extension unit   */ -static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name) +static int build_audio_procunit(struct mixer_build *state, int unitid, +				void *raw_desc, struct procunit_info *list, +				char *name)  {  	struct uac_processing_unit_descriptor *desc = raw_desc;  	int num_ins = desc->bNrInPins; @@ -1712,7 +1788,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw  	if (desc->bLength < 13 || desc->bLength < 13 + num_ins ||  	    desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) { -		snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid); +		usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid);  		return -EINVAL;  	} @@ -1725,22 +1801,20 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw  	for (info = list; info && info->type; info++)  		if (info->type == type)  			break; -	if (! info || ! info->type) +	if (!info || !info->type)  		info = &default_info;  	for (valinfo = info->values; valinfo->control; valinfo++) {  		__u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol); -		if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1)))) +		if (!(controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))  			continue;  		map = find_map(state, unitid, valinfo->control);  		if (check_ignored_ctl(map))  			continue;  		cval = kzalloc(sizeof(*cval), GFP_KERNEL); -		if (! cval) { -			snd_printk(KERN_ERR "cannot malloc kcontrol\n"); +		if (!cval)  			return -ENOMEM; -		}  		cval->mixer = state->mixer;  		cval->id = unitid;  		cval->control = valinfo->control; @@ -1757,7 +1831,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw  			cval->initialized = 1;  		} else {  			if (type == USB_XU_CLOCK_RATE) { -				/* E-Mu USB 0404/0202/TrackerPre/0204 +				/* +				 * E-Mu USB 0404/0202/TrackerPre/0204  				 * samplerate control quirk  				 */  				cval->min = 0; @@ -1769,59 +1844,69 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw  		}  		kctl = snd_ctl_new1(&mixer_procunit_ctl, cval); -		if (! kctl) { -			snd_printk(KERN_ERR "cannot malloc kcontrol\n"); +		if (!kctl) {  			kfree(cval);  			return -ENOMEM;  		}  		kctl->private_free = usb_mixer_elem_free; -		if (check_mapped_name(map, kctl->id.name, -						sizeof(kctl->id.name))) +		if (check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name))) {  			/* nothing */ ; -		else if (info->name) +		} else if (info->name) {  			strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); -		else { +		} else {  			nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);  			len = 0;  			if (nameid) -				len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); -			if (! len) +				len = snd_usb_copy_string_desc(state, nameid, +							       kctl->id.name, +							       sizeof(kctl->id.name)); +			if (!len)  				strlcpy(kctl->id.name, name, sizeof(kctl->id.name));  		}  		append_ctl_name(kctl, " ");  		append_ctl_name(kctl, valinfo->suffix); -		snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n", -			    cval->id, kctl->id.name, cval->channels, cval->min, cval->max); -		if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0) +		usb_audio_dbg(state->chip, +			      "[%d] PU [%s] ch = %d, val = %d/%d\n", +			      cval->id, kctl->id.name, cval->channels, +			      cval->min, cval->max); + +		err = snd_usb_mixer_add_control(state->mixer, kctl); +		if (err < 0)  			return err;  	}  	return 0;  } - -static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc) +static int parse_audio_processing_unit(struct mixer_build *state, int unitid, +				       void *raw_desc)  { -	return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit"); +	return build_audio_procunit(state, unitid, raw_desc, +				    procunits, "Processing Unit");  } -static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc) +static int parse_audio_extension_unit(struct mixer_build *state, int unitid, +				      void *raw_desc)  { -	/* Note that we parse extension units with processing unit descriptors. -	 * That's ok as the layout is the same */ -	return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit"); +	/* +	 * Note that we parse extension units with processing unit descriptors. +	 * That's ok as the layout is the same. +	 */ +	return build_audio_procunit(state, unitid, raw_desc, +				    extunits, "Extension Unit");  } -  /*   * Selector Unit   */ -/* info callback for selector unit +/* + * info callback for selector unit   * use an enumerator type for routing   */ -static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, +				   struct snd_ctl_elem_info *uinfo)  {  	struct usb_mixer_elem_info *cval = kcontrol->private_data;  	const char **itemlist = (const char **)kcontrol->private_value; @@ -1832,7 +1917,8 @@ static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl  }  /* get callback for selector unit */ -static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol)  {  	struct usb_mixer_elem_info *cval = kcontrol->private_data;  	int val, err; @@ -1851,7 +1937,8 @@ static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_  }  /* put callback for selector unit */ -static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_value *ucontrol)  {  	struct usb_mixer_elem_info *cval = kcontrol->private_data;  	int val, oval, err; @@ -1880,8 +1967,8 @@ static struct snd_kcontrol_new mixer_selectunit_ctl = {  	.put = mixer_ctl_selector_put,  }; - -/* private free callback. +/* + * private free callback.   * free both private_data and private_value   */  static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl) @@ -1906,7 +1993,8 @@ static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)  /*   * parse a selector unit   */ -static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc) +static int parse_audio_selector_unit(struct mixer_build *state, int unitid, +				     void *raw_desc)  {  	struct uac_selector_unit_descriptor *desc = raw_desc;  	unsigned int i, nameid, len; @@ -1917,7 +2005,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void  	char **namelist;  	if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) { -		snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid); +		usb_audio_err(state->chip, +			"invalid SELECTOR UNIT descriptor %d\n", unitid);  		return -EINVAL;  	} @@ -1934,10 +2023,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void  		return 0;  	cval = kzalloc(sizeof(*cval), GFP_KERNEL); -	if (! cval) { -		snd_printk(KERN_ERR "cannot malloc kcontrol\n"); +	if (!cval)  		return -ENOMEM; -	}  	cval->mixer = state->mixer;  	cval->id = unitid;  	cval->val_type = USB_MIXER_U8; @@ -1953,8 +2040,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void  		cval->control = 0;  	namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL); -	if (! namelist) { -		snd_printk(KERN_ERR "cannot malloc\n"); +	if (!namelist) {  		kfree(cval);  		return -ENOMEM;  	} @@ -1963,8 +2049,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void  		struct usb_audio_term iterm;  		len = 0;  		namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL); -		if (! namelist[i]) { -			snd_printk(KERN_ERR "cannot malloc\n"); +		if (!namelist[i]) {  			while (i--)  				kfree(namelist[i]);  			kfree(namelist); @@ -1976,12 +2061,12 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void  		if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)  			len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);  		if (! len) -			sprintf(namelist[i], "Input %d", i); +			sprintf(namelist[i], "Input %u", i);  	}  	kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);  	if (! kctl) { -		snd_printk(KERN_ERR "cannot malloc kcontrol\n"); +		usb_audio_err(state->chip, "cannot malloc kcontrol\n");  		kfree(namelist);  		kfree(cval);  		return -ENOMEM; @@ -1994,11 +2079,12 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void  	if (len)  		;  	else if (nameid) -		snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); +		snd_usb_copy_string_desc(state, nameid, kctl->id.name, +					 sizeof(kctl->id.name));  	else {  		len = get_term_name(state, &state->oterm,  				    kctl->id.name, sizeof(kctl->id.name), 0); -		if (! len) +		if (!len)  			strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));  		if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) @@ -2009,7 +2095,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void  			append_ctl_name(kctl, " Playback Source");  	} -	snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", +	usb_audio_dbg(state->chip, "[%d] SU [%s] items = %d\n",  		    cval->id, kctl->id.name, desc->bNrInPins);  	if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0)  		return err; @@ -2017,7 +2103,6 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void  	return 0;  } -  /*   * parse an audio unit recursively   */ @@ -2031,7 +2116,7 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)  	p1 = find_audio_control_unit(state, unitid);  	if (!p1) { -		snd_printk(KERN_ERR "usbaudio: unit %d not found!\n", unitid); +		usb_audio_err(state->chip, "unit %d not found!\n", unitid);  		return -EINVAL;  	} @@ -2061,7 +2146,8 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)  	case UAC2_EXTENSION_UNIT_V2:  		return parse_audio_extension_unit(state, unitid, p1);  	default: -		snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); +		usb_audio_err(state->chip, +			"unit %u: unexpected type 0x%02x\n", unitid, p1[2]);  		return -EINVAL;  	}  } @@ -2114,14 +2200,16 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)  	}  	p = NULL; -	while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen, +	while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, +					    mixer->hostif->extralen,  					    p, UAC_OUTPUT_TERMINAL)) != NULL) {  		if (mixer->protocol == UAC_VERSION_1) {  			struct uac1_output_terminal_descriptor *desc = p;  			if (desc->bLength < sizeof(*desc))  				continue; /* invalid descriptor? */ -			set_bit(desc->bTerminalID, state.unitbitmap);  /* mark terminal ID as visited */ +			/* mark terminal ID as visited */ +			set_bit(desc->bTerminalID, state.unitbitmap);  			state.oterm.id = desc->bTerminalID;  			state.oterm.type = le16_to_cpu(desc->wTerminalType);  			state.oterm.name = desc->iTerminal; @@ -2133,7 +2221,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)  			if (desc->bLength < sizeof(*desc))  				continue; /* invalid descriptor? */ -			set_bit(desc->bTerminalID, state.unitbitmap);  /* mark terminal ID as visited */ +			/* mark terminal ID as visited */ +			set_bit(desc->bTerminalID, state.unitbitmap);  			state.oterm.id = desc->bTerminalID;  			state.oterm.type = le16_to_cpu(desc->wTerminalType);  			state.oterm.name = desc->iTerminal; @@ -2141,7 +2230,10 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)  			if (err < 0 && err != -EINVAL)  				return err; -			/* for UAC2, use the same approach to also add the clock selectors */ +			/* +			 * For UAC2, use the same approach to also add the +			 * clock selectors +			 */  			err = parse_audio_unit(&state, desc->bCSourceID);  			if (err < 0 && err != -EINVAL)  				return err; @@ -2209,8 +2301,9 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,  	__u8 channel = value & 0xff;  	if (channel >= MAX_CHANNELS) { -		snd_printk(KERN_DEBUG "%s(): bogus channel number %d\n", -				__func__, channel); +		usb_audio_dbg(mixer->chip, +			"%s(): bogus channel number %d\n", +			__func__, channel);  		return;  	} @@ -2239,8 +2332,9 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,  			break;  		default: -			snd_printk(KERN_DEBUG "unknown attribute %d in interrupt\n", -						attribute); +			usb_audio_dbg(mixer->chip, +				"unknown attribute %d in interrupt\n", +				attribute);  			break;  		} /* switch */  	} @@ -2261,7 +2355,7 @@ static void snd_usb_mixer_interrupt(struct urb *urb)  		for (status = urb->transfer_buffer;  		     len >= sizeof(*status);  		     len -= sizeof(*status), status++) { -			snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n", +			dev_dbg(&urb->dev->dev, "status interrupt: %02x %02x\n",  						status->bStatusType,  						status->bOriginator); @@ -2293,32 +2387,14 @@ static void snd_usb_mixer_interrupt(struct urb *urb)  	}  requeue: -	if (ustatus != -ENOENT && ustatus != -ECONNRESET && ustatus != -ESHUTDOWN) { +	if (ustatus != -ENOENT && +	    ustatus != -ECONNRESET && +	    ustatus != -ESHUTDOWN) {  		urb->dev = mixer->chip->dev;  		usb_submit_urb(urb, GFP_ATOMIC);  	}  } -/* stop any bus activity of a mixer */ -void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer) -{ -	usb_kill_urb(mixer->urb); -	usb_kill_urb(mixer->rc_urb); -} - -int snd_usb_mixer_activate(struct usb_mixer_interface *mixer) -{ -	int err; - -	if (mixer->urb) { -		err = usb_submit_urb(mixer->urb, GFP_NOIO); -		if (err < 0) -			return err; -	} - -	return 0; -} -  /* create the handler for the optional status interrupt endpoint */  static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)  { @@ -2393,7 +2469,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,  	snd_usb_mixer_apply_create_quirk(mixer); -	err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); +	err = snd_device_new(chip->card, SNDRV_DEV_CODEC, mixer, &dev_ops);  	if (err < 0)  		goto _error; @@ -2417,3 +2493,82 @@ void snd_usb_mixer_disconnect(struct list_head *p)  	usb_kill_urb(mixer->urb);  	usb_kill_urb(mixer->rc_urb);  } + +#ifdef CONFIG_PM +/* stop any bus activity of a mixer */ +static void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer) +{ +	usb_kill_urb(mixer->urb); +	usb_kill_urb(mixer->rc_urb); +} + +static int snd_usb_mixer_activate(struct usb_mixer_interface *mixer) +{ +	int err; + +	if (mixer->urb) { +		err = usb_submit_urb(mixer->urb, GFP_NOIO); +		if (err < 0) +			return err; +	} + +	return 0; +} + +int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer) +{ +	snd_usb_mixer_inactivate(mixer); +	return 0; +} + +static int restore_mixer_value(struct usb_mixer_elem_info *cval) +{ +	int c, err, idx; + +	if (cval->cmask) { +		idx = 0; +		for (c = 0; c < MAX_CHANNELS; c++) { +			if (!(cval->cmask & (1 << c))) +				continue; +			if (cval->cached & (1 << c)) { +				err = set_cur_mix_value(cval, c + 1, idx, +							cval->cache_val[idx]); +				if (err < 0) +					return err; +			} +			idx++; +		} +	} else { +		/* master */ +		if (cval->cached) { +			err = set_cur_mix_value(cval, 0, 0, *cval->cache_val); +			if (err < 0) +				return err; +		} +	} + +	return 0; +} + +int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume) +{ +	struct usb_mixer_elem_info *cval; +	int id, err; + +	/* FIXME: any mixer quirks? */ + +	if (reset_resume) { +		/* restore cached mixer values */ +		for (id = 0; id < MAX_ID_ELEMS; id++) { +			for (cval = mixer->id_elems[id]; cval; +			     cval = cval->next_id_elem) { +				err = restore_mixer_value(cval); +				if (err < 0) +					return err; +			} +		} +	} + +	return snd_usb_mixer_activate(mixer); +} +#endif diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index aab80df201b..73b1f649447 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h @@ -63,8 +63,6 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);  int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,  				int request, int validx, int value_set); -void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer); -int snd_usb_mixer_activate(struct usb_mixer_interface *mixer);  int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,  			      struct snd_kcontrol *kctl); @@ -72,4 +70,9 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,  int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,  			  unsigned int size, unsigned int __user *_tlv); +#ifdef CONFIG_PM +int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer); +int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume); +#endif +  #endif /* __USBMIXER_H */ diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index cc2dd1f0dec..d1d72ff5034 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -322,6 +322,17 @@ static struct usbmix_name_map hercules_usb51_map[] = {  	{ 0 }				/* terminator */  }; +/* Plantronics Gamecom 780 has a broken volume control, better to disable it */ +static struct usbmix_name_map gamecom780_map[] = { +	{ 9, NULL }, /* FU, speaker out */ +	{} +}; + +static const struct usbmix_name_map kef_x300a_map[] = { +	{ 10, NULL }, /* firmware locks up (?) when we try to access this FU */ +	{ 0 } +}; +  /*   * Control map entries   */ @@ -358,6 +369,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {  		.id = USB_ID(0x046d, 0x09a4),  		.ignore_ctl_error = 1,  	}, +	{	/* Plantronics GameCom 780 */ +		.id = USB_ID(0x047f, 0xc010), +		.map = gamecom780_map, +	},  	{  		/* Hercules DJ Console (Windows Edition) */  		.id = USB_ID(0x06f8, 0xb000), @@ -409,6 +424,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {  		.id = USB_ID(0x200c, 0x1018),  		.map = ebox44_map,  	}, +	{ +		.id = USB_ID(0x27ac, 0x1000), +		.map = kef_x300a_map, +	},  	{ 0 } /* terminator */  }; diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index d42a584cf82..f119a41ed9a 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -433,6 +433,89 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,  	}  } +/* EMU0204 */ +static int snd_emu0204_ch_switch_info(struct snd_kcontrol *kcontrol, +				      struct snd_ctl_elem_info *uinfo) +{ +	static const char *texts[2] = {"1/2", +				       "3/4" +	}; + +	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; +	uinfo->count = 1; +	uinfo->value.enumerated.items = 2; +	if (uinfo->value.enumerated.item > 1) +		uinfo->value.enumerated.item = 1; +	strcpy(uinfo->value.enumerated.name, +		texts[uinfo->value.enumerated.item]); + +	return 0; +} + +static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol, +				     struct snd_ctl_elem_value *ucontrol) +{ +	ucontrol->value.enumerated.item[0] = kcontrol->private_value; +	return 0; +} + +static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, +				     struct snd_ctl_elem_value *ucontrol) +{ +	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); +	unsigned int value = ucontrol->value.enumerated.item[0]; +	int err, changed; +	unsigned char buf[2]; + +	if (value > 1) +		return -EINVAL; + +	buf[0] = 0x01; +	buf[1] = value ? 0x02 : 0x01; + +	changed = value != kcontrol->private_value; +	down_read(&mixer->chip->shutdown_rwsem); +	if (mixer->chip->shutdown) { +		err = -ENODEV; +		goto out; +	} +	err = snd_usb_ctl_msg(mixer->chip->dev, +		      usb_sndctrlpipe(mixer->chip->dev, 0), UAC_SET_CUR, +		      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, +		      0x0400, 0x0e00, buf, 2); + out: +	up_read(&mixer->chip->shutdown_rwsem); +	if (err < 0) +		return err; +	kcontrol->private_value = value; +	return changed; +} + + +static struct snd_kcontrol_new snd_emu0204_controls[] = { +	{ +		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, +		.name = "Front Jack Channels", +		.info = snd_emu0204_ch_switch_info, +		.get = snd_emu0204_ch_switch_get, +		.put = snd_emu0204_ch_switch_put, +		.private_value = 0, +	}, +}; + +static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) +{ +	int i, err; + +	for (i = 0; i < ARRAY_SIZE(snd_emu0204_controls); ++i) { +		err = snd_ctl_add(mixer->chip->card, +			snd_ctl_new1(&snd_emu0204_controls[i], mixer)); +		if (err < 0) +			return err; +	} + +	return 0; +}  /* ASUS Xonar U1 / U3 controls */  static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, @@ -517,8 +600,8 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,  	up_read(&mixer->chip->shutdown_rwsem);  	if (ret < 0) { -		snd_printk(KERN_ERR -			   "unable to issue vendor read request (ret = %d)", ret); +		dev_err(&dev->dev, +			"unable to issue vendor read request (ret = %d)", ret);  		return ret;  	} @@ -548,8 +631,8 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,  	up_read(&mixer->chip->shutdown_rwsem);  	if (ret < 0) { -		snd_printk(KERN_ERR -			   "unable to issue vendor write request (ret = %d)", ret); +		dev_err(&dev->dev, +			"unable to issue vendor write request (ret = %d)", ret);  		return ret;  	} @@ -1520,7 +1603,7 @@ static int snd_microii_controls_create(struct usb_mixer_interface *mixer)  			return err;  	} -	return err; +	return 0;  }  int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) @@ -1545,6 +1628,13 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)  					      snd_audigy2nx_proc_read);  		break; +	/* EMU0204 */ +	case USB_ID(0x041e, 0x3f19): +		err = snd_emu0204_controls_create(mixer); +		if (err < 0) +			break; +		break; +  	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */  	case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C400 */  		err = snd_c400_create_mixer(mixer); @@ -1609,7 +1699,7 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,  			snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);  		break;  	default: -		snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid); +		usb_audio_dbg(mixer->chip, "memory change in unknown unit %d\n", unitid);  		break;  	}  } diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index b375d58871e..c62a1659106 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -166,8 +166,8 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface,  				   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,  				   UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep,  				   data, sizeof(data))) < 0) { -		snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", -			   dev->devnum, iface, ep); +		usb_audio_err(chip, "%d:%d: cannot set enable PITCH\n", +			      iface, ep);  		return err;  	} @@ -187,8 +187,8 @@ static int init_pitch_v2(struct snd_usb_audio *chip, int iface,  				   USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,  				   UAC2_EP_CS_PITCH << 8, 0,  				   data, sizeof(data))) < 0) { -		snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n", -			   dev->devnum, iface, fmt->altsetting); +		usb_audio_err(chip, "%d:%d: cannot set enable PITCH (v2)\n", +			      iface, fmt->altsetting);  		return err;  	} @@ -226,7 +226,7 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep)  	if (!test_and_set_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags)) {  		struct snd_usb_endpoint *ep = subs->data_endpoint; -		snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep); +		dev_dbg(&subs->dev->dev, "Starting data EP @%p\n", ep);  		ep->data_subs = subs;  		err = snd_usb_endpoint_start(ep, can_sleep); @@ -241,21 +241,21 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep)  		struct snd_usb_endpoint *ep = subs->sync_endpoint;  		if (subs->data_endpoint->iface != subs->sync_endpoint->iface || -		    subs->data_endpoint->alt_idx != subs->sync_endpoint->alt_idx) { +		    subs->data_endpoint->altsetting != subs->sync_endpoint->altsetting) {  			err = usb_set_interface(subs->dev,  						subs->sync_endpoint->iface, -						subs->sync_endpoint->alt_idx); +						subs->sync_endpoint->altsetting);  			if (err < 0) { -				snd_printk(KERN_ERR -					   "%d:%d:%d: cannot set interface (%d)\n", -					   subs->dev->devnum, +				clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags); +				dev_err(&subs->dev->dev, +					   "%d:%d: cannot set interface (%d)\n",  					   subs->sync_endpoint->iface, -					   subs->sync_endpoint->alt_idx, err); +					   subs->sync_endpoint->altsetting, err);  				return -EIO;  			}  		} -		snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep); +		dev_dbg(&subs->dev->dev, "Starting sync EP @%p\n", ep);  		ep->sync_slave = subs->data_endpoint;  		err = snd_usb_endpoint_start(ep, can_sleep); @@ -282,22 +282,6 @@ static void stop_endpoints(struct snd_usb_substream *subs, bool wait)  	}  } -static int deactivate_endpoints(struct snd_usb_substream *subs) -{ -	int reta, retb; - -	reta = snd_usb_endpoint_deactivate(subs->sync_endpoint); -	retb = snd_usb_endpoint_deactivate(subs->data_endpoint); - -	if (reta < 0) -		return reta; - -	if (retb < 0) -		return retb; - -	return 0; -} -  static int search_roland_implicit_fb(struct usb_device *dev, int ifnum,  				     unsigned int altsetting,  				     struct usb_host_interface **alts, @@ -425,8 +409,9 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,  	if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC ||  	    (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&  	     get_endpoint(alts, 1)->bSynchAddress != 0)) { -		snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n", -			   dev->devnum, fmt->iface, fmt->altsetting, +		dev_err(&dev->dev, +			"%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n", +			   fmt->iface, fmt->altsetting,  			   get_endpoint(alts, 1)->bmAttributes,  			   get_endpoint(alts, 1)->bLength,  			   get_endpoint(alts, 1)->bSynchAddress); @@ -436,8 +421,9 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,  	if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&  	    ((is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||  	     (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) { -		snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n", -			   dev->devnum, fmt->iface, fmt->altsetting, +		dev_err(&dev->dev, +			"%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n", +			   fmt->iface, fmt->altsetting,  			   is_playback, ep, get_endpoint(alts, 0)->bSynchAddress);  		return -EINVAL;  	} @@ -484,8 +470,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)  	if (subs->interface >= 0 && subs->interface != fmt->iface) {  		err = usb_set_interface(subs->dev, subs->interface, 0);  		if (err < 0) { -			snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed (%d)\n", -				dev->devnum, fmt->iface, fmt->altsetting, err); +			dev_err(&dev->dev, +				"%d:%d: return to setting 0 failed (%d)\n", +				fmt->iface, fmt->altsetting, err);  			return -EIO;  		}  		subs->interface = -1; @@ -497,12 +484,13 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)  	    subs->altset_idx != fmt->altset_idx) {  		err = usb_set_interface(dev, fmt->iface, fmt->altsetting);  		if (err < 0) { -			snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed (%d)\n", -				   dev->devnum, fmt->iface, fmt->altsetting, err); +			dev_err(&dev->dev, +				"%d:%d: usb_set_interface failed (%d)\n", +				fmt->iface, fmt->altsetting, err);  			return -EIO;  		} -		snd_printdd(KERN_INFO "setting usb interface %d:%d\n", -				fmt->iface, fmt->altsetting); +		dev_dbg(&dev->dev, "setting usb interface %d:%d\n", +			fmt->iface, fmt->altsetting);  		subs->interface = fmt->iface;  		subs->altset_idx = fmt->altset_idx; @@ -538,20 +526,23 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)   * - Requested PCM format is not supported.   * - Requested sample rate is not supported.   */ -static int match_endpoint_audioformats(struct audioformat *fp, -	struct audioformat *match, int rate, -	snd_pcm_format_t pcm_format) +static int match_endpoint_audioformats(struct snd_usb_substream *subs, +				       struct audioformat *fp, +				       struct audioformat *match, int rate, +				       snd_pcm_format_t pcm_format)  {  	int i;  	int score = 0;  	if (fp->channels < 1) { -		snd_printdd("%s: (fmt @%p) no channels\n", __func__, fp); +		dev_dbg(&subs->dev->dev, +			"%s: (fmt @%p) no channels\n", __func__, fp);  		return 0;  	}  	if (!(fp->formats & pcm_format_to_bits(pcm_format))) { -		snd_printdd("%s: (fmt @%p) no match for format %d\n", __func__, +		dev_dbg(&subs->dev->dev, +			"%s: (fmt @%p) no match for format %d\n", __func__,  			fp, pcm_format);  		return 0;  	} @@ -563,7 +554,8 @@ static int match_endpoint_audioformats(struct audioformat *fp,  		}  	}  	if (!score) { -		snd_printdd("%s: (fmt @%p) no match for rate %d\n", __func__, +		dev_dbg(&subs->dev->dev, +			"%s: (fmt @%p) no match for rate %d\n", __func__,  			fp, rate);  		return 0;  	} @@ -571,7 +563,8 @@ static int match_endpoint_audioformats(struct audioformat *fp,  	if (fp->channels == match->channels)  		score++; -	snd_printdd("%s: (fmt @%p) score %d\n", __func__, fp, score); +	dev_dbg(&subs->dev->dev, +		"%s: (fmt @%p) score %d\n", __func__, fp, score);  	return score;  } @@ -595,13 +588,15 @@ static int configure_sync_endpoint(struct snd_usb_substream *subs)  						   subs->pcm_format,  						   subs->channels,  						   subs->period_bytes, +						   0, 0,  						   subs->cur_rate,  						   subs->cur_audiofmt,  						   NULL);  	/* Try to find the best matching audioformat. */  	list_for_each_entry(fp, &sync_subs->fmt_list, list) { -		int score = match_endpoint_audioformats(fp, subs->cur_audiofmt, +		int score = match_endpoint_audioformats(subs, +							fp, subs->cur_audiofmt,  			subs->cur_rate, subs->pcm_format);  		if (score > cur_score) { @@ -611,7 +606,8 @@ static int configure_sync_endpoint(struct snd_usb_substream *subs)  	}  	if (unlikely(sync_fp == NULL)) { -		snd_printk(KERN_ERR "%s: no valid audioformat for sync ep %x found\n", +		dev_err(&subs->dev->dev, +			"%s: no valid audioformat for sync ep %x found\n",  			__func__, sync_subs->ep_num);  		return -EINVAL;  	} @@ -623,7 +619,8 @@ static int configure_sync_endpoint(struct snd_usb_substream *subs)  	if (sync_fp->channels != subs->channels) {  		sync_period_bytes = (subs->period_bytes / subs->channels) *  			sync_fp->channels; -		snd_printdd("%s: adjusted sync ep period bytes (%d -> %d)\n", +		dev_dbg(&subs->dev->dev, +			"%s: adjusted sync ep period bytes (%d -> %d)\n",  			__func__, subs->period_bytes, sync_period_bytes);  	} @@ -631,6 +628,7 @@ static int configure_sync_endpoint(struct snd_usb_substream *subs)  					  subs->pcm_format,  					  sync_fp->channels,  					  sync_period_bytes, +					  0, 0,  					  subs->cur_rate,  					  sync_fp,  					  NULL); @@ -653,6 +651,8 @@ static int configure_endpoint(struct snd_usb_substream *subs)  					  subs->pcm_format,  					  subs->channels,  					  subs->period_bytes, +					  subs->period_frames, +					  subs->buffer_periods,  					  subs->cur_rate,  					  subs->cur_audiofmt,  					  subs->sync_endpoint); @@ -689,12 +689,15 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,  	subs->pcm_format = params_format(hw_params);  	subs->period_bytes = params_period_bytes(hw_params); +	subs->period_frames = params_period_size(hw_params); +	subs->buffer_periods = params_periods(hw_params);  	subs->channels = params_channels(hw_params);  	subs->cur_rate = params_rate(hw_params);  	fmt = find_format(subs);  	if (!fmt) { -		snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n", +		dev_dbg(&subs->dev->dev, +			"cannot set format: format = %#x, rate = %d, channels = %d\n",  			   subs->pcm_format, subs->cur_rate, subs->channels);  		return -EINVAL;  	} @@ -730,7 +733,8 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)  	down_read(&subs->stream->chip->shutdown_rwsem);  	if (!subs->stream->chip->shutdown) {  		stop_endpoints(subs, true); -		deactivate_endpoints(subs); +		snd_usb_endpoint_deactivate(subs->sync_endpoint); +		snd_usb_endpoint_deactivate(subs->data_endpoint);  	}  	up_read(&subs->stream->chip->shutdown_rwsem);  	return snd_pcm_lib_free_vmalloc_buffer(substream); @@ -750,7 +754,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)  	int ret;  	if (! subs->cur_audiofmt) { -		snd_printk(KERN_ERR "usbaudio: no format is specified!\n"); +		dev_err(&subs->dev->dev, "no format is specified!\n");  		return -ENXIO;  	} @@ -1243,7 +1247,8 @@ static void retire_capture_urb(struct snd_usb_substream *subs,  	for (i = 0; i < urb->number_of_packets; i++) {  		cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset + subs->pkt_offset_adj;  		if (urb->iso_frame_desc[i].status && printk_ratelimit()) { -			snd_printdd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); +			dev_dbg(&subs->dev->dev, "frame %d active: %d\n", +				i, urb->iso_frame_desc[i].status);  			// continue;  		}  		bytes = urb->iso_frame_desc[i].actual_length; @@ -1253,7 +1258,8 @@ static void retire_capture_urb(struct snd_usb_substream *subs,  		if (bytes % (runtime->sample_bits >> 3) != 0) {  			int oldbytes = bytes;  			bytes = frames * stride; -			snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n", +			dev_warn(&subs->dev->dev, +				 "Corrected urb data len. %d->%d\n",  							oldbytes, bytes);  		}  		/* update the current pointer */ @@ -1363,6 +1369,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,  	frames = 0;  	urb->number_of_packets = 0;  	spin_lock_irqsave(&subs->lock, flags); +	subs->frame_limit += ep->max_urb_frames;  	for (i = 0; i < ctx->packets; i++) {  		if (ctx->packet_size[i])  			counts = ctx->packet_size[i]; @@ -1377,6 +1384,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,  		subs->transfer_done += counts;  		if (subs->transfer_done >= runtime->period_size) {  			subs->transfer_done -= runtime->period_size; +			subs->frame_limit = 0;  			period_elapsed = 1;  			if (subs->fmt_type == UAC_FORMAT_TYPE_II) {  				if (subs->transfer_done > 0) { @@ -1399,8 +1407,10 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,  				break;  			}  		} -		if (period_elapsed && -		    !snd_usb_endpoint_implicit_feedback_sink(subs->data_endpoint)) /* finish at the period boundary */ +		/* finish at the period boundary or after enough frames */ +		if ((period_elapsed || +				subs->transfer_done >= subs->frame_limit) && +		    !snd_usb_endpoint_implicit_feedback_sink(ep))  			break;  	}  	bytes = frames * ep->stride; @@ -1492,7 +1502,8 @@ static void retire_playback_urb(struct snd_usb_substream *subs,  	 * on two reads of a counter updated every ms.  	 */  	if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2) -		snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n", +		dev_dbg_ratelimited(&subs->dev->dev, +			"delay: estimated %d, actual %d\n",  			est_delay, subs->last_delay);  	if (!subs->running) { diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index f5f0595ef9c..f652b10ce90 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -72,22 +72,21 @@  	}  }, -/* Creative/Toshiba Multimedia Center SB-0500 */ +/* Creative/E-Mu devices */  { -	USB_DEVICE(0x041e, 0x3048), +	USB_DEVICE(0x041e, 0x3010),  	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { -		.vendor_name = "Toshiba", -		.product_name = "SB-0500", +		.vendor_name = "Creative Labs", +		.product_name = "Sound Blaster MP3+",  		.ifnum = QUIRK_NO_INTERFACE  	}  }, - -/* Creative/E-Mu devices */ +/* Creative/Toshiba Multimedia Center SB-0500 */  { -	USB_DEVICE(0x041e, 0x3010), +	USB_DEVICE(0x041e, 0x3048),  	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { -		.vendor_name = "Creative Labs", -		.product_name = "Sound Blaster MP3+", +		.vendor_name = "Toshiba", +		.product_name = "SB-0500",  		.ifnum = QUIRK_NO_INTERFACE  	}  }, @@ -2521,6 +2520,46 @@ YAMAHA_DEVICE(0x7010, "UB99"),  	}  },  { +	USB_DEVICE(0x1235, 0x0010), +	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { +		.vendor_name = "Focusrite", +		.product_name = "Saffire 6 USB", +		.ifnum = QUIRK_ANY_INTERFACE, +		.type = QUIRK_COMPOSITE, +		.data = (const struct snd_usb_audio_quirk[]) { +			{ +				.ifnum = 0, +				.type = QUIRK_AUDIO_FIXED_ENDPOINT, +				.data = &(const struct audioformat) { +					.formats = SNDRV_PCM_FMTBIT_S24_3LE, +					.channels = 4, +					.iface = 0, +					.altsetting = 1, +					.altset_idx = 1, +					.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, +					.endpoint = 0x01, +					.ep_attr = USB_ENDPOINT_XFER_ISOC, +					.rates = SNDRV_PCM_RATE_44100 | +						 SNDRV_PCM_RATE_48000, +					.rate_min = 44100, +					.rate_max = 48000, +					.nr_rates = 2, +					.rate_table = (unsigned int[]) { +						44100, 48000 +					} +				} +			}, +			{ +				.ifnum = 1, +				.type = QUIRK_MIDI_RAW_BYTES +			}, +			{ +				.ifnum = -1 +			} +		} +	} +}, +{  	USB_DEVICE(0x1235, 0x0018),  	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {  		.vendor_name = "Novation", @@ -2569,6 +2608,57 @@ YAMAHA_DEVICE(0x7010, "UB99"),  		.type = QUIRK_MIDI_NOVATION  	}  }, +{ +	/* +	 * Focusrite Scarlett 18i6 +	 * +	 * Avoid mixer creation, which otherwise fails because some of +	 * the interface descriptor subtypes for interface 0 are +	 * unknown.  That should be fixed or worked-around but this at +	 * least allows the device to be used successfully with a DAW +	 * and an external mixer.  See comments below about other +	 * ignored interfaces. +	 */ +	USB_DEVICE(0x1235, 0x8004), +	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { +		.vendor_name = "Focusrite", +		.product_name = "Scarlett 18i6", +		.ifnum = QUIRK_ANY_INTERFACE, +		.type = QUIRK_COMPOSITE, +		.data = & (const struct snd_usb_audio_quirk[]) { +			{ +				/* InterfaceSubClass 1 (Control Device) */ +				.ifnum = 0, +				.type = QUIRK_IGNORE_INTERFACE +			}, +			{ +				.ifnum = 1, +				.type = QUIRK_AUDIO_STANDARD_INTERFACE +			}, +			{ +				.ifnum = 2, +				.type = QUIRK_AUDIO_STANDARD_INTERFACE +			}, +			{ +				/* InterfaceSubClass 1 (Control Device) */ +				.ifnum = 3, +				.type = QUIRK_IGNORE_INTERFACE +			}, +			{ +				.ifnum = 4, +				.type = QUIRK_MIDI_STANDARD_INTERFACE +			}, +			{ +				/* InterfaceSubClass 1 (Device Firmware Update) */ +				.ifnum = 5, +				.type = QUIRK_IGNORE_INTERFACE +			}, +			{ +				.ifnum = -1 +			} +		} +	} +},  /* Access Music devices */  { @@ -2671,7 +2761,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),  	}  },  { -	USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240), +	USB_DEVICE_VENDOR_SPEC(0x2040, 0x7210),  	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |  		       USB_DEVICE_ID_MATCH_INT_CLASS |  		       USB_DEVICE_ID_MATCH_INT_SUBCLASS, @@ -2679,13 +2769,13 @@ YAMAHA_DEVICE(0x7010, "UB99"),  	.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,  	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {  		.vendor_name = "Hauppauge", -		.product_name = "HVR-850", +		.product_name = "HVR-950Q",  		.ifnum = QUIRK_ANY_INTERFACE,  		.type = QUIRK_AUDIO_ALIGN_TRANSFER,  	}  },  { -	USB_DEVICE_VENDOR_SPEC(0x2040, 0x7210), +	USB_DEVICE_VENDOR_SPEC(0x2040, 0x7217),  	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |  		       USB_DEVICE_ID_MATCH_INT_CLASS |  		       USB_DEVICE_ID_MATCH_INT_SUBCLASS, @@ -2699,7 +2789,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),  	}  },  { -	USB_DEVICE_VENDOR_SPEC(0x2040, 0x7217), +	USB_DEVICE_VENDOR_SPEC(0x2040, 0x721b),  	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |  		       USB_DEVICE_ID_MATCH_INT_CLASS |  		       USB_DEVICE_ID_MATCH_INT_SUBCLASS, @@ -2713,7 +2803,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),  	}  },  { -	USB_DEVICE_VENDOR_SPEC(0x2040, 0x721b), +	USB_DEVICE_VENDOR_SPEC(0x2040, 0x721e),  	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |  		       USB_DEVICE_ID_MATCH_INT_CLASS |  		       USB_DEVICE_ID_MATCH_INT_SUBCLASS, @@ -2727,7 +2817,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),  	}  },  { -	USB_DEVICE_VENDOR_SPEC(0x2040, 0x721e), +	USB_DEVICE_VENDOR_SPEC(0x2040, 0x721f),  	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |  		       USB_DEVICE_ID_MATCH_INT_CLASS |  		       USB_DEVICE_ID_MATCH_INT_SUBCLASS, @@ -2741,7 +2831,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),  	}  },  { -	USB_DEVICE_VENDOR_SPEC(0x2040, 0x721f), +	USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240),  	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |  		       USB_DEVICE_ID_MATCH_INT_CLASS |  		       USB_DEVICE_ID_MATCH_INT_SUBCLASS, @@ -2749,7 +2839,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),  	.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,  	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {  		.vendor_name = "Hauppauge", -		.product_name = "HVR-950Q", +		.product_name = "HVR-850",  		.ifnum = QUIRK_ANY_INTERFACE,  		.type = QUIRK_AUDIO_ALIGN_TRANSFER,  	} @@ -3054,58 +3144,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),  {  	/* -	 * Focusrite Scarlett 18i6 -	 * -	 * Avoid mixer creation, which otherwise fails because some of -	 * the interface descriptor subtypes for interface 0 are -	 * unknown.  That should be fixed or worked-around but this at -	 * least allows the device to be used successfully with a DAW -	 * and an external mixer.  See comments below about other -	 * ignored interfaces. -	 */ -	USB_DEVICE(0x1235, 0x8004), -	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { -		.vendor_name = "Focusrite", -		.product_name = "Scarlett 18i6", -		.ifnum = QUIRK_ANY_INTERFACE, -		.type = QUIRK_COMPOSITE, -		.data = & (const struct snd_usb_audio_quirk[]) { -			{ -				/* InterfaceSubClass 1 (Control Device) */ -				.ifnum = 0, -				.type = QUIRK_IGNORE_INTERFACE -			}, -			{ -				.ifnum = 1, -				.type = QUIRK_AUDIO_STANDARD_INTERFACE -			}, -			{ -				.ifnum = 2, -				.type = QUIRK_AUDIO_STANDARD_INTERFACE -			}, -			{ -				/* InterfaceSubClass 1 (Control Device) */ -				.ifnum = 3, -				.type = QUIRK_IGNORE_INTERFACE -			}, -			{ -				.ifnum = 4, -				.type = QUIRK_MIDI_STANDARD_INTERFACE -			}, -			{ -				/* InterfaceSubClass 1 (Device Firmware Update) */ -				.ifnum = 5, -				.type = QUIRK_IGNORE_INTERFACE -			}, -			{ -				.ifnum = -1 -			} -		} -	} -}, - -{ -	/*  	 * Some USB MIDI devices don't have an audio control interface,  	 * so we have to grab MIDI streaming interfaces here.  	 */ diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 0df9ede99df..7c57f2268dd 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -110,7 +110,7 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip,  	altsd = get_iface_desc(alts);  	err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber);  	if (err < 0) { -		snd_printk(KERN_ERR "cannot setup if %d: error %d\n", +		usb_audio_err(chip, "cannot setup if %d: error %d\n",  			   altsd->bInterfaceNumber, err);  		return err;  	} @@ -135,7 +135,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,  	fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);  	if (!fp) { -		snd_printk(KERN_ERR "cannot memdup\n"); +		usb_audio_err(chip, "cannot memdup\n");  		return -ENOMEM;  	}  	if (fp->nr_rates > MAX_NR_RATES) { @@ -464,7 +464,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,  		fp->rate_max = fp->rate_min = 96000;  		break;  	default: -		snd_printk(KERN_ERR "unknown sample rate\n"); +		usb_audio_err(chip, "unknown sample rate\n");  		kfree(fp);  		return -ENXIO;  	} @@ -536,7 +536,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,  	if (quirk->type < QUIRK_TYPE_COUNT) {  		return quirk_funcs[quirk->type](chip, iface, driver, quirk);  	} else { -		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); +		usb_audio_err(chip, "invalid quirk type %d\n", quirk->type);  		return -ENXIO;  	}  } @@ -555,18 +555,21 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac  	if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||  	    le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) { -		snd_printdd("sending Extigy boot sequence...\n"); +		dev_dbg(&dev->dev, "sending Extigy boot sequence...\n");  		/* Send message to force it to reconnect with full interface. */  		err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),  				      0x10, 0x43, 0x0001, 0x000a, NULL, 0); -		if (err < 0) snd_printdd("error sending boot message: %d\n", err); +		if (err < 0) +			dev_dbg(&dev->dev, "error sending boot message: %d\n", err);  		err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,  				&dev->descriptor, sizeof(dev->descriptor));  		config = dev->actconfig; -		if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err); +		if (err < 0) +			dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);  		err = usb_reset_configuration(dev); -		if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err); -		snd_printdd("extigy_boot: new boot length = %d\n", +		if (err < 0) +			dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err); +		dev_dbg(&dev->dev, "extigy_boot: new boot length = %d\n",  			    le16_to_cpu(get_cfg_desc(config)->wTotalLength));  		return -ENODEV; /* quit this anyway */  	} @@ -594,7 +597,7 @@ static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)  	int err;  	if (dev->actconfig->desc.bConfigurationValue == 1) { -		snd_printk(KERN_INFO "usb-audio: " +		dev_info(&dev->dev,  			   "Fast Track Pro switching to config #2\n");  		/* This function has to be available by the usb core module.  		 * if it is not avialable the boot quirk has to be left out @@ -603,14 +606,15 @@ static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)  		 */  		err = usb_driver_set_configuration(dev, 2);  		if (err < 0) -			snd_printdd("error usb_driver_set_configuration: %d\n", -				    err); +			dev_dbg(&dev->dev, +				"error usb_driver_set_configuration: %d\n", +				err);  		/* Always return an error, so that we stop creating a device  		   that will just be destroyed and recreated with a new  		   configuration */  		return -ENODEV;  	} else -		snd_printk(KERN_INFO "usb-audio: Fast Track Pro config OK\n"); +		dev_info(&dev->dev, "Fast Track Pro config OK\n");  	return 0;  } @@ -660,10 +664,23 @@ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)  	return err;  } +/* quirk for Plantronics GameCom 780 with CM6302 chip */ +static int snd_usb_gamecon780_boot_quirk(struct usb_device *dev) +{ +	/* set the initial volume and don't change; other values are either +	 * too loud or silent due to firmware bug (bko#65251) +	 */ +	u8 buf[2] = { 0x74, 0xdc }; +	return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, +			USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, +			UAC_FU_VOLUME << 8, 9 << 8, buf, 2); +} +  /*   * Novation Twitch DJ controller + * Focusrite Novation Saffire 6 USB audio card   */ -static int snd_usb_twitch_boot_quirk(struct usb_device *dev) +static int snd_usb_novation_boot_quirk(struct usb_device *dev)  {  	/* preemptively set up the device because otherwise the  	 * raw MIDI endpoints are not active */ @@ -766,11 +783,11 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev)  	fwsize = le16_to_cpu(get_cfg_desc(config)->wTotalLength);  	if (fwsize != MBOX2_FIRMWARE_SIZE) { -		snd_printk(KERN_ERR "usb-audio: Invalid firmware size=%d.\n", fwsize); +		dev_err(&dev->dev, "Invalid firmware size=%d.\n", fwsize);  		return -ENODEV;  	} -	snd_printd("usb-audio: Sending Digidesign Mbox 2 boot sequence...\n"); +	dev_dbg(&dev->dev, "Sending Digidesign Mbox 2 boot sequence...\n");  	count = 0;  	bootresponse[0] = MBOX2_BOOT_LOADING; @@ -781,32 +798,32 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev)  			0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012);  		if (bootresponse[0] == MBOX2_BOOT_READY)  			break; -		snd_printd("usb-audio: device not ready, resending boot sequence...\n"); +		dev_dbg(&dev->dev, "device not ready, resending boot sequence...\n");  		count++;  	}  	if (bootresponse[0] != MBOX2_BOOT_READY) { -		snd_printk(KERN_ERR "usb-audio: Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse[0]); +		dev_err(&dev->dev, "Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse[0]);  		return -ENODEV;  	} -	snd_printdd("usb-audio: device initialised!\n"); +	dev_dbg(&dev->dev, "device initialised!\n");  	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,  		&dev->descriptor, sizeof(dev->descriptor));  	config = dev->actconfig;  	if (err < 0) -		snd_printd("error usb_get_descriptor: %d\n", err); +		dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);  	err = usb_reset_configuration(dev);  	if (err < 0) -		snd_printd("error usb_reset_configuration: %d\n", err); -	snd_printdd("mbox2_boot: new boot length = %d\n", +		dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err); +	dev_dbg(&dev->dev, "mbox2_boot: new boot length = %d\n",  		le16_to_cpu(get_cfg_desc(config)->wTotalLength));  	mbox2_setup_48_24_magic(dev); -	snd_printk(KERN_INFO "usb-audio: Digidesign Mbox 2: 24bit 48kHz"); +	dev_info(&dev->dev, "Digidesign Mbox 2: 24bit 48kHz");  	return 0; /* Successful boot */  } @@ -852,7 +869,7 @@ static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,  				return 1; /* skip this altsetting */  		}  	} -	snd_printdd(KERN_INFO +	usb_audio_dbg(chip,  		    "using altsetting %d for interface %d config %d\n",  		    altno, iface, chip->setup);  	return 0; /* keep this altsetting */ @@ -919,7 +936,7 @@ static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,  			return 1;  	} -	snd_printdd(KERN_INFO +	usb_audio_dbg(chip,  		    "using altsetting %d for interface %d config %d\n",  		    altno, iface, chip->setup);  	return 0; /* keep this altsetting */ @@ -972,9 +989,9 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,  		/* Digidesign Mbox 2 */  		return snd_usb_mbox2_boot_quirk(dev); -	case USB_ID(0x1235, 0x0018): -		/* Focusrite Novation Twitch */ -		return snd_usb_twitch_boot_quirk(dev); +	case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */ +	case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */ +		return snd_usb_novation_boot_quirk(dev);  	case USB_ID(0x133e, 0x0815):  		/* Access Music VirusTI Desktop */ @@ -986,6 +1003,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,  		return snd_usb_nativeinstruments_boot_quirk(dev);  	case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */  		return snd_usb_fasttrackpro_boot_quirk(dev); +	case USB_ID(0x047f, 0xc010): /* Plantronics Gamecom 780 */ +		return snd_usb_gamecon780_boot_quirk(dev);  	}  	return 0; diff --git a/sound/usb/stream.c b/sound/usb/stream.c index c4339f97226..310a3822d2b 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -273,16 +273,14 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits,  		SNDRV_CHMAP_TSL,	/* top side left */  		SNDRV_CHMAP_TSR,	/* top side right */  		SNDRV_CHMAP_BC,		/* bottom center */ -		SNDRV_CHMAP_BLC,	/* bottom left center */ -		SNDRV_CHMAP_BRC,	/* bottom right center */ +		SNDRV_CHMAP_RLC,	/* back left of center */ +		SNDRV_CHMAP_RRC,	/* back right of center */  		0 /* terminator */  	};  	struct snd_pcm_chmap_elem *chmap;  	const unsigned int *maps;  	int c; -	if (!bits) -		return NULL;  	if (channels > ARRAY_SIZE(chmap->map))  		return NULL; @@ -293,9 +291,19 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits,  	maps = protocol == UAC_VERSION_2 ? uac2_maps : uac1_maps;  	chmap->channels = channels;  	c = 0; -	for (; bits && *maps; maps++, bits >>= 1) { -		if (bits & 1) -			chmap->map[c++] = *maps; + +	if (bits) { +		for (; bits && *maps; maps++, bits >>= 1) +			if (bits & 1) +				chmap->map[c++] = *maps; +	} else { +		/* If we're missing wChannelConfig, then guess something +		    to make sure the channel map is not skipped entirely */ +		if (channels == 1) +			chmap->map[c++] = SNDRV_CHMAP_MONO; +		else +			for (; c < channels && *maps; maps++) +				chmap->map[c++] = *maps;  	}  	for (; c < channels; c++) @@ -403,10 +411,9 @@ static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,  	if (!csep || csep->bLength < 7 ||  	    csep->bDescriptorSubtype != UAC_EP_GENERAL) { -		snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" -			   " class specific endpoint descriptor\n", -			   chip->dev->devnum, iface_no, -			   altsd->bAlternateSetting); +		usb_audio_warn(chip, +			       "%u:%d : no or invalid class specific endpoint descriptor\n", +			       iface_no, altsd->bAlternateSetting);  		return 0;  	} @@ -525,8 +532,8 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)  		/* get audio formats */  		switch (protocol) {  		default: -			snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n", -				    dev->devnum, iface_no, altno, protocol); +			dev_dbg(&dev->dev, "%u:%d: unknown interface protocol %#02x, assuming v1\n", +				iface_no, altno, protocol);  			protocol = UAC_VERSION_1;  			/* fall through */ @@ -536,14 +543,16 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)  			struct uac_input_terminal_descriptor *iterm;  			if (!as) { -				snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", -					   dev->devnum, iface_no, altno); +				dev_err(&dev->dev, +					"%u:%d : UAC_AS_GENERAL descriptor not found\n", +					iface_no, altno);  				continue;  			}  			if (as->bLength < sizeof(*as)) { -				snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", -					   dev->devnum, iface_no, altno); +				dev_err(&dev->dev, +					"%u:%d : invalid UAC_AS_GENERAL desc\n", +					iface_no, altno);  				continue;  			} @@ -566,19 +575,22 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)  				snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);  			if (!as) { -				snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", -					   dev->devnum, iface_no, altno); +				dev_err(&dev->dev, +					"%u:%d : UAC_AS_GENERAL descriptor not found\n", +					iface_no, altno);  				continue;  			}  			if (as->bLength < sizeof(*as)) { -				snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", -					   dev->devnum, iface_no, altno); +				dev_err(&dev->dev, +					"%u:%d : invalid UAC_AS_GENERAL desc\n", +					iface_no, altno);  				continue;  			}  			num_channels = as->bNrChannels;  			format = le32_to_cpu(as->bmFormats); +			chconfig = le32_to_cpu(as->bmChannelConfig);  			/* lookup the terminal associated to this interface  			 * to extract the clock */ @@ -586,7 +598,8 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)  									    as->bTerminalLink);  			if (input_term) {  				clock = input_term->bCSourceID; -				chconfig = le32_to_cpu(input_term->bmChannelConfig); +				if (!chconfig && (num_channels == input_term->bNrChannels)) +					chconfig = le32_to_cpu(input_term->bmChannelConfig);  				break;  			} @@ -597,8 +610,9 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)  				break;  			} -			snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n", -				   dev->devnum, iface_no, altno, as->bTerminalLink); +			dev_err(&dev->dev, +				"%u:%d : bogus bTerminalLink %d\n", +				iface_no, altno, as->bTerminalLink);  			continue;  		}  		} @@ -606,14 +620,16 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)  		/* get format type */  		fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);  		if (!fmt) { -			snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n", -				   dev->devnum, iface_no, altno); +			dev_err(&dev->dev, +				"%u:%d : no UAC_FORMAT_TYPE desc\n", +				iface_no, altno);  			continue;  		}  		if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||  		    ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { -			snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", -				   dev->devnum, iface_no, altno); +			dev_err(&dev->dev, +				"%u:%d : invalid UAC_FORMAT_TYPE desc\n", +				iface_no, altno);  			continue;  		} @@ -634,7 +650,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)  		fp = kzalloc(sizeof(*fp), GFP_KERNEL);  		if (! fp) { -			snd_printk(KERN_ERR "cannot malloc\n"); +			dev_err(&dev->dev, "cannot malloc\n");  			return -ENOMEM;  		} @@ -652,7 +668,6 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)  					* (fp->maxpacksize & 0x7ff);  		fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);  		fp->clock = clock; -		fp->chmap = convert_chmap(num_channels, chconfig, protocol);  		/* some quirks for attributes here */ @@ -688,13 +703,17 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)  		/* ok, let's parse further... */  		if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream) < 0) {  			kfree(fp->rate_table); -			kfree(fp->chmap);  			kfree(fp);  			fp = NULL;  			continue;  		} -		snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint); +		/* Create chmap */ +		if (fp->channels != num_channels) +			chconfig = 0; +		fp->chmap = convert_chmap(fp->channels, chconfig, protocol); + +		dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint);  		err = snd_usb_add_audio_stream(chip, stream, fp);  		if (err < 0) {  			kfree(fp->rate_table); diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index caabe9b3af4..91d0380431b 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -40,6 +40,7 @@ struct snd_usb_audio {  	struct rw_semaphore shutdown_rwsem;  	unsigned int shutdown:1;  	unsigned int probing:1; +	unsigned int in_pm:1;  	unsigned int autosuspended:1;	  	unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ @@ -55,12 +56,20 @@ struct snd_usb_audio {  	struct list_head mixer_list;	/* list of mixer interfaces */  	int setup;			/* from the 'device_setup' module param */ -	int nrpacks;			/* from the 'nrpacks' module param */  	bool autoclock;			/* from the 'autoclock' module param */  	struct usb_host_interface *ctrl_intf;	/* the audio control interface */  }; +#define usb_audio_err(chip, fmt, args...) \ +	dev_err(&(chip)->dev->dev, fmt, ##args) +#define usb_audio_warn(chip, fmt, args...) \ +	dev_warn(&(chip)->dev->dev, fmt, ##args) +#define usb_audio_info(chip, fmt, args...) \ +	dev_info(&(chip)->dev->dev, fmt, ##args) +#define usb_audio_dbg(chip, fmt, args...) \ +	dev_dbg(&(chip)->dev->dev, fmt, ##args) +  /*   * Information about devices with broken descriptors   */ diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index d0323a693ba..cf5dc33f4a6 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c @@ -262,7 +262,9 @@ static int usb_stream_hwdep_mmap(struct snd_hwdep *hw,  	}  	area->vm_ops = &usb_stream_hwdep_vm_ops; -	area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; +	area->vm_flags |= VM_DONTDUMP; +	if (!read) +		area->vm_flags |= VM_DONTEXPAND;  	area->vm_private_data = us122l;  	atomic_inc(&us122l->mmap_count);  out: @@ -533,7 +535,9 @@ static void snd_us122l_free(struct snd_card *card)  		snd_us122l_card_used[index] = 0;  } -static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) +static int usx2y_create_card(struct usb_device *device, +			     struct usb_interface *intf, +			     struct snd_card **cardp)  {  	int		dev;  	struct snd_card *card; @@ -544,8 +548,8 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)  			break;  	if (dev >= SNDRV_CARDS)  		return -ENODEV; -	err = snd_card_create(index[dev], id[dev], THIS_MODULE, -			      sizeof(struct us122l), &card); +	err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE, +			   sizeof(struct us122l), &card);  	if (err < 0)  		return err;  	snd_us122l_card_used[US122L(card)->card_index = dev] = 1; @@ -576,11 +580,10 @@ static int us122l_usb_probe(struct usb_interface *intf,  	struct snd_card *card;  	int err; -	err = usx2y_create_card(device, &card); +	err = usx2y_create_card(device, intf, &card);  	if (err < 0)  		return err; -	snd_card_set_dev(card, &intf->dev);  	if (!us122l_create_card(card)) {  		snd_card_free(card);  		return -EINVAL; diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index 5a51b18c50f..91e0e2a4808 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -332,7 +332,9 @@ static struct usb_device_id snd_usX2Y_usb_id_table[] = {  	{ /* terminator */ }  }; -static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp) +static int usX2Y_create_card(struct usb_device *device, +			     struct usb_interface *intf, +			     struct snd_card **cardp)  {  	int		dev;  	struct snd_card *	card; @@ -343,15 +345,15 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)  			break;  	if (dev >= SNDRV_CARDS)  		return -ENODEV; -	err = snd_card_create(index[dev], id[dev], THIS_MODULE, -			      sizeof(struct usX2Ydev), &card); +	err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE, +			   sizeof(struct usX2Ydev), &card);  	if (err < 0)  		return err;  	snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;  	card->private_free = snd_usX2Y_card_private_free;  	usX2Y(card)->dev = device;  	init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); -	mutex_init(&usX2Y(card)->prepare_mutex); +	mutex_init(&usX2Y(card)->pcm_mutex);  	INIT_LIST_HEAD(&usX2Y(card)->midi_list);  	strcpy(card->driver, "USB "NAME_ALLCAPS"");  	sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); @@ -382,10 +384,9 @@ static int usX2Y_usb_probe(struct usb_device *device,  	     le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))  		return -EINVAL; -	err = usX2Y_create_card(device, &card); +	err = usX2Y_create_card(device, intf, &card);  	if (err < 0)  		return err; -	snd_card_set_dev(card, &intf->dev);  	if ((err = usX2Y_hwdep_new(card, device)) < 0  ||  	    (err = snd_card_register(card)) < 0) {  		snd_card_free(card); diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h index e43c0a86441..6ae6b080693 100644 --- a/sound/usb/usx2y/usbusx2y.h +++ b/sound/usb/usx2y/usbusx2y.h @@ -36,7 +36,7 @@ struct usX2Ydev {  	unsigned int		rate,  				format;  	int			chip_status; -	struct mutex		prepare_mutex; +	struct mutex		pcm_mutex;  	struct us428ctls_sharedmem	*us428ctls_sharedmem;  	int			wait_iso_frame;  	wait_queue_head_t	us428ctls_wait_queue_head; diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 63fb5219f0f..a63330dd140 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -299,19 +299,6 @@ static void usX2Y_error_urb_status(struct usX2Ydev *usX2Y,  	usX2Y_clients_stop(usX2Y);  } -static void usX2Y_error_sequence(struct usX2Ydev *usX2Y, -				 struct snd_usX2Y_substream *subs, struct urb *urb) -{ -	snd_printk(KERN_ERR -"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" -"Most probably some urb of usb-frame %i is still missing.\n" -"Cause could be too long delays in usb-hcd interrupt handling.\n", -		   usb_get_current_frame_number(usX2Y->dev), -		   subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", -		   usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame); -	usX2Y_clients_stop(usX2Y); -} -  static void i_usX2Y_urb_complete(struct urb *urb)  {  	struct snd_usX2Y_substream *subs = urb->context; @@ -328,12 +315,9 @@ static void i_usX2Y_urb_complete(struct urb *urb)  		usX2Y_error_urb_status(usX2Y, subs, urb);  		return;  	} -	if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) -		subs->completed_urb = urb; -	else { -		usX2Y_error_sequence(usX2Y, subs, urb); -		return; -	} + +	subs->completed_urb = urb; +  	{  		struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],  			*playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; @@ -768,36 +752,44 @@ static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,  	unsigned int		rate = params_rate(hw_params);  	snd_pcm_format_t	format = params_format(hw_params);  	struct snd_card *card = substream->pstr->pcm->card; -	struct list_head *list; +	struct usX2Ydev	*dev = usX2Y(card); +	int i; +	mutex_lock(&usX2Y(card)->pcm_mutex);  	snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params); -	// all pcm substreams off one usX2Y have to operate at the same rate & format -	list_for_each(list, &card->devices) { -		struct snd_device *dev; -		struct snd_pcm *pcm; -		int s; -		dev = snd_device(list); -		if (dev->type != SNDRV_DEV_PCM) +	/* all pcm substreams off one usX2Y have to operate at the same +	 * rate & format +	 */ +	for (i = 0; i < dev->pcm_devs * 2; i++) { +		struct snd_usX2Y_substream *subs = dev->subs[i]; +		struct snd_pcm_substream *test_substream; + +		if (!subs) +			continue; +		test_substream = subs->pcm_substream; +		if (!test_substream || test_substream == substream || +		    !test_substream->runtime)  			continue; -		pcm = dev->device_data; -		for (s = 0; s < 2; ++s) { -			struct snd_pcm_substream *test_substream; -			test_substream = pcm->streams[s].substream; -			if (test_substream && test_substream != substream  && -			    test_substream->runtime && -			    ((test_substream->runtime->format && -			      test_substream->runtime->format != format) || -			     (test_substream->runtime->rate && -			      test_substream->runtime->rate != rate))) -				return -EINVAL; +		if ((test_substream->runtime->format && +		     test_substream->runtime->format != format) || +		    (test_substream->runtime->rate && +		     test_substream->runtime->rate != rate)) { +			err = -EINVAL; +			goto error;  		}  	} -	if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) { + +	err = snd_pcm_lib_malloc_pages(substream, +				       params_buffer_bytes(hw_params)); +	if (err < 0) {  		snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n",  			   substream, params_buffer_bytes(hw_params), err); -		return err; +		goto error;  	} -	return 0; + + error: +	mutex_unlock(&usX2Y(card)->pcm_mutex); +	return err;  }  /* @@ -807,7 +799,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)  {  	struct snd_pcm_runtime *runtime = substream->runtime;  	struct snd_usX2Y_substream *subs = runtime->private_data; -	mutex_lock(&subs->usX2Y->prepare_mutex); +	mutex_lock(&subs->usX2Y->pcm_mutex);  	snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);  	if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { @@ -828,7 +820,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)  			usX2Y_urbs_release(subs);  		}  	} -	mutex_unlock(&subs->usX2Y->prepare_mutex); +	mutex_unlock(&subs->usX2Y->pcm_mutex);  	return snd_pcm_lib_free_pages(substream);  }  /* @@ -845,7 +837,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)  	int err = 0;  	snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream); -	mutex_lock(&usX2Y->prepare_mutex); +	mutex_lock(&usX2Y->pcm_mutex);  	usX2Y_subs_prepare(subs);  // Start hardware streams  // SyncStream first.... @@ -865,7 +857,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)  		err = usX2Y_urbs_start(subs);   up_prepare_mutex: -	mutex_unlock(&usX2Y->prepare_mutex); +	mutex_unlock(&usX2Y->pcm_mutex);  	return err;  } diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index f2a1acdc4d8..90766a92e7f 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -244,13 +244,8 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)  		usX2Y_error_urb_status(usX2Y, subs, urb);  		return;  	} -	if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) -		subs->completed_urb = urb; -	else { -		usX2Y_error_sequence(usX2Y, subs, urb); -		return; -	} +	subs->completed_urb = urb;  	capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];  	capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];  	playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; @@ -363,7 +358,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)  	struct snd_pcm_runtime *runtime = substream->runtime;  	struct snd_usX2Y_substream *subs = runtime->private_data,  		*cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; -	mutex_lock(&subs->usX2Y->prepare_mutex); +	mutex_lock(&subs->usX2Y->pcm_mutex);  	snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);  	if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { @@ -392,7 +387,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)  				usX2Y_usbpcm_urbs_release(cap_subs2);  		}  	} -	mutex_unlock(&subs->usX2Y->prepare_mutex); +	mutex_unlock(&subs->usX2Y->pcm_mutex);  	return snd_pcm_lib_free_pages(substream);  } @@ -498,7 +493,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)  		memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm));  	} -	mutex_lock(&usX2Y->prepare_mutex); +	mutex_lock(&usX2Y->pcm_mutex);  	usX2Y_subs_prepare(subs);  // Start hardware streams  // SyncStream first.... @@ -539,7 +534,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)  		usX2Y->hwdep_pcm_shm->capture_iso_start = -1;   up_prepare_mutex: -	mutex_unlock(&usX2Y->prepare_mutex); +	mutex_unlock(&usX2Y->pcm_mutex);  	return err;  } @@ -605,59 +600,30 @@ static struct snd_pcm_ops snd_usX2Y_usbpcm_ops =  }; -static int usX2Y_pcms_lock_check(struct snd_card *card) +static int usX2Y_pcms_busy_check(struct snd_card *card)  { -	struct list_head *list; -	struct snd_device *dev; -	struct snd_pcm *pcm; -	int err = 0; -	list_for_each(list, &card->devices) { -		dev = snd_device(list); -		if (dev->type != SNDRV_DEV_PCM) -			continue; -		pcm = dev->device_data; -		mutex_lock(&pcm->open_mutex); -	} -	list_for_each(list, &card->devices) { -		int s; -		dev = snd_device(list); -		if (dev->type != SNDRV_DEV_PCM) -			continue; -		pcm = dev->device_data; -		for (s = 0; s < 2; ++s) { -			struct snd_pcm_substream *substream; -			substream = pcm->streams[s].substream; -			if (substream && SUBSTREAM_BUSY(substream)) -				err = -EBUSY; -		} -	} -	return err; -} - +	struct usX2Ydev	*dev = usX2Y(card); +	int i; -static void usX2Y_pcms_unlock(struct snd_card *card) -{ -	struct list_head *list; -	struct snd_device *dev; -	struct snd_pcm *pcm; -	list_for_each(list, &card->devices) { -		dev = snd_device(list); -		if (dev->type != SNDRV_DEV_PCM) -			continue; -		pcm = dev->device_data; -		mutex_unlock(&pcm->open_mutex); +	for (i = 0; i < dev->pcm_devs * 2; i++) { +		struct snd_usX2Y_substream *subs = dev->subs[i]; +		if (subs && subs->pcm_substream && +		    SUBSTREAM_BUSY(subs->pcm_substream)) +			return -EBUSY;  	} +	return 0;  } -  static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)  { -	// we need to be the first   	struct snd_card *card = hw->card; -	int err = usX2Y_pcms_lock_check(card); -	if (0 == err) +	int err; + +	mutex_lock(&usX2Y(card)->pcm_mutex); +	err = usX2Y_pcms_busy_check(card); +	if (!err)  		usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS; -	usX2Y_pcms_unlock(card); +	mutex_unlock(&usX2Y(card)->pcm_mutex);  	return err;  } @@ -665,10 +631,13 @@ static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)  static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)  {  	struct snd_card *card = hw->card; -	int err = usX2Y_pcms_lock_check(card); -	if (0 == err) +	int err; + +	mutex_lock(&usX2Y(card)->pcm_mutex); +	err = usX2Y_pcms_busy_check(card); +	if (!err)  		usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS; -	usX2Y_pcms_unlock(card); +	mutex_unlock(&usX2Y(card)->pcm_mutex);  	return err;  }  | 
