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