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