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