The Tascam US-122L (and US-144) under Linux
This page is about getting the Tascam US-122L (and US-144) work under Linux. If you have some more information, feel free to mail me at samuel.mimram@ens-lyon.org.
This page was last updated on 2009-10-14.
Happy news
Support for the US-122L has now been integrated to the kernel. In order to use it you need libasound2-plugins and use the usb_stream:US122L interface in jack. You first need to add the following in .asoundrc:
pcm.!usb_stream {
@args [ CARD ]
@args.CARD {
type string
default "2"
}
type usb_stream
card $CARD
}
ctl.!usb_stream {
@args [ CARD ]
@args.CARD {
type string
default "2"
}
type hw
card $CARD
}
A few good links
- A more up-to-date webpage on the subject.
- A tutorial explaining how to apply and use the patch for US-122L.
- A tutorial explaining how to use the US-144 under Ubuntu.
Patch for ALSA (and linux kernel)
- Karsten Wiese has submitted a patch to add ALSA support for US-122L! Unfortunately, it seems to be difficult to install and make it work for now...
- An updated version of the patch is available.
- A patch for US-144L was made by Tobias Hansen.
Is the US-122L using standard protocols?
His predecessor, the US-122, has an alsa driver but has been discontinued. Loading a firmware was needed to get it running.
The hardware has apparently changed much between the US-122 and the
US-122L. On
the request of
Derek Pidhirnyj, Martin Langer, who developed
the firmware for the US-122,
has looked at the usbsnoop logs and lsusb
output. He thinks that the US-122L uses a different chip compared to the old
usx2y boxes, and that firmware is not loaded at connection. Possibly the
device fits better into the USB audio specification (snd-usb-audio
driver) and may only need an entry into usbquirks.h (and
possibly also usbaudio.c and usbaudio.h).
Effectively, the logs show that the driver does hardly
only isochronous
transfers of data.
For example, here is a data reception:
[367 ms] <<< URB 33 coming back <<<
-- URB_FUNCTION_ISOCH_TRANSFER:
PipeHandle = 896f89bc [endpoint 0x00000081]
TransferFlags = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK
TransferBufferLength = 00000528
TransferBuffer = 89143000
TransferBufferMDL = 897078d0
StartFrame = 00037009
NumberOfPackets = 00000028
ErrorCount = 00000000
IsoPacket[0].Offset = 0
IsoPacket[0].Length = 30
IsoPacket[0].Status = 00000000
00000000: 75 fb 00 5b f4 00 39 fd 00 d1 f4 00 c7 fb 00 1b
00000010: f6 00 03 fc 00 da f5 00 a6 fb 00 83 f6 00
IsoPacket[1].Offset = 78
IsoPacket[1].Length = 36
IsoPacket[1].Status = 00000000
00000000: 8d f9 00 26 f6 00 8c fb 00 9c f5 00 7d fb 00 b9
00000010: f6 00 bd fc 00 a2 f6 00 03 fc 00 38 f6 00 1a fb
00000020: 00 e8 f6 00
IsoPacket[2].Offset = 156
IsoPacket[2].Length = 30
IsoPacket[2].Status = 00000000
00000000: b1 fc 00 ed f5 00 72 fb 00 2d f6 00 ed fa 00 21
00000010: f6 00 d9 fb 00 2a f5 00 61 fc 00 23 f7 00
IsoPacket[3].Offset = 234
IsoPacket[3].Length = 36
IsoPacket[3].Status = 00000000
00000000: ae fa 00 90 f5 00 47 fb 00 66 f6 00 5f fb 00 7a
00000010: f6 00 7e fc 00 74 f6 00 a0 fb 00 d8 f7 00 8f f9
00000020: 00 bb f7 00
[...]
Notice that by grouping the bytes by series of 3 you get similar values, and that the rightmost byte does not change much. This makes me think that the format of samples is S24_3LE (i.e. stereo, 24 bits per sample, grouped by 3 bytes, in little endian).
This lead me to the following entry in usbquirks.h:
{
USB_DEVICE(0x644, 0x800e),
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
.vendor_name = "Tascam",
.product_name = "US-122L",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_COMPOSITE,
.data = (const struct snd_usb_audio_quirk[]) {
{
.ifnum = 0,
.type = QUIRK_IGNORE_INTERFACE
},
{
.ifnum = 1,
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
.data = & (const struct audioformat) {
.format = SNDRV_PCM_FORMAT_S24_3LE,
.channels = 2,
.iface = 1,
.altsetting = 1,
.altset_idx = 1,
.attributes = 0,
.endpoint = 0x02,
.ep_attr = 0x01,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 44100,
.rate_max = 44100,
}
},
{
.ifnum = -1
}
}
}
},
The good news is that aplay now accepts to play files using command lines like aplay --device=hw:1,0 -f S24_3LE -r 44100 -c 2 /tmp/test.raw. The bad news is that it only produces a very low noise... If someone has comments about how to improve this, I'd be glad to hear them!
An other idea would be to modify the usx2y module. I've made a simple patch to add support for the US-122L to this module but unfortunately, it makes my linux slow down and eventually crash after a few seconds as soon as I plug the US-122L...
Technical facts
A nice people opened up its US-144 and wrote a webpage about what he found inside. Maybe is it of interest for some of you?
Output of lsusb -vv:
Bus 002 Device 002: ID 0644:800e TEAC Corp.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0644 TEAC Corp.
idProduct 0x800e
bcdDevice 1.00
iManufacturer 1 TASCAM
iProduct 2 US-122L
iSerial 3 no serial number
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 72
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
MaxPower 480mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 4
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0126 1x 294 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0126 1x 294 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0009 1x 9 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
bNumConfigurations 1
Infos given by usbfs:
T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#= 16 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0644 ProdID=800e Rev= 1.00
S: Manufacturer=TASCAM
S: Product=US-122L
S: SerialNumber=no serial number
C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=480mA
I: If#= 0 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none)
I: If#= 1 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none)
I: If#= 1 Alt= 1 #EPs= 4 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none)
E: Ad=81(I) Atr=05(Isoc) MxPS= 78 Ivl=125us
E: Ad=02(O) Atr=05(Isoc) MxPS= 78 Ivl=125us
E: Ad=83(I) Atr=02(Bulk) MxPS= 9 Ivl=0ms
E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=500us