mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
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:
parent
78f28b7c55
commit
4f272341c7
1 changed files with 67 additions and 8 deletions
|
@ -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 */ }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue