File Index
Files and directories
Sign in
FILE

us144mkii.c

File preview with syntax highlighting.

linux-6.19.14/sound/usb/usx2y/us144mkii.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2// Copyright (c) 2025 Šerif Rami <ramiserifpersia@gmail.com>
  3/*
  4 * ALSA Driver for TASCAM US-144MKII Audio Interface
  5 */
  6
  7#include "us144mkii.h"
  8
  9MODULE_AUTHOR("Šerif Rami <ramiserifpersia@gmail.com>");
 10MODULE_DESCRIPTION("ALSA Driver for TASCAM US-144MKII");
 11MODULE_LICENSE("GPL");
 12
 13/**
 14 * @brief Module parameters for ALSA card instantiation.
 15 *
 16 * These parameters allow users to configure how the ALSA sound card
 17 * for the TASCAM US-144MKII is instantiated.
 18 *
 19 * @param index: Array of integers specifying the ALSA card index for each
 20 * device. Defaults to -1 (automatic).
 21 * @param id: Array of strings specifying the ALSA card ID for each device.
 22 *            Defaults to "US144MKII".
 23 * @param enable: Array of booleans to enable or disable each device.
 24 *                Defaults to {1, 0, ..., 0} (first device enabled).
 25 * @param dev_idx: Internal counter for the number of TASCAM devices probed.
 26 */
 27static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 28static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 29static bool enable[SNDRV_CARDS] = { 1, [1 ...(SNDRV_CARDS - 1)] = 0 };
 30static int dev_idx;
 31
 32static int tascam_probe(struct usb_interface *intf,
 33			const struct usb_device_id *usb_id);
 34static void tascam_disconnect(struct usb_interface *intf);
 35static int tascam_suspend(struct usb_interface *intf, pm_message_t message);
 36static int tascam_resume(struct usb_interface *intf);
 37
 38void tascam_free_urbs(struct tascam_card *tascam)
 39{
 40	int i;
 41
 42	usb_kill_anchored_urbs(&tascam->playback_anchor);
 43	for (i = 0; i < NUM_PLAYBACK_URBS; i++) {
 44		if (tascam->playback_urbs[i]) {
 45			usb_free_coherent(
 46				tascam->dev, tascam->playback_urb_alloc_size,
 47				tascam->playback_urbs[i]->transfer_buffer,
 48				tascam->playback_urbs[i]->transfer_dma);
 49			usb_free_urb(tascam->playback_urbs[i]);
 50			tascam->playback_urbs[i] = NULL;
 51		}
 52	}
 53
 54	usb_kill_anchored_urbs(&tascam->feedback_anchor);
 55	for (i = 0; i < NUM_FEEDBACK_URBS; i++) {
 56		if (tascam->feedback_urbs[i]) {
 57			usb_free_coherent(
 58				tascam->dev, tascam->feedback_urb_alloc_size,
 59				tascam->feedback_urbs[i]->transfer_buffer,
 60				tascam->feedback_urbs[i]->transfer_dma);
 61			usb_free_urb(tascam->feedback_urbs[i]);
 62			tascam->feedback_urbs[i] = NULL;
 63		}
 64	}
 65
 66	usb_kill_anchored_urbs(&tascam->capture_anchor);
 67	for (i = 0; i < NUM_CAPTURE_URBS; i++) {
 68		if (tascam->capture_urbs[i]) {
 69			usb_free_coherent(
 70				tascam->dev, tascam->capture_urb_alloc_size,
 71				tascam->capture_urbs[i]->transfer_buffer,
 72				tascam->capture_urbs[i]->transfer_dma);
 73			usb_free_urb(tascam->capture_urbs[i]);
 74			tascam->capture_urbs[i] = NULL;
 75		}
 76	}
 77
 78	usb_kill_anchored_urbs(&tascam->midi_in_anchor);
 79	for (i = 0; i < NUM_MIDI_IN_URBS; i++) {
 80		if (tascam->midi_in_urbs[i]) {
 81			usb_free_coherent(
 82				tascam->dev, MIDI_IN_BUF_SIZE,
 83				tascam->midi_in_urbs[i]->transfer_buffer,
 84				tascam->midi_in_urbs[i]->transfer_dma);
 85			usb_free_urb(tascam->midi_in_urbs[i]);
 86			tascam->midi_in_urbs[i] = NULL;
 87		}
 88	}
 89
 90	usb_kill_anchored_urbs(&tascam->midi_out_anchor);
 91	for (i = 0; i < NUM_MIDI_OUT_URBS; i++) {
 92		if (tascam->midi_out_urbs[i]) {
 93			usb_free_coherent(
 94				tascam->dev, MIDI_OUT_BUF_SIZE,
 95				tascam->midi_out_urbs[i]->transfer_buffer,
 96				tascam->midi_out_urbs[i]->transfer_dma);
 97			usb_free_urb(tascam->midi_out_urbs[i]);
 98			tascam->midi_out_urbs[i] = NULL;
 99		}
100	}
101
102	kfree(tascam->capture_routing_buffer);
103	tascam->capture_routing_buffer = NULL;
104	kfree(tascam->capture_decode_dst_block);
105	tascam->capture_decode_dst_block = NULL;
106	kfree(tascam->capture_decode_raw_block);
107	tascam->capture_decode_raw_block = NULL;
108	kfree(tascam->capture_ring_buffer);
109	tascam->capture_ring_buffer = NULL;
110}
111
112int tascam_alloc_urbs(struct tascam_card *tascam)
113{
114	int i;
115	size_t max_packet_size;
116
117	max_packet_size = ((96000 / 8000) + 2) * BYTES_PER_FRAME;
118	tascam->playback_urb_alloc_size =
119		max_packet_size * PLAYBACK_URB_PACKETS;
120
121	for (i = 0; i < NUM_PLAYBACK_URBS; i++) {
122		struct urb *urb =
123			usb_alloc_urb(PLAYBACK_URB_PACKETS, GFP_KERNEL);
124
125		if (!urb)
126			goto error;
127		tascam->playback_urbs[i] = urb;
128
129		urb->transfer_buffer = usb_alloc_coherent(
130			tascam->dev, tascam->playback_urb_alloc_size,
131			GFP_KERNEL, &urb->transfer_dma);
132		if (!urb->transfer_buffer)
133			goto error;
134
135		urb->dev = tascam->dev;
136		urb->pipe = usb_sndisocpipe(tascam->dev, EP_AUDIO_OUT);
137		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
138		urb->interval = 1;
139		urb->context = tascam;
140		urb->complete = playback_urb_complete;
141	}
142
143	tascam->feedback_urb_alloc_size =
144		FEEDBACK_PACKET_SIZE * FEEDBACK_URB_PACKETS;
145
146	for (i = 0; i < NUM_FEEDBACK_URBS; i++) {
147		struct urb *f_urb =
148			usb_alloc_urb(FEEDBACK_URB_PACKETS, GFP_KERNEL);
149
150		if (!f_urb)
151			goto error;
152		tascam->feedback_urbs[i] = f_urb;
153
154		f_urb->transfer_buffer = usb_alloc_coherent(
155			tascam->dev, tascam->feedback_urb_alloc_size,
156			GFP_KERNEL, &f_urb->transfer_dma);
157		if (!f_urb->transfer_buffer)
158			goto error;
159
160		f_urb->dev = tascam->dev;
161		f_urb->pipe =
162			usb_rcvisocpipe(tascam->dev, EP_PLAYBACK_FEEDBACK);
163		f_urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
164		f_urb->interval = 4;
165		f_urb->context = tascam;
166		f_urb->complete = feedback_urb_complete;
167	}
168
169	tascam->capture_urb_alloc_size = CAPTURE_URB_SIZE;
170	for (i = 0; i < NUM_CAPTURE_URBS; i++) {
171		struct urb *c_urb = usb_alloc_urb(0, GFP_KERNEL);
172
173		if (!c_urb)
174			goto error;
175		tascam->capture_urbs[i] = c_urb;
176
177		c_urb->transfer_buffer = usb_alloc_coherent(
178			tascam->dev, tascam->capture_urb_alloc_size, GFP_KERNEL,
179			&c_urb->transfer_dma);
180		if (!c_urb->transfer_buffer)
181			goto error;
182
183		usb_fill_bulk_urb(c_urb, tascam->dev,
184				  usb_rcvbulkpipe(tascam->dev, EP_AUDIO_IN),
185				  c_urb->transfer_buffer,
186				  tascam->capture_urb_alloc_size,
187				  capture_urb_complete, tascam);
188		c_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
189	}
190
191	/* MIDI URB and buffer allocation */
192	for (i = 0; i < NUM_MIDI_IN_URBS; i++) {
193		struct urb *m_urb = usb_alloc_urb(0, GFP_KERNEL);
194
195		if (!m_urb)
196			goto error;
197		tascam->midi_in_urbs[i] = m_urb;
198		m_urb->transfer_buffer =
199			usb_alloc_coherent(tascam->dev, MIDI_IN_BUF_SIZE,
200					   GFP_KERNEL, &m_urb->transfer_dma);
201		if (!m_urb->transfer_buffer)
202			goto error;
203		usb_fill_bulk_urb(m_urb, tascam->dev,
204				  usb_rcvbulkpipe(tascam->dev, EP_MIDI_IN),
205				  m_urb->transfer_buffer, MIDI_IN_BUF_SIZE,
206				  tascam_midi_in_urb_complete, tascam);
207		m_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
208	}
209
210	for (i = 0; i < NUM_MIDI_OUT_URBS; i++) {
211		struct urb *m_urb = usb_alloc_urb(0, GFP_KERNEL);
212
213		if (!m_urb)
214			goto error;
215		tascam->midi_out_urbs[i] = m_urb;
216		m_urb->transfer_buffer =
217			usb_alloc_coherent(tascam->dev, MIDI_OUT_BUF_SIZE,
218					   GFP_KERNEL, &m_urb->transfer_dma);
219		if (!m_urb->transfer_buffer)
220			goto error;
221		usb_fill_bulk_urb(m_urb, tascam->dev,
222				  usb_sndbulkpipe(tascam->dev, EP_MIDI_OUT),
223				  m_urb->transfer_buffer,
224				  0, /* length set later */
225				  tascam_midi_out_urb_complete, tascam);
226		m_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
227	}
228
229	tascam->capture_ring_buffer =
230		kmalloc(CAPTURE_RING_BUFFER_SIZE, GFP_KERNEL);
231	if (!tascam->capture_ring_buffer)
232		goto error;
233
234	tascam->capture_decode_raw_block =
235		kmalloc(RAW_BYTES_PER_DECODE_BLOCK, GFP_KERNEL);
236	if (!tascam->capture_decode_raw_block)
237		goto error;
238
239	tascam->capture_decode_dst_block =
240		kmalloc(FRAMES_PER_DECODE_BLOCK * DECODED_CHANNELS_PER_FRAME *
241				DECODED_SAMPLE_SIZE,
242			GFP_KERNEL);
243	if (!tascam->capture_decode_dst_block)
244		goto error;
245
246	tascam->capture_routing_buffer =
247		kmalloc(FRAMES_PER_DECODE_BLOCK * DECODED_CHANNELS_PER_FRAME *
248				DECODED_SAMPLE_SIZE,
249			GFP_KERNEL);
250	if (!tascam->capture_routing_buffer)
251		goto error;
252
253	return 0;
254
255error:
256	dev_err(tascam->card->dev, "Failed to allocate URBs\n");
257	tascam_free_urbs(tascam);
258	return -ENOMEM;
259}
260
261void tascam_stop_work_handler(struct work_struct *work)
262{
263	struct tascam_card *tascam =
264		container_of(work, struct tascam_card, stop_work);
265
266	usb_kill_anchored_urbs(&tascam->playback_anchor);
267	usb_kill_anchored_urbs(&tascam->feedback_anchor);
268	usb_kill_anchored_urbs(&tascam->capture_anchor);
269	atomic_set(&tascam->active_urbs, 0);
270}
271
272/**
273 * tascam_card_private_free() - Frees private data associated with the sound
274 * card.
275 * @card: Pointer to the ALSA sound card instance.
276 *
277 * This function is called when the sound card is being freed. It releases
278 * resources allocated for the tascam_card structure, including the MIDI
279 * input FIFO and decrements the USB device reference count.
280 */
281static void tascam_card_private_free(struct snd_card *card)
282{
283	struct tascam_card *tascam = card->private_data;
284
285	if (tascam) {
286		kfifo_free(&tascam->midi_in_fifo);
287		if (tascam->dev) {
288			usb_put_dev(tascam->dev);
289			tascam->dev = NULL;
290		}
291	}
292}
293
294/**
295 * tascam_suspend() - Handles device suspension.
296 * @intf: The USB interface being suspended.
297 * @message: Power management message.
298 *
299 * This function is called when the device is suspended. It stops all active
300 * streams, kills all URBs, and sends a vendor-specific deep sleep command
301 * to the device to ensure a stable low-power state.
302 *
303 * Return: 0 on success.
304 */
305static int tascam_suspend(struct usb_interface *intf, pm_message_t message)
306{
307	struct tascam_card *tascam = usb_get_intfdata(intf);
308
309	if (!tascam)
310		return 0;
311
312	snd_pcm_suspend_all(tascam->pcm);
313
314	cancel_work_sync(&tascam->stop_work);
315	cancel_work_sync(&tascam->capture_work);
316	cancel_work_sync(&tascam->midi_in_work);
317	cancel_work_sync(&tascam->midi_out_work);
318	cancel_work_sync(&tascam->stop_pcm_work);
319	usb_kill_anchored_urbs(&tascam->playback_anchor);
320	usb_kill_anchored_urbs(&tascam->capture_anchor);
321	usb_kill_anchored_urbs(&tascam->feedback_anchor);
322	usb_kill_anchored_urbs(&tascam->midi_in_anchor);
323	usb_kill_anchored_urbs(&tascam->midi_out_anchor);
324
325	dev_info(&intf->dev, "sending deep sleep command\n");
326	int err = usb_control_msg(tascam->dev, usb_sndctrlpipe(tascam->dev, 0),
327				  VENDOR_REQ_DEEP_SLEEP, RT_H2D_VENDOR_DEV,
328				  0x0000, 0x0000, NULL, 0, USB_CTRL_TIMEOUT_MS);
329	if (err < 0)
330		dev_err(&intf->dev, "deep sleep command failed: %d\n", err);
331
332	return 0;
333}
334
335/**
336 * tascam_resume() - Handles device resumption from suspend.
337 * @intf: The USB interface being resumed.
338 *
339 * This function is called when the device resumes from suspend. It
340 * re-establishes the active USB interface settings and re-configures the sample
341 * rate if it was previously active.
342 *
343 * Return: 0 on success, or a negative error code on failure.
344 */
345static int tascam_resume(struct usb_interface *intf)
346{
347	struct tascam_card *tascam = usb_get_intfdata(intf);
348	int err;
349
350	if (!tascam)
351		return 0;
352
353	dev_info(&intf->dev, "resuming TASCAM US-144MKII\n");
354
355	/*
356	 * The device requires a full re-initialization sequence upon resume.
357	 * First, re-establish the active USB interface settings.
358	 */
359	err = usb_set_interface(tascam->dev, 0, 1);
360	if (err < 0) {
361		dev_err(&intf->dev,
362			"resume: failed to set alt setting on intf 0: %d\n",
363			err);
364		return err;
365	}
366	err = usb_set_interface(tascam->dev, 1, 1);
367	if (err < 0) {
368		dev_err(&intf->dev,
369			"resume: failed to set alt setting on intf 1: %d\n",
370			err);
371		return err;
372	}
373
374	/* Re-configure the sample rate if one was previously active */
375	if (tascam->current_rate > 0)
376		us144mkii_configure_device_for_rate(tascam,
377						    tascam->current_rate);
378
379	return 0;
380}
381
382static void tascam_error_timer(struct timer_list *t)
383{
384	struct tascam_card *tascam =
385		container_of(t, struct tascam_card, error_timer);
386
387	if (atomic_read(&tascam->midi_in_active))
388		schedule_work(&tascam->midi_in_work);
389	if (atomic_read(&tascam->midi_out_active))
390		schedule_work(&tascam->midi_out_work);
391}
392
393/**
394 * tascam_probe() - Probes for the TASCAM US-144MKII device.
395 * @intf: The USB interface being probed.
396 * @usb_id: The USB device ID.
397 *
398 * This function is the entry point for the USB driver when a matching device
399 * is found. It performs initial device setup, including:
400 * - Checking for the second interface (MIDI) and associating it.
401 * - Performing a vendor-specific handshake with the device.
402 * - Setting alternate settings for USB interfaces.
403 * - Creating and registering the ALSA sound card, PCM device, and MIDI device.
404 * - Allocating and initializing URBs for audio and MIDI transfers.
405 *
406 * Return: 0 on success, or a negative error code on failure.
407 */
408static int tascam_probe(struct usb_interface *intf,
409			const struct usb_device_id *usb_id)
410{
411	struct usb_device *dev = interface_to_usbdev(intf);
412	struct snd_card *card;
413	struct tascam_card *tascam;
414	int err;
415
416	if (dev->speed != USB_SPEED_HIGH)
417		dev_info(
418			&dev->dev,
419			"Device is connected to a USB 1.1 port, this is not supported.\n");
420
421	/* The device has two interfaces; we drive both from this driver. */
422	if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
423		struct usb_interface *intf_zero = usb_ifnum_to_if(dev, 0);
424
425		if (!intf_zero)
426			return -ENODEV;
427		tascam = usb_get_intfdata(intf_zero);
428		if (tascam) {
429			usb_set_intfdata(intf, tascam);
430			tascam->iface1 = intf;
431		}
432		return 0; /* Let the core handle this interface */
433	}
434
435	if (dev_idx >= SNDRV_CARDS) {
436		dev_err(&dev->dev, "Too many TASCAM devices present");
437		return -ENODEV;
438	}
439
440	if (!enable[dev_idx]) {
441		dev_info(&dev->dev, "TASCAM US-144MKII device disabled");
442		return -ENOENT;
443	}
444
445	char *handshake_buf __free(kfree) =
446		kmalloc(1, GFP_KERNEL);
447	if (!handshake_buf)
448		return -ENOMEM;
449
450	/* Perform vendor-specific handshake */
451	err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
452			      VENDOR_REQ_MODE_CONTROL, RT_D2H_VENDOR_DEV,
453			      MODE_VAL_HANDSHAKE_READ, 0x0000, handshake_buf, 1,
454			      USB_CTRL_TIMEOUT_MS);
455	if (err < 0) {
456		dev_err(&dev->dev, "Handshake read failed with %d\n", err);
457		return err;
458	}
459
460	if (handshake_buf[0] != 0x12 && handshake_buf[0] != 0x16 &&
461	    handshake_buf[0] != 0x30 && handshake_buf[0] != 0x32) {
462		dev_err(&dev->dev, "Unexpected handshake value: 0x%x\n",
463			handshake_buf[0]);
464		return -ENODEV;
465	}
466
467	/* Set alternate settings to enable audio/MIDI endpoints */
468	err = usb_set_interface(dev, 0, 1);
469	if (err < 0) {
470		dev_err(&dev->dev,
471			"Failed to set alt setting 1 on interface 0: %d\n",
472			err);
473		return err;
474	}
475
476	err = usb_set_interface(dev, 1, 1);
477	if (err < 0) {
478		dev_err(&dev->dev,
479			"Failed to set alt setting 1 on interface 1: %d\n",
480			err);
481		return err;
482	}
483
484	err = snd_card_new(&dev->dev, index[dev_idx], id[dev_idx], THIS_MODULE,
485			   sizeof(struct tascam_card), &card);
486	if (err < 0) {
487		dev_err(&dev->dev, "Failed to create sound card instance\n");
488		return err;
489	}
490
491	tascam = card->private_data;
492	card->private_free = tascam_card_private_free;
493	tascam->dev = usb_get_dev(dev);
494	tascam->card = card;
495	tascam->iface0 = intf;
496	tascam->digital_out_source = 1;
497	tascam->capture_34_source = 1;
498
499	spin_lock_init(&tascam->lock);
500	spin_lock_init(&tascam->midi_in_lock);
501	spin_lock_init(&tascam->midi_out_lock);
502	init_usb_anchor(&tascam->playback_anchor);
503	init_usb_anchor(&tascam->capture_anchor);
504	init_usb_anchor(&tascam->feedback_anchor);
505	init_usb_anchor(&tascam->midi_in_anchor);
506	init_usb_anchor(&tascam->midi_out_anchor);
507
508	timer_setup(&tascam->error_timer, tascam_error_timer, 0);
509
510	INIT_WORK(&tascam->stop_work, tascam_stop_work_handler);
511	INIT_WORK(&tascam->stop_pcm_work, tascam_stop_pcm_work_handler);
512	INIT_WORK(&tascam->capture_work, tascam_capture_work_handler);
513	init_completion(&tascam->midi_out_drain_completion);
514
515	if (kfifo_alloc(&tascam->midi_in_fifo, MIDI_IN_FIFO_SIZE, GFP_KERNEL)) {
516		snd_card_free(card);
517		return -ENOMEM;
518	}
519
520	strscpy(card->driver, DRIVER_NAME, sizeof(card->driver));
521	if (le16_to_cpu(dev->descriptor.idProduct) == USB_PID_TASCAM_US144) {
522		strscpy(card->shortname, "TASCAM US-144",
523			sizeof(card->shortname));
524	} else if (le16_to_cpu(dev->descriptor.idProduct) == USB_PID_TASCAM_US144MKII) {
525		strscpy(card->shortname, "TASCAM US-144MKII",
526			sizeof(card->shortname));
527	} else {
528		strscpy(card->shortname, "TASCAM Unknown",
529			sizeof(card->shortname));
530	}
531	snprintf(card->longname, sizeof(card->longname), "%s (%04x:%04x) at %s",
532		 card->shortname, USB_VID_TASCAM, dev->descriptor.idProduct,
533		 dev_name(&dev->dev));
534
535	err = snd_pcm_new(card, "US144MKII PCM", 0, 1, 1, &tascam->pcm);
536	if (err < 0)
537		goto free_card;
538	tascam->pcm->private_data = tascam;
539	strscpy(tascam->pcm->name, "US144MKII PCM", sizeof(tascam->pcm->name));
540
541	err = tascam_init_pcm(tascam->pcm);
542	if (err < 0)
543		goto free_card;
544
545	err = tascam_create_midi(tascam);
546	if (err < 0)
547		goto free_card;
548
549	err = tascam_create_controls(tascam);
550	if (err < 0)
551		goto free_card;
552
553	err = tascam_alloc_urbs(tascam);
554	if (err < 0)
555		goto free_card;
556
557	err = snd_card_register(card);
558	if (err < 0)
559		goto free_card;
560
561	usb_set_intfdata(intf, tascam);
562
563	dev_idx++;
564	return 0;
565
566free_card:
567	tascam_free_urbs(tascam);
568	snd_card_free(card);
569	return err;
570}
571
572/**
573 * tascam_disconnect() - Disconnects the TASCAM US-144MKII device.
574 * @intf: The USB interface being disconnected.
575 *
576 * This function is called when the device is disconnected from the system.
577 * It cleans up all allocated resources, including killing URBs, freeing
578 * the sound card, and releasing memory.
579 */
580static void tascam_disconnect(struct usb_interface *intf)
581{
582	struct tascam_card *tascam = usb_get_intfdata(intf);
583
584	if (!tascam)
585		return;
586
587	if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
588		/* Ensure all deferred work is complete before freeing resources */
589		snd_card_disconnect(tascam->card);
590		cancel_work_sync(&tascam->stop_work);
591		cancel_work_sync(&tascam->capture_work);
592		cancel_work_sync(&tascam->midi_in_work);
593		cancel_work_sync(&tascam->midi_out_work);
594		cancel_work_sync(&tascam->stop_pcm_work);
595
596		usb_kill_anchored_urbs(&tascam->playback_anchor);
597		usb_kill_anchored_urbs(&tascam->capture_anchor);
598		usb_kill_anchored_urbs(&tascam->feedback_anchor);
599		usb_kill_anchored_urbs(&tascam->midi_in_anchor);
600		usb_kill_anchored_urbs(&tascam->midi_out_anchor);
601		timer_delete_sync(&tascam->error_timer);
602		tascam_free_urbs(tascam);
603		snd_card_free(tascam->card);
604		dev_idx--;
605	}
606}
607
608static const struct usb_device_id tascam_usb_ids[] = {
609	{ USB_DEVICE(USB_VID_TASCAM, USB_PID_TASCAM_US144) },
610	{ USB_DEVICE(USB_VID_TASCAM, USB_PID_TASCAM_US144MKII) },
611	{ /* Terminating entry */ }
612};
613MODULE_DEVICE_TABLE(usb, tascam_usb_ids);
614
615static struct usb_driver tascam_alsa_driver = {
616	.name = DRIVER_NAME,
617	.probe = tascam_probe,
618	.disconnect = tascam_disconnect,
619	.suspend = tascam_suspend,
620	.resume = tascam_resume,
621	.id_table = tascam_usb_ids,
622};
623
624module_usb_driver(tascam_alsa_driver);
~/ Read-only file preview.