Skip to content

Commit

Permalink
ALSA: snd-usb-us122l: add support for US-144
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tobias Hansen authored and Takashi Iwai committed Sep 22, 2009
1 parent 78f28b7 commit 4f27234
Showing 1 changed file with 67 additions and 8 deletions.
75 changes: 67 additions & 8 deletions sound/usb/usx2y/us122l.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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 */ }
};

Expand Down

0 comments on commit 4f27234

Please sign in to comment.