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