aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/core/compress_offload.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 2d620688cfb7..c84abc886e90 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -486,6 +486,8 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
486 if (retval) 486 if (retval)
487 goto out; 487 goto out;
488 stream->runtime->state = SNDRV_PCM_STATE_SETUP; 488 stream->runtime->state = SNDRV_PCM_STATE_SETUP;
489 stream->metadata_set = false;
490 stream->next_track = false;
489 } else { 491 } else {
490 return -EPERM; 492 return -EPERM;
491 } 493 }
@@ -517,6 +519,49 @@ out:
517 return retval; 519 return retval;
518} 520}
519 521
522static int
523snd_compr_get_metadata(struct snd_compr_stream *stream, unsigned long arg)
524{
525 struct snd_compr_metadata metadata;
526 int retval;
527
528 if (!stream->ops->get_metadata)
529 return -ENXIO;
530
531 if (copy_from_user(&metadata, (void __user *)arg, sizeof(metadata)))
532 return -EFAULT;
533
534 retval = stream->ops->get_metadata(stream, &metadata);
535 if (retval != 0)
536 return retval;
537
538 if (copy_to_user((void __user *)arg, &metadata, sizeof(metadata)))
539 return -EFAULT;
540
541 return 0;
542}
543
544static int
545snd_compr_set_metadata(struct snd_compr_stream *stream, unsigned long arg)
546{
547 struct snd_compr_metadata metadata;
548 int retval;
549
550 if (!stream->ops->set_metadata)
551 return -ENXIO;
552 /*
553 * we should allow parameter change only when stream has been
554 * opened not in other cases
555 */
556 if (copy_from_user(&metadata, (void __user *)arg, sizeof(metadata)))
557 return -EFAULT;
558
559 retval = stream->ops->set_metadata(stream, &metadata);
560 stream->metadata_set = true;
561
562 return retval;
563}
564
520static inline int 565static inline int
521snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) 566snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg)
522{ 567{
@@ -600,6 +645,44 @@ static int snd_compr_drain(struct snd_compr_stream *stream)
600 return retval; 645 return retval;
601} 646}
602 647
648static int snd_compr_next_track(struct snd_compr_stream *stream)
649{
650 int retval;
651
652 /* only a running stream can transition to next track */
653 if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
654 return -EPERM;
655
656 /* you can signal next track isf this is intended to be a gapless stream
657 * and current track metadata is set
658 */
659 if (stream->metadata_set == false)
660 return -EPERM;
661
662 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_NEXT_TRACK);
663 if (retval != 0)
664 return retval;
665 stream->metadata_set = false;
666 stream->next_track = true;
667 return 0;
668}
669
670static int snd_compr_partial_drain(struct snd_compr_stream *stream)
671{
672 int retval;
673 if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED ||
674 stream->runtime->state == SNDRV_PCM_STATE_SETUP)
675 return -EPERM;
676 /* stream can be drained only when next track has been signalled */
677 if (stream->next_track == false)
678 return -EPERM;
679
680 retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN);
681
682 stream->next_track = false;
683 return retval;
684}
685
603static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 686static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
604{ 687{
605 struct snd_compr_file *data = f->private_data; 688 struct snd_compr_file *data = f->private_data;
@@ -629,6 +712,12 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
629 case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS): 712 case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS):
630 retval = snd_compr_get_params(stream, arg); 713 retval = snd_compr_get_params(stream, arg);
631 break; 714 break;
715 case _IOC_NR(SNDRV_COMPRESS_SET_METADATA):
716 retval = snd_compr_set_metadata(stream, arg);
717 break;
718 case _IOC_NR(SNDRV_COMPRESS_GET_METADATA):
719 retval = snd_compr_get_metadata(stream, arg);
720 break;
632 case _IOC_NR(SNDRV_COMPRESS_TSTAMP): 721 case _IOC_NR(SNDRV_COMPRESS_TSTAMP):
633 retval = snd_compr_tstamp(stream, arg); 722 retval = snd_compr_tstamp(stream, arg);
634 break; 723 break;
@@ -650,6 +739,13 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
650 case _IOC_NR(SNDRV_COMPRESS_DRAIN): 739 case _IOC_NR(SNDRV_COMPRESS_DRAIN):
651 retval = snd_compr_drain(stream); 740 retval = snd_compr_drain(stream);
652 break; 741 break;
742 case _IOC_NR(SNDRV_COMPRESS_PARTIAL_DRAIN):
743 retval = snd_compr_partial_drain(stream);
744 break;
745 case _IOC_NR(SNDRV_COMPRESS_NEXT_TRACK):
746 retval = snd_compr_next_track(stream);
747 break;
748
653 } 749 }
654 mutex_unlock(&stream->device->lock); 750 mutex_unlock(&stream->device->lock);
655 return retval; 751 return retval;