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