xref: /openbmc/linux/sound/soc/soc-compress.c (revision 78560d41)
1 // SPDX-License-Identifier: GPL-2.0+
2 //
3 // soc-compress.c  --  ALSA SoC Compress
4 //
5 // Copyright (C) 2012 Intel Corp.
6 //
7 // Authors: Namarta Kohli <namartax.kohli@intel.com>
8 //          Ramesh Babu K V <ramesh.babu@linux.intel.com>
9 //          Vinod Koul <vinod.koul@linux.intel.com>
10 
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/delay.h>
14 #include <linux/slab.h>
15 #include <linux/workqueue.h>
16 #include <sound/core.h>
17 #include <sound/compress_params.h>
18 #include <sound/compress_driver.h>
19 #include <sound/soc.h>
20 #include <sound/initval.h>
21 #include <sound/soc-dpcm.h>
22 #include <linux/pm_runtime.h>
23 
24 static int soc_compr_components_open(struct snd_compr_stream *cstream,
25 				     struct snd_soc_component **last)
26 {
27 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
28 	struct snd_soc_component *component;
29 	int i, ret;
30 
31 	for_each_rtd_components(rtd, i, component) {
32 		if (!component->driver->compr_ops ||
33 		    !component->driver->compr_ops->open)
34 			continue;
35 
36 		ret = component->driver->compr_ops->open(cstream);
37 		if (ret < 0) {
38 			dev_err(component->dev,
39 				"Compress ASoC: can't open platform %s: %d\n",
40 				component->name, ret);
41 
42 			*last = component;
43 			return ret;
44 		}
45 	}
46 
47 	*last = NULL;
48 	return 0;
49 }
50 
51 static int soc_compr_components_free(struct snd_compr_stream *cstream,
52 				     struct snd_soc_component *last)
53 {
54 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
55 	struct snd_soc_component *component;
56 	int i;
57 
58 	for_each_rtd_components(rtd, i, component) {
59 		if (component == last)
60 			break;
61 
62 		if (!component->driver->compr_ops ||
63 		    !component->driver->compr_ops->free)
64 			continue;
65 
66 		component->driver->compr_ops->free(cstream);
67 	}
68 
69 	return 0;
70 }
71 
72 static int soc_compr_open(struct snd_compr_stream *cstream)
73 {
74 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
75 	struct snd_soc_component *component, *save = NULL;
76 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
77 	int ret, i;
78 
79 	for_each_rtd_components(rtd, i, component) {
80 		ret = pm_runtime_get_sync(component->dev);
81 		if (ret < 0 && ret != -EACCES) {
82 			pm_runtime_put_noidle(component->dev);
83 			save = component;
84 			goto pm_err;
85 		}
86 	}
87 
88 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
89 
90 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
91 		ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
92 		if (ret < 0) {
93 			dev_err(cpu_dai->dev,
94 				"Compress ASoC: can't open interface %s: %d\n",
95 				cpu_dai->name, ret);
96 			goto out;
97 		}
98 	}
99 
100 	ret = soc_compr_components_open(cstream, &component);
101 	if (ret < 0)
102 		goto machine_err;
103 
104 	if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
105 		ret = rtd->dai_link->compr_ops->startup(cstream);
106 		if (ret < 0) {
107 			dev_err(rtd->dev,
108 				"Compress ASoC: %s startup failed: %d\n",
109 				rtd->dai_link->name, ret);
110 			goto machine_err;
111 		}
112 	}
113 
114 	snd_soc_runtime_activate(rtd, cstream->direction);
115 
116 	mutex_unlock(&rtd->card->pcm_mutex);
117 
118 	return 0;
119 
120 machine_err:
121 	soc_compr_components_free(cstream, component);
122 
123 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
124 		cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
125 out:
126 	mutex_unlock(&rtd->card->pcm_mutex);
127 pm_err:
128 	for_each_rtd_components(rtd, i, component) {
129 		if (component == save)
130 			break;
131 		pm_runtime_mark_last_busy(component->dev);
132 		pm_runtime_put_autosuspend(component->dev);
133 	}
134 
135 	return ret;
136 }
137 
138 static int soc_compr_open_fe(struct snd_compr_stream *cstream)
139 {
140 	struct snd_soc_pcm_runtime *fe = cstream->private_data;
141 	struct snd_pcm_substream *fe_substream =
142 		 fe->pcm->streams[cstream->direction].substream;
143 	struct snd_soc_component *component;
144 	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
145 	struct snd_soc_dpcm *dpcm;
146 	struct snd_soc_dapm_widget_list *list;
147 	int stream;
148 	int ret;
149 
150 	if (cstream->direction == SND_COMPRESS_PLAYBACK)
151 		stream = SNDRV_PCM_STREAM_PLAYBACK;
152 	else
153 		stream = SNDRV_PCM_STREAM_CAPTURE;
154 
155 	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
156 	fe->dpcm[stream].runtime = fe_substream->runtime;
157 
158 	ret = dpcm_path_get(fe, stream, &list);
159 	if (ret < 0)
160 		goto be_err;
161 	else if (ret == 0)
162 		dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
163 			fe->dai_link->name, stream ? "capture" : "playback");
164 	/* calculate valid and active FE <-> BE dpcms */
165 	dpcm_process_paths(fe, stream, &list, 1);
166 	fe->dpcm[stream].runtime = fe_substream->runtime;
167 
168 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
169 
170 	ret = dpcm_be_dai_startup(fe, stream);
171 	if (ret < 0) {
172 		/* clean up all links */
173 		for_each_dpcm_be(fe, stream, dpcm)
174 			dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
175 
176 		dpcm_be_disconnect(fe, stream);
177 		fe->dpcm[stream].runtime = NULL;
178 		goto out;
179 	}
180 
181 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
182 		ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
183 		if (ret < 0) {
184 			dev_err(cpu_dai->dev,
185 				"Compress ASoC: can't open interface %s: %d\n",
186 				cpu_dai->name, ret);
187 			goto out;
188 		}
189 	}
190 
191 	ret = soc_compr_components_open(cstream, &component);
192 	if (ret < 0)
193 		goto open_err;
194 
195 	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
196 		ret = fe->dai_link->compr_ops->startup(cstream);
197 		if (ret < 0) {
198 			pr_err("Compress ASoC: %s startup failed: %d\n",
199 			       fe->dai_link->name, ret);
200 			goto machine_err;
201 		}
202 	}
203 
204 	dpcm_clear_pending_state(fe, stream);
205 	dpcm_path_put(&list);
206 
207 	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
208 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
209 
210 	snd_soc_runtime_activate(fe, stream);
211 
212 	mutex_unlock(&fe->card->mutex);
213 
214 	return 0;
215 
216 machine_err:
217 	soc_compr_components_free(cstream, component);
218 open_err:
219 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
220 		cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
221 out:
222 	dpcm_path_put(&list);
223 be_err:
224 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
225 	mutex_unlock(&fe->card->mutex);
226 	return ret;
227 }
228 
229 static int soc_compr_free(struct snd_compr_stream *cstream)
230 {
231 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
232 	struct snd_soc_component *component;
233 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
234 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
235 	int stream, i;
236 
237 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
238 
239 	if (cstream->direction == SND_COMPRESS_PLAYBACK)
240 		stream = SNDRV_PCM_STREAM_PLAYBACK;
241 	else
242 		stream = SNDRV_PCM_STREAM_CAPTURE;
243 
244 	snd_soc_runtime_deactivate(rtd, stream);
245 
246 	snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
247 
248 	if (!cpu_dai->active)
249 		cpu_dai->rate = 0;
250 
251 	if (!codec_dai->active)
252 		codec_dai->rate = 0;
253 
254 	if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
255 		rtd->dai_link->compr_ops->shutdown(cstream);
256 
257 	soc_compr_components_free(cstream, NULL);
258 
259 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
260 		cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
261 
262 	snd_soc_dapm_stream_stop(rtd, stream);
263 
264 	mutex_unlock(&rtd->card->pcm_mutex);
265 
266 	for_each_rtd_components(rtd, i, component) {
267 		pm_runtime_mark_last_busy(component->dev);
268 		pm_runtime_put_autosuspend(component->dev);
269 	}
270 
271 	return 0;
272 }
273 
274 static int soc_compr_free_fe(struct snd_compr_stream *cstream)
275 {
276 	struct snd_soc_pcm_runtime *fe = cstream->private_data;
277 	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
278 	struct snd_soc_dpcm *dpcm;
279 	int stream, ret;
280 
281 	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
282 
283 	if (cstream->direction == SND_COMPRESS_PLAYBACK)
284 		stream = SNDRV_PCM_STREAM_PLAYBACK;
285 	else
286 		stream = SNDRV_PCM_STREAM_CAPTURE;
287 
288 	snd_soc_runtime_deactivate(fe, stream);
289 
290 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
291 
292 	ret = dpcm_be_dai_hw_free(fe, stream);
293 	if (ret < 0)
294 		dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
295 
296 	ret = dpcm_be_dai_shutdown(fe, stream);
297 
298 	/* mark FE's links ready to prune */
299 	for_each_dpcm_be(fe, stream, dpcm)
300 		dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
301 
302 	snd_soc_dapm_stream_stop(fe, stream);
303 
304 	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
305 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
306 
307 	dpcm_be_disconnect(fe, stream);
308 
309 	fe->dpcm[stream].runtime = NULL;
310 
311 	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
312 		fe->dai_link->compr_ops->shutdown(cstream);
313 
314 	soc_compr_components_free(cstream, NULL);
315 
316 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
317 		cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
318 
319 	mutex_unlock(&fe->card->mutex);
320 	return 0;
321 }
322 
323 static int soc_compr_components_trigger(struct snd_compr_stream *cstream,
324 					int cmd)
325 {
326 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
327 	struct snd_soc_component *component;
328 	int i, ret;
329 
330 	for_each_rtd_components(rtd, i, component) {
331 		if (!component->driver->compr_ops ||
332 		    !component->driver->compr_ops->trigger)
333 			continue;
334 
335 		ret = component->driver->compr_ops->trigger(cstream, cmd);
336 		if (ret < 0)
337 			return ret;
338 	}
339 
340 	return 0;
341 }
342 
343 static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
344 {
345 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
346 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
347 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
348 	int ret;
349 
350 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
351 
352 	ret = soc_compr_components_trigger(cstream, cmd);
353 	if (ret < 0)
354 		goto out;
355 
356 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
357 		cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
358 
359 	switch (cmd) {
360 	case SNDRV_PCM_TRIGGER_START:
361 		snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
362 		break;
363 	case SNDRV_PCM_TRIGGER_STOP:
364 		snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
365 		break;
366 	}
367 
368 out:
369 	mutex_unlock(&rtd->card->pcm_mutex);
370 	return ret;
371 }
372 
373 static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
374 {
375 	struct snd_soc_pcm_runtime *fe = cstream->private_data;
376 	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
377 	int ret, stream;
378 
379 	if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
380 	    cmd == SND_COMPR_TRIGGER_DRAIN)
381 		return soc_compr_components_trigger(cstream, cmd);
382 
383 	if (cstream->direction == SND_COMPRESS_PLAYBACK)
384 		stream = SNDRV_PCM_STREAM_PLAYBACK;
385 	else
386 		stream = SNDRV_PCM_STREAM_CAPTURE;
387 
388 	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
389 
390 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) {
391 		ret = cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
392 		if (ret < 0)
393 			goto out;
394 	}
395 
396 	ret = soc_compr_components_trigger(cstream, cmd);
397 	if (ret < 0)
398 		goto out;
399 
400 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
401 
402 	ret = dpcm_be_dai_trigger(fe, stream, cmd);
403 
404 	switch (cmd) {
405 	case SNDRV_PCM_TRIGGER_START:
406 	case SNDRV_PCM_TRIGGER_RESUME:
407 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
408 		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
409 		break;
410 	case SNDRV_PCM_TRIGGER_STOP:
411 	case SNDRV_PCM_TRIGGER_SUSPEND:
412 		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
413 		break;
414 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
415 		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
416 		break;
417 	}
418 
419 out:
420 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
421 	mutex_unlock(&fe->card->mutex);
422 	return ret;
423 }
424 
425 static int soc_compr_components_set_params(struct snd_compr_stream *cstream,
426 					   struct snd_compr_params *params)
427 {
428 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
429 	struct snd_soc_component *component;
430 	int i, ret;
431 
432 	for_each_rtd_components(rtd, i, component) {
433 		if (!component->driver->compr_ops ||
434 		    !component->driver->compr_ops->set_params)
435 			continue;
436 
437 		ret = component->driver->compr_ops->set_params(cstream, params);
438 		if (ret < 0)
439 			return ret;
440 	}
441 
442 	return 0;
443 }
444 
445 static int soc_compr_set_params(struct snd_compr_stream *cstream,
446 				struct snd_compr_params *params)
447 {
448 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
449 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
450 	int ret;
451 
452 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
453 
454 	/*
455 	 * First we call set_params for the CPU DAI, then the component
456 	 * driver this should configure the SoC side. If the machine has
457 	 * compressed ops then we call that as well. The expectation is
458 	 * that these callbacks will configure everything for this compress
459 	 * path, like configuring a PCM port for a CODEC.
460 	 */
461 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
462 		ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
463 		if (ret < 0)
464 			goto err;
465 	}
466 
467 	ret = soc_compr_components_set_params(cstream, params);
468 	if (ret < 0)
469 		goto err;
470 
471 	if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
472 		ret = rtd->dai_link->compr_ops->set_params(cstream);
473 		if (ret < 0)
474 			goto err;
475 	}
476 
477 	if (cstream->direction == SND_COMPRESS_PLAYBACK)
478 		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
479 					  SND_SOC_DAPM_STREAM_START);
480 	else
481 		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
482 					  SND_SOC_DAPM_STREAM_START);
483 
484 	/* cancel any delayed stream shutdown that is pending */
485 	rtd->pop_wait = 0;
486 	mutex_unlock(&rtd->card->pcm_mutex);
487 
488 	cancel_delayed_work_sync(&rtd->delayed_work);
489 
490 	return 0;
491 
492 err:
493 	mutex_unlock(&rtd->card->pcm_mutex);
494 	return ret;
495 }
496 
497 static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
498 				   struct snd_compr_params *params)
499 {
500 	struct snd_soc_pcm_runtime *fe = cstream->private_data;
501 	struct snd_pcm_substream *fe_substream =
502 		 fe->pcm->streams[cstream->direction].substream;
503 	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
504 	int ret, stream;
505 
506 	if (cstream->direction == SND_COMPRESS_PLAYBACK)
507 		stream = SNDRV_PCM_STREAM_PLAYBACK;
508 	else
509 		stream = SNDRV_PCM_STREAM_CAPTURE;
510 
511 	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
512 
513 	/*
514 	 * Create an empty hw_params for the BE as the machine driver must
515 	 * fix this up to match DSP decoder and ASRC configuration.
516 	 * I.e. machine driver fixup for compressed BE is mandatory.
517 	 */
518 	memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
519 		sizeof(struct snd_pcm_hw_params));
520 
521 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
522 
523 	ret = dpcm_be_dai_hw_params(fe, stream);
524 	if (ret < 0)
525 		goto out;
526 
527 	ret = dpcm_be_dai_prepare(fe, stream);
528 	if (ret < 0)
529 		goto out;
530 
531 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
532 		ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
533 		if (ret < 0)
534 			goto out;
535 	}
536 
537 	ret = soc_compr_components_set_params(cstream, params);
538 	if (ret < 0)
539 		goto out;
540 
541 	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
542 		ret = fe->dai_link->compr_ops->set_params(cstream);
543 		if (ret < 0)
544 			goto out;
545 	}
546 
547 	dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
548 	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
549 
550 out:
551 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
552 	mutex_unlock(&fe->card->mutex);
553 	return ret;
554 }
555 
556 static int soc_compr_get_params(struct snd_compr_stream *cstream,
557 				struct snd_codec *params)
558 {
559 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
560 	struct snd_soc_component *component;
561 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
562 	int i, ret = 0;
563 
564 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
565 
566 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
567 		ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
568 		if (ret < 0)
569 			goto err;
570 	}
571 
572 	for_each_rtd_components(rtd, i, component) {
573 		if (!component->driver->compr_ops ||
574 		    !component->driver->compr_ops->get_params)
575 			continue;
576 
577 		ret = component->driver->compr_ops->get_params(cstream, params);
578 		break;
579 	}
580 
581 err:
582 	mutex_unlock(&rtd->card->pcm_mutex);
583 	return ret;
584 }
585 
586 static int soc_compr_get_caps(struct snd_compr_stream *cstream,
587 			      struct snd_compr_caps *caps)
588 {
589 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
590 	struct snd_soc_component *component;
591 	int i, ret = 0;
592 
593 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
594 
595 	for_each_rtd_components(rtd, i, component) {
596 		if (!component->driver->compr_ops ||
597 		    !component->driver->compr_ops->get_caps)
598 			continue;
599 
600 		ret = component->driver->compr_ops->get_caps(cstream, caps);
601 		break;
602 	}
603 
604 	mutex_unlock(&rtd->card->pcm_mutex);
605 	return ret;
606 }
607 
608 static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
609 				    struct snd_compr_codec_caps *codec)
610 {
611 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
612 	struct snd_soc_component *component;
613 	int i, ret = 0;
614 
615 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
616 
617 	for_each_rtd_components(rtd, i, component) {
618 		if (!component->driver->compr_ops ||
619 		    !component->driver->compr_ops->get_codec_caps)
620 			continue;
621 
622 		ret = component->driver->compr_ops->get_codec_caps(cstream,
623 								   codec);
624 		break;
625 	}
626 
627 	mutex_unlock(&rtd->card->pcm_mutex);
628 	return ret;
629 }
630 
631 static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
632 {
633 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
634 	struct snd_soc_component *component;
635 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
636 	int i, ret = 0;
637 
638 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
639 
640 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
641 		ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
642 		if (ret < 0)
643 			goto err;
644 	}
645 
646 	for_each_rtd_components(rtd, i, component) {
647 		if (!component->driver->compr_ops ||
648 		    !component->driver->compr_ops->ack)
649 			continue;
650 
651 		ret = component->driver->compr_ops->ack(cstream, bytes);
652 		if (ret < 0)
653 			goto err;
654 	}
655 
656 err:
657 	mutex_unlock(&rtd->card->pcm_mutex);
658 	return ret;
659 }
660 
661 static int soc_compr_pointer(struct snd_compr_stream *cstream,
662 			     struct snd_compr_tstamp *tstamp)
663 {
664 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
665 	struct snd_soc_component *component;
666 	int i, ret = 0;
667 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
668 
669 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
670 
671 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
672 		cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
673 
674 	for_each_rtd_components(rtd, i, component) {
675 		if (!component->driver->compr_ops ||
676 		    !component->driver->compr_ops->pointer)
677 			continue;
678 
679 		ret = component->driver->compr_ops->pointer(cstream, tstamp);
680 		break;
681 	}
682 
683 	mutex_unlock(&rtd->card->pcm_mutex);
684 	return ret;
685 }
686 
687 static int soc_compr_copy(struct snd_compr_stream *cstream,
688 			  char __user *buf, size_t count)
689 {
690 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
691 	struct snd_soc_component *component;
692 	int i, ret = 0;
693 
694 	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
695 
696 	for_each_rtd_components(rtd, i, component) {
697 		if (!component->driver->compr_ops ||
698 		    !component->driver->compr_ops->copy)
699 			continue;
700 
701 		ret = component->driver->compr_ops->copy(cstream, buf, count);
702 		break;
703 	}
704 
705 	mutex_unlock(&rtd->card->pcm_mutex);
706 	return ret;
707 }
708 
709 static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
710 				  struct snd_compr_metadata *metadata)
711 {
712 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
713 	struct snd_soc_component *component;
714 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
715 	int i, ret;
716 
717 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
718 		ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
719 		if (ret < 0)
720 			return ret;
721 	}
722 
723 	for_each_rtd_components(rtd, i, component) {
724 		if (!component->driver->compr_ops ||
725 		    !component->driver->compr_ops->set_metadata)
726 			continue;
727 
728 		ret = component->driver->compr_ops->set_metadata(cstream,
729 								 metadata);
730 		if (ret < 0)
731 			return ret;
732 	}
733 
734 	return 0;
735 }
736 
737 static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
738 				  struct snd_compr_metadata *metadata)
739 {
740 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
741 	struct snd_soc_component *component;
742 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
743 	int i, ret;
744 
745 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
746 		ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
747 		if (ret < 0)
748 			return ret;
749 	}
750 
751 	for_each_rtd_components(rtd, i, component) {
752 		if (!component->driver->compr_ops ||
753 		    !component->driver->compr_ops->get_metadata)
754 			continue;
755 
756 		return component->driver->compr_ops->get_metadata(cstream,
757 								  metadata);
758 	}
759 
760 	return 0;
761 }
762 
763 /* ASoC Compress operations */
764 static struct snd_compr_ops soc_compr_ops = {
765 	.open		= soc_compr_open,
766 	.free		= soc_compr_free,
767 	.set_params	= soc_compr_set_params,
768 	.set_metadata   = soc_compr_set_metadata,
769 	.get_metadata	= soc_compr_get_metadata,
770 	.get_params	= soc_compr_get_params,
771 	.trigger	= soc_compr_trigger,
772 	.pointer	= soc_compr_pointer,
773 	.ack		= soc_compr_ack,
774 	.get_caps	= soc_compr_get_caps,
775 	.get_codec_caps = soc_compr_get_codec_caps
776 };
777 
778 /* ASoC Dynamic Compress operations */
779 static struct snd_compr_ops soc_compr_dyn_ops = {
780 	.open		= soc_compr_open_fe,
781 	.free		= soc_compr_free_fe,
782 	.set_params	= soc_compr_set_params_fe,
783 	.get_params	= soc_compr_get_params,
784 	.set_metadata   = soc_compr_set_metadata,
785 	.get_metadata	= soc_compr_get_metadata,
786 	.trigger	= soc_compr_trigger_fe,
787 	.pointer	= soc_compr_pointer,
788 	.ack		= soc_compr_ack,
789 	.get_caps	= soc_compr_get_caps,
790 	.get_codec_caps = soc_compr_get_codec_caps
791 };
792 
793 /**
794  * snd_soc_new_compress - create a new compress.
795  *
796  * @rtd: The runtime for which we will create compress
797  * @num: the device index number (zero based - shared with normal PCMs)
798  *
799  * Return: 0 for success, else error.
800  */
801 int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
802 {
803 	struct snd_soc_component *component;
804 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
805 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
806 	struct snd_compr *compr;
807 	struct snd_pcm *be_pcm;
808 	char new_name[64];
809 	int ret = 0, direction = 0;
810 	int playback = 0, capture = 0;
811 	int i;
812 
813 	if (rtd->num_codecs > 1) {
814 		dev_err(rtd->card->dev,
815 			"Compress ASoC: Multicodec not supported\n");
816 		return -EINVAL;
817 	}
818 
819 	/* check client and interface hw capabilities */
820 	if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
821 	    snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_PLAYBACK))
822 		playback = 1;
823 	if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
824 	    snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_CAPTURE))
825 		capture = 1;
826 
827 	/*
828 	 * Compress devices are unidirectional so only one of the directions
829 	 * should be set, check for that (xor)
830 	 */
831 	if (playback + capture != 1) {
832 		dev_err(rtd->card->dev,
833 			"Compress ASoC: Invalid direction for P %d, C %d\n",
834 			playback, capture);
835 		return -EINVAL;
836 	}
837 
838 	if (playback)
839 		direction = SND_COMPRESS_PLAYBACK;
840 	else
841 		direction = SND_COMPRESS_CAPTURE;
842 
843 	compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL);
844 	if (!compr)
845 		return -ENOMEM;
846 
847 	compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
848 				  GFP_KERNEL);
849 	if (!compr->ops)
850 		return -ENOMEM;
851 
852 	if (rtd->dai_link->dynamic) {
853 		snprintf(new_name, sizeof(new_name), "(%s)",
854 			rtd->dai_link->stream_name);
855 
856 		ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
857 				rtd->dai_link->dpcm_playback,
858 				rtd->dai_link->dpcm_capture, &be_pcm);
859 		if (ret < 0) {
860 			dev_err(rtd->card->dev,
861 				"Compress ASoC: can't create compressed for %s: %d\n",
862 				rtd->dai_link->name, ret);
863 			return ret;
864 		}
865 
866 		rtd->pcm = be_pcm;
867 		rtd->fe_compr = 1;
868 		if (rtd->dai_link->dpcm_playback)
869 			be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
870 		else if (rtd->dai_link->dpcm_capture)
871 			be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
872 		memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
873 	} else {
874 		snprintf(new_name, sizeof(new_name), "%s %s-%d",
875 			rtd->dai_link->stream_name, codec_dai->name, num);
876 
877 		memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
878 	}
879 
880 	for_each_rtd_components(rtd, i, component) {
881 		if (!component->driver->compr_ops ||
882 		    !component->driver->compr_ops->copy)
883 			continue;
884 
885 		compr->ops->copy = soc_compr_copy;
886 		break;
887 	}
888 
889 	mutex_init(&compr->lock);
890 	ret = snd_compress_new(rtd->card->snd_card, num, direction,
891 				new_name, compr);
892 	if (ret < 0) {
893 		component = rtd->codec_dai->component;
894 		dev_err(component->dev,
895 			"Compress ASoC: can't create compress for codec %s: %d\n",
896 			component->name, ret);
897 		return ret;
898 	}
899 
900 	/* DAPM dai link stream work */
901 	rtd->close_delayed_work_func = snd_soc_close_delayed_work;
902 
903 	rtd->compr = compr;
904 	compr->private_data = rtd;
905 
906 	dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
907 		 codec_dai->name, cpu_dai->name);
908 
909 	return 0;
910 }
911 EXPORT_SYMBOL_GPL(snd_soc_new_compress);
912