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