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