soc-compress.c (18366B)
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 <sound/soc-link.h> 23#include <linux/pm_runtime.h> 24 25static int snd_soc_compr_components_open(struct snd_compr_stream *cstream) 26{ 27 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 28 struct snd_soc_component *component; 29 int ret = 0; 30 int i; 31 32 for_each_rtd_components(rtd, i, component) { 33 ret = snd_soc_component_module_get_when_open(component, cstream); 34 if (ret < 0) 35 break; 36 37 ret = snd_soc_component_compr_open(component, cstream); 38 if (ret < 0) 39 break; 40 } 41 42 return ret; 43} 44 45static void snd_soc_compr_components_free(struct snd_compr_stream *cstream, 46 int rollback) 47{ 48 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 49 struct snd_soc_component *component; 50 int i; 51 52 for_each_rtd_components(rtd, i, component) { 53 snd_soc_component_compr_free(component, cstream, rollback); 54 snd_soc_component_module_put_when_close(component, cstream, rollback); 55 } 56} 57 58static int soc_compr_clean(struct snd_compr_stream *cstream, int rollback) 59{ 60 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 61 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 62 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 63 int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ 64 65 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 66 67 if (!rollback) 68 snd_soc_runtime_deactivate(rtd, stream); 69 70 snd_soc_dai_digital_mute(codec_dai, 1, stream); 71 72 if (!snd_soc_dai_active(cpu_dai)) 73 cpu_dai->rate = 0; 74 75 if (!snd_soc_dai_active(codec_dai)) 76 codec_dai->rate = 0; 77 78 snd_soc_link_compr_shutdown(cstream, rollback); 79 80 snd_soc_compr_components_free(cstream, rollback); 81 82 snd_soc_dai_compr_shutdown(cpu_dai, cstream, rollback); 83 84 if (!rollback) 85 snd_soc_dapm_stream_stop(rtd, stream); 86 87 mutex_unlock(&rtd->card->pcm_mutex); 88 89 snd_soc_pcm_component_pm_runtime_put(rtd, cstream, rollback); 90 91 return 0; 92} 93 94static int soc_compr_free(struct snd_compr_stream *cstream) 95{ 96 return soc_compr_clean(cstream, 0); 97} 98 99static int soc_compr_open(struct snd_compr_stream *cstream) 100{ 101 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 102 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 103 int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ 104 int ret; 105 106 ret = snd_soc_pcm_component_pm_runtime_get(rtd, cstream); 107 if (ret < 0) 108 goto err_no_lock; 109 110 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 111 112 ret = snd_soc_dai_compr_startup(cpu_dai, cstream); 113 if (ret < 0) 114 goto err; 115 116 ret = snd_soc_compr_components_open(cstream); 117 if (ret < 0) 118 goto err; 119 120 ret = snd_soc_link_compr_startup(cstream); 121 if (ret < 0) 122 goto err; 123 124 snd_soc_runtime_activate(rtd, stream); 125err: 126 mutex_unlock(&rtd->card->pcm_mutex); 127err_no_lock: 128 if (ret < 0) 129 soc_compr_clean(cstream, 1); 130 131 return ret; 132} 133 134static int soc_compr_open_fe(struct snd_compr_stream *cstream) 135{ 136 struct snd_soc_pcm_runtime *fe = cstream->private_data; 137 struct snd_pcm_substream *fe_substream = 138 fe->pcm->streams[cstream->direction].substream; 139 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0); 140 struct snd_soc_dpcm *dpcm; 141 struct snd_soc_dapm_widget_list *list; 142 int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ 143 int ret; 144 145 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 146 fe->dpcm[stream].runtime = fe_substream->runtime; 147 148 ret = dpcm_path_get(fe, stream, &list); 149 if (ret < 0) 150 goto be_err; 151 152 /* calculate valid and active FE <-> BE dpcms */ 153 dpcm_process_paths(fe, stream, &list, 1); 154 fe->dpcm[stream].runtime = fe_substream->runtime; 155 156 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 157 158 ret = dpcm_be_dai_startup(fe, stream); 159 if (ret < 0) { 160 /* clean up all links */ 161 for_each_dpcm_be(fe, stream, dpcm) 162 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; 163 164 dpcm_be_disconnect(fe, stream); 165 fe->dpcm[stream].runtime = NULL; 166 goto out; 167 } 168 169 ret = snd_soc_dai_compr_startup(cpu_dai, cstream); 170 if (ret < 0) 171 goto out; 172 173 ret = snd_soc_compr_components_open(cstream); 174 if (ret < 0) 175 goto open_err; 176 177 ret = snd_soc_link_compr_startup(cstream); 178 if (ret < 0) 179 goto machine_err; 180 181 dpcm_clear_pending_state(fe, stream); 182 dpcm_path_put(&list); 183 184 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; 185 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 186 187 mutex_lock_nested(&fe->card->pcm_mutex, fe->card->pcm_subclass); 188 snd_soc_runtime_activate(fe, stream); 189 mutex_unlock(&fe->card->pcm_mutex); 190 191 mutex_unlock(&fe->card->mutex); 192 193 return 0; 194 195machine_err: 196 snd_soc_compr_components_free(cstream, 1); 197open_err: 198 snd_soc_dai_compr_shutdown(cpu_dai, cstream, 1); 199out: 200 dpcm_path_put(&list); 201be_err: 202 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 203 mutex_unlock(&fe->card->mutex); 204 return ret; 205} 206 207static int soc_compr_free_fe(struct snd_compr_stream *cstream) 208{ 209 struct snd_soc_pcm_runtime *fe = cstream->private_data; 210 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0); 211 struct snd_soc_dpcm *dpcm; 212 int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ 213 214 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 215 216 mutex_lock_nested(&fe->card->pcm_mutex, fe->card->pcm_subclass); 217 snd_soc_runtime_deactivate(fe, stream); 218 mutex_unlock(&fe->card->pcm_mutex); 219 220 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 221 222 dpcm_be_dai_hw_free(fe, stream); 223 224 dpcm_be_dai_shutdown(fe, stream); 225 226 /* mark FE's links ready to prune */ 227 for_each_dpcm_be(fe, stream, dpcm) 228 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; 229 230 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); 231 232 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; 233 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 234 235 dpcm_be_disconnect(fe, stream); 236 237 fe->dpcm[stream].runtime = NULL; 238 239 snd_soc_link_compr_shutdown(cstream, 0); 240 241 snd_soc_compr_components_free(cstream, 0); 242 243 snd_soc_dai_compr_shutdown(cpu_dai, cstream, 0); 244 245 mutex_unlock(&fe->card->mutex); 246 return 0; 247} 248 249static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) 250{ 251 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 252 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 253 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 254 int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ 255 int ret; 256 257 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 258 259 ret = snd_soc_component_compr_trigger(cstream, cmd); 260 if (ret < 0) 261 goto out; 262 263 ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd); 264 if (ret < 0) 265 goto out; 266 267 switch (cmd) { 268 case SNDRV_PCM_TRIGGER_START: 269 snd_soc_dai_digital_mute(codec_dai, 0, stream); 270 break; 271 case SNDRV_PCM_TRIGGER_STOP: 272 snd_soc_dai_digital_mute(codec_dai, 1, stream); 273 break; 274 } 275 276out: 277 mutex_unlock(&rtd->card->pcm_mutex); 278 return ret; 279} 280 281static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd) 282{ 283 struct snd_soc_pcm_runtime *fe = cstream->private_data; 284 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0); 285 int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ 286 int ret; 287 288 if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN || 289 cmd == SND_COMPR_TRIGGER_DRAIN) 290 return snd_soc_component_compr_trigger(cstream, cmd); 291 292 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 293 294 ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd); 295 if (ret < 0) 296 goto out; 297 298 ret = snd_soc_component_compr_trigger(cstream, cmd); 299 if (ret < 0) 300 goto out; 301 302 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 303 304 ret = dpcm_be_dai_trigger(fe, stream, cmd); 305 306 switch (cmd) { 307 case SNDRV_PCM_TRIGGER_START: 308 case SNDRV_PCM_TRIGGER_RESUME: 309 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 310 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START; 311 break; 312 case SNDRV_PCM_TRIGGER_STOP: 313 case SNDRV_PCM_TRIGGER_SUSPEND: 314 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; 315 break; 316 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 317 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; 318 break; 319 } 320 321out: 322 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 323 mutex_unlock(&fe->card->mutex); 324 return ret; 325} 326 327static int soc_compr_set_params(struct snd_compr_stream *cstream, 328 struct snd_compr_params *params) 329{ 330 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 331 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 332 int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ 333 int ret; 334 335 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 336 337 /* 338 * First we call set_params for the CPU DAI, then the component 339 * driver this should configure the SoC side. If the machine has 340 * compressed ops then we call that as well. The expectation is 341 * that these callbacks will configure everything for this compress 342 * path, like configuring a PCM port for a CODEC. 343 */ 344 ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params); 345 if (ret < 0) 346 goto err; 347 348 ret = snd_soc_component_compr_set_params(cstream, params); 349 if (ret < 0) 350 goto err; 351 352 ret = snd_soc_link_compr_set_params(cstream); 353 if (ret < 0) 354 goto err; 355 356 snd_soc_dapm_stream_event(rtd, stream, SND_SOC_DAPM_STREAM_START); 357 358 /* cancel any delayed stream shutdown that is pending */ 359 rtd->pop_wait = 0; 360 mutex_unlock(&rtd->card->pcm_mutex); 361 362 cancel_delayed_work_sync(&rtd->delayed_work); 363 364 return 0; 365 366err: 367 mutex_unlock(&rtd->card->pcm_mutex); 368 return ret; 369} 370 371static int soc_compr_set_params_fe(struct snd_compr_stream *cstream, 372 struct snd_compr_params *params) 373{ 374 struct snd_soc_pcm_runtime *fe = cstream->private_data; 375 struct snd_pcm_substream *fe_substream = 376 fe->pcm->streams[cstream->direction].substream; 377 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0); 378 int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ 379 int ret; 380 381 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 382 383 /* 384 * Create an empty hw_params for the BE as the machine driver must 385 * fix this up to match DSP decoder and ASRC configuration. 386 * I.e. machine driver fixup for compressed BE is mandatory. 387 */ 388 memset(&fe->dpcm[fe_substream->stream].hw_params, 0, 389 sizeof(struct snd_pcm_hw_params)); 390 391 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 392 393 ret = dpcm_be_dai_hw_params(fe, stream); 394 if (ret < 0) 395 goto out; 396 397 ret = dpcm_be_dai_prepare(fe, stream); 398 if (ret < 0) 399 goto out; 400 401 ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params); 402 if (ret < 0) 403 goto out; 404 405 ret = snd_soc_component_compr_set_params(cstream, params); 406 if (ret < 0) 407 goto out; 408 409 ret = snd_soc_link_compr_set_params(cstream); 410 if (ret < 0) 411 goto out; 412 413 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START); 414 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; 415 416out: 417 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 418 mutex_unlock(&fe->card->mutex); 419 return ret; 420} 421 422static int soc_compr_get_params(struct snd_compr_stream *cstream, 423 struct snd_codec *params) 424{ 425 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 426 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 427 int ret = 0; 428 429 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 430 431 ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params); 432 if (ret < 0) 433 goto err; 434 435 ret = snd_soc_component_compr_get_params(cstream, params); 436err: 437 mutex_unlock(&rtd->card->pcm_mutex); 438 return ret; 439} 440 441static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes) 442{ 443 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 444 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 445 int ret; 446 447 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 448 449 ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes); 450 if (ret < 0) 451 goto err; 452 453 ret = snd_soc_component_compr_ack(cstream, bytes); 454err: 455 mutex_unlock(&rtd->card->pcm_mutex); 456 return ret; 457} 458 459static int soc_compr_pointer(struct snd_compr_stream *cstream, 460 struct snd_compr_tstamp *tstamp) 461{ 462 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 463 int ret; 464 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 465 466 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 467 468 ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp); 469 if (ret < 0) 470 goto out; 471 472 ret = snd_soc_component_compr_pointer(cstream, tstamp); 473out: 474 mutex_unlock(&rtd->card->pcm_mutex); 475 return ret; 476} 477 478static int soc_compr_set_metadata(struct snd_compr_stream *cstream, 479 struct snd_compr_metadata *metadata) 480{ 481 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 482 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 483 int ret; 484 485 ret = snd_soc_dai_compr_set_metadata(cpu_dai, cstream, metadata); 486 if (ret < 0) 487 return ret; 488 489 return snd_soc_component_compr_set_metadata(cstream, metadata); 490} 491 492static int soc_compr_get_metadata(struct snd_compr_stream *cstream, 493 struct snd_compr_metadata *metadata) 494{ 495 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 496 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 497 int ret; 498 499 ret = snd_soc_dai_compr_get_metadata(cpu_dai, cstream, metadata); 500 if (ret < 0) 501 return ret; 502 503 return snd_soc_component_compr_get_metadata(cstream, metadata); 504} 505 506/* ASoC Compress operations */ 507static struct snd_compr_ops soc_compr_ops = { 508 .open = soc_compr_open, 509 .free = soc_compr_free, 510 .set_params = soc_compr_set_params, 511 .set_metadata = soc_compr_set_metadata, 512 .get_metadata = soc_compr_get_metadata, 513 .get_params = soc_compr_get_params, 514 .trigger = soc_compr_trigger, 515 .pointer = soc_compr_pointer, 516 .ack = soc_compr_ack, 517 .get_caps = snd_soc_component_compr_get_caps, 518 .get_codec_caps = snd_soc_component_compr_get_codec_caps, 519}; 520 521/* ASoC Dynamic Compress operations */ 522static struct snd_compr_ops soc_compr_dyn_ops = { 523 .open = soc_compr_open_fe, 524 .free = soc_compr_free_fe, 525 .set_params = soc_compr_set_params_fe, 526 .get_params = soc_compr_get_params, 527 .set_metadata = soc_compr_set_metadata, 528 .get_metadata = soc_compr_get_metadata, 529 .trigger = soc_compr_trigger_fe, 530 .pointer = soc_compr_pointer, 531 .ack = soc_compr_ack, 532 .get_caps = snd_soc_component_compr_get_caps, 533 .get_codec_caps = snd_soc_component_compr_get_codec_caps, 534}; 535 536/** 537 * snd_soc_new_compress - create a new compress. 538 * 539 * @rtd: The runtime for which we will create compress 540 * @num: the device index number (zero based - shared with normal PCMs) 541 * 542 * Return: 0 for success, else error. 543 */ 544int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) 545{ 546 struct snd_soc_component *component; 547 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 548 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 549 struct snd_compr *compr; 550 struct snd_pcm *be_pcm; 551 char new_name[64]; 552 int ret = 0, direction = 0; 553 int playback = 0, capture = 0; 554 int i; 555 556 /* 557 * make sure these are same value, 558 * and then use these as equally 559 */ 560 BUILD_BUG_ON((int)SNDRV_PCM_STREAM_PLAYBACK != (int)SND_COMPRESS_PLAYBACK); 561 BUILD_BUG_ON((int)SNDRV_PCM_STREAM_CAPTURE != (int)SND_COMPRESS_CAPTURE); 562 563 if (rtd->num_cpus > 1 || 564 rtd->num_codecs > 1) { 565 dev_err(rtd->card->dev, 566 "Compress ASoC: Multi CPU/Codec not supported\n"); 567 return -EINVAL; 568 } 569 570 if (!codec_dai) { 571 dev_err(rtd->card->dev, "Missing codec\n"); 572 return -EINVAL; 573 } 574 575 /* check client and interface hw capabilities */ 576 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) && 577 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK)) 578 playback = 1; 579 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) && 580 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE)) 581 capture = 1; 582 583 /* 584 * Compress devices are unidirectional so only one of the directions 585 * should be set, check for that (xor) 586 */ 587 if (playback + capture != 1) { 588 dev_err(rtd->card->dev, 589 "Compress ASoC: Invalid direction for P %d, C %d\n", 590 playback, capture); 591 return -EINVAL; 592 } 593 594 if (playback) 595 direction = SND_COMPRESS_PLAYBACK; 596 else 597 direction = SND_COMPRESS_CAPTURE; 598 599 compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL); 600 if (!compr) 601 return -ENOMEM; 602 603 compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops), 604 GFP_KERNEL); 605 if (!compr->ops) 606 return -ENOMEM; 607 608 if (rtd->dai_link->dynamic) { 609 snprintf(new_name, sizeof(new_name), "(%s)", 610 rtd->dai_link->stream_name); 611 612 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, 613 rtd->dai_link->dpcm_playback, 614 rtd->dai_link->dpcm_capture, &be_pcm); 615 if (ret < 0) { 616 dev_err(rtd->card->dev, 617 "Compress ASoC: can't create compressed for %s: %d\n", 618 rtd->dai_link->name, ret); 619 return ret; 620 } 621 622 rtd->pcm = be_pcm; 623 rtd->fe_compr = 1; 624 if (rtd->dai_link->dpcm_playback) 625 be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; 626 else if (rtd->dai_link->dpcm_capture) 627 be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; 628 memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops)); 629 } else { 630 snprintf(new_name, sizeof(new_name), "%s %s-%d", 631 rtd->dai_link->stream_name, codec_dai->name, num); 632 633 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); 634 } 635 636 for_each_rtd_components(rtd, i, component) { 637 if (!component->driver->compress_ops || 638 !component->driver->compress_ops->copy) 639 continue; 640 641 compr->ops->copy = snd_soc_component_compr_copy; 642 break; 643 } 644 645 ret = snd_compress_new(rtd->card->snd_card, num, direction, 646 new_name, compr); 647 if (ret < 0) { 648 component = asoc_rtd_to_codec(rtd, 0)->component; 649 dev_err(component->dev, 650 "Compress ASoC: can't create compress for codec %s: %d\n", 651 component->name, ret); 652 return ret; 653 } 654 655 /* DAPM dai link stream work */ 656 rtd->close_delayed_work_func = snd_soc_close_delayed_work; 657 658 rtd->compr = compr; 659 compr->private_data = rtd; 660 661 dev_dbg(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n", 662 codec_dai->name, cpu_dai->name); 663 664 return 0; 665} 666EXPORT_SYMBOL_GPL(snd_soc_new_compress);