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