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 141 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 142 static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 143 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 144 145 module_param_array(index, int, NULL, 0444); 146 MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); 147 module_param_array(id, charp, NULL, 0444); 148 MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS"."); 149 module_param_array(enable, bool, NULL, 0444); 150 MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS"."); 151 152 153 static int snd_usX2Y_card_used[SNDRV_CARDS]; 154 155 static void usX2Y_usb_disconnect(struct usb_device* usb_device, void* ptr); 156 static void snd_usX2Y_card_private_free(struct snd_card *card); 157 158 /* 159 * pipe 4 is used for switching the lamps, setting samplerate, volumes .... 160 */ 161 static void i_usX2Y_Out04Int(struct urb *urb) 162 { 163 #ifdef CONFIG_SND_DEBUG 164 if (urb->status) { 165 int i; 166 struct usX2Ydev *usX2Y = urb->context; 167 for (i = 0; i < 10 && usX2Y->AS04.urb[i] != urb; i++); 168 snd_printdd("i_usX2Y_Out04Int() urb %i status=%i\n", i, urb->status); 169 } 170 #endif 171 } 172 173 static void i_usX2Y_In04Int(struct urb *urb) 174 { 175 int err = 0; 176 struct usX2Ydev *usX2Y = urb->context; 177 struct us428ctls_sharedmem *us428ctls = usX2Y->us428ctls_sharedmem; 178 179 usX2Y->In04IntCalls++; 180 181 if (urb->status) { 182 snd_printdd("Interrupt Pipe 4 came back with status=%i\n", urb->status); 183 return; 184 } 185 186 // printk("%i:0x%02X ", 8, (int)((unsigned char*)usX2Y->In04Buf)[8]); Master volume shows 0 here if fader is at max during boot ?!? 187 if (us428ctls) { 188 int diff = -1; 189 if (-2 == us428ctls->CtlSnapShotLast) { 190 diff = 0; 191 memcpy(usX2Y->In04Last, usX2Y->In04Buf, sizeof(usX2Y->In04Last)); 192 us428ctls->CtlSnapShotLast = -1; 193 } else { 194 int i; 195 for (i = 0; i < 21; i++) { 196 if (usX2Y->In04Last[i] != ((char*)usX2Y->In04Buf)[i]) { 197 if (diff < 0) 198 diff = i; 199 usX2Y->In04Last[i] = ((char*)usX2Y->In04Buf)[i]; 200 } 201 } 202 } 203 if (0 <= diff) { 204 int n = us428ctls->CtlSnapShotLast + 1; 205 if (n >= N_us428_ctl_BUFS || n < 0) 206 n = 0; 207 memcpy(us428ctls->CtlSnapShot + n, usX2Y->In04Buf, sizeof(us428ctls->CtlSnapShot[0])); 208 us428ctls->CtlSnapShotDiffersAt[n] = diff; 209 us428ctls->CtlSnapShotLast = n; 210 wake_up(&usX2Y->us428ctls_wait_queue_head); 211 } 212 } 213 214 215 if (usX2Y->US04) { 216 if (0 == usX2Y->US04->submitted) 217 do { 218 err = usb_submit_urb(usX2Y->US04->urb[usX2Y->US04->submitted++], GFP_ATOMIC); 219 } while (!err && usX2Y->US04->submitted < usX2Y->US04->len); 220 } else 221 if (us428ctls && us428ctls->p4outLast >= 0 && us428ctls->p4outLast < N_us428_p4out_BUFS) { 222 if (us428ctls->p4outLast != us428ctls->p4outSent) { 223 int j, send = us428ctls->p4outSent + 1; 224 if (send >= N_us428_p4out_BUFS) 225 send = 0; 226 for (j = 0; j < URBS_AsyncSeq && !err; ++j) 227 if (0 == usX2Y->AS04.urb[j]->status) { 228 struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost. 229 usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->dev, 230 usb_sndbulkpipe(usX2Y->dev, 0x04), &p4out->val.vol, 231 p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5, 232 i_usX2Y_Out04Int, usX2Y); 233 err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC); 234 us428ctls->p4outSent = send; 235 break; 236 } 237 } 238 } 239 240 if (err) 241 snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err); 242 243 urb->dev = usX2Y->dev; 244 usb_submit_urb(urb, GFP_ATOMIC); 245 } 246 247 /* 248 * Prepare some urbs 249 */ 250 int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y) 251 { 252 int err = 0, 253 i; 254 255 usX2Y->AS04.buffer = kmalloc_array(URBS_AsyncSeq, 256 URB_DataLen_AsyncSeq, GFP_KERNEL); 257 if (NULL == usX2Y->AS04.buffer) { 258 err = -ENOMEM; 259 } else 260 for (i = 0; i < URBS_AsyncSeq; ++i) { 261 if (NULL == (usX2Y->AS04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) { 262 err = -ENOMEM; 263 break; 264 } 265 usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->dev, 266 usb_sndbulkpipe(usX2Y->dev, 0x04), 267 usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0, 268 i_usX2Y_Out04Int, usX2Y 269 ); 270 err = usb_urb_ep_type_check(usX2Y->AS04.urb[i]); 271 if (err < 0) 272 break; 273 } 274 return err; 275 } 276 277 int usX2Y_In04_init(struct usX2Ydev *usX2Y) 278 { 279 if (! (usX2Y->In04urb = usb_alloc_urb(0, GFP_KERNEL))) 280 return -ENOMEM; 281 282 if (! (usX2Y->In04Buf = kmalloc(21, GFP_KERNEL))) 283 return -ENOMEM; 284 285 init_waitqueue_head(&usX2Y->In04WaitQueue); 286 usb_fill_int_urb(usX2Y->In04urb, usX2Y->dev, usb_rcvintpipe(usX2Y->dev, 0x4), 287 usX2Y->In04Buf, 21, 288 i_usX2Y_In04Int, usX2Y, 289 10); 290 if (usb_urb_ep_type_check(usX2Y->In04urb)) 291 return -EINVAL; 292 return usb_submit_urb(usX2Y->In04urb, GFP_KERNEL); 293 } 294 295 static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S) 296 { 297 int i; 298 for (i = 0; i < URBS_AsyncSeq; ++i) { 299 usb_kill_urb(S->urb[i]); 300 usb_free_urb(S->urb[i]); 301 S->urb[i] = NULL; 302 } 303 kfree(S->buffer); 304 } 305 306 307 static const struct usb_device_id snd_usX2Y_usb_id_table[] = { 308 { 309 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 310 .idVendor = 0x1604, 311 .idProduct = USB_ID_US428 312 }, 313 { 314 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 315 .idVendor = 0x1604, 316 .idProduct = USB_ID_US122 317 }, 318 { 319 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 320 .idVendor = 0x1604, 321 .idProduct = USB_ID_US224 322 }, 323 { /* terminator */ } 324 }; 325 326 static int usX2Y_create_card(struct usb_device *device, 327 struct usb_interface *intf, 328 struct snd_card **cardp) 329 { 330 int dev; 331 struct snd_card * card; 332 int err; 333 334 for (dev = 0; dev < SNDRV_CARDS; ++dev) 335 if (enable[dev] && !snd_usX2Y_card_used[dev]) 336 break; 337 if (dev >= SNDRV_CARDS) 338 return -ENODEV; 339 err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE, 340 sizeof(struct usX2Ydev), &card); 341 if (err < 0) 342 return err; 343 snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1; 344 card->private_free = snd_usX2Y_card_private_free; 345 usX2Y(card)->dev = device; 346 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); 347 mutex_init(&usX2Y(card)->pcm_mutex); 348 INIT_LIST_HEAD(&usX2Y(card)->midi_list); 349 strcpy(card->driver, "USB "NAME_ALLCAPS""); 350 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); 351 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", 352 card->shortname, 353 le16_to_cpu(device->descriptor.idVendor), 354 le16_to_cpu(device->descriptor.idProduct), 355 0,//us428(card)->usbmidi.ifnum, 356 usX2Y(card)->dev->bus->busnum, usX2Y(card)->dev->devnum 357 ); 358 *cardp = card; 359 return 0; 360 } 361 362 363 static int usX2Y_usb_probe(struct usb_device *device, 364 struct usb_interface *intf, 365 const struct usb_device_id *device_id, 366 struct snd_card **cardp) 367 { 368 int err; 369 struct snd_card * card; 370 371 *cardp = NULL; 372 if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || 373 (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && 374 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && 375 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) 376 return -EINVAL; 377 378 err = usX2Y_create_card(device, intf, &card); 379 if (err < 0) 380 return err; 381 if ((err = usX2Y_hwdep_new(card, device)) < 0 || 382 (err = snd_card_register(card)) < 0) { 383 snd_card_free(card); 384 return err; 385 } 386 *cardp = card; 387 return 0; 388 } 389 390 /* 391 * new 2.5 USB kernel API 392 */ 393 static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id) 394 { 395 struct snd_card *card; 396 int err; 397 398 err = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id, &card); 399 if (err < 0) 400 return err; 401 dev_set_drvdata(&intf->dev, card); 402 return 0; 403 } 404 405 static void snd_usX2Y_disconnect(struct usb_interface *intf) 406 { 407 usX2Y_usb_disconnect(interface_to_usbdev(intf), 408 usb_get_intfdata(intf)); 409 } 410 411 MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table); 412 static struct usb_driver snd_usX2Y_usb_driver = { 413 .name = "snd-usb-usx2y", 414 .probe = snd_usX2Y_probe, 415 .disconnect = snd_usX2Y_disconnect, 416 .id_table = snd_usX2Y_usb_id_table, 417 }; 418 419 static void snd_usX2Y_card_private_free(struct snd_card *card) 420 { 421 kfree(usX2Y(card)->In04Buf); 422 usb_free_urb(usX2Y(card)->In04urb); 423 if (usX2Y(card)->us428ctls_sharedmem) 424 free_pages_exact(usX2Y(card)->us428ctls_sharedmem, 425 sizeof(*usX2Y(card)->us428ctls_sharedmem)); 426 if (usX2Y(card)->card_index >= 0 && usX2Y(card)->card_index < SNDRV_CARDS) 427 snd_usX2Y_card_used[usX2Y(card)->card_index] = 0; 428 } 429 430 /* 431 * Frees the device. 432 */ 433 static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr) 434 { 435 if (ptr) { 436 struct snd_card *card = ptr; 437 struct usX2Ydev *usX2Y = usX2Y(card); 438 struct list_head *p; 439 usX2Y->chip_status = USX2Y_STAT_CHIP_HUP; 440 usX2Y_unlinkSeq(&usX2Y->AS04); 441 usb_kill_urb(usX2Y->In04urb); 442 snd_card_disconnect(card); 443 /* release the midi resources */ 444 list_for_each(p, &usX2Y->midi_list) { 445 snd_usbmidi_disconnect(p); 446 } 447 if (usX2Y->us428ctls_sharedmem) 448 wake_up(&usX2Y->us428ctls_wait_queue_head); 449 snd_card_free(card); 450 } 451 } 452 453 module_usb_driver(snd_usX2Y_usb_driver); 454