1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * usbusy2y.c - ALSA USB US-428 Driver 4 * 5 2005-04-14 Karsten Wiese 6 Version 0.8.7.2: 7 Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom. 8 Tested ok with kernel 2.6.12-rc2. 9 10 2004-12-14 Karsten Wiese 11 Version 0.8.7.1: 12 snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open. 13 14 2004-12-02 Karsten Wiese 15 Version 0.8.7: 16 Use macro usb_maxpacket() for portability. 17 18 2004-10-26 Karsten Wiese 19 Version 0.8.6: 20 wake_up() process waiting in usX2Y_urbs_start() on error. 21 22 2004-10-21 Karsten Wiese 23 Version 0.8.5: 24 nrpacks is runtime or compiletime configurable now with tested values from 1 to 4. 25 26 2004-10-03 Karsten Wiese 27 Version 0.8.2: 28 Avoid any possible racing while in prepare callback. 29 30 2004-09-30 Karsten Wiese 31 Version 0.8.0: 32 Simplified things and made ohci work again. 33 34 2004-09-20 Karsten Wiese 35 Version 0.7.3: 36 Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb(). 37 38 2004-07-13 Karsten Wiese 39 Version 0.7.1: 40 Don't sleep in START/STOP callbacks anymore. 41 us428 channels C/D not handled just for this version, sorry. 42 43 2004-06-21 Karsten Wiese 44 Version 0.6.4: 45 Temporarely suspend midi input 46 to sanely call usb_set_interface() when setting format. 47 48 2004-06-12 Karsten Wiese 49 Version 0.6.3: 50 Made it thus the following rule is enforced: 51 "All pcm substreams of one usX2Y have to operate at the same rate & format." 52 53 2004-04-06 Karsten Wiese 54 Version 0.6.0: 55 Runs on 2.6.5 kernel without any "--with-debug=" things. 56 us224 reported running. 57 58 2004-01-14 Karsten Wiese 59 Version 0.5.1: 60 Runs with 2.6.1 kernel. 61 62 2003-12-30 Karsten Wiese 63 Version 0.4.1: 64 Fix 24Bit 4Channel capturing for the us428. 65 66 2003-11-27 Karsten Wiese, Martin Langer 67 Version 0.4: 68 us122 support. 69 us224 could be tested by uncommenting the sections containing USB_ID_US224 70 71 2003-11-03 Karsten Wiese 72 Version 0.3: 73 24Bit support. 74 "arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works. 75 76 2003-08-22 Karsten Wiese 77 Version 0.0.8: 78 Removed EZUSB Firmware. First Stage Firmwaredownload is now done by tascam-firmware downloader. 79 See: 80 http://usb-midi-fw.sourceforge.net/tascam-firmware.tar.gz 81 82 2003-06-18 Karsten Wiese 83 Version 0.0.5: 84 changed to compile with kernel 2.4.21 and alsa 0.9.4 85 86 2002-10-16 Karsten Wiese 87 Version 0.0.4: 88 compiles again with alsa-current. 89 USB_ISO_ASAP not used anymore (most of the time), instead 90 urb->start_frame is calculated here now, some calls inside usb-driver don't need to happen anymore. 91 92 To get the best out of this: 93 Disable APM-support in the kernel as APM-BIOS calls (once each second) hard disable interrupt for many precious milliseconds. 94 This helped me much on my slowish PII 400 & PIII 500. 95 ACPI yet untested but might cause the same bad behaviour. 96 Use a kernel with lowlatency and preemptiv patches applied. 97 To autoload snd-usb-midi append a line 98 post-install snd-usb-us428 modprobe snd-usb-midi 99 to /etc/modules.conf. 100 101 known problems: 102 sliders, knobs, lights not yet handled except MASTER Volume slider. 103 "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does. 104 KDE3: "Enable full duplex operation" deadlocks. 105 106 107 2002-08-31 Karsten Wiese 108 Version 0.0.3: audio also simplex; 109 simplifying: iso urbs only 1 packet, melted structs. 110 ASYNC_UNLINK not used anymore: no more crashes so far..... 111 for alsa 0.9 rc3. 112 113 2002-08-09 Karsten Wiese 114 Version 0.0.2: midi works with snd-usb-midi, audio (only fullduplex now) with i.e. bristol. 115 The firmware has been sniffed from win2k us-428 driver 3.09. 116 117 * Copyright (c) 2002 - 2004 Karsten Wiese 118 */ 119 120 #include <linux/init.h> 121 #include <linux/module.h> 122 #include <linux/moduleparam.h> 123 #include <linux/slab.h> 124 #include <linux/interrupt.h> 125 #include <linux/usb.h> 126 #include <sound/core.h> 127 #include <sound/initval.h> 128 #include <sound/pcm.h> 129 130 #include <sound/rawmidi.h> 131 #include "usx2y.h" 132 #include "usbusx2y.h" 133 #include "usX2Yhwdep.h" 134 135 136 137 MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>"); 138 MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2"); 139 MODULE_LICENSE("GPL"); 140 MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604),"NAME_ALLCAPS"(0x8001)(0x8005)(0x8007)}}"); 141 142 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 143 static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 144 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 145 146 module_param_array(index, int, NULL, 0444); 147 MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); 148 module_param_array(id, charp, NULL, 0444); 149 MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS"."); 150 module_param_array(enable, bool, NULL, 0444); 151 MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS"."); 152 153 154 static int snd_usX2Y_card_used[SNDRV_CARDS]; 155 156 static void usX2Y_usb_disconnect(struct usb_device* usb_device, void* ptr); 157 static void snd_usX2Y_card_private_free(struct snd_card *card); 158 159 /* 160 * pipe 4 is used for switching the lamps, setting samplerate, volumes .... 161 */ 162 static void i_usX2Y_Out04Int(struct urb *urb) 163 { 164 #ifdef CONFIG_SND_DEBUG 165 if (urb->status) { 166 int i; 167 struct usX2Ydev *usX2Y = urb->context; 168 for (i = 0; i < 10 && usX2Y->AS04.urb[i] != urb; i++); 169 snd_printdd("i_usX2Y_Out04Int() urb %i status=%i\n", i, urb->status); 170 } 171 #endif 172 } 173 174 static void i_usX2Y_In04Int(struct urb *urb) 175 { 176 int err = 0; 177 struct usX2Ydev *usX2Y = urb->context; 178 struct us428ctls_sharedmem *us428ctls = usX2Y->us428ctls_sharedmem; 179 180 usX2Y->In04IntCalls++; 181 182 if (urb->status) { 183 snd_printdd("Interrupt Pipe 4 came back with status=%i\n", urb->status); 184 return; 185 } 186 187 // printk("%i:0x%02X ", 8, (int)((unsigned char*)usX2Y->In04Buf)[8]); Master volume shows 0 here if fader is at max during boot ?!? 188 if (us428ctls) { 189 int diff = -1; 190 if (-2 == us428ctls->CtlSnapShotLast) { 191 diff = 0; 192 memcpy(usX2Y->In04Last, usX2Y->In04Buf, sizeof(usX2Y->In04Last)); 193 us428ctls->CtlSnapShotLast = -1; 194 } else { 195 int i; 196 for (i = 0; i < 21; i++) { 197 if (usX2Y->In04Last[i] != ((char*)usX2Y->In04Buf)[i]) { 198 if (diff < 0) 199 diff = i; 200 usX2Y->In04Last[i] = ((char*)usX2Y->In04Buf)[i]; 201 } 202 } 203 } 204 if (0 <= diff) { 205 int n = us428ctls->CtlSnapShotLast + 1; 206 if (n >= N_us428_ctl_BUFS || n < 0) 207 n = 0; 208 memcpy(us428ctls->CtlSnapShot + n, usX2Y->In04Buf, sizeof(us428ctls->CtlSnapShot[0])); 209 us428ctls->CtlSnapShotDiffersAt[n] = diff; 210 us428ctls->CtlSnapShotLast = n; 211 wake_up(&usX2Y->us428ctls_wait_queue_head); 212 } 213 } 214 215 216 if (usX2Y->US04) { 217 if (0 == usX2Y->US04->submitted) 218 do { 219 err = usb_submit_urb(usX2Y->US04->urb[usX2Y->US04->submitted++], GFP_ATOMIC); 220 } while (!err && usX2Y->US04->submitted < usX2Y->US04->len); 221 } else 222 if (us428ctls && us428ctls->p4outLast >= 0 && us428ctls->p4outLast < N_us428_p4out_BUFS) { 223 if (us428ctls->p4outLast != us428ctls->p4outSent) { 224 int j, send = us428ctls->p4outSent + 1; 225 if (send >= N_us428_p4out_BUFS) 226 send = 0; 227 for (j = 0; j < URBS_AsyncSeq && !err; ++j) 228 if (0 == usX2Y->AS04.urb[j]->status) { 229 struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost. 230 usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->dev, 231 usb_sndbulkpipe(usX2Y->dev, 0x04), &p4out->val.vol, 232 p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5, 233 i_usX2Y_Out04Int, usX2Y); 234 err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC); 235 us428ctls->p4outSent = send; 236 break; 237 } 238 } 239 } 240 241 if (err) 242 snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err); 243 244 urb->dev = usX2Y->dev; 245 usb_submit_urb(urb, GFP_ATOMIC); 246 } 247 248 /* 249 * Prepare some urbs 250 */ 251 int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y) 252 { 253 int err = 0, 254 i; 255 256 usX2Y->AS04.buffer = kmalloc_array(URBS_AsyncSeq, 257 URB_DataLen_AsyncSeq, GFP_KERNEL); 258 if (NULL == usX2Y->AS04.buffer) { 259 err = -ENOMEM; 260 } else 261 for (i = 0; i < URBS_AsyncSeq; ++i) { 262 if (NULL == (usX2Y->AS04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) { 263 err = -ENOMEM; 264 break; 265 } 266 usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->dev, 267 usb_sndbulkpipe(usX2Y->dev, 0x04), 268 usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0, 269 i_usX2Y_Out04Int, usX2Y 270 ); 271 err = usb_urb_ep_type_check(usX2Y->AS04.urb[i]); 272 if (err < 0) 273 break; 274 } 275 return err; 276 } 277 278 int usX2Y_In04_init(struct usX2Ydev *usX2Y) 279 { 280 if (! (usX2Y->In04urb = usb_alloc_urb(0, GFP_KERNEL))) 281 return -ENOMEM; 282 283 if (! (usX2Y->In04Buf = kmalloc(21, GFP_KERNEL))) 284 return -ENOMEM; 285 286 init_waitqueue_head(&usX2Y->In04WaitQueue); 287 usb_fill_int_urb(usX2Y->In04urb, usX2Y->dev, usb_rcvintpipe(usX2Y->dev, 0x4), 288 usX2Y->In04Buf, 21, 289 i_usX2Y_In04Int, usX2Y, 290 10); 291 if (usb_urb_ep_type_check(usX2Y->In04urb)) 292 return -EINVAL; 293 return usb_submit_urb(usX2Y->In04urb, GFP_KERNEL); 294 } 295 296 static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S) 297 { 298 int i; 299 for (i = 0; i < URBS_AsyncSeq; ++i) { 300 usb_kill_urb(S->urb[i]); 301 usb_free_urb(S->urb[i]); 302 S->urb[i] = NULL; 303 } 304 kfree(S->buffer); 305 } 306 307 308 static const struct usb_device_id snd_usX2Y_usb_id_table[] = { 309 { 310 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 311 .idVendor = 0x1604, 312 .idProduct = USB_ID_US428 313 }, 314 { 315 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 316 .idVendor = 0x1604, 317 .idProduct = USB_ID_US122 318 }, 319 { 320 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 321 .idVendor = 0x1604, 322 .idProduct = USB_ID_US224 323 }, 324 { /* terminator */ } 325 }; 326 327 static int usX2Y_create_card(struct usb_device *device, 328 struct usb_interface *intf, 329 struct snd_card **cardp) 330 { 331 int dev; 332 struct snd_card * card; 333 int err; 334 335 for (dev = 0; dev < SNDRV_CARDS; ++dev) 336 if (enable[dev] && !snd_usX2Y_card_used[dev]) 337 break; 338 if (dev >= SNDRV_CARDS) 339 return -ENODEV; 340 err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE, 341 sizeof(struct usX2Ydev), &card); 342 if (err < 0) 343 return err; 344 snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1; 345 card->private_free = snd_usX2Y_card_private_free; 346 usX2Y(card)->dev = device; 347 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); 348 mutex_init(&usX2Y(card)->pcm_mutex); 349 INIT_LIST_HEAD(&usX2Y(card)->midi_list); 350 strcpy(card->driver, "USB "NAME_ALLCAPS""); 351 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); 352 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", 353 card->shortname, 354 le16_to_cpu(device->descriptor.idVendor), 355 le16_to_cpu(device->descriptor.idProduct), 356 0,//us428(card)->usbmidi.ifnum, 357 usX2Y(card)->dev->bus->busnum, usX2Y(card)->dev->devnum 358 ); 359 *cardp = card; 360 return 0; 361 } 362 363 364 static int usX2Y_usb_probe(struct usb_device *device, 365 struct usb_interface *intf, 366 const struct usb_device_id *device_id, 367 struct snd_card **cardp) 368 { 369 int err; 370 struct snd_card * card; 371 372 *cardp = NULL; 373 if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || 374 (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && 375 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && 376 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) 377 return -EINVAL; 378 379 err = usX2Y_create_card(device, intf, &card); 380 if (err < 0) 381 return err; 382 if ((err = usX2Y_hwdep_new(card, device)) < 0 || 383 (err = snd_card_register(card)) < 0) { 384 snd_card_free(card); 385 return err; 386 } 387 *cardp = card; 388 return 0; 389 } 390 391 /* 392 * new 2.5 USB kernel API 393 */ 394 static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id) 395 { 396 struct snd_card *card; 397 int err; 398 399 err = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id, &card); 400 if (err < 0) 401 return err; 402 dev_set_drvdata(&intf->dev, card); 403 return 0; 404 } 405 406 static void snd_usX2Y_disconnect(struct usb_interface *intf) 407 { 408 usX2Y_usb_disconnect(interface_to_usbdev(intf), 409 usb_get_intfdata(intf)); 410 } 411 412 MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table); 413 static struct usb_driver snd_usX2Y_usb_driver = { 414 .name = "snd-usb-usx2y", 415 .probe = snd_usX2Y_probe, 416 .disconnect = snd_usX2Y_disconnect, 417 .id_table = snd_usX2Y_usb_id_table, 418 }; 419 420 static void snd_usX2Y_card_private_free(struct snd_card *card) 421 { 422 kfree(usX2Y(card)->In04Buf); 423 usb_free_urb(usX2Y(card)->In04urb); 424 if (usX2Y(card)->us428ctls_sharedmem) 425 free_pages_exact(usX2Y(card)->us428ctls_sharedmem, 426 sizeof(*usX2Y(card)->us428ctls_sharedmem)); 427 if (usX2Y(card)->card_index >= 0 && usX2Y(card)->card_index < SNDRV_CARDS) 428 snd_usX2Y_card_used[usX2Y(card)->card_index] = 0; 429 } 430 431 /* 432 * Frees the device. 433 */ 434 static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr) 435 { 436 if (ptr) { 437 struct snd_card *card = ptr; 438 struct usX2Ydev *usX2Y = usX2Y(card); 439 struct list_head *p; 440 usX2Y->chip_status = USX2Y_STAT_CHIP_HUP; 441 usX2Y_unlinkSeq(&usX2Y->AS04); 442 usb_kill_urb(usX2Y->In04urb); 443 snd_card_disconnect(card); 444 /* release the midi resources */ 445 list_for_each(p, &usX2Y->midi_list) { 446 snd_usbmidi_disconnect(p); 447 } 448 if (usX2Y->us428ctls_sharedmem) 449 wake_up(&usX2Y->us428ctls_wait_queue_head); 450 snd_card_free(card); 451 } 452 } 453 454 module_usb_driver(snd_usX2Y_usb_driver); 455