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