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