ALSA: snd-usb-us122l: add support for US-144

Adds support for US-144 when attached on USB1.1.
Unlike the US-122L it uses both USB interfaces 0 and 1.

Signed-off-by: Tobias Hansen <Tobias.Hansen@physik.uni-hamburg.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Tobias Hansen 2009-09-22 16:52:08 +02:00 committed by Takashi Iwai
parent 78f28b7c55
commit 4f272341c7
1 changed files with 67 additions and 8 deletions

View File

@ -66,6 +66,28 @@ static int us122l_create_usbmidi(struct snd_card *card)
iface, &quirk);
}
static int us144_create_usbmidi(struct snd_card *card)
{
static struct snd_usb_midi_endpoint_info quirk_data = {
.out_ep = 4,
.in_ep = 3,
.out_cables = 0x001,
.in_cables = 0x001
};
static struct snd_usb_audio_quirk quirk = {
.vendor_name = "US144",
.product_name = NAME_ALLCAPS,
.ifnum = 0,
.type = QUIRK_MIDI_US122L,
.data = &quirk_data
};
struct usb_device *dev = US122L(card)->chip.dev;
struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
return snd_usb_create_midi_interface(&US122L(card)->chip,
iface, &quirk);
}
/*
* Wrapper for usb_control_msg().
* Allocates a temp buffer to prevent dmaing from/to the stack.
@ -171,6 +193,11 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
if (!us122l->first)
us122l->first = file;
if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
iface = usb_ifnum_to_if(us122l->chip.dev, 0);
usb_autopm_get_interface(iface);
}
iface = usb_ifnum_to_if(us122l->chip.dev, 1);
usb_autopm_get_interface(iface);
return 0;
@ -179,8 +206,14 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
{
struct us122l *us122l = hw->private_data;
struct usb_interface *iface = usb_ifnum_to_if(us122l->chip.dev, 1);
struct usb_interface *iface;
snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
iface = usb_ifnum_to_if(us122l->chip.dev, 0);
usb_autopm_put_interface(iface);
}
iface = usb_ifnum_to_if(us122l->chip.dev, 1);
usb_autopm_put_interface(iface);
if (us122l->first == file)
us122l->first = NULL;
@ -443,6 +476,13 @@ static bool us122l_create_card(struct snd_card *card)
int err;
struct us122l *us122l = US122L(card);
if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
err = usb_set_interface(us122l->chip.dev, 0, 1);
if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n");
return false;
}
}
err = usb_set_interface(us122l->chip.dev, 1, 1);
if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n");
@ -455,7 +495,10 @@ static bool us122l_create_card(struct snd_card *card)
if (!us122l_start(us122l, 44100, 256))
return false;
err = us122l_create_usbmidi(card);
if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144)
err = us144_create_usbmidi(card);
else
err = us122l_create_usbmidi(card);
if (err < 0) {
snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
us122l_stop(us122l);
@ -542,6 +585,7 @@ static int us122l_usb_probe(struct usb_interface *intf,
return err;
}
usb_get_intf(usb_ifnum_to_if(device, 0));
usb_get_dev(device);
*cardp = card;
return 0;
@ -550,9 +594,16 @@ static int us122l_usb_probe(struct usb_interface *intf,
static int snd_us122l_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *device = interface_to_usbdev(intf);
struct snd_card *card;
int err;
if (device->descriptor.idProduct == USB_ID_US144
&& device->speed == USB_SPEED_HIGH) {
snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
return -ENOENT;
}
snd_printdd(KERN_DEBUG"%p:%i\n",
intf, intf->cur_altsetting->desc.bInterfaceNumber);
if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
@ -591,7 +642,8 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
snd_usbmidi_disconnect(p);
}
usb_put_intf(intf);
usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 0));
usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 1));
usb_put_dev(us122l->chip.dev);
while (atomic_read(&us122l->mmap_count))
@ -642,6 +694,13 @@ static int snd_us122l_resume(struct usb_interface *intf)
mutex_lock(&us122l->mutex);
/* needed, doesn't restart without: */
if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
err = usb_set_interface(us122l->chip.dev, 0, 1);
if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n");
goto unlock;
}
}
err = usb_set_interface(us122l->chip.dev, 1, 1);
if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n");
@ -675,11 +734,11 @@ static struct usb_device_id snd_us122l_usb_id_table[] = {
.idVendor = 0x0644,
.idProduct = USB_ID_US122L
},
/* { */ /* US-144 maybe works when @USB1.1. Untested. */
/* .match_flags = USB_DEVICE_ID_MATCH_DEVICE, */
/* .idVendor = 0x0644, */
/* .idProduct = USB_ID_US144 */
/* }, */
{ /* US-144 only works at USB1.1! Disable module ehci-hcd. */
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x0644,
.idProduct = USB_ID_US144
},
{ /* terminator */ }
};