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