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