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