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