1 /* 2 * compress_core.c - compress offload core 3 * 4 * Copyright (C) 2011 Intel Corporation 5 * Authors: Vinod Koul <vinod.koul@linux.intel.com> 6 * Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; version 2 of the License. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 * 22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 * 24 */ 25 #define FORMAT(fmt) "%s: %d: " fmt, __func__, __LINE__ 26 #define pr_fmt(fmt) KBUILD_MODNAME ": " FORMAT(fmt) 27 28 #include <linux/file.h> 29 #include <linux/fs.h> 30 #include <linux/list.h> 31 #include <linux/math64.h> 32 #include <linux/mm.h> 33 #include <linux/mutex.h> 34 #include <linux/poll.h> 35 #include <linux/slab.h> 36 #include <linux/sched.h> 37 #include <linux/types.h> 38 #include <linux/uio.h> 39 #include <linux/uaccess.h> 40 #include <linux/module.h> 41 #include <sound/core.h> 42 #include <sound/initval.h> 43 #include <sound/compress_params.h> 44 #include <sound/compress_offload.h> 45 #include <sound/compress_driver.h> 46 47 /* TODO: 48 * - add substream support for multiple devices in case of 49 * SND_DYNAMIC_MINORS is not used 50 * - Multiple node representation 51 * driver should be able to register multiple nodes 52 */ 53 54 static DEFINE_MUTEX(device_mutex); 55 56 struct snd_compr_file { 57 unsigned long caps; 58 struct snd_compr_stream stream; 59 }; 60 61 /* 62 * a note on stream states used: 63 * we use follwing states in the compressed core 64 * SNDRV_PCM_STATE_OPEN: When stream has been opened. 65 * SNDRV_PCM_STATE_SETUP: When stream has been initialized. This is done by 66 * calling SNDRV_COMPRESS_SET_PARAMS. running streams will come to this 67 * state at stop by calling SNDRV_COMPRESS_STOP, or at end of drain. 68 * SNDRV_PCM_STATE_RUNNING: When stream has been started and is 69 * decoding/encoding and rendering/capturing data. 70 * SNDRV_PCM_STATE_DRAINING: When stream is draining current data. This is done 71 * by calling SNDRV_COMPRESS_DRAIN. 72 * SNDRV_PCM_STATE_PAUSED: When stream is paused. This is done by calling 73 * SNDRV_COMPRESS_PAUSE. It can be stopped or resumed by calling 74 * SNDRV_COMPRESS_STOP or SNDRV_COMPRESS_RESUME respectively. 75 */ 76 static int snd_compr_open(struct inode *inode, struct file *f) 77 { 78 struct snd_compr *compr; 79 struct snd_compr_file *data; 80 struct snd_compr_runtime *runtime; 81 enum snd_compr_direction dirn; 82 int maj = imajor(inode); 83 int ret; 84 85 if ((f->f_flags & O_ACCMODE) == O_WRONLY) 86 dirn = SND_COMPRESS_PLAYBACK; 87 else if ((f->f_flags & O_ACCMODE) == O_RDONLY) 88 dirn = SND_COMPRESS_CAPTURE; 89 else 90 return -EINVAL; 91 92 if (maj == snd_major) 93 compr = snd_lookup_minor_data(iminor(inode), 94 SNDRV_DEVICE_TYPE_COMPRESS); 95 else 96 return -EBADFD; 97 98 if (compr == NULL) { 99 pr_err("no device data!!!\n"); 100 return -ENODEV; 101 } 102 103 if (dirn != compr->direction) { 104 pr_err("this device doesn't support this direction\n"); 105 snd_card_unref(compr->card); 106 return -EINVAL; 107 } 108 109 data = kzalloc(sizeof(*data), GFP_KERNEL); 110 if (!data) { 111 snd_card_unref(compr->card); 112 return -ENOMEM; 113 } 114 data->stream.ops = compr->ops; 115 data->stream.direction = dirn; 116 data->stream.private_data = compr->private_data; 117 data->stream.device = compr; 118 runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); 119 if (!runtime) { 120 kfree(data); 121 snd_card_unref(compr->card); 122 return -ENOMEM; 123 } 124 runtime->state = SNDRV_PCM_STATE_OPEN; 125 init_waitqueue_head(&runtime->sleep); 126 data->stream.runtime = runtime; 127 f->private_data = (void *)data; 128 mutex_lock(&compr->lock); 129 ret = compr->ops->open(&data->stream); 130 mutex_unlock(&compr->lock); 131 if (ret) { 132 kfree(runtime); 133 kfree(data); 134 } 135 snd_card_unref(compr->card); 136 return 0; 137 } 138 139 static int snd_compr_free(struct inode *inode, struct file *f) 140 { 141 struct snd_compr_file *data = f->private_data; 142 struct snd_compr_runtime *runtime = data->stream.runtime; 143 144 switch (runtime->state) { 145 case SNDRV_PCM_STATE_RUNNING: 146 case SNDRV_PCM_STATE_DRAINING: 147 case SNDRV_PCM_STATE_PAUSED: 148 data->stream.ops->trigger(&data->stream, SNDRV_PCM_TRIGGER_STOP); 149 break; 150 default: 151 break; 152 } 153 154 data->stream.ops->free(&data->stream); 155 kfree(data->stream.runtime->buffer); 156 kfree(data->stream.runtime); 157 kfree(data); 158 return 0; 159 } 160 161 static int snd_compr_update_tstamp(struct snd_compr_stream *stream, 162 struct snd_compr_tstamp *tstamp) 163 { 164 if (!stream->ops->pointer) 165 return -ENOTSUPP; 166 stream->ops->pointer(stream, tstamp); 167 pr_debug("dsp consumed till %d total %d bytes\n", 168 tstamp->byte_offset, tstamp->copied_total); 169 if (stream->direction == SND_COMPRESS_PLAYBACK) 170 stream->runtime->total_bytes_transferred = tstamp->copied_total; 171 else 172 stream->runtime->total_bytes_available = tstamp->copied_total; 173 return 0; 174 } 175 176 static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, 177 struct snd_compr_avail *avail) 178 { 179 memset(avail, 0, sizeof(*avail)); 180 snd_compr_update_tstamp(stream, &avail->tstamp); 181 /* Still need to return avail even if tstamp can't be filled in */ 182 183 if (stream->runtime->total_bytes_available == 0 && 184 stream->runtime->state == SNDRV_PCM_STATE_SETUP && 185 stream->direction == SND_COMPRESS_PLAYBACK) { 186 pr_debug("detected init and someone forgot to do a write\n"); 187 return stream->runtime->buffer_size; 188 } 189 pr_debug("app wrote %lld, DSP consumed %lld\n", 190 stream->runtime->total_bytes_available, 191 stream->runtime->total_bytes_transferred); 192 if (stream->runtime->total_bytes_available == 193 stream->runtime->total_bytes_transferred) { 194 if (stream->direction == SND_COMPRESS_PLAYBACK) { 195 pr_debug("both pointers are same, returning full avail\n"); 196 return stream->runtime->buffer_size; 197 } else { 198 pr_debug("both pointers are same, returning no avail\n"); 199 return 0; 200 } 201 } 202 203 avail->avail = stream->runtime->total_bytes_available - 204 stream->runtime->total_bytes_transferred; 205 if (stream->direction == SND_COMPRESS_PLAYBACK) 206 avail->avail = stream->runtime->buffer_size - avail->avail; 207 208 pr_debug("ret avail as %lld\n", avail->avail); 209 return avail->avail; 210 } 211 212 static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream) 213 { 214 struct snd_compr_avail avail; 215 216 return snd_compr_calc_avail(stream, &avail); 217 } 218 219 static int 220 snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg) 221 { 222 struct snd_compr_avail ioctl_avail; 223 size_t avail; 224 225 avail = snd_compr_calc_avail(stream, &ioctl_avail); 226 ioctl_avail.avail = avail; 227 228 if (copy_to_user((__u64 __user *)arg, 229 &ioctl_avail, sizeof(ioctl_avail))) 230 return -EFAULT; 231 return 0; 232 } 233 234 static int snd_compr_write_data(struct snd_compr_stream *stream, 235 const char __user *buf, size_t count) 236 { 237 void *dstn; 238 size_t copy; 239 struct snd_compr_runtime *runtime = stream->runtime; 240 /* 64-bit Modulus */ 241 u64 app_pointer = div64_u64(runtime->total_bytes_available, 242 runtime->buffer_size); 243 app_pointer = runtime->total_bytes_available - 244 (app_pointer * runtime->buffer_size); 245 246 dstn = runtime->buffer + app_pointer; 247 pr_debug("copying %ld at %lld\n", 248 (unsigned long)count, app_pointer); 249 if (count < runtime->buffer_size - app_pointer) { 250 if (copy_from_user(dstn, buf, count)) 251 return -EFAULT; 252 } else { 253 copy = runtime->buffer_size - app_pointer; 254 if (copy_from_user(dstn, buf, copy)) 255 return -EFAULT; 256 if (copy_from_user(runtime->buffer, buf + copy, count - copy)) 257 return -EFAULT; 258 } 259 /* if DSP cares, let it know data has been written */ 260 if (stream->ops->ack) 261 stream->ops->ack(stream, count); 262 return count; 263 } 264 265 static ssize_t snd_compr_write(struct file *f, const char __user *buf, 266 size_t count, loff_t *offset) 267 { 268 struct snd_compr_file *data = f->private_data; 269 struct snd_compr_stream *stream; 270 size_t avail; 271 int retval; 272 273 if (snd_BUG_ON(!data)) 274 return -EFAULT; 275 276 stream = &data->stream; 277 mutex_lock(&stream->device->lock); 278 /* write is allowed when stream is running or has been steup */ 279 if (stream->runtime->state != SNDRV_PCM_STATE_SETUP && 280 stream->runtime->state != SNDRV_PCM_STATE_RUNNING) { 281 mutex_unlock(&stream->device->lock); 282 return -EBADFD; 283 } 284 285 avail = snd_compr_get_avail(stream); 286 pr_debug("avail returned %ld\n", (unsigned long)avail); 287 /* calculate how much we can write to buffer */ 288 if (avail > count) 289 avail = count; 290 291 if (stream->ops->copy) { 292 char __user* cbuf = (char __user*)buf; 293 retval = stream->ops->copy(stream, cbuf, avail); 294 } else { 295 retval = snd_compr_write_data(stream, buf, avail); 296 } 297 if (retval > 0) 298 stream->runtime->total_bytes_available += retval; 299 300 /* while initiating the stream, write should be called before START 301 * call, so in setup move state */ 302 if (stream->runtime->state == SNDRV_PCM_STATE_SETUP) { 303 stream->runtime->state = SNDRV_PCM_STATE_PREPARED; 304 pr_debug("stream prepared, Houston we are good to go\n"); 305 } 306 307 mutex_unlock(&stream->device->lock); 308 return retval; 309 } 310 311 312 static ssize_t snd_compr_read(struct file *f, char __user *buf, 313 size_t count, loff_t *offset) 314 { 315 struct snd_compr_file *data = f->private_data; 316 struct snd_compr_stream *stream; 317 size_t avail; 318 int retval; 319 320 if (snd_BUG_ON(!data)) 321 return -EFAULT; 322 323 stream = &data->stream; 324 mutex_lock(&stream->device->lock); 325 326 /* read is allowed when stream is running, paused, draining and setup 327 * (yes setup is state which we transition to after stop, so if user 328 * wants to read data after stop we allow that) 329 */ 330 switch (stream->runtime->state) { 331 case SNDRV_PCM_STATE_OPEN: 332 case SNDRV_PCM_STATE_PREPARED: 333 case SNDRV_PCM_STATE_XRUN: 334 case SNDRV_PCM_STATE_SUSPENDED: 335 case SNDRV_PCM_STATE_DISCONNECTED: 336 retval = -EBADFD; 337 goto out; 338 } 339 340 avail = snd_compr_get_avail(stream); 341 pr_debug("avail returned %ld\n", (unsigned long)avail); 342 /* calculate how much we can read from buffer */ 343 if (avail > count) 344 avail = count; 345 346 if (stream->ops->copy) { 347 retval = stream->ops->copy(stream, buf, avail); 348 } else { 349 retval = -ENXIO; 350 goto out; 351 } 352 if (retval > 0) 353 stream->runtime->total_bytes_transferred += retval; 354 355 out: 356 mutex_unlock(&stream->device->lock); 357 return retval; 358 } 359 360 static int snd_compr_mmap(struct file *f, struct vm_area_struct *vma) 361 { 362 return -ENXIO; 363 } 364 365 static inline int snd_compr_get_poll(struct snd_compr_stream *stream) 366 { 367 if (stream->direction == SND_COMPRESS_PLAYBACK) 368 return POLLOUT | POLLWRNORM; 369 else 370 return POLLIN | POLLRDNORM; 371 } 372 373 static unsigned int snd_compr_poll(struct file *f, poll_table *wait) 374 { 375 struct snd_compr_file *data = f->private_data; 376 struct snd_compr_stream *stream; 377 size_t avail; 378 int retval = 0; 379 380 if (snd_BUG_ON(!data)) 381 return -EFAULT; 382 stream = &data->stream; 383 if (snd_BUG_ON(!stream)) 384 return -EFAULT; 385 386 mutex_lock(&stream->device->lock); 387 if (stream->runtime->state == SNDRV_PCM_STATE_PAUSED || 388 stream->runtime->state == SNDRV_PCM_STATE_OPEN) { 389 retval = -EBADFD; 390 goto out; 391 } 392 poll_wait(f, &stream->runtime->sleep, wait); 393 394 avail = snd_compr_get_avail(stream); 395 pr_debug("avail is %ld\n", (unsigned long)avail); 396 /* check if we have at least one fragment to fill */ 397 switch (stream->runtime->state) { 398 case SNDRV_PCM_STATE_DRAINING: 399 /* stream has been woken up after drain is complete 400 * draining done so set stream state to stopped 401 */ 402 retval = snd_compr_get_poll(stream); 403 stream->runtime->state = SNDRV_PCM_STATE_SETUP; 404 break; 405 case SNDRV_PCM_STATE_RUNNING: 406 case SNDRV_PCM_STATE_PREPARED: 407 case SNDRV_PCM_STATE_PAUSED: 408 if (avail >= stream->runtime->fragment_size) 409 retval = snd_compr_get_poll(stream); 410 break; 411 default: 412 if (stream->direction == SND_COMPRESS_PLAYBACK) 413 retval = POLLOUT | POLLWRNORM | POLLERR; 414 else 415 retval = POLLIN | POLLRDNORM | POLLERR; 416 break; 417 } 418 out: 419 mutex_unlock(&stream->device->lock); 420 return retval; 421 } 422 423 static int 424 snd_compr_get_caps(struct snd_compr_stream *stream, unsigned long arg) 425 { 426 int retval; 427 struct snd_compr_caps caps; 428 429 if (!stream->ops->get_caps) 430 return -ENXIO; 431 432 memset(&caps, 0, sizeof(caps)); 433 retval = stream->ops->get_caps(stream, &caps); 434 if (retval) 435 goto out; 436 if (copy_to_user((void __user *)arg, &caps, sizeof(caps))) 437 retval = -EFAULT; 438 out: 439 return retval; 440 } 441 442 static int 443 snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg) 444 { 445 int retval; 446 struct snd_compr_codec_caps *caps; 447 448 if (!stream->ops->get_codec_caps) 449 return -ENXIO; 450 451 caps = kzalloc(sizeof(*caps), GFP_KERNEL); 452 if (!caps) 453 return -ENOMEM; 454 455 retval = stream->ops->get_codec_caps(stream, caps); 456 if (retval) 457 goto out; 458 if (copy_to_user((void __user *)arg, caps, sizeof(*caps))) 459 retval = -EFAULT; 460 461 out: 462 kfree(caps); 463 return retval; 464 } 465 466 /* revisit this with snd_pcm_preallocate_xxx */ 467 static int snd_compr_allocate_buffer(struct snd_compr_stream *stream, 468 struct snd_compr_params *params) 469 { 470 unsigned int buffer_size; 471 void *buffer; 472 473 buffer_size = params->buffer.fragment_size * params->buffer.fragments; 474 if (stream->ops->copy) { 475 buffer = NULL; 476 /* if copy is defined the driver will be required to copy 477 * the data from core 478 */ 479 } else { 480 buffer = kmalloc(buffer_size, GFP_KERNEL); 481 if (!buffer) 482 return -ENOMEM; 483 } 484 stream->runtime->fragment_size = params->buffer.fragment_size; 485 stream->runtime->fragments = params->buffer.fragments; 486 stream->runtime->buffer = buffer; 487 stream->runtime->buffer_size = buffer_size; 488 return 0; 489 } 490 491 static int snd_compress_check_input(struct snd_compr_params *params) 492 { 493 /* first let's check the buffer parameter's */ 494 if (params->buffer.fragment_size == 0 || 495 params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size) 496 return -EINVAL; 497 498 /* now codec parameters */ 499 if (params->codec.id == 0 || params->codec.id > SND_AUDIOCODEC_MAX) 500 return -EINVAL; 501 502 if (params->codec.ch_in == 0 || params->codec.ch_out == 0) 503 return -EINVAL; 504 505 if (!(params->codec.sample_rate & SNDRV_PCM_RATE_8000_192000)) 506 return -EINVAL; 507 508 return 0; 509 } 510 511 static int 512 snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) 513 { 514 struct snd_compr_params *params; 515 int retval; 516 517 if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) { 518 /* 519 * we should allow parameter change only when stream has been 520 * opened not in other cases 521 */ 522 params = kmalloc(sizeof(*params), GFP_KERNEL); 523 if (!params) 524 return -ENOMEM; 525 if (copy_from_user(params, (void __user *)arg, sizeof(*params))) { 526 retval = -EFAULT; 527 goto out; 528 } 529 530 retval = snd_compress_check_input(params); 531 if (retval) 532 goto out; 533 534 retval = snd_compr_allocate_buffer(stream, params); 535 if (retval) { 536 retval = -ENOMEM; 537 goto out; 538 } 539 540 retval = stream->ops->set_params(stream, params); 541 if (retval) 542 goto out; 543 544 stream->metadata_set = false; 545 stream->next_track = false; 546 547 if (stream->direction == SND_COMPRESS_PLAYBACK) 548 stream->runtime->state = SNDRV_PCM_STATE_SETUP; 549 else 550 stream->runtime->state = SNDRV_PCM_STATE_PREPARED; 551 } else { 552 return -EPERM; 553 } 554 out: 555 kfree(params); 556 return retval; 557 } 558 559 static int 560 snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg) 561 { 562 struct snd_codec *params; 563 int retval; 564 565 if (!stream->ops->get_params) 566 return -EBADFD; 567 568 params = kzalloc(sizeof(*params), GFP_KERNEL); 569 if (!params) 570 return -ENOMEM; 571 retval = stream->ops->get_params(stream, params); 572 if (retval) 573 goto out; 574 if (copy_to_user((char __user *)arg, params, sizeof(*params))) 575 retval = -EFAULT; 576 577 out: 578 kfree(params); 579 return retval; 580 } 581 582 static int 583 snd_compr_get_metadata(struct snd_compr_stream *stream, unsigned long arg) 584 { 585 struct snd_compr_metadata metadata; 586 int retval; 587 588 if (!stream->ops->get_metadata) 589 return -ENXIO; 590 591 if (copy_from_user(&metadata, (void __user *)arg, sizeof(metadata))) 592 return -EFAULT; 593 594 retval = stream->ops->get_metadata(stream, &metadata); 595 if (retval != 0) 596 return retval; 597 598 if (copy_to_user((void __user *)arg, &metadata, sizeof(metadata))) 599 return -EFAULT; 600 601 return 0; 602 } 603 604 static int 605 snd_compr_set_metadata(struct snd_compr_stream *stream, unsigned long arg) 606 { 607 struct snd_compr_metadata metadata; 608 int retval; 609 610 if (!stream->ops->set_metadata) 611 return -ENXIO; 612 /* 613 * we should allow parameter change only when stream has been 614 * opened not in other cases 615 */ 616 if (copy_from_user(&metadata, (void __user *)arg, sizeof(metadata))) 617 return -EFAULT; 618 619 retval = stream->ops->set_metadata(stream, &metadata); 620 stream->metadata_set = true; 621 622 return retval; 623 } 624 625 static inline int 626 snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) 627 { 628 struct snd_compr_tstamp tstamp = {0}; 629 int ret; 630 631 ret = snd_compr_update_tstamp(stream, &tstamp); 632 if (ret == 0) 633 ret = copy_to_user((struct snd_compr_tstamp __user *)arg, 634 &tstamp, sizeof(tstamp)) ? -EFAULT : 0; 635 return ret; 636 } 637 638 static int snd_compr_pause(struct snd_compr_stream *stream) 639 { 640 int retval; 641 642 if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING) 643 return -EPERM; 644 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH); 645 if (!retval) 646 stream->runtime->state = SNDRV_PCM_STATE_PAUSED; 647 return retval; 648 } 649 650 static int snd_compr_resume(struct snd_compr_stream *stream) 651 { 652 int retval; 653 654 if (stream->runtime->state != SNDRV_PCM_STATE_PAUSED) 655 return -EPERM; 656 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE); 657 if (!retval) 658 stream->runtime->state = SNDRV_PCM_STATE_RUNNING; 659 return retval; 660 } 661 662 static int snd_compr_start(struct snd_compr_stream *stream) 663 { 664 int retval; 665 666 if (stream->runtime->state != SNDRV_PCM_STATE_PREPARED) 667 return -EPERM; 668 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_START); 669 if (!retval) 670 stream->runtime->state = SNDRV_PCM_STATE_RUNNING; 671 return retval; 672 } 673 674 static int snd_compr_stop(struct snd_compr_stream *stream) 675 { 676 int retval; 677 678 if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED || 679 stream->runtime->state == SNDRV_PCM_STATE_SETUP) 680 return -EPERM; 681 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP); 682 if (!retval) { 683 snd_compr_drain_notify(stream); 684 stream->runtime->total_bytes_available = 0; 685 stream->runtime->total_bytes_transferred = 0; 686 } 687 return retval; 688 } 689 690 static int snd_compress_wait_for_drain(struct snd_compr_stream *stream) 691 { 692 int ret; 693 694 /* 695 * We are called with lock held. So drop the lock while we wait for 696 * drain complete notfication from the driver 697 * 698 * It is expected that driver will notify the drain completion and then 699 * stream will be moved to SETUP state, even if draining resulted in an 700 * error. We can trigger next track after this. 701 */ 702 stream->runtime->state = SNDRV_PCM_STATE_DRAINING; 703 mutex_unlock(&stream->device->lock); 704 705 /* we wait for drain to complete here, drain can return when 706 * interruption occurred, wait returned error or success. 707 * For the first two cases we don't do anything different here and 708 * return after waking up 709 */ 710 711 ret = wait_event_interruptible(stream->runtime->sleep, 712 (stream->runtime->state != SNDRV_PCM_STATE_DRAINING)); 713 if (ret == -ERESTARTSYS) 714 pr_debug("wait aborted by a signal"); 715 else if (ret) 716 pr_debug("wait for drain failed with %d\n", ret); 717 718 719 wake_up(&stream->runtime->sleep); 720 mutex_lock(&stream->device->lock); 721 722 return ret; 723 } 724 725 static int snd_compr_drain(struct snd_compr_stream *stream) 726 { 727 int retval; 728 729 if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED || 730 stream->runtime->state == SNDRV_PCM_STATE_SETUP) 731 return -EPERM; 732 733 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN); 734 if (retval) { 735 pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval); 736 wake_up(&stream->runtime->sleep); 737 return retval; 738 } 739 740 return snd_compress_wait_for_drain(stream); 741 } 742 743 static int snd_compr_next_track(struct snd_compr_stream *stream) 744 { 745 int retval; 746 747 /* only a running stream can transition to next track */ 748 if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING) 749 return -EPERM; 750 751 /* you can signal next track isf this is intended to be a gapless stream 752 * and current track metadata is set 753 */ 754 if (stream->metadata_set == false) 755 return -EPERM; 756 757 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_NEXT_TRACK); 758 if (retval != 0) 759 return retval; 760 stream->metadata_set = false; 761 stream->next_track = true; 762 return 0; 763 } 764 765 static int snd_compr_partial_drain(struct snd_compr_stream *stream) 766 { 767 int retval; 768 if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED || 769 stream->runtime->state == SNDRV_PCM_STATE_SETUP) 770 return -EPERM; 771 /* stream can be drained only when next track has been signalled */ 772 if (stream->next_track == false) 773 return -EPERM; 774 775 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN); 776 if (retval) { 777 pr_debug("Partial drain returned failure\n"); 778 wake_up(&stream->runtime->sleep); 779 return retval; 780 } 781 782 stream->next_track = false; 783 return snd_compress_wait_for_drain(stream); 784 } 785 786 static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 787 { 788 struct snd_compr_file *data = f->private_data; 789 struct snd_compr_stream *stream; 790 int retval = -ENOTTY; 791 792 if (snd_BUG_ON(!data)) 793 return -EFAULT; 794 stream = &data->stream; 795 if (snd_BUG_ON(!stream)) 796 return -EFAULT; 797 mutex_lock(&stream->device->lock); 798 switch (_IOC_NR(cmd)) { 799 case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION): 800 retval = put_user(SNDRV_COMPRESS_VERSION, 801 (int __user *)arg) ? -EFAULT : 0; 802 break; 803 case _IOC_NR(SNDRV_COMPRESS_GET_CAPS): 804 retval = snd_compr_get_caps(stream, arg); 805 break; 806 case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS): 807 retval = snd_compr_get_codec_caps(stream, arg); 808 break; 809 case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS): 810 retval = snd_compr_set_params(stream, arg); 811 break; 812 case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS): 813 retval = snd_compr_get_params(stream, arg); 814 break; 815 case _IOC_NR(SNDRV_COMPRESS_SET_METADATA): 816 retval = snd_compr_set_metadata(stream, arg); 817 break; 818 case _IOC_NR(SNDRV_COMPRESS_GET_METADATA): 819 retval = snd_compr_get_metadata(stream, arg); 820 break; 821 case _IOC_NR(SNDRV_COMPRESS_TSTAMP): 822 retval = snd_compr_tstamp(stream, arg); 823 break; 824 case _IOC_NR(SNDRV_COMPRESS_AVAIL): 825 retval = snd_compr_ioctl_avail(stream, arg); 826 break; 827 case _IOC_NR(SNDRV_COMPRESS_PAUSE): 828 retval = snd_compr_pause(stream); 829 break; 830 case _IOC_NR(SNDRV_COMPRESS_RESUME): 831 retval = snd_compr_resume(stream); 832 break; 833 case _IOC_NR(SNDRV_COMPRESS_START): 834 retval = snd_compr_start(stream); 835 break; 836 case _IOC_NR(SNDRV_COMPRESS_STOP): 837 retval = snd_compr_stop(stream); 838 break; 839 case _IOC_NR(SNDRV_COMPRESS_DRAIN): 840 retval = snd_compr_drain(stream); 841 break; 842 case _IOC_NR(SNDRV_COMPRESS_PARTIAL_DRAIN): 843 retval = snd_compr_partial_drain(stream); 844 break; 845 case _IOC_NR(SNDRV_COMPRESS_NEXT_TRACK): 846 retval = snd_compr_next_track(stream); 847 break; 848 849 } 850 mutex_unlock(&stream->device->lock); 851 return retval; 852 } 853 854 static const struct file_operations snd_compr_file_ops = { 855 .owner = THIS_MODULE, 856 .open = snd_compr_open, 857 .release = snd_compr_free, 858 .write = snd_compr_write, 859 .read = snd_compr_read, 860 .unlocked_ioctl = snd_compr_ioctl, 861 .mmap = snd_compr_mmap, 862 .poll = snd_compr_poll, 863 }; 864 865 static int snd_compress_dev_register(struct snd_device *device) 866 { 867 int ret = -EINVAL; 868 char str[16]; 869 struct snd_compr *compr; 870 871 if (snd_BUG_ON(!device || !device->device_data)) 872 return -EBADFD; 873 compr = device->device_data; 874 875 sprintf(str, "comprC%iD%i", compr->card->number, compr->device); 876 pr_debug("reg %s for device %s, direction %d\n", str, compr->name, 877 compr->direction); 878 /* register compressed device */ 879 ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS, compr->card, 880 compr->device, &snd_compr_file_ops, compr, str); 881 if (ret < 0) { 882 pr_err("snd_register_device failed\n %d", ret); 883 return ret; 884 } 885 return ret; 886 887 } 888 889 static int snd_compress_dev_disconnect(struct snd_device *device) 890 { 891 struct snd_compr *compr; 892 893 compr = device->device_data; 894 snd_unregister_device(SNDRV_DEVICE_TYPE_COMPRESS, compr->card, 895 compr->device); 896 return 0; 897 } 898 899 /* 900 * snd_compress_new: create new compress device 901 * @card: sound card pointer 902 * @device: device number 903 * @dirn: device direction, should be of type enum snd_compr_direction 904 * @compr: compress device pointer 905 */ 906 int snd_compress_new(struct snd_card *card, int device, 907 int dirn, struct snd_compr *compr) 908 { 909 static struct snd_device_ops ops = { 910 .dev_free = NULL, 911 .dev_register = snd_compress_dev_register, 912 .dev_disconnect = snd_compress_dev_disconnect, 913 }; 914 915 compr->card = card; 916 compr->device = device; 917 compr->direction = dirn; 918 return snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops); 919 } 920 EXPORT_SYMBOL_GPL(snd_compress_new); 921 922 static int snd_compress_add_device(struct snd_compr *device) 923 { 924 int ret; 925 926 if (!device->card) 927 return -EINVAL; 928 929 /* register the card */ 930 ret = snd_card_register(device->card); 931 if (ret) 932 goto out; 933 return 0; 934 935 out: 936 pr_err("failed with %d\n", ret); 937 return ret; 938 939 } 940 941 static int snd_compress_remove_device(struct snd_compr *device) 942 { 943 return snd_card_free(device->card); 944 } 945 946 /** 947 * snd_compress_register - register compressed device 948 * 949 * @device: compressed device to register 950 */ 951 int snd_compress_register(struct snd_compr *device) 952 { 953 int retval; 954 955 if (device->name == NULL || device->dev == NULL || device->ops == NULL) 956 return -EINVAL; 957 958 pr_debug("Registering compressed device %s\n", device->name); 959 if (snd_BUG_ON(!device->ops->open)) 960 return -EINVAL; 961 if (snd_BUG_ON(!device->ops->free)) 962 return -EINVAL; 963 if (snd_BUG_ON(!device->ops->set_params)) 964 return -EINVAL; 965 if (snd_BUG_ON(!device->ops->trigger)) 966 return -EINVAL; 967 968 mutex_init(&device->lock); 969 970 /* register a compressed card */ 971 mutex_lock(&device_mutex); 972 retval = snd_compress_add_device(device); 973 mutex_unlock(&device_mutex); 974 return retval; 975 } 976 EXPORT_SYMBOL_GPL(snd_compress_register); 977 978 int snd_compress_deregister(struct snd_compr *device) 979 { 980 pr_debug("Removing compressed device %s\n", device->name); 981 mutex_lock(&device_mutex); 982 snd_compress_remove_device(device); 983 mutex_unlock(&device_mutex); 984 return 0; 985 } 986 EXPORT_SYMBOL_GPL(snd_compress_deregister); 987 988 static int __init snd_compress_init(void) 989 { 990 return 0; 991 } 992 993 static void __exit snd_compress_exit(void) 994 { 995 } 996 997 module_init(snd_compress_init); 998 module_exit(snd_compress_exit); 999 1000 MODULE_DESCRIPTION("ALSA Compressed offload framework"); 1001 MODULE_AUTHOR("Vinod Koul <vinod.koul@linux.intel.com>"); 1002 MODULE_LICENSE("GPL v2"); 1003