1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Linux driver for TerraTec DMX 6Fire USB 4 * 5 * PCM driver 6 * 7 * Author: Torsten Schenk <torsten.schenk@zoho.com> 8 * Created: Jan 01, 2011 9 * Copyright: (C) Torsten Schenk 10 */ 11 12 #include "pcm.h" 13 #include "chip.h" 14 #include "comm.h" 15 #include "control.h" 16 17 enum { 18 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4 19 }; 20 21 /* keep next two synced with 22 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE 23 * and CONTROL_RATE_XXX in control.h */ 24 static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 }; 25 static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 }; 26 static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; 27 static const int rates_alsaid[] = { 28 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000, 29 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000, 30 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 }; 31 32 enum { /* settings for pcm */ 33 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024 34 }; 35 36 enum { /* pcm streaming states */ 37 STREAM_DISABLED, /* no pcm streaming */ 38 STREAM_STARTING, /* pcm streaming requested, waiting to become ready */ 39 STREAM_RUNNING, /* pcm streaming running */ 40 STREAM_STOPPING 41 }; 42 43 static const struct snd_pcm_hardware pcm_hw = { 44 .info = SNDRV_PCM_INFO_MMAP | 45 SNDRV_PCM_INFO_INTERLEAVED | 46 SNDRV_PCM_INFO_BLOCK_TRANSFER | 47 SNDRV_PCM_INFO_MMAP_VALID | 48 SNDRV_PCM_INFO_BATCH, 49 50 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, 51 52 .rates = SNDRV_PCM_RATE_44100 | 53 SNDRV_PCM_RATE_48000 | 54 SNDRV_PCM_RATE_88200 | 55 SNDRV_PCM_RATE_96000 | 56 SNDRV_PCM_RATE_176400 | 57 SNDRV_PCM_RATE_192000, 58 59 .rate_min = 44100, 60 .rate_max = 192000, 61 .channels_min = 1, 62 .channels_max = 0, /* set in pcm_open, depending on capture/playback */ 63 .buffer_bytes_max = MAX_BUFSIZE, 64 .period_bytes_min = PCM_N_PACKETS_PER_URB * (PCM_MAX_PACKET_SIZE - 4), 65 .period_bytes_max = MAX_BUFSIZE, 66 .periods_min = 2, 67 .periods_max = 1024 68 }; 69 70 static int usb6fire_pcm_set_rate(struct pcm_runtime *rt) 71 { 72 int ret; 73 struct control_runtime *ctrl_rt = rt->chip->control; 74 75 ctrl_rt->usb_streaming = false; 76 ret = ctrl_rt->update_streaming(ctrl_rt); 77 if (ret < 0) { 78 dev_err(&rt->chip->dev->dev, 79 "error stopping streaming while setting samplerate %d.\n", 80 rates[rt->rate]); 81 return ret; 82 } 83 84 ret = ctrl_rt->set_rate(ctrl_rt, rt->rate); 85 if (ret < 0) { 86 dev_err(&rt->chip->dev->dev, 87 "error setting samplerate %d.\n", 88 rates[rt->rate]); 89 return ret; 90 } 91 92 ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS, 93 false, false); 94 if (ret < 0) { 95 dev_err(&rt->chip->dev->dev, 96 "error initializing channels while setting samplerate %d.\n", 97 rates[rt->rate]); 98 return ret; 99 } 100 101 ctrl_rt->usb_streaming = true; 102 ret = ctrl_rt->update_streaming(ctrl_rt); 103 if (ret < 0) { 104 dev_err(&rt->chip->dev->dev, 105 "error starting streaming while setting samplerate %d.\n", 106 rates[rt->rate]); 107 return ret; 108 } 109 110 rt->in_n_analog = IN_N_CHANNELS; 111 rt->out_n_analog = OUT_N_CHANNELS; 112 rt->in_packet_size = rates_in_packet_size[rt->rate]; 113 rt->out_packet_size = rates_out_packet_size[rt->rate]; 114 return 0; 115 } 116 117 static struct pcm_substream *usb6fire_pcm_get_substream( 118 struct snd_pcm_substream *alsa_sub) 119 { 120 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 121 122 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) 123 return &rt->playback; 124 else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) 125 return &rt->capture; 126 dev_err(&rt->chip->dev->dev, "error getting pcm substream slot.\n"); 127 return NULL; 128 } 129 130 /* call with stream_mutex locked */ 131 static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt) 132 { 133 int i; 134 struct control_runtime *ctrl_rt = rt->chip->control; 135 136 if (rt->stream_state != STREAM_DISABLED) { 137 138 rt->stream_state = STREAM_STOPPING; 139 140 for (i = 0; i < PCM_N_URBS; i++) { 141 usb_kill_urb(&rt->in_urbs[i].instance); 142 usb_kill_urb(&rt->out_urbs[i].instance); 143 } 144 ctrl_rt->usb_streaming = false; 145 ctrl_rt->update_streaming(ctrl_rt); 146 rt->stream_state = STREAM_DISABLED; 147 } 148 } 149 150 /* call with stream_mutex locked */ 151 static int usb6fire_pcm_stream_start(struct pcm_runtime *rt) 152 { 153 int ret; 154 int i; 155 int k; 156 struct usb_iso_packet_descriptor *packet; 157 158 if (rt->stream_state == STREAM_DISABLED) { 159 /* submit our in urbs */ 160 rt->stream_wait_cond = false; 161 rt->stream_state = STREAM_STARTING; 162 for (i = 0; i < PCM_N_URBS; i++) { 163 for (k = 0; k < PCM_N_PACKETS_PER_URB; k++) { 164 packet = &rt->in_urbs[i].packets[k]; 165 packet->offset = k * rt->in_packet_size; 166 packet->length = rt->in_packet_size; 167 packet->actual_length = 0; 168 packet->status = 0; 169 } 170 ret = usb_submit_urb(&rt->in_urbs[i].instance, 171 GFP_ATOMIC); 172 if (ret) { 173 usb6fire_pcm_stream_stop(rt); 174 return ret; 175 } 176 } 177 178 /* wait for first out urb to return (sent in urb handler) */ 179 wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond, 180 HZ); 181 if (rt->stream_wait_cond) 182 rt->stream_state = STREAM_RUNNING; 183 else { 184 usb6fire_pcm_stream_stop(rt); 185 return -EIO; 186 } 187 } 188 return 0; 189 } 190 191 /* call with substream locked */ 192 static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb) 193 { 194 int i; 195 int frame; 196 int frame_count; 197 unsigned int total_length = 0; 198 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); 199 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; 200 u32 *src = NULL; 201 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off 202 * (alsa_rt->frame_bits >> 3)); 203 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 204 * (alsa_rt->frame_bits >> 3)); 205 int bytes_per_frame = alsa_rt->channels << 2; 206 207 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { 208 /* at least 4 header bytes for valid packet. 209 * after that: 32 bits per sample for analog channels */ 210 if (urb->packets[i].actual_length > 4) 211 frame_count = (urb->packets[i].actual_length - 4) 212 / (rt->in_n_analog << 2); 213 else 214 frame_count = 0; 215 216 if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) 217 src = (u32 *) (urb->buffer + total_length); 218 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) 219 src = (u32 *) (urb->buffer - 1 + total_length); 220 else 221 return; 222 src++; /* skip leading 4 bytes of every packet */ 223 total_length += urb->packets[i].length; 224 for (frame = 0; frame < frame_count; frame++) { 225 memcpy(dest, src, bytes_per_frame); 226 dest += alsa_rt->channels; 227 src += rt->in_n_analog; 228 sub->dma_off++; 229 sub->period_off++; 230 if (dest == dest_end) { 231 sub->dma_off = 0; 232 dest = (u32 *) alsa_rt->dma_area; 233 } 234 } 235 } 236 } 237 238 /* call with substream locked */ 239 static void usb6fire_pcm_playback(struct pcm_substream *sub, 240 struct pcm_urb *urb) 241 { 242 int i; 243 int frame; 244 int frame_count; 245 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); 246 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; 247 u32 *src = (u32 *) (alsa_rt->dma_area + sub->dma_off 248 * (alsa_rt->frame_bits >> 3)); 249 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 250 * (alsa_rt->frame_bits >> 3)); 251 u32 *dest; 252 int bytes_per_frame = alsa_rt->channels << 2; 253 254 if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) 255 dest = (u32 *) (urb->buffer - 1); 256 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) 257 dest = (u32 *) (urb->buffer); 258 else { 259 dev_err(&rt->chip->dev->dev, "Unknown sample format."); 260 return; 261 } 262 263 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { 264 /* at least 4 header bytes for valid packet. 265 * after that: 32 bits per sample for analog channels */ 266 if (urb->packets[i].length > 4) 267 frame_count = (urb->packets[i].length - 4) 268 / (rt->out_n_analog << 2); 269 else 270 frame_count = 0; 271 dest++; /* skip leading 4 bytes of every frame */ 272 for (frame = 0; frame < frame_count; frame++) { 273 memcpy(dest, src, bytes_per_frame); 274 src += alsa_rt->channels; 275 dest += rt->out_n_analog; 276 sub->dma_off++; 277 sub->period_off++; 278 if (src == src_end) { 279 src = (u32 *) alsa_rt->dma_area; 280 sub->dma_off = 0; 281 } 282 } 283 } 284 } 285 286 static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb) 287 { 288 struct pcm_urb *in_urb = usb_urb->context; 289 struct pcm_urb *out_urb = in_urb->peer; 290 struct pcm_runtime *rt = in_urb->chip->pcm; 291 struct pcm_substream *sub; 292 unsigned long flags; 293 int total_length = 0; 294 int frame_count; 295 int frame; 296 int channel; 297 int i; 298 u8 *dest; 299 300 if (usb_urb->status || rt->panic || rt->stream_state == STREAM_STOPPING) 301 return; 302 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) 303 if (in_urb->packets[i].status) { 304 rt->panic = true; 305 return; 306 } 307 308 if (rt->stream_state == STREAM_DISABLED) { 309 dev_err(&rt->chip->dev->dev, 310 "internal error: stream disabled in in-urb handler.\n"); 311 return; 312 } 313 314 /* receive our capture data */ 315 sub = &rt->capture; 316 spin_lock_irqsave(&sub->lock, flags); 317 if (sub->active) { 318 usb6fire_pcm_capture(sub, in_urb); 319 if (sub->period_off >= sub->instance->runtime->period_size) { 320 sub->period_off %= sub->instance->runtime->period_size; 321 spin_unlock_irqrestore(&sub->lock, flags); 322 snd_pcm_period_elapsed(sub->instance); 323 } else 324 spin_unlock_irqrestore(&sub->lock, flags); 325 } else 326 spin_unlock_irqrestore(&sub->lock, flags); 327 328 /* setup out urb structure */ 329 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { 330 out_urb->packets[i].offset = total_length; 331 out_urb->packets[i].length = (in_urb->packets[i].actual_length 332 - 4) / (rt->in_n_analog << 2) 333 * (rt->out_n_analog << 2) + 4; 334 out_urb->packets[i].status = 0; 335 total_length += out_urb->packets[i].length; 336 } 337 memset(out_urb->buffer, 0, total_length); 338 339 /* now send our playback data (if a free out urb was found) */ 340 sub = &rt->playback; 341 spin_lock_irqsave(&sub->lock, flags); 342 if (sub->active) { 343 usb6fire_pcm_playback(sub, out_urb); 344 if (sub->period_off >= sub->instance->runtime->period_size) { 345 sub->period_off %= sub->instance->runtime->period_size; 346 spin_unlock_irqrestore(&sub->lock, flags); 347 snd_pcm_period_elapsed(sub->instance); 348 } else 349 spin_unlock_irqrestore(&sub->lock, flags); 350 } else 351 spin_unlock_irqrestore(&sub->lock, flags); 352 353 /* setup the 4th byte of each sample (0x40 for analog channels) */ 354 dest = out_urb->buffer; 355 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) 356 if (out_urb->packets[i].length >= 4) { 357 frame_count = (out_urb->packets[i].length - 4) 358 / (rt->out_n_analog << 2); 359 *(dest++) = 0xaa; 360 *(dest++) = 0xaa; 361 *(dest++) = frame_count; 362 *(dest++) = 0x00; 363 for (frame = 0; frame < frame_count; frame++) 364 for (channel = 0; 365 channel < rt->out_n_analog; 366 channel++) { 367 dest += 3; /* skip sample data */ 368 *(dest++) = 0x40; 369 } 370 } 371 usb_submit_urb(&out_urb->instance, GFP_ATOMIC); 372 usb_submit_urb(&in_urb->instance, GFP_ATOMIC); 373 } 374 375 static void usb6fire_pcm_out_urb_handler(struct urb *usb_urb) 376 { 377 struct pcm_urb *urb = usb_urb->context; 378 struct pcm_runtime *rt = urb->chip->pcm; 379 380 if (rt->stream_state == STREAM_STARTING) { 381 rt->stream_wait_cond = true; 382 wake_up(&rt->stream_wait_queue); 383 } 384 } 385 386 static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub) 387 { 388 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 389 struct pcm_substream *sub = NULL; 390 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; 391 392 if (rt->panic) 393 return -EPIPE; 394 395 mutex_lock(&rt->stream_mutex); 396 alsa_rt->hw = pcm_hw; 397 398 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) { 399 if (rt->rate < ARRAY_SIZE(rates)) 400 alsa_rt->hw.rates = rates_alsaid[rt->rate]; 401 alsa_rt->hw.channels_max = OUT_N_CHANNELS; 402 sub = &rt->playback; 403 } else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) { 404 if (rt->rate < ARRAY_SIZE(rates)) 405 alsa_rt->hw.rates = rates_alsaid[rt->rate]; 406 alsa_rt->hw.channels_max = IN_N_CHANNELS; 407 sub = &rt->capture; 408 } 409 410 if (!sub) { 411 mutex_unlock(&rt->stream_mutex); 412 dev_err(&rt->chip->dev->dev, "invalid stream type.\n"); 413 return -EINVAL; 414 } 415 416 sub->instance = alsa_sub; 417 sub->active = false; 418 mutex_unlock(&rt->stream_mutex); 419 return 0; 420 } 421 422 static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub) 423 { 424 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 425 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); 426 unsigned long flags; 427 428 if (rt->panic) 429 return 0; 430 431 mutex_lock(&rt->stream_mutex); 432 if (sub) { 433 /* deactivate substream */ 434 spin_lock_irqsave(&sub->lock, flags); 435 sub->instance = NULL; 436 sub->active = false; 437 spin_unlock_irqrestore(&sub->lock, flags); 438 439 /* all substreams closed? if so, stop streaming */ 440 if (!rt->playback.instance && !rt->capture.instance) { 441 usb6fire_pcm_stream_stop(rt); 442 rt->rate = ARRAY_SIZE(rates); 443 } 444 } 445 mutex_unlock(&rt->stream_mutex); 446 return 0; 447 } 448 449 static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub) 450 { 451 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 452 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); 453 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; 454 int ret; 455 456 if (rt->panic) 457 return -EPIPE; 458 if (!sub) 459 return -ENODEV; 460 461 mutex_lock(&rt->stream_mutex); 462 sub->dma_off = 0; 463 sub->period_off = 0; 464 465 if (rt->stream_state == STREAM_DISABLED) { 466 for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++) 467 if (alsa_rt->rate == rates[rt->rate]) 468 break; 469 if (rt->rate == ARRAY_SIZE(rates)) { 470 mutex_unlock(&rt->stream_mutex); 471 dev_err(&rt->chip->dev->dev, 472 "invalid rate %d in prepare.\n", 473 alsa_rt->rate); 474 return -EINVAL; 475 } 476 477 ret = usb6fire_pcm_set_rate(rt); 478 if (ret) { 479 mutex_unlock(&rt->stream_mutex); 480 return ret; 481 } 482 ret = usb6fire_pcm_stream_start(rt); 483 if (ret) { 484 mutex_unlock(&rt->stream_mutex); 485 dev_err(&rt->chip->dev->dev, 486 "could not start pcm stream.\n"); 487 return ret; 488 } 489 } 490 mutex_unlock(&rt->stream_mutex); 491 return 0; 492 } 493 494 static int usb6fire_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd) 495 { 496 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); 497 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 498 unsigned long flags; 499 500 if (rt->panic) 501 return -EPIPE; 502 if (!sub) 503 return -ENODEV; 504 505 switch (cmd) { 506 case SNDRV_PCM_TRIGGER_START: 507 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 508 spin_lock_irqsave(&sub->lock, flags); 509 sub->active = true; 510 spin_unlock_irqrestore(&sub->lock, flags); 511 return 0; 512 513 case SNDRV_PCM_TRIGGER_STOP: 514 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 515 spin_lock_irqsave(&sub->lock, flags); 516 sub->active = false; 517 spin_unlock_irqrestore(&sub->lock, flags); 518 return 0; 519 520 default: 521 return -EINVAL; 522 } 523 } 524 525 static snd_pcm_uframes_t usb6fire_pcm_pointer( 526 struct snd_pcm_substream *alsa_sub) 527 { 528 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); 529 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 530 unsigned long flags; 531 snd_pcm_uframes_t ret; 532 533 if (rt->panic || !sub) 534 return SNDRV_PCM_POS_XRUN; 535 536 spin_lock_irqsave(&sub->lock, flags); 537 ret = sub->dma_off; 538 spin_unlock_irqrestore(&sub->lock, flags); 539 return ret; 540 } 541 542 static const struct snd_pcm_ops pcm_ops = { 543 .open = usb6fire_pcm_open, 544 .close = usb6fire_pcm_close, 545 .prepare = usb6fire_pcm_prepare, 546 .trigger = usb6fire_pcm_trigger, 547 .pointer = usb6fire_pcm_pointer, 548 }; 549 550 static void usb6fire_pcm_init_urb(struct pcm_urb *urb, 551 struct sfire_chip *chip, bool in, int ep, 552 void (*handler)(struct urb *)) 553 { 554 urb->chip = chip; 555 usb_init_urb(&urb->instance); 556 urb->instance.transfer_buffer = urb->buffer; 557 urb->instance.transfer_buffer_length = 558 PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE; 559 urb->instance.dev = chip->dev; 560 urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep) 561 : usb_sndisocpipe(chip->dev, ep); 562 urb->instance.interval = 1; 563 urb->instance.complete = handler; 564 urb->instance.context = urb; 565 urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; 566 } 567 568 static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt) 569 { 570 int i; 571 572 for (i = 0; i < PCM_N_URBS; i++) { 573 rt->out_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE, 574 PCM_N_PACKETS_PER_URB, 575 GFP_KERNEL); 576 if (!rt->out_urbs[i].buffer) 577 return -ENOMEM; 578 rt->in_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE, 579 PCM_N_PACKETS_PER_URB, 580 GFP_KERNEL); 581 if (!rt->in_urbs[i].buffer) 582 return -ENOMEM; 583 } 584 return 0; 585 } 586 587 static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt) 588 { 589 int i; 590 591 for (i = 0; i < PCM_N_URBS; i++) { 592 kfree(rt->out_urbs[i].buffer); 593 kfree(rt->in_urbs[i].buffer); 594 } 595 } 596 597 int usb6fire_pcm_init(struct sfire_chip *chip) 598 { 599 int i; 600 int ret; 601 struct snd_pcm *pcm; 602 struct pcm_runtime *rt = 603 kzalloc(sizeof(struct pcm_runtime), GFP_KERNEL); 604 605 if (!rt) 606 return -ENOMEM; 607 608 ret = usb6fire_pcm_buffers_init(rt); 609 if (ret) { 610 usb6fire_pcm_buffers_destroy(rt); 611 kfree(rt); 612 return ret; 613 } 614 615 rt->chip = chip; 616 rt->stream_state = STREAM_DISABLED; 617 rt->rate = ARRAY_SIZE(rates); 618 init_waitqueue_head(&rt->stream_wait_queue); 619 mutex_init(&rt->stream_mutex); 620 621 spin_lock_init(&rt->playback.lock); 622 spin_lock_init(&rt->capture.lock); 623 624 for (i = 0; i < PCM_N_URBS; i++) { 625 usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP, 626 usb6fire_pcm_in_urb_handler); 627 usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP, 628 usb6fire_pcm_out_urb_handler); 629 630 rt->in_urbs[i].peer = &rt->out_urbs[i]; 631 rt->out_urbs[i].peer = &rt->in_urbs[i]; 632 } 633 634 ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm); 635 if (ret < 0) { 636 usb6fire_pcm_buffers_destroy(rt); 637 kfree(rt); 638 dev_err(&chip->dev->dev, "cannot create pcm instance.\n"); 639 return ret; 640 } 641 642 pcm->private_data = rt; 643 strcpy(pcm->name, "DMX 6Fire USB"); 644 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops); 645 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops); 646 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0); 647 648 rt->instance = pcm; 649 650 chip->pcm = rt; 651 return 0; 652 } 653 654 void usb6fire_pcm_abort(struct sfire_chip *chip) 655 { 656 struct pcm_runtime *rt = chip->pcm; 657 int i; 658 659 if (rt) { 660 rt->panic = true; 661 662 if (rt->playback.instance) 663 snd_pcm_stop_xrun(rt->playback.instance); 664 665 if (rt->capture.instance) 666 snd_pcm_stop_xrun(rt->capture.instance); 667 668 for (i = 0; i < PCM_N_URBS; i++) { 669 usb_poison_urb(&rt->in_urbs[i].instance); 670 usb_poison_urb(&rt->out_urbs[i].instance); 671 } 672 673 } 674 } 675 676 void usb6fire_pcm_destroy(struct sfire_chip *chip) 677 { 678 struct pcm_runtime *rt = chip->pcm; 679 680 usb6fire_pcm_buffers_destroy(rt); 681 kfree(rt); 682 chip->pcm = NULL; 683 } 684
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.