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 soc_compr_components_open(struct snd_compr_stream *cstream, 26 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 for_each_rtd_components(rtd, i, component) { 33 if (!component->driver->compress_ops || 34 !component->driver->compress_ops->open) 35 continue; 36 37 ret = component->driver->compress_ops->open(component, 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 int i; 58 59 for_each_rtd_components(rtd, i, component) { 60 if (component == last) 61 break; 62 63 if (!component->driver->compress_ops || 64 !component->driver->compress_ops->free) 65 continue; 66 67 component->driver->compress_ops->free(component, 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 = 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 ret = pm_runtime_get_sync(component->dev); 82 if (ret < 0 && ret != -EACCES) { 83 pm_runtime_put_noidle(component->dev); 84 save = component; 85 goto pm_err; 86 } 87 } 88 89 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 90 91 ret = snd_soc_dai_compr_startup(cpu_dai, cstream); 92 if (ret < 0) 93 goto out; 94 95 ret = soc_compr_components_open(cstream, &component); 96 if (ret < 0) 97 goto machine_err; 98 99 ret = snd_soc_link_compr_startup(cstream); 100 if (ret < 0) 101 goto machine_err; 102 103 snd_soc_runtime_activate(rtd, cstream->direction); 104 105 mutex_unlock(&rtd->card->pcm_mutex); 106 107 return 0; 108 109 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 if (component == save) 118 break; 119 pm_runtime_mark_last_busy(component->dev); 120 pm_runtime_put_autosuspend(component->dev); 121 } 122 123 return ret; 124 } 125 126 static int soc_compr_open_fe(struct snd_compr_stream *cstream) 127 { 128 struct snd_soc_pcm_runtime *fe = cstream->private_data; 129 struct snd_pcm_substream *fe_substream = 130 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 struct snd_soc_dpcm *dpcm; 134 struct snd_soc_dapm_widget_list *list; 135 int stream; 136 int ret; 137 138 if (cstream->direction == SND_COMPRESS_PLAYBACK) 139 stream = SNDRV_PCM_STREAM_PLAYBACK; 140 else 141 stream = SNDRV_PCM_STREAM_CAPTURE; 142 143 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 144 fe->dpcm[stream].runtime = fe_substream->runtime; 145 146 ret = dpcm_path_get(fe, stream, &list); 147 if (ret < 0) 148 goto be_err; 149 else if (ret == 0) 150 dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n", 151 fe->dai_link->name, stream ? "capture" : "playback"); 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 = soc_compr_components_open(cstream, &component); 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 snd_soc_runtime_activate(fe, stream); 188 189 mutex_unlock(&fe->card->mutex); 190 191 return 0; 192 193 machine_err: 194 soc_compr_components_free(cstream, component); 195 open_err: 196 snd_soc_dai_compr_shutdown(cpu_dai, cstream); 197 out: 198 dpcm_path_put(&list); 199 be_err: 200 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 201 mutex_unlock(&fe->card->mutex); 202 return ret; 203 } 204 205 static int soc_compr_free(struct snd_compr_stream *cstream) 206 { 207 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 208 struct snd_soc_component *component; 209 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 210 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 if (cstream->direction == SND_COMPRESS_PLAYBACK) 216 stream = SNDRV_PCM_STREAM_PLAYBACK; 217 else 218 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 cpu_dai->rate = 0; 226 227 if (!snd_soc_dai_active(codec_dai)) 228 codec_dai->rate = 0; 229 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 pm_runtime_mark_last_busy(component->dev); 242 pm_runtime_put_autosuspend(component->dev); 243 } 244 245 return 0; 246 } 247 248 static int soc_compr_free_fe(struct snd_compr_stream *cstream) 249 { 250 struct snd_soc_pcm_runtime *fe = cstream->private_data; 251 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0); 252 struct snd_soc_dpcm *dpcm; 253 int stream, ret; 254 255 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 256 257 if (cstream->direction == SND_COMPRESS_PLAYBACK) 258 stream = SNDRV_PCM_STREAM_PLAYBACK; 259 else 260 stream = SNDRV_PCM_STREAM_CAPTURE; 261 262 snd_soc_runtime_deactivate(fe, stream); 263 264 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 265 266 ret = dpcm_be_dai_hw_free(fe, stream); 267 if (ret < 0) 268 dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret); 269 270 ret = dpcm_be_dai_shutdown(fe, stream); 271 272 /* mark FE's links ready to prune */ 273 for_each_dpcm_be(fe, stream, dpcm) 274 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; 275 276 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); 277 278 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; 279 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 280 281 dpcm_be_disconnect(fe, stream); 282 283 fe->dpcm[stream].runtime = NULL; 284 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 mutex_unlock(&fe->card->mutex); 292 return 0; 293 } 294 295 static int soc_compr_components_trigger(struct snd_compr_stream *cstream, 296 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 for_each_rtd_components(rtd, i, component) { 303 if (!component->driver->compress_ops || 304 !component->driver->compress_ops->trigger) 305 continue; 306 307 ret = component->driver->compress_ops->trigger( 308 component, cstream, cmd); 309 if (ret < 0) 310 return ret; 311 } 312 313 return 0; 314 } 315 316 static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) 317 { 318 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 319 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 320 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 321 int ret; 322 323 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 324 325 ret = soc_compr_components_trigger(cstream, cmd); 326 if (ret < 0) 327 goto out; 328 329 ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd); 330 if (ret < 0) 331 goto out; 332 333 switch (cmd) { 334 case SNDRV_PCM_TRIGGER_START: 335 snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction); 336 break; 337 case SNDRV_PCM_TRIGGER_STOP: 338 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); 339 break; 340 } 341 342 out: 343 mutex_unlock(&rtd->card->pcm_mutex); 344 return ret; 345 } 346 347 static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd) 348 { 349 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 cmd == SND_COMPR_TRIGGER_DRAIN) 355 return soc_compr_components_trigger(cstream, cmd); 356 357 if (cstream->direction == SND_COMPRESS_PLAYBACK) 358 stream = SNDRV_PCM_STREAM_PLAYBACK; 359 else 360 stream = SNDRV_PCM_STREAM_CAPTURE; 361 362 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 363 364 ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd); 365 if (ret < 0) 366 goto out; 367 368 ret = soc_compr_components_trigger(cstream, cmd); 369 if (ret < 0) 370 goto out; 371 372 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 373 374 ret = dpcm_be_dai_trigger(fe, stream, cmd); 375 376 switch (cmd) { 377 case SNDRV_PCM_TRIGGER_START: 378 case SNDRV_PCM_TRIGGER_RESUME: 379 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 380 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START; 381 break; 382 case SNDRV_PCM_TRIGGER_STOP: 383 case SNDRV_PCM_TRIGGER_SUSPEND: 384 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; 385 break; 386 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 387 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; 388 break; 389 } 390 391 out: 392 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 393 mutex_unlock(&fe->card->mutex); 394 return ret; 395 } 396 397 static int soc_compr_components_set_params(struct snd_compr_stream *cstream, 398 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 for_each_rtd_components(rtd, i, component) { 405 if (!component->driver->compress_ops || 406 !component->driver->compress_ops->set_params) 407 continue; 408 409 ret = component->driver->compress_ops->set_params( 410 component, cstream, params); 411 if (ret < 0) 412 return ret; 413 } 414 415 return 0; 416 } 417 418 static int soc_compr_set_params(struct snd_compr_stream *cstream, 419 struct snd_compr_params *params) 420 { 421 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 * First we call set_params for the CPU DAI, then the component 429 * driver this should configure the SoC side. If the machine has 430 * compressed ops then we call that as well. The expectation is 431 * that these callbacks will configure everything for this compress 432 * path, like configuring a PCM port for a CODEC. 433 */ 434 ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params); 435 if (ret < 0) 436 goto err; 437 438 ret = soc_compr_components_set_params(cstream, params); 439 if (ret < 0) 440 goto err; 441 442 ret = snd_soc_link_compr_set_params(cstream); 443 if (ret < 0) 444 goto err; 445 446 if (cstream->direction == SND_COMPRESS_PLAYBACK) 447 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, 448 SND_SOC_DAPM_STREAM_START); 449 else 450 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE, 451 SND_SOC_DAPM_STREAM_START); 452 453 /* cancel any delayed stream shutdown that is pending */ 454 rtd->pop_wait = 0; 455 mutex_unlock(&rtd->card->pcm_mutex); 456 457 cancel_delayed_work_sync(&rtd->delayed_work); 458 459 return 0; 460 461 err: 462 mutex_unlock(&rtd->card->pcm_mutex); 463 return ret; 464 } 465 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 struct snd_pcm_substream *fe_substream = 471 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 if (cstream->direction == SND_COMPRESS_PLAYBACK) 476 stream = SNDRV_PCM_STREAM_PLAYBACK; 477 else 478 stream = SNDRV_PCM_STREAM_CAPTURE; 479 480 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 481 482 /* 483 * Create an empty hw_params for the BE as the machine driver must 484 * fix this up to match DSP decoder and ASRC configuration. 485 * I.e. machine driver fixup for compressed BE is mandatory. 486 */ 487 memset(&fe->dpcm[fe_substream->stream].hw_params, 0, 488 sizeof(struct snd_pcm_hw_params)); 489 490 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 491 492 ret = dpcm_be_dai_hw_params(fe, stream); 493 if (ret < 0) 494 goto out; 495 496 ret = dpcm_be_dai_prepare(fe, stream); 497 if (ret < 0) 498 goto out; 499 500 ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params); 501 if (ret < 0) 502 goto out; 503 504 ret = soc_compr_components_set_params(cstream, params); 505 if (ret < 0) 506 goto out; 507 508 ret = snd_soc_link_compr_set_params(cstream); 509 if (ret < 0) 510 goto out; 511 512 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START); 513 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; 514 515 out: 516 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 517 mutex_unlock(&fe->card->mutex); 518 return ret; 519 } 520 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 ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params); 532 if (ret < 0) 533 goto err; 534 535 for_each_rtd_components(rtd, i, component) { 536 if (!component->driver->compress_ops || 537 !component->driver->compress_ops->get_params) 538 continue; 539 540 ret = component->driver->compress_ops->get_params( 541 component, cstream, params); 542 break; 543 } 544 545 err: 546 mutex_unlock(&rtd->card->pcm_mutex); 547 return ret; 548 } 549 550 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 for_each_rtd_components(rtd, i, component) { 560 if (!component->driver->compress_ops || 561 !component->driver->compress_ops->get_caps) 562 continue; 563 564 ret = component->driver->compress_ops->get_caps( 565 component, cstream, caps); 566 break; 567 } 568 569 mutex_unlock(&rtd->card->pcm_mutex); 570 return ret; 571 } 572 573 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 for_each_rtd_components(rtd, i, component) { 583 if (!component->driver->compress_ops || 584 !component->driver->compress_ops->get_codec_caps) 585 continue; 586 587 ret = component->driver->compress_ops->get_codec_caps( 588 component, cstream, codec); 589 break; 590 } 591 592 mutex_unlock(&rtd->card->pcm_mutex); 593 return ret; 594 } 595 596 static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes) 597 { 598 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 ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes); 606 if (ret < 0) 607 goto err; 608 609 for_each_rtd_components(rtd, i, component) { 610 if (!component->driver->compress_ops || 611 !component->driver->compress_ops->ack) 612 continue; 613 614 ret = component->driver->compress_ops->ack( 615 component, cstream, bytes); 616 if (ret < 0) 617 goto err; 618 } 619 620 err: 621 mutex_unlock(&rtd->card->pcm_mutex); 622 return ret; 623 } 624 625 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 ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp); 636 if (ret < 0) 637 goto out; 638 639 for_each_rtd_components(rtd, i, component) { 640 if (!component->driver->compress_ops || 641 !component->driver->compress_ops->pointer) 642 continue; 643 644 ret = component->driver->compress_ops->pointer( 645 component, cstream, tstamp); 646 break; 647 } 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 for_each_rtd_components(rtd, i, component) { 663 if (!component->driver->compress_ops || 664 !component->driver->compress_ops->copy) 665 continue; 666 667 ret = component->driver->compress_ops->copy( 668 component, cstream, buf, count); 669 break; 670 } 671 672 mutex_unlock(&rtd->card->pcm_mutex); 673 return ret; 674 } 675 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 ret = snd_soc_dai_compr_set_metadata(cpu_dai, cstream, metadata); 685 if (ret < 0) 686 return ret; 687 688 for_each_rtd_components(rtd, i, component) { 689 if (!component->driver->compress_ops || 690 !component->driver->compress_ops->set_metadata) 691 continue; 692 693 ret = component->driver->compress_ops->set_metadata( 694 component, cstream, metadata); 695 if (ret < 0) 696 return ret; 697 } 698 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 ret = snd_soc_dai_compr_get_metadata(cpu_dai, cstream, metadata); 711 if (ret < 0) 712 return ret; 713 714 for_each_rtd_components(rtd, i, component) { 715 if (!component->driver->compress_ops || 716 !component->driver->compress_ops->get_metadata) 717 continue; 718 719 return component->driver->compress_ops->get_metadata( 720 component, cstream, metadata); 721 } 722 723 return 0; 724 } 725 726 /* ASoC Compress operations */ 727 static struct snd_compr_ops soc_compr_ops = { 728 .open = soc_compr_open, 729 .free = soc_compr_free, 730 .set_params = soc_compr_set_params, 731 .set_metadata = soc_compr_set_metadata, 732 .get_metadata = soc_compr_get_metadata, 733 .get_params = soc_compr_get_params, 734 .trigger = soc_compr_trigger, 735 .pointer = soc_compr_pointer, 736 .ack = soc_compr_ack, 737 .get_caps = soc_compr_get_caps, 738 .get_codec_caps = soc_compr_get_codec_caps 739 }; 740 741 /* ASoC Dynamic Compress operations */ 742 static struct snd_compr_ops soc_compr_dyn_ops = { 743 .open = soc_compr_open_fe, 744 .free = soc_compr_free_fe, 745 .set_params = soc_compr_set_params_fe, 746 .get_params = soc_compr_get_params, 747 .set_metadata = soc_compr_set_metadata, 748 .get_metadata = soc_compr_get_metadata, 749 .trigger = soc_compr_trigger_fe, 750 .pointer = soc_compr_pointer, 751 .ack = soc_compr_ack, 752 .get_caps = soc_compr_get_caps, 753 .get_codec_caps = soc_compr_get_codec_caps 754 }; 755 756 /** 757 * snd_soc_new_compress - create a new compress. 758 * 759 * @rtd: The runtime for which we will create compress 760 * @num: the device index number (zero based - shared with normal PCMs) 761 * 762 * Return: 0 for success, else error. 763 */ 764 int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) 765 { 766 struct snd_soc_component *component; 767 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 768 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 769 struct snd_compr *compr; 770 struct snd_pcm *be_pcm; 771 char new_name[64]; 772 int ret = 0, direction = 0; 773 int playback = 0, capture = 0; 774 int i; 775 776 if (rtd->num_cpus > 1 || 777 rtd->num_codecs > 1) { 778 dev_err(rtd->card->dev, 779 "Compress ASoC: Multi CPU/Codec not supported\n"); 780 return -EINVAL; 781 } 782 783 /* check client and interface hw capabilities */ 784 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) && 785 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK)) 786 playback = 1; 787 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) && 788 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE)) 789 capture = 1; 790 791 /* 792 * Compress devices are unidirectional so only one of the directions 793 * should be set, check for that (xor) 794 */ 795 if (playback + capture != 1) { 796 dev_err(rtd->card->dev, 797 "Compress ASoC: Invalid direction for P %d, C %d\n", 798 playback, capture); 799 return -EINVAL; 800 } 801 802 if (playback) 803 direction = SND_COMPRESS_PLAYBACK; 804 else 805 direction = SND_COMPRESS_CAPTURE; 806 807 compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL); 808 if (!compr) 809 return -ENOMEM; 810 811 compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops), 812 GFP_KERNEL); 813 if (!compr->ops) 814 return -ENOMEM; 815 816 if (rtd->dai_link->dynamic) { 817 snprintf(new_name, sizeof(new_name), "(%s)", 818 rtd->dai_link->stream_name); 819 820 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, 821 rtd->dai_link->dpcm_playback, 822 rtd->dai_link->dpcm_capture, &be_pcm); 823 if (ret < 0) { 824 dev_err(rtd->card->dev, 825 "Compress ASoC: can't create compressed for %s: %d\n", 826 rtd->dai_link->name, ret); 827 return ret; 828 } 829 830 rtd->pcm = be_pcm; 831 rtd->fe_compr = 1; 832 if (rtd->dai_link->dpcm_playback) 833 be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; 834 else if (rtd->dai_link->dpcm_capture) 835 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 } else { 838 snprintf(new_name, sizeof(new_name), "%s %s-%d", 839 rtd->dai_link->stream_name, codec_dai->name, num); 840 841 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); 842 } 843 844 for_each_rtd_components(rtd, i, component) { 845 if (!component->driver->compress_ops || 846 !component->driver->compress_ops->copy) 847 continue; 848 849 compr->ops->copy = soc_compr_copy; 850 break; 851 } 852 853 mutex_init(&compr->lock); 854 ret = snd_compress_new(rtd->card->snd_card, num, direction, 855 new_name, compr); 856 if (ret < 0) { 857 component = asoc_rtd_to_codec(rtd, 0)->component; 858 dev_err(component->dev, 859 "Compress ASoC: can't create compress for codec %s: %d\n", 860 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 rtd->compr = compr; 868 compr->private_data = rtd; 869 870 dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n", 871 codec_dai->name, cpu_dai->name); 872 873 return 0; 874 } 875 EXPORT_SYMBOL_GPL(snd_soc_new_compress); 876