0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define FORMAT(fmt) "%s: %d: " fmt, __func__, __LINE__
0013 #define pr_fmt(fmt) KBUILD_MODNAME ": " FORMAT(fmt)
0014
0015 #include <linux/file.h>
0016 #include <linux/fs.h>
0017 #include <linux/list.h>
0018 #include <linux/math64.h>
0019 #include <linux/mm.h>
0020 #include <linux/mutex.h>
0021 #include <linux/poll.h>
0022 #include <linux/slab.h>
0023 #include <linux/sched.h>
0024 #include <linux/types.h>
0025 #include <linux/uio.h>
0026 #include <linux/uaccess.h>
0027 #include <linux/module.h>
0028 #include <linux/compat.h>
0029 #include <sound/core.h>
0030 #include <sound/initval.h>
0031 #include <sound/info.h>
0032 #include <sound/compress_params.h>
0033 #include <sound/compress_offload.h>
0034 #include <sound/compress_driver.h>
0035
0036
0037
0038
0039 #if _IOC_SIZEBITS < 14
0040 #define COMPR_CODEC_CAPS_OVERFLOW
0041 #endif
0042
0043
0044
0045
0046
0047
0048
0049
0050 struct snd_compr_file {
0051 unsigned long caps;
0052 struct snd_compr_stream stream;
0053 };
0054
0055 static void error_delayed_work(struct work_struct *work);
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 static int snd_compr_open(struct inode *inode, struct file *f)
0076 {
0077 struct snd_compr *compr;
0078 struct snd_compr_file *data;
0079 struct snd_compr_runtime *runtime;
0080 enum snd_compr_direction dirn;
0081 int maj = imajor(inode);
0082 int ret;
0083
0084 if ((f->f_flags & O_ACCMODE) == O_WRONLY)
0085 dirn = SND_COMPRESS_PLAYBACK;
0086 else if ((f->f_flags & O_ACCMODE) == O_RDONLY)
0087 dirn = SND_COMPRESS_CAPTURE;
0088 else
0089 return -EINVAL;
0090
0091 if (maj == snd_major)
0092 compr = snd_lookup_minor_data(iminor(inode),
0093 SNDRV_DEVICE_TYPE_COMPRESS);
0094 else
0095 return -EBADFD;
0096
0097 if (compr == NULL) {
0098 pr_err("no device data!!!\n");
0099 return -ENODEV;
0100 }
0101
0102 if (dirn != compr->direction) {
0103 pr_err("this device doesn't support this direction\n");
0104 snd_card_unref(compr->card);
0105 return -EINVAL;
0106 }
0107
0108 data = kzalloc(sizeof(*data), GFP_KERNEL);
0109 if (!data) {
0110 snd_card_unref(compr->card);
0111 return -ENOMEM;
0112 }
0113
0114 INIT_DELAYED_WORK(&data->stream.error_work, error_delayed_work);
0115
0116 data->stream.ops = compr->ops;
0117 data->stream.direction = dirn;
0118 data->stream.private_data = compr->private_data;
0119 data->stream.device = compr;
0120 runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
0121 if (!runtime) {
0122 kfree(data);
0123 snd_card_unref(compr->card);
0124 return -ENOMEM;
0125 }
0126 runtime->state = SNDRV_PCM_STATE_OPEN;
0127 init_waitqueue_head(&runtime->sleep);
0128 data->stream.runtime = runtime;
0129 f->private_data = (void *)data;
0130 mutex_lock(&compr->lock);
0131 ret = compr->ops->open(&data->stream);
0132 mutex_unlock(&compr->lock);
0133 if (ret) {
0134 kfree(runtime);
0135 kfree(data);
0136 }
0137 snd_card_unref(compr->card);
0138 return ret;
0139 }
0140
0141 static int snd_compr_free(struct inode *inode, struct file *f)
0142 {
0143 struct snd_compr_file *data = f->private_data;
0144 struct snd_compr_runtime *runtime = data->stream.runtime;
0145
0146 cancel_delayed_work_sync(&data->stream.error_work);
0147
0148 switch (runtime->state) {
0149 case SNDRV_PCM_STATE_RUNNING:
0150 case SNDRV_PCM_STATE_DRAINING:
0151 case SNDRV_PCM_STATE_PAUSED:
0152 data->stream.ops->trigger(&data->stream, SNDRV_PCM_TRIGGER_STOP);
0153 break;
0154 default:
0155 break;
0156 }
0157
0158 data->stream.ops->free(&data->stream);
0159 if (!data->stream.runtime->dma_buffer_p)
0160 kfree(data->stream.runtime->buffer);
0161 kfree(data->stream.runtime);
0162 kfree(data);
0163 return 0;
0164 }
0165
0166 static int snd_compr_update_tstamp(struct snd_compr_stream *stream,
0167 struct snd_compr_tstamp *tstamp)
0168 {
0169 if (!stream->ops->pointer)
0170 return -ENOTSUPP;
0171 stream->ops->pointer(stream, tstamp);
0172 pr_debug("dsp consumed till %d total %d bytes\n",
0173 tstamp->byte_offset, tstamp->copied_total);
0174 if (stream->direction == SND_COMPRESS_PLAYBACK)
0175 stream->runtime->total_bytes_transferred = tstamp->copied_total;
0176 else
0177 stream->runtime->total_bytes_available = tstamp->copied_total;
0178 return 0;
0179 }
0180
0181 static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
0182 struct snd_compr_avail *avail)
0183 {
0184 memset(avail, 0, sizeof(*avail));
0185 snd_compr_update_tstamp(stream, &avail->tstamp);
0186
0187
0188 if (stream->runtime->total_bytes_available == 0 &&
0189 stream->runtime->state == SNDRV_PCM_STATE_SETUP &&
0190 stream->direction == SND_COMPRESS_PLAYBACK) {
0191 pr_debug("detected init and someone forgot to do a write\n");
0192 return stream->runtime->buffer_size;
0193 }
0194 pr_debug("app wrote %lld, DSP consumed %lld\n",
0195 stream->runtime->total_bytes_available,
0196 stream->runtime->total_bytes_transferred);
0197 if (stream->runtime->total_bytes_available ==
0198 stream->runtime->total_bytes_transferred) {
0199 if (stream->direction == SND_COMPRESS_PLAYBACK) {
0200 pr_debug("both pointers are same, returning full avail\n");
0201 return stream->runtime->buffer_size;
0202 } else {
0203 pr_debug("both pointers are same, returning no avail\n");
0204 return 0;
0205 }
0206 }
0207
0208 avail->avail = stream->runtime->total_bytes_available -
0209 stream->runtime->total_bytes_transferred;
0210 if (stream->direction == SND_COMPRESS_PLAYBACK)
0211 avail->avail = stream->runtime->buffer_size - avail->avail;
0212
0213 pr_debug("ret avail as %lld\n", avail->avail);
0214 return avail->avail;
0215 }
0216
0217 static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream)
0218 {
0219 struct snd_compr_avail avail;
0220
0221 return snd_compr_calc_avail(stream, &avail);
0222 }
0223
0224 static int
0225 snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg)
0226 {
0227 struct snd_compr_avail ioctl_avail;
0228 size_t avail;
0229
0230 avail = snd_compr_calc_avail(stream, &ioctl_avail);
0231 ioctl_avail.avail = avail;
0232
0233 switch (stream->runtime->state) {
0234 case SNDRV_PCM_STATE_OPEN:
0235 return -EBADFD;
0236 case SNDRV_PCM_STATE_XRUN:
0237 return -EPIPE;
0238 default:
0239 break;
0240 }
0241
0242 if (copy_to_user((__u64 __user *)arg,
0243 &ioctl_avail, sizeof(ioctl_avail)))
0244 return -EFAULT;
0245 return 0;
0246 }
0247
0248 static int snd_compr_write_data(struct snd_compr_stream *stream,
0249 const char __user *buf, size_t count)
0250 {
0251 void *dstn;
0252 size_t copy;
0253 struct snd_compr_runtime *runtime = stream->runtime;
0254
0255 u64 app_pointer = div64_u64(runtime->total_bytes_available,
0256 runtime->buffer_size);
0257 app_pointer = runtime->total_bytes_available -
0258 (app_pointer * runtime->buffer_size);
0259
0260 dstn = runtime->buffer + app_pointer;
0261 pr_debug("copying %ld at %lld\n",
0262 (unsigned long)count, app_pointer);
0263 if (count < runtime->buffer_size - app_pointer) {
0264 if (copy_from_user(dstn, buf, count))
0265 return -EFAULT;
0266 } else {
0267 copy = runtime->buffer_size - app_pointer;
0268 if (copy_from_user(dstn, buf, copy))
0269 return -EFAULT;
0270 if (copy_from_user(runtime->buffer, buf + copy, count - copy))
0271 return -EFAULT;
0272 }
0273
0274 if (stream->ops->ack)
0275 stream->ops->ack(stream, count);
0276 return count;
0277 }
0278
0279 static ssize_t snd_compr_write(struct file *f, const char __user *buf,
0280 size_t count, loff_t *offset)
0281 {
0282 struct snd_compr_file *data = f->private_data;
0283 struct snd_compr_stream *stream;
0284 size_t avail;
0285 int retval;
0286
0287 if (snd_BUG_ON(!data))
0288 return -EFAULT;
0289
0290 stream = &data->stream;
0291 mutex_lock(&stream->device->lock);
0292
0293 switch (stream->runtime->state) {
0294 case SNDRV_PCM_STATE_SETUP:
0295 case SNDRV_PCM_STATE_PREPARED:
0296 case SNDRV_PCM_STATE_RUNNING:
0297 break;
0298 default:
0299 mutex_unlock(&stream->device->lock);
0300 return -EBADFD;
0301 }
0302
0303 avail = snd_compr_get_avail(stream);
0304 pr_debug("avail returned %ld\n", (unsigned long)avail);
0305
0306 if (avail > count)
0307 avail = count;
0308
0309 if (stream->ops->copy) {
0310 char __user* cbuf = (char __user*)buf;
0311 retval = stream->ops->copy(stream, cbuf, avail);
0312 } else {
0313 retval = snd_compr_write_data(stream, buf, avail);
0314 }
0315 if (retval > 0)
0316 stream->runtime->total_bytes_available += retval;
0317
0318
0319
0320 if (stream->runtime->state == SNDRV_PCM_STATE_SETUP) {
0321 stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
0322 pr_debug("stream prepared, Houston we are good to go\n");
0323 }
0324
0325 mutex_unlock(&stream->device->lock);
0326 return retval;
0327 }
0328
0329
0330 static ssize_t snd_compr_read(struct file *f, char __user *buf,
0331 size_t count, loff_t *offset)
0332 {
0333 struct snd_compr_file *data = f->private_data;
0334 struct snd_compr_stream *stream;
0335 size_t avail;
0336 int retval;
0337
0338 if (snd_BUG_ON(!data))
0339 return -EFAULT;
0340
0341 stream = &data->stream;
0342 mutex_lock(&stream->device->lock);
0343
0344
0345
0346
0347
0348 switch (stream->runtime->state) {
0349 case SNDRV_PCM_STATE_OPEN:
0350 case SNDRV_PCM_STATE_PREPARED:
0351 case SNDRV_PCM_STATE_SUSPENDED:
0352 case SNDRV_PCM_STATE_DISCONNECTED:
0353 retval = -EBADFD;
0354 goto out;
0355 case SNDRV_PCM_STATE_XRUN:
0356 retval = -EPIPE;
0357 goto out;
0358 }
0359
0360 avail = snd_compr_get_avail(stream);
0361 pr_debug("avail returned %ld\n", (unsigned long)avail);
0362
0363 if (avail > count)
0364 avail = count;
0365
0366 if (stream->ops->copy) {
0367 retval = stream->ops->copy(stream, buf, avail);
0368 } else {
0369 retval = -ENXIO;
0370 goto out;
0371 }
0372 if (retval > 0)
0373 stream->runtime->total_bytes_transferred += retval;
0374
0375 out:
0376 mutex_unlock(&stream->device->lock);
0377 return retval;
0378 }
0379
0380 static int snd_compr_mmap(struct file *f, struct vm_area_struct *vma)
0381 {
0382 return -ENXIO;
0383 }
0384
0385 static __poll_t snd_compr_get_poll(struct snd_compr_stream *stream)
0386 {
0387 if (stream->direction == SND_COMPRESS_PLAYBACK)
0388 return EPOLLOUT | EPOLLWRNORM;
0389 else
0390 return EPOLLIN | EPOLLRDNORM;
0391 }
0392
0393 static __poll_t snd_compr_poll(struct file *f, poll_table *wait)
0394 {
0395 struct snd_compr_file *data = f->private_data;
0396 struct snd_compr_stream *stream;
0397 size_t avail;
0398 __poll_t retval = 0;
0399
0400 if (snd_BUG_ON(!data))
0401 return EPOLLERR;
0402
0403 stream = &data->stream;
0404
0405 mutex_lock(&stream->device->lock);
0406
0407 switch (stream->runtime->state) {
0408 case SNDRV_PCM_STATE_OPEN:
0409 case SNDRV_PCM_STATE_XRUN:
0410 retval = snd_compr_get_poll(stream) | EPOLLERR;
0411 goto out;
0412 default:
0413 break;
0414 }
0415
0416 poll_wait(f, &stream->runtime->sleep, wait);
0417
0418 avail = snd_compr_get_avail(stream);
0419 pr_debug("avail is %ld\n", (unsigned long)avail);
0420
0421 switch (stream->runtime->state) {
0422 case SNDRV_PCM_STATE_DRAINING:
0423
0424
0425
0426 retval = snd_compr_get_poll(stream);
0427 stream->runtime->state = SNDRV_PCM_STATE_SETUP;
0428 break;
0429 case SNDRV_PCM_STATE_RUNNING:
0430 case SNDRV_PCM_STATE_PREPARED:
0431 case SNDRV_PCM_STATE_PAUSED:
0432 if (avail >= stream->runtime->fragment_size)
0433 retval = snd_compr_get_poll(stream);
0434 break;
0435 default:
0436 retval = snd_compr_get_poll(stream) | EPOLLERR;
0437 break;
0438 }
0439 out:
0440 mutex_unlock(&stream->device->lock);
0441 return retval;
0442 }
0443
0444 static int
0445 snd_compr_get_caps(struct snd_compr_stream *stream, unsigned long arg)
0446 {
0447 int retval;
0448 struct snd_compr_caps caps;
0449
0450 if (!stream->ops->get_caps)
0451 return -ENXIO;
0452
0453 memset(&caps, 0, sizeof(caps));
0454 retval = stream->ops->get_caps(stream, &caps);
0455 if (retval)
0456 goto out;
0457 if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
0458 retval = -EFAULT;
0459 out:
0460 return retval;
0461 }
0462
0463 #ifndef COMPR_CODEC_CAPS_OVERFLOW
0464 static int
0465 snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg)
0466 {
0467 int retval;
0468 struct snd_compr_codec_caps *caps;
0469
0470 if (!stream->ops->get_codec_caps)
0471 return -ENXIO;
0472
0473 caps = kzalloc(sizeof(*caps), GFP_KERNEL);
0474 if (!caps)
0475 return -ENOMEM;
0476
0477 retval = stream->ops->get_codec_caps(stream, caps);
0478 if (retval)
0479 goto out;
0480 if (copy_to_user((void __user *)arg, caps, sizeof(*caps)))
0481 retval = -EFAULT;
0482
0483 out:
0484 kfree(caps);
0485 return retval;
0486 }
0487 #endif
0488
0489 int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size)
0490 {
0491 struct snd_dma_buffer *dmab;
0492 int ret;
0493
0494 if (snd_BUG_ON(!(stream) || !(stream)->runtime))
0495 return -EINVAL;
0496 dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
0497 if (!dmab)
0498 return -ENOMEM;
0499 dmab->dev = stream->dma_buffer.dev;
0500 ret = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, size, dmab);
0501 if (ret < 0) {
0502 kfree(dmab);
0503 return ret;
0504 }
0505
0506 snd_compr_set_runtime_buffer(stream, dmab);
0507 stream->runtime->dma_bytes = size;
0508 return 1;
0509 }
0510 EXPORT_SYMBOL(snd_compr_malloc_pages);
0511
0512 int snd_compr_free_pages(struct snd_compr_stream *stream)
0513 {
0514 struct snd_compr_runtime *runtime;
0515
0516 if (snd_BUG_ON(!(stream) || !(stream)->runtime))
0517 return -EINVAL;
0518 runtime = stream->runtime;
0519 if (runtime->dma_area == NULL)
0520 return 0;
0521 if (runtime->dma_buffer_p != &stream->dma_buffer) {
0522
0523 snd_dma_free_pages(runtime->dma_buffer_p);
0524 kfree(runtime->dma_buffer_p);
0525 }
0526
0527 snd_compr_set_runtime_buffer(stream, NULL);
0528 return 0;
0529 }
0530 EXPORT_SYMBOL(snd_compr_free_pages);
0531
0532
0533 static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
0534 struct snd_compr_params *params)
0535 {
0536 unsigned int buffer_size;
0537 void *buffer = NULL;
0538
0539 buffer_size = params->buffer.fragment_size * params->buffer.fragments;
0540 if (stream->ops->copy) {
0541 buffer = NULL;
0542
0543
0544
0545 } else {
0546 if (stream->runtime->dma_buffer_p) {
0547
0548 if (buffer_size > stream->runtime->dma_buffer_p->bytes)
0549 dev_err(&stream->device->dev,
0550 "Not enough DMA buffer");
0551 else
0552 buffer = stream->runtime->dma_buffer_p->area;
0553
0554 } else {
0555 buffer = kmalloc(buffer_size, GFP_KERNEL);
0556 }
0557
0558 if (!buffer)
0559 return -ENOMEM;
0560 }
0561 stream->runtime->fragment_size = params->buffer.fragment_size;
0562 stream->runtime->fragments = params->buffer.fragments;
0563 stream->runtime->buffer = buffer;
0564 stream->runtime->buffer_size = buffer_size;
0565 return 0;
0566 }
0567
0568 static int snd_compress_check_input(struct snd_compr_params *params)
0569 {
0570
0571 if (params->buffer.fragment_size == 0 ||
0572 params->buffer.fragments > U32_MAX / params->buffer.fragment_size ||
0573 params->buffer.fragments == 0)
0574 return -EINVAL;
0575
0576
0577 if (params->codec.id == 0 || params->codec.id > SND_AUDIOCODEC_MAX)
0578 return -EINVAL;
0579
0580 if (params->codec.ch_in == 0 || params->codec.ch_out == 0)
0581 return -EINVAL;
0582
0583 return 0;
0584 }
0585
0586 static int
0587 snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
0588 {
0589 struct snd_compr_params *params;
0590 int retval;
0591
0592 if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
0593
0594
0595
0596
0597 params = memdup_user((void __user *)arg, sizeof(*params));
0598 if (IS_ERR(params))
0599 return PTR_ERR(params);
0600
0601 retval = snd_compress_check_input(params);
0602 if (retval)
0603 goto out;
0604
0605 retval = snd_compr_allocate_buffer(stream, params);
0606 if (retval) {
0607 retval = -ENOMEM;
0608 goto out;
0609 }
0610
0611 retval = stream->ops->set_params(stream, params);
0612 if (retval)
0613 goto out;
0614
0615 stream->metadata_set = false;
0616 stream->next_track = false;
0617
0618 stream->runtime->state = SNDRV_PCM_STATE_SETUP;
0619 } else {
0620 return -EPERM;
0621 }
0622 out:
0623 kfree(params);
0624 return retval;
0625 }
0626
0627 static int
0628 snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg)
0629 {
0630 struct snd_codec *params;
0631 int retval;
0632
0633 if (!stream->ops->get_params)
0634 return -EBADFD;
0635
0636 params = kzalloc(sizeof(*params), GFP_KERNEL);
0637 if (!params)
0638 return -ENOMEM;
0639 retval = stream->ops->get_params(stream, params);
0640 if (retval)
0641 goto out;
0642 if (copy_to_user((char __user *)arg, params, sizeof(*params)))
0643 retval = -EFAULT;
0644
0645 out:
0646 kfree(params);
0647 return retval;
0648 }
0649
0650 static int
0651 snd_compr_get_metadata(struct snd_compr_stream *stream, unsigned long arg)
0652 {
0653 struct snd_compr_metadata metadata;
0654 int retval;
0655
0656 if (!stream->ops->get_metadata)
0657 return -ENXIO;
0658
0659 if (copy_from_user(&metadata, (void __user *)arg, sizeof(metadata)))
0660 return -EFAULT;
0661
0662 retval = stream->ops->get_metadata(stream, &metadata);
0663 if (retval != 0)
0664 return retval;
0665
0666 if (copy_to_user((void __user *)arg, &metadata, sizeof(metadata)))
0667 return -EFAULT;
0668
0669 return 0;
0670 }
0671
0672 static int
0673 snd_compr_set_metadata(struct snd_compr_stream *stream, unsigned long arg)
0674 {
0675 struct snd_compr_metadata metadata;
0676 int retval;
0677
0678 if (!stream->ops->set_metadata)
0679 return -ENXIO;
0680
0681
0682
0683
0684 if (copy_from_user(&metadata, (void __user *)arg, sizeof(metadata)))
0685 return -EFAULT;
0686
0687 retval = stream->ops->set_metadata(stream, &metadata);
0688 stream->metadata_set = true;
0689
0690 return retval;
0691 }
0692
0693 static inline int
0694 snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg)
0695 {
0696 struct snd_compr_tstamp tstamp = {0};
0697 int ret;
0698
0699 ret = snd_compr_update_tstamp(stream, &tstamp);
0700 if (ret == 0)
0701 ret = copy_to_user((struct snd_compr_tstamp __user *)arg,
0702 &tstamp, sizeof(tstamp)) ? -EFAULT : 0;
0703 return ret;
0704 }
0705
0706 static int snd_compr_pause(struct snd_compr_stream *stream)
0707 {
0708 int retval;
0709
0710 switch (stream->runtime->state) {
0711 case SNDRV_PCM_STATE_RUNNING:
0712 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
0713 if (!retval)
0714 stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
0715 break;
0716 case SNDRV_PCM_STATE_DRAINING:
0717 if (!stream->device->use_pause_in_draining)
0718 return -EPERM;
0719 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
0720 if (!retval)
0721 stream->pause_in_draining = true;
0722 break;
0723 default:
0724 return -EPERM;
0725 }
0726 return retval;
0727 }
0728
0729 static int snd_compr_resume(struct snd_compr_stream *stream)
0730 {
0731 int retval;
0732
0733 switch (stream->runtime->state) {
0734 case SNDRV_PCM_STATE_PAUSED:
0735 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
0736 if (!retval)
0737 stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
0738 break;
0739 case SNDRV_PCM_STATE_DRAINING:
0740 if (!stream->pause_in_draining)
0741 return -EPERM;
0742 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
0743 if (!retval)
0744 stream->pause_in_draining = false;
0745 break;
0746 default:
0747 return -EPERM;
0748 }
0749 return retval;
0750 }
0751
0752 static int snd_compr_start(struct snd_compr_stream *stream)
0753 {
0754 int retval;
0755
0756 switch (stream->runtime->state) {
0757 case SNDRV_PCM_STATE_SETUP:
0758 if (stream->direction != SND_COMPRESS_CAPTURE)
0759 return -EPERM;
0760 break;
0761 case SNDRV_PCM_STATE_PREPARED:
0762 break;
0763 default:
0764 return -EPERM;
0765 }
0766
0767 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_START);
0768 if (!retval)
0769 stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
0770 return retval;
0771 }
0772
0773 static int snd_compr_stop(struct snd_compr_stream *stream)
0774 {
0775 int retval;
0776
0777 switch (stream->runtime->state) {
0778 case SNDRV_PCM_STATE_OPEN:
0779 case SNDRV_PCM_STATE_SETUP:
0780 case SNDRV_PCM_STATE_PREPARED:
0781 return -EPERM;
0782 default:
0783 break;
0784 }
0785
0786 retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
0787 if (!retval) {
0788
0789 stream->partial_drain = false;
0790 stream->metadata_set = false;
0791 stream->pause_in_draining = false;
0792 snd_compr_drain_notify(stream);
0793 stream->runtime->total_bytes_available = 0;
0794 stream->runtime->total_bytes_transferred = 0;
0795 }
0796 return retval;
0797 }
0798
0799 static void error_delayed_work(struct work_struct *work)
0800 {
0801 struct snd_compr_stream *stream;
0802
0803 stream = container_of(work, struct snd_compr_stream, error_work.work);
0804
0805 mutex_lock(&stream->device->lock);
0806
0807 stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
0808 wake_up(&stream->runtime->sleep);
0809
0810 mutex_unlock(&stream->device->lock);
0811 }
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824 int snd_compr_stop_error(struct snd_compr_stream *stream,
0825 snd_pcm_state_t state)
0826 {
0827 if (stream->runtime->state == state)
0828 return 0;
0829
0830 stream->runtime->state = state;
0831
0832 pr_debug("Changing state to: %d\n", state);
0833
0834 queue_delayed_work(system_power_efficient_wq, &stream->error_work, 0);
0835
0836 return 0;
0837 }
0838 EXPORT_SYMBOL_GPL(snd_compr_stop_error);
0839
0840 static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
0841 {
0842 int ret;
0843
0844
0845
0846
0847
0848
0849
0850
0851
0852 stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
0853 mutex_unlock(&stream->device->lock);
0854
0855
0856
0857
0858
0859
0860
0861 ret = wait_event_interruptible(stream->runtime->sleep,
0862 (stream->runtime->state != SNDRV_PCM_STATE_DRAINING));
0863 if (ret == -ERESTARTSYS)
0864 pr_debug("wait aborted by a signal\n");
0865 else if (ret)
0866 pr_debug("wait for drain failed with %d\n", ret);
0867
0868
0869 wake_up(&stream->runtime->sleep);
0870 mutex_lock(&stream->device->lock);
0871
0872 return ret;
0873 }
0874
0875 static int snd_compr_drain(struct snd_compr_stream *stream)
0876 {
0877 int retval;
0878
0879 switch (stream->runtime->state) {
0880 case SNDRV_PCM_STATE_OPEN:
0881 case SNDRV_PCM_STATE_SETUP:
0882 case SNDRV_PCM_STATE_PREPARED:
0883 case SNDRV_PCM_STATE_PAUSED:
0884 return -EPERM;
0885 case SNDRV_PCM_STATE_XRUN:
0886 return -EPIPE;
0887 default:
0888 break;
0889 }
0890
0891 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
0892 if (retval) {
0893 pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
0894 wake_up(&stream->runtime->sleep);
0895 return retval;
0896 }
0897
0898 return snd_compress_wait_for_drain(stream);
0899 }
0900
0901 static int snd_compr_next_track(struct snd_compr_stream *stream)
0902 {
0903 int retval;
0904
0905
0906 if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
0907 return -EPERM;
0908
0909
0910 if (stream->direction == SND_COMPRESS_CAPTURE)
0911 return -EPERM;
0912
0913
0914
0915
0916 if (stream->metadata_set == false)
0917 return -EPERM;
0918
0919 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_NEXT_TRACK);
0920 if (retval != 0)
0921 return retval;
0922 stream->metadata_set = false;
0923 stream->next_track = true;
0924 return 0;
0925 }
0926
0927 static int snd_compr_partial_drain(struct snd_compr_stream *stream)
0928 {
0929 int retval;
0930
0931 switch (stream->runtime->state) {
0932 case SNDRV_PCM_STATE_OPEN:
0933 case SNDRV_PCM_STATE_SETUP:
0934 case SNDRV_PCM_STATE_PREPARED:
0935 case SNDRV_PCM_STATE_PAUSED:
0936 return -EPERM;
0937 case SNDRV_PCM_STATE_XRUN:
0938 return -EPIPE;
0939 default:
0940 break;
0941 }
0942
0943
0944 if (stream->direction == SND_COMPRESS_CAPTURE)
0945 return -EPERM;
0946
0947
0948 if (stream->next_track == false)
0949 return -EPERM;
0950
0951 stream->partial_drain = true;
0952 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN);
0953 if (retval) {
0954 pr_debug("Partial drain returned failure\n");
0955 wake_up(&stream->runtime->sleep);
0956 return retval;
0957 }
0958
0959 stream->next_track = false;
0960 return snd_compress_wait_for_drain(stream);
0961 }
0962
0963 static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
0964 {
0965 struct snd_compr_file *data = f->private_data;
0966 struct snd_compr_stream *stream;
0967 int retval = -ENOTTY;
0968
0969 if (snd_BUG_ON(!data))
0970 return -EFAULT;
0971
0972 stream = &data->stream;
0973
0974 mutex_lock(&stream->device->lock);
0975 switch (_IOC_NR(cmd)) {
0976 case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
0977 retval = put_user(SNDRV_COMPRESS_VERSION,
0978 (int __user *)arg) ? -EFAULT : 0;
0979 break;
0980 case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
0981 retval = snd_compr_get_caps(stream, arg);
0982 break;
0983 #ifndef COMPR_CODEC_CAPS_OVERFLOW
0984 case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
0985 retval = snd_compr_get_codec_caps(stream, arg);
0986 break;
0987 #endif
0988 case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS):
0989 retval = snd_compr_set_params(stream, arg);
0990 break;
0991 case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS):
0992 retval = snd_compr_get_params(stream, arg);
0993 break;
0994 case _IOC_NR(SNDRV_COMPRESS_SET_METADATA):
0995 retval = snd_compr_set_metadata(stream, arg);
0996 break;
0997 case _IOC_NR(SNDRV_COMPRESS_GET_METADATA):
0998 retval = snd_compr_get_metadata(stream, arg);
0999 break;
1000 case _IOC_NR(SNDRV_COMPRESS_TSTAMP):
1001 retval = snd_compr_tstamp(stream, arg);
1002 break;
1003 case _IOC_NR(SNDRV_COMPRESS_AVAIL):
1004 retval = snd_compr_ioctl_avail(stream, arg);
1005 break;
1006 case _IOC_NR(SNDRV_COMPRESS_PAUSE):
1007 retval = snd_compr_pause(stream);
1008 break;
1009 case _IOC_NR(SNDRV_COMPRESS_RESUME):
1010 retval = snd_compr_resume(stream);
1011 break;
1012 case _IOC_NR(SNDRV_COMPRESS_START):
1013 retval = snd_compr_start(stream);
1014 break;
1015 case _IOC_NR(SNDRV_COMPRESS_STOP):
1016 retval = snd_compr_stop(stream);
1017 break;
1018 case _IOC_NR(SNDRV_COMPRESS_DRAIN):
1019 retval = snd_compr_drain(stream);
1020 break;
1021 case _IOC_NR(SNDRV_COMPRESS_PARTIAL_DRAIN):
1022 retval = snd_compr_partial_drain(stream);
1023 break;
1024 case _IOC_NR(SNDRV_COMPRESS_NEXT_TRACK):
1025 retval = snd_compr_next_track(stream);
1026 break;
1027
1028 }
1029 mutex_unlock(&stream->device->lock);
1030 return retval;
1031 }
1032
1033
1034 #ifdef CONFIG_COMPAT
1035 static long snd_compr_ioctl_compat(struct file *file, unsigned int cmd,
1036 unsigned long arg)
1037 {
1038 return snd_compr_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
1039 }
1040 #endif
1041
1042 static const struct file_operations snd_compr_file_ops = {
1043 .owner = THIS_MODULE,
1044 .open = snd_compr_open,
1045 .release = snd_compr_free,
1046 .write = snd_compr_write,
1047 .read = snd_compr_read,
1048 .unlocked_ioctl = snd_compr_ioctl,
1049 #ifdef CONFIG_COMPAT
1050 .compat_ioctl = snd_compr_ioctl_compat,
1051 #endif
1052 .mmap = snd_compr_mmap,
1053 .poll = snd_compr_poll,
1054 };
1055
1056 static int snd_compress_dev_register(struct snd_device *device)
1057 {
1058 int ret;
1059 struct snd_compr *compr;
1060
1061 if (snd_BUG_ON(!device || !device->device_data))
1062 return -EBADFD;
1063 compr = device->device_data;
1064
1065 pr_debug("reg device %s, direction %d\n", compr->name,
1066 compr->direction);
1067
1068 ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS,
1069 compr->card, compr->device,
1070 &snd_compr_file_ops, compr, &compr->dev);
1071 if (ret < 0) {
1072 pr_err("snd_register_device failed %d\n", ret);
1073 return ret;
1074 }
1075 return ret;
1076
1077 }
1078
1079 static int snd_compress_dev_disconnect(struct snd_device *device)
1080 {
1081 struct snd_compr *compr;
1082
1083 compr = device->device_data;
1084 snd_unregister_device(&compr->dev);
1085 return 0;
1086 }
1087
1088 #ifdef CONFIG_SND_VERBOSE_PROCFS
1089 static void snd_compress_proc_info_read(struct snd_info_entry *entry,
1090 struct snd_info_buffer *buffer)
1091 {
1092 struct snd_compr *compr = (struct snd_compr *)entry->private_data;
1093
1094 snd_iprintf(buffer, "card: %d\n", compr->card->number);
1095 snd_iprintf(buffer, "device: %d\n", compr->device);
1096 snd_iprintf(buffer, "stream: %s\n",
1097 compr->direction == SND_COMPRESS_PLAYBACK
1098 ? "PLAYBACK" : "CAPTURE");
1099 snd_iprintf(buffer, "id: %s\n", compr->id);
1100 }
1101
1102 static int snd_compress_proc_init(struct snd_compr *compr)
1103 {
1104 struct snd_info_entry *entry;
1105 char name[16];
1106
1107 sprintf(name, "compr%i", compr->device);
1108 entry = snd_info_create_card_entry(compr->card, name,
1109 compr->card->proc_root);
1110 if (!entry)
1111 return -ENOMEM;
1112 entry->mode = S_IFDIR | 0555;
1113 compr->proc_root = entry;
1114
1115 entry = snd_info_create_card_entry(compr->card, "info",
1116 compr->proc_root);
1117 if (entry)
1118 snd_info_set_text_ops(entry, compr,
1119 snd_compress_proc_info_read);
1120 compr->proc_info_entry = entry;
1121
1122 return 0;
1123 }
1124
1125 static void snd_compress_proc_done(struct snd_compr *compr)
1126 {
1127 snd_info_free_entry(compr->proc_info_entry);
1128 compr->proc_info_entry = NULL;
1129 snd_info_free_entry(compr->proc_root);
1130 compr->proc_root = NULL;
1131 }
1132
1133 static inline void snd_compress_set_id(struct snd_compr *compr, const char *id)
1134 {
1135 strscpy(compr->id, id, sizeof(compr->id));
1136 }
1137 #else
1138 static inline int snd_compress_proc_init(struct snd_compr *compr)
1139 {
1140 return 0;
1141 }
1142
1143 static inline void snd_compress_proc_done(struct snd_compr *compr)
1144 {
1145 }
1146
1147 static inline void snd_compress_set_id(struct snd_compr *compr, const char *id)
1148 {
1149 }
1150 #endif
1151
1152 static int snd_compress_dev_free(struct snd_device *device)
1153 {
1154 struct snd_compr *compr;
1155
1156 compr = device->device_data;
1157 snd_compress_proc_done(compr);
1158 put_device(&compr->dev);
1159 return 0;
1160 }
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172 int snd_compress_new(struct snd_card *card, int device,
1173 int dirn, const char *id, struct snd_compr *compr)
1174 {
1175 static const struct snd_device_ops ops = {
1176 .dev_free = snd_compress_dev_free,
1177 .dev_register = snd_compress_dev_register,
1178 .dev_disconnect = snd_compress_dev_disconnect,
1179 };
1180 int ret;
1181
1182 compr->card = card;
1183 compr->device = device;
1184 compr->direction = dirn;
1185 mutex_init(&compr->lock);
1186
1187 snd_compress_set_id(compr, id);
1188
1189 snd_device_initialize(&compr->dev, card);
1190 dev_set_name(&compr->dev, "comprC%iD%i", card->number, device);
1191
1192 ret = snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);
1193 if (ret == 0)
1194 snd_compress_proc_init(compr);
1195
1196 return ret;
1197 }
1198 EXPORT_SYMBOL_GPL(snd_compress_new);
1199
1200 MODULE_DESCRIPTION("ALSA Compressed offload framework");
1201 MODULE_AUTHOR("Vinod Koul <vinod.koul@linux.intel.com>");
1202 MODULE_LICENSE("GPL v2");