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