soc-compress.c 22.5 KB
Newer Older
1 2 3 4 5 6 7 8 9
// SPDX-License-Identifier: GPL-2.0+
//
// soc-compress.c  --  ALSA SoC Compress
//
// Copyright (C) 2012 Intel Corp.
//
// Authors: Namarta Kohli <namartax.kohli@intel.com>
//          Ramesh Babu K V <ramesh.babu@linux.intel.com>
//          Vinod Koul <vinod.koul@linux.intel.com>
10 11 12 13 14 15 16 17 18 19 20

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <sound/core.h>
#include <sound/compress_params.h>
#include <sound/compress_driver.h>
#include <sound/soc.h>
#include <sound/initval.h>
21
#include <sound/soc-dpcm.h>
22
#include <sound/soc-link.h>
23
#include <linux/pm_runtime.h>
24

25 26
static int soc_compr_components_open(struct snd_compr_stream *cstream,
				     struct snd_soc_component **last)
27 28
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
29
	struct snd_soc_component *component;
30
	int i, ret;
31

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->open)
			continue;

		ret = component->driver->compress_ops->open(component, cstream);
		if (ret < 0) {
			dev_err(component->dev,
				"Compress ASoC: can't open platform %s: %d\n",
				component->name, ret);

			*last = component;
			return ret;
		}
	}

48 49 50 51 52 53 54 55 56
	*last = NULL;
	return 0;
}

static int soc_compr_components_free(struct snd_compr_stream *cstream,
				     struct snd_soc_component *last)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
57
	int i;
58

59 60 61 62 63 64 65 66 67 68 69
	for_each_rtd_components(rtd, i, component) {
		if (component == last)
			break;

		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->free)
			continue;

		component->driver->compress_ops->free(component, cstream);
	}

70 71 72 73 74 75
	return 0;
}

static int soc_compr_open(struct snd_compr_stream *cstream)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
76
	struct snd_soc_component *component = NULL, *save = NULL;
77
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
78
	int ret, i;
79

80
	for_each_rtd_components(rtd, i, component) {
81 82 83 84 85 86 87 88
		ret = pm_runtime_get_sync(component->dev);
		if (ret < 0 && ret != -EACCES) {
			pm_runtime_put_noidle(component->dev);
			save = component;
			goto pm_err;
		}
	}

89
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
90

91 92 93
	ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
	if (ret < 0)
		goto out;
94 95 96 97

	ret = soc_compr_components_open(cstream, &component);
	if (ret < 0)
		goto machine_err;
98

99 100 101
	ret = snd_soc_link_compr_startup(cstream);
	if (ret < 0)
		goto machine_err;
102

103
	snd_soc_runtime_activate(rtd, cstream->direction);
104

105
	mutex_unlock(&rtd->card->pcm_mutex);
106

107 108 109
	return 0;

machine_err:
110
	soc_compr_components_free(cstream, component);
111

112
	snd_soc_dai_compr_shutdown(cpu_dai, cstream);
113
out:
114
	mutex_unlock(&rtd->card->pcm_mutex);
115
pm_err:
116
	for_each_rtd_components(rtd, i, component) {
117 118 119 120 121 122
		if (component == save)
			break;
		pm_runtime_mark_last_busy(component->dev);
		pm_runtime_put_autosuspend(component->dev);
	}

123 124 125
	return ret;
}

126 127 128
static int soc_compr_open_fe(struct snd_compr_stream *cstream)
{
	struct snd_soc_pcm_runtime *fe = cstream->private_data;
129 130
	struct snd_pcm_substream *fe_substream =
		 fe->pcm->streams[cstream->direction].substream;
131
	struct snd_soc_component *component;
132
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
133 134 135
	struct snd_soc_dpcm *dpcm;
	struct snd_soc_dapm_widget_list *list;
	int stream;
136
	int ret;
137 138 139 140 141 142 143

	if (cstream->direction == SND_COMPRESS_PLAYBACK)
		stream = SNDRV_PCM_STREAM_PLAYBACK;
	else
		stream = SNDRV_PCM_STREAM_CAPTURE;

	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
	fe->dpcm[stream].runtime = fe_substream->runtime;

	ret = dpcm_path_get(fe, stream, &list);
	if (ret < 0)
		goto be_err;
	else if (ret == 0)
		dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
			fe->dai_link->name, stream ? "capture" : "playback");
	/* calculate valid and active FE <-> BE dpcms */
	dpcm_process_paths(fe, stream, &list, 1);
	fe->dpcm[stream].runtime = fe_substream->runtime;

	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;

	ret = dpcm_be_dai_startup(fe, stream);
	if (ret < 0) {
		/* clean up all links */
161
		for_each_dpcm_be(fe, stream, dpcm)
162 163 164 165 166 167
			dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;

		dpcm_be_disconnect(fe, stream);
		fe->dpcm[stream].runtime = NULL;
		goto out;
	}
168

169 170 171
	ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
	if (ret < 0)
		goto out;
172

173 174
	ret = soc_compr_components_open(cstream, &component);
	if (ret < 0)
175
		goto open_err;
176

177 178 179
	ret = snd_soc_link_compr_startup(cstream);
	if (ret < 0)
		goto machine_err;
180 181 182 183 184 185 186

	dpcm_clear_pending_state(fe, stream);
	dpcm_path_put(&list);

	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;

187
	snd_soc_runtime_activate(fe, stream);
188 189 190 191 192 193

	mutex_unlock(&fe->card->mutex);

	return 0;

machine_err:
194
	soc_compr_components_free(cstream, component);
195
open_err:
196
	snd_soc_dai_compr_shutdown(cpu_dai, cstream);
197
out:
198 199
	dpcm_path_put(&list);
be_err:
200 201 202 203 204
	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
	mutex_unlock(&fe->card->mutex);
	return ret;
}

205 206 207
static int soc_compr_free(struct snd_compr_stream *cstream)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
208
	struct snd_soc_component *component;
209 210
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
211
	int stream, i;
212

213
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
214

215 216 217 218
	if (cstream->direction == SND_COMPRESS_PLAYBACK)
		stream = SNDRV_PCM_STREAM_PLAYBACK;
	else
		stream = SNDRV_PCM_STREAM_CAPTURE;
219

220
	snd_soc_runtime_deactivate(rtd, stream);
221

222
	snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
223

224
	if (!snd_soc_dai_active(cpu_dai))
225 226
		cpu_dai->rate = 0;

227
	if (!snd_soc_dai_active(codec_dai))
228 229
		codec_dai->rate = 0;

230
	snd_soc_link_compr_shutdown(cstream);
231

232
	soc_compr_components_free(cstream, NULL);
233

234
	snd_soc_dai_compr_shutdown(cpu_dai, cstream);
235

236
	snd_soc_dapm_stream_stop(rtd, stream);
237

238
	mutex_unlock(&rtd->card->pcm_mutex);
239

240
	for_each_rtd_components(rtd, i, component) {
241 242 243 244
		pm_runtime_mark_last_busy(component->dev);
		pm_runtime_put_autosuspend(component->dev);
	}

245 246 247
	return 0;
}

248 249 250
static int soc_compr_free_fe(struct snd_compr_stream *cstream)
{
	struct snd_soc_pcm_runtime *fe = cstream->private_data;
251
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
252 253 254 255 256
	struct snd_soc_dpcm *dpcm;
	int stream, ret;

	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);

257
	if (cstream->direction == SND_COMPRESS_PLAYBACK)
258
		stream = SNDRV_PCM_STREAM_PLAYBACK;
259
	else
260 261
		stream = SNDRV_PCM_STREAM_CAPTURE;

262
	snd_soc_runtime_deactivate(fe, stream);
263 264 265 266 267

	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;

	ret = dpcm_be_dai_hw_free(fe, stream);
	if (ret < 0)
268
		dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
269 270 271 272

	ret = dpcm_be_dai_shutdown(fe, stream);

	/* mark FE's links ready to prune */
273
	for_each_dpcm_be(fe, stream, dpcm)
274 275
		dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;

276
	dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
277 278 279 280 281 282 283 284

	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;

	dpcm_be_disconnect(fe, stream);

	fe->dpcm[stream].runtime = NULL;

285
	snd_soc_link_compr_shutdown(cstream);
286

287
	soc_compr_components_free(cstream, NULL);
288

289
	snd_soc_dai_compr_shutdown(cpu_dai, cstream);
290

291 292 293 294
	mutex_unlock(&fe->card->mutex);
	return 0;
}

295 296
static int soc_compr_components_trigger(struct snd_compr_stream *cstream,
					int cmd)
297 298
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
299
	struct snd_soc_component *component;
300
	int i, ret;
301

302 303 304 305 306 307 308 309 310 311 312
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->trigger)
			continue;

		ret = component->driver->compress_ops->trigger(
			component, cstream, cmd);
		if (ret < 0)
			return ret;
	}

313 314 315 316 317 318
	return 0;
}

static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
319 320
	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
321 322
	int ret;

323
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
324 325 326 327 328

	ret = soc_compr_components_trigger(cstream, cmd);
	if (ret < 0)
		goto out;

329 330 331
	ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
	if (ret < 0)
		goto out;
332

333 334 335 336 337 338 339
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
		break;
340
	}
341

342
out:
343
	mutex_unlock(&rtd->card->pcm_mutex);
344 345 346
	return ret;
}

347 348 349
static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
{
	struct snd_soc_pcm_runtime *fe = cstream->private_data;
350
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
351
	int ret, stream;
352 353

	if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
354 355
	    cmd == SND_COMPR_TRIGGER_DRAIN)
		return soc_compr_components_trigger(cstream, cmd);
356 357 358 359 360 361 362 363

	if (cstream->direction == SND_COMPRESS_PLAYBACK)
		stream = SNDRV_PCM_STREAM_PLAYBACK;
	else
		stream = SNDRV_PCM_STREAM_CAPTURE;

	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);

364 365 366
	ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
	if (ret < 0)
		goto out;
367

368 369 370
	ret = soc_compr_components_trigger(cstream, cmd);
	if (ret < 0)
		goto out;
371

372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;

	ret = dpcm_be_dai_trigger(fe, stream, cmd);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
		break;
	}

out:
	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
	mutex_unlock(&fe->card->mutex);
	return ret;
}

397 398
static int soc_compr_components_set_params(struct snd_compr_stream *cstream,
					   struct snd_compr_params *params)
399 400
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
401
	struct snd_soc_component *component;
402
	int i, ret;
403

404 405 406 407 408 409 410 411 412 413 414
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->set_params)
			continue;

		ret = component->driver->compress_ops->set_params(
			component, cstream, params);
		if (ret < 0)
			return ret;
	}

415 416 417 418 419 420 421
	return 0;
}

static int soc_compr_set_params(struct snd_compr_stream *cstream,
				struct snd_compr_params *params)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
422
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
423
	int ret;
424

425
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
426

427 428 429 430 431 432
	/*
	 * First we call set_params for the CPU DAI, then the component
	 * driver this should configure the SoC side. If the machine has
	 * compressed ops then we call that as well. The expectation is
	 * that these callbacks will configure everything for this compress
	 * path, like configuring a PCM port for a CODEC.
433
	 */
434 435 436
	ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
	if (ret < 0)
		goto err;
437

438 439 440
	ret = soc_compr_components_set_params(cstream, params);
	if (ret < 0)
		goto err;
441

442 443 444
	ret = snd_soc_link_compr_set_params(cstream);
	if (ret < 0)
		goto err;
445

446 447
	if (cstream->direction == SND_COMPRESS_PLAYBACK)
		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
448
					  SND_SOC_DAPM_STREAM_START);
449 450
	else
		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
451
					  SND_SOC_DAPM_STREAM_START);
452

453 454
	/* cancel any delayed stream shutdown that is pending */
	rtd->pop_wait = 0;
455
	mutex_unlock(&rtd->card->pcm_mutex);
456 457 458

	cancel_delayed_work_sync(&rtd->delayed_work);

459
	return 0;
460 461

err:
462
	mutex_unlock(&rtd->card->pcm_mutex);
463 464 465
	return ret;
}

466
static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
467
				   struct snd_compr_params *params)
468 469
{
	struct snd_soc_pcm_runtime *fe = cstream->private_data;
470 471
	struct snd_pcm_substream *fe_substream =
		 fe->pcm->streams[cstream->direction].substream;
472
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
473
	int ret, stream;
474 475 476 477 478 479 480 481

	if (cstream->direction == SND_COMPRESS_PLAYBACK)
		stream = SNDRV_PCM_STREAM_PLAYBACK;
	else
		stream = SNDRV_PCM_STREAM_CAPTURE;

	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);

482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
	/*
	 * Create an empty hw_params for the BE as the machine driver must
	 * fix this up to match DSP decoder and ASRC configuration.
	 * I.e. machine driver fixup for compressed BE is mandatory.
	 */
	memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
		sizeof(struct snd_pcm_hw_params));

	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;

	ret = dpcm_be_dai_hw_params(fe, stream);
	if (ret < 0)
		goto out;

	ret = dpcm_be_dai_prepare(fe, stream);
	if (ret < 0)
		goto out;

500 501 502
	ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
	if (ret < 0)
		goto out;
503

504 505 506
	ret = soc_compr_components_set_params(cstream, params);
	if (ret < 0)
		goto out;
507

508 509 510
	ret = snd_soc_link_compr_set_params(cstream);
	if (ret < 0)
		goto out;
511

512
	dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
513 514 515 516 517 518 519 520
	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;

out:
	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
	mutex_unlock(&fe->card->mutex);
	return ret;
}

521
static int soc_compr_get_params(struct snd_compr_stream *cstream,
522
				struct snd_codec *params)
523 524
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
525
	struct snd_soc_component *component;
526
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
527
	int i, ret = 0;
528

529
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
530

531 532 533
	ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params);
	if (ret < 0)
		goto err;
534

535 536 537 538 539 540 541 542 543 544
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->get_params)
			continue;

		ret = component->driver->compress_ops->get_params(
			component, cstream, params);
		break;
	}

545
err:
546
	mutex_unlock(&rtd->card->pcm_mutex);
547 548 549 550
	return ret;
}

static int soc_compr_get_caps(struct snd_compr_stream *cstream,
551
			      struct snd_compr_caps *caps)
552 553
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
554
	struct snd_soc_component *component;
555
	int i, ret = 0;
556

557
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
558

559 560 561 562 563 564 565 566 567 568
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->get_caps)
			continue;

		ret = component->driver->compress_ops->get_caps(
			component, cstream, caps);
		break;
	}

569
	mutex_unlock(&rtd->card->pcm_mutex);
570 571 572 573
	return ret;
}

static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
574
				    struct snd_compr_codec_caps *codec)
575 576
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
577
	struct snd_soc_component *component;
578
	int i, ret = 0;
579

580
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
581

582 583 584 585 586 587 588 589 590 591
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->get_codec_caps)
			continue;

		ret = component->driver->compress_ops->get_codec_caps(
			component, cstream, codec);
		break;
	}

592
	mutex_unlock(&rtd->card->pcm_mutex);
593 594 595 596 597 598
	return ret;
}

static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
599
	struct snd_soc_component *component;
600
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
601
	int i, ret = 0;
602

603
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
604

605 606 607
	ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes);
	if (ret < 0)
		goto err;
608

609 610 611 612 613 614 615 616 617 618 619
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->ack)
			continue;

		ret = component->driver->compress_ops->ack(
			component, cstream, bytes);
		if (ret < 0)
			goto err;
	}

620
err:
621
	mutex_unlock(&rtd->card->pcm_mutex);
622 623 624 625
	return ret;
}

static int soc_compr_pointer(struct snd_compr_stream *cstream,
626
			     struct snd_compr_tstamp *tstamp)
627 628
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
629
	struct snd_soc_component *component;
630
	int i, ret = 0;
631
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
632

633
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
634

635 636 637
	ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp);
	if (ret < 0)
		goto out;
638

639 640 641 642 643 644 645 646 647
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->pointer)
			continue;

		ret = component->driver->compress_ops->pointer(
			component, cstream, tstamp);
		break;
	}
648
out:
649
	mutex_unlock(&rtd->card->pcm_mutex);
650
	return ret;
651 652
}

653
static int soc_compr_copy(struct snd_compr_stream *cstream,
654
			  char __user *buf, size_t count)
655 656
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
657
	struct snd_soc_component *component;
658
	int i, ret = 0;
659

660
	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
661

662 663 664 665 666 667 668 669 670 671
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->copy)
			continue;

		ret = component->driver->compress_ops->copy(
			component, cstream, buf, count);
		break;
	}

672
	mutex_unlock(&rtd->card->pcm_mutex);
673 674 675
	return ret;
}

676
static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
677
				  struct snd_compr_metadata *metadata)
678 679
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
680
	struct snd_soc_component *component;
681
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
682
	int i, ret;
683

684 685 686
	ret = snd_soc_dai_compr_set_metadata(cpu_dai, cstream, metadata);
	if (ret < 0)
		return ret;
687

688 689 690 691 692 693 694 695 696 697 698
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->set_metadata)
			continue;

		ret = component->driver->compress_ops->set_metadata(
			component, cstream, metadata);
		if (ret < 0)
			return ret;
	}

699
	return 0;
700 701
}

702
static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
703
				  struct snd_compr_metadata *metadata)
704 705
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
706
	struct snd_soc_component *component;
707
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
708
	int i, ret;
709

710 711 712
	ret = snd_soc_dai_compr_get_metadata(cpu_dai, cstream, metadata);
	if (ret < 0)
		return ret;
713

714 715 716 717 718 719 720 721 722
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->get_metadata)
			continue;

		return component->driver->compress_ops->get_metadata(
			component, cstream, metadata);
	}

723
	return 0;
724
}
725

726 727 728 729 730
/* ASoC Compress operations */
static struct snd_compr_ops soc_compr_ops = {
	.open		= soc_compr_open,
	.free		= soc_compr_free,
	.set_params	= soc_compr_set_params,
731 732
	.set_metadata   = soc_compr_set_metadata,
	.get_metadata	= soc_compr_get_metadata,
733 734 735 736 737 738 739 740
	.get_params	= soc_compr_get_params,
	.trigger	= soc_compr_trigger,
	.pointer	= soc_compr_pointer,
	.ack		= soc_compr_ack,
	.get_caps	= soc_compr_get_caps,
	.get_codec_caps = soc_compr_get_codec_caps
};

741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
/* ASoC Dynamic Compress operations */
static struct snd_compr_ops soc_compr_dyn_ops = {
	.open		= soc_compr_open_fe,
	.free		= soc_compr_free_fe,
	.set_params	= soc_compr_set_params_fe,
	.get_params	= soc_compr_get_params,
	.set_metadata   = soc_compr_set_metadata,
	.get_metadata	= soc_compr_get_metadata,
	.trigger	= soc_compr_trigger_fe,
	.pointer	= soc_compr_pointer,
	.ack		= soc_compr_ack,
	.get_caps	= soc_compr_get_caps,
	.get_codec_caps = soc_compr_get_codec_caps
};

756 757 758 759 760 761 762 763 764
/**
 * snd_soc_new_compress - create a new compress.
 *
 * @rtd: The runtime for which we will create compress
 * @num: the device index number (zero based - shared with normal PCMs)
 *
 * Return: 0 for success, else error.
 */
int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
765
{
766
	struct snd_soc_component *component;
767 768
	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
769
	struct snd_compr *compr;
770
	struct snd_pcm *be_pcm;
771 772
	char new_name[64];
	int ret = 0, direction = 0;
773
	int playback = 0, capture = 0;
774
	int i;
775

776 777
	if (rtd->num_cpus > 1 ||
	    rtd->num_codecs > 1) {
778
		dev_err(rtd->card->dev,
779
			"Compress ASoC: Multi CPU/Codec not supported\n");
780 781 782
		return -EINVAL;
	}

783
	/* check client and interface hw capabilities */
784 785
	if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
	    snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_PLAYBACK))
786
		playback = 1;
787 788
	if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
	    snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_CAPTURE))
789 790 791 792 793 794 795
		capture = 1;

	/*
	 * Compress devices are unidirectional so only one of the directions
	 * should be set, check for that (xor)
	 */
	if (playback + capture != 1) {
796 797 798
		dev_err(rtd->card->dev,
			"Compress ASoC: Invalid direction for P %d, C %d\n",
			playback, capture);
799 800 801
		return -EINVAL;
	}

802
	if (playback)
803 804
		direction = SND_COMPRESS_PLAYBACK;
	else
805
		direction = SND_COMPRESS_CAPTURE;
806

807
	compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL);
808
	if (!compr)
809 810
		return -ENOMEM;

811 812
	compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
				  GFP_KERNEL);
813 814
	if (!compr->ops)
		return -ENOMEM;
815 816 817 818 819 820

	if (rtd->dai_link->dynamic) {
		snprintf(new_name, sizeof(new_name), "(%s)",
			rtd->dai_link->stream_name);

		ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
821 822
				rtd->dai_link->dpcm_playback,
				rtd->dai_link->dpcm_capture, &be_pcm);
823
		if (ret < 0) {
824 825 826
			dev_err(rtd->card->dev,
				"Compress ASoC: can't create compressed for %s: %d\n",
				rtd->dai_link->name, ret);
827
			return ret;
828 829 830 831
		}

		rtd->pcm = be_pcm;
		rtd->fe_compr = 1;
832 833 834 835
		if (rtd->dai_link->dpcm_playback)
			be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
		else if (rtd->dai_link->dpcm_capture)
			be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
836
		memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
837 838 839 840
	} else {
		snprintf(new_name, sizeof(new_name), "%s %s-%d",
			rtd->dai_link->stream_name, codec_dai->name, num);

841
		memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
842
	}
843

844 845 846 847 848 849 850 851 852
	for_each_rtd_components(rtd, i, component) {
		if (!component->driver->compress_ops ||
		    !component->driver->compress_ops->copy)
			continue;

		compr->ops->copy = soc_compr_copy;
		break;
	}

853
	mutex_init(&compr->lock);
854 855
	ret = snd_compress_new(rtd->card->snd_card, num, direction,
				new_name, compr);
856
	if (ret < 0) {
857
		component = asoc_rtd_to_codec(rtd, 0)->component;
858 859 860
		dev_err(component->dev,
			"Compress ASoC: can't create compress for codec %s: %d\n",
			component->name, ret);
861
		return ret;
862 863
	}

864
	/* DAPM dai link stream work */
865
	rtd->close_delayed_work_func = snd_soc_close_delayed_work;
866

867 868 869
	rtd->compr = compr;
	compr->private_data = rtd;

870 871
	dev_dbg(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
		codec_dai->name, cpu_dai->name);
872

873
	return 0;
874
}
875
EXPORT_SYMBOL_GPL(snd_soc_new_compress);