1 /* 2 * soc-pcm.c -- ALSA SoC PCM 3 * 4 * Copyright 2005 Wolfson Microelectronics PLC. 5 * Copyright 2005 Openedhand Ltd. 6 * Copyright (C) 2010 Slimlogic Ltd. 7 * Copyright (C) 2010 Texas Instruments Inc. 8 * 9 * Authors: Liam Girdwood <lrg@ti.com> 10 * Mark Brown <broonie@opensource.wolfsonmicro.com> 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License as published by the 14 * Free Software Foundation; either version 2 of the License, or (at your 15 * option) any later version. 16 * 17 */ 18 19 #include <linux/kernel.h> 20 #include <linux/init.h> 21 #include <linux/delay.h> 22 #include <linux/pm_runtime.h> 23 #include <linux/slab.h> 24 #include <linux/workqueue.h> 25 #include <sound/core.h> 26 #include <sound/pcm.h> 27 #include <sound/pcm_params.h> 28 #include <sound/soc.h> 29 #include <sound/initval.h> 30 31 static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, 32 struct snd_soc_dai *soc_dai) 33 { 34 struct snd_soc_pcm_runtime *rtd = substream->private_data; 35 int ret; 36 37 if (!soc_dai->driver->symmetric_rates && 38 !rtd->dai_link->symmetric_rates) 39 return 0; 40 41 /* This can happen if multiple streams are starting simultaneously - 42 * the second can need to get its constraints before the first has 43 * picked a rate. Complain and allow the application to carry on. 44 */ 45 if (!soc_dai->rate) { 46 dev_warn(soc_dai->dev, 47 "Not enforcing symmetric_rates due to race\n"); 48 return 0; 49 } 50 51 dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate); 52 53 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 54 SNDRV_PCM_HW_PARAM_RATE, 55 soc_dai->rate, soc_dai->rate); 56 if (ret < 0) { 57 dev_err(soc_dai->dev, 58 "Unable to apply rate symmetry constraint: %d\n", ret); 59 return ret; 60 } 61 62 return 0; 63 } 64 65 /* 66 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 67 * then initialized and any private data can be allocated. This also calls 68 * startup for the cpu DAI, platform, machine and codec DAI. 69 */ 70 static int soc_pcm_open(struct snd_pcm_substream *substream) 71 { 72 struct snd_soc_pcm_runtime *rtd = substream->private_data; 73 struct snd_pcm_runtime *runtime = substream->runtime; 74 struct snd_soc_platform *platform = rtd->platform; 75 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 76 struct snd_soc_dai *codec_dai = rtd->codec_dai; 77 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; 78 struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver; 79 int ret = 0; 80 81 pm_runtime_get_sync(cpu_dai->dev); 82 pm_runtime_get_sync(codec_dai->dev); 83 pm_runtime_get_sync(platform->dev); 84 85 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 86 87 /* startup the audio subsystem */ 88 if (cpu_dai->driver->ops->startup) { 89 ret = cpu_dai->driver->ops->startup(substream, cpu_dai); 90 if (ret < 0) { 91 printk(KERN_ERR "asoc: can't open interface %s\n", 92 cpu_dai->name); 93 goto out; 94 } 95 } 96 97 if (platform->driver->ops && platform->driver->ops->open) { 98 ret = platform->driver->ops->open(substream); 99 if (ret < 0) { 100 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name); 101 goto platform_err; 102 } 103 } 104 105 if (codec_dai->driver->ops->startup) { 106 ret = codec_dai->driver->ops->startup(substream, codec_dai); 107 if (ret < 0) { 108 printk(KERN_ERR "asoc: can't open codec %s\n", 109 codec_dai->name); 110 goto codec_dai_err; 111 } 112 } 113 114 if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { 115 ret = rtd->dai_link->ops->startup(substream); 116 if (ret < 0) { 117 printk(KERN_ERR "asoc: %s startup failed\n", rtd->dai_link->name); 118 goto machine_err; 119 } 120 } 121 122 /* Check that the codec and cpu DAIs are compatible */ 123 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 124 runtime->hw.rate_min = 125 max(codec_dai_drv->playback.rate_min, 126 cpu_dai_drv->playback.rate_min); 127 runtime->hw.rate_max = 128 min(codec_dai_drv->playback.rate_max, 129 cpu_dai_drv->playback.rate_max); 130 runtime->hw.channels_min = 131 max(codec_dai_drv->playback.channels_min, 132 cpu_dai_drv->playback.channels_min); 133 runtime->hw.channels_max = 134 min(codec_dai_drv->playback.channels_max, 135 cpu_dai_drv->playback.channels_max); 136 runtime->hw.formats = 137 codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats; 138 runtime->hw.rates = 139 codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates; 140 if (codec_dai_drv->playback.rates 141 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) 142 runtime->hw.rates |= cpu_dai_drv->playback.rates; 143 if (cpu_dai_drv->playback.rates 144 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) 145 runtime->hw.rates |= codec_dai_drv->playback.rates; 146 } else { 147 runtime->hw.rate_min = 148 max(codec_dai_drv->capture.rate_min, 149 cpu_dai_drv->capture.rate_min); 150 runtime->hw.rate_max = 151 min(codec_dai_drv->capture.rate_max, 152 cpu_dai_drv->capture.rate_max); 153 runtime->hw.channels_min = 154 max(codec_dai_drv->capture.channels_min, 155 cpu_dai_drv->capture.channels_min); 156 runtime->hw.channels_max = 157 min(codec_dai_drv->capture.channels_max, 158 cpu_dai_drv->capture.channels_max); 159 runtime->hw.formats = 160 codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats; 161 runtime->hw.rates = 162 codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates; 163 if (codec_dai_drv->capture.rates 164 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) 165 runtime->hw.rates |= cpu_dai_drv->capture.rates; 166 if (cpu_dai_drv->capture.rates 167 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) 168 runtime->hw.rates |= codec_dai_drv->capture.rates; 169 } 170 171 ret = -EINVAL; 172 snd_pcm_limit_hw_rates(runtime); 173 if (!runtime->hw.rates) { 174 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n", 175 codec_dai->name, cpu_dai->name); 176 goto config_err; 177 } 178 if (!runtime->hw.formats) { 179 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n", 180 codec_dai->name, cpu_dai->name); 181 goto config_err; 182 } 183 if (!runtime->hw.channels_min || !runtime->hw.channels_max || 184 runtime->hw.channels_min > runtime->hw.channels_max) { 185 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", 186 codec_dai->name, cpu_dai->name); 187 goto config_err; 188 } 189 190 /* Symmetry only applies if we've already got an active stream. */ 191 if (cpu_dai->active) { 192 ret = soc_pcm_apply_symmetry(substream, cpu_dai); 193 if (ret != 0) 194 goto config_err; 195 } 196 197 if (codec_dai->active) { 198 ret = soc_pcm_apply_symmetry(substream, codec_dai); 199 if (ret != 0) 200 goto config_err; 201 } 202 203 pr_debug("asoc: %s <-> %s info:\n", 204 codec_dai->name, cpu_dai->name); 205 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates); 206 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, 207 runtime->hw.channels_max); 208 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 209 runtime->hw.rate_max); 210 211 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 212 cpu_dai->playback_active++; 213 codec_dai->playback_active++; 214 } else { 215 cpu_dai->capture_active++; 216 codec_dai->capture_active++; 217 } 218 cpu_dai->active++; 219 codec_dai->active++; 220 rtd->codec->active++; 221 mutex_unlock(&rtd->pcm_mutex); 222 return 0; 223 224 config_err: 225 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown) 226 rtd->dai_link->ops->shutdown(substream); 227 228 machine_err: 229 if (codec_dai->driver->ops->shutdown) 230 codec_dai->driver->ops->shutdown(substream, codec_dai); 231 232 codec_dai_err: 233 if (platform->driver->ops && platform->driver->ops->close) 234 platform->driver->ops->close(substream); 235 236 platform_err: 237 if (cpu_dai->driver->ops->shutdown) 238 cpu_dai->driver->ops->shutdown(substream, cpu_dai); 239 out: 240 mutex_unlock(&rtd->pcm_mutex); 241 242 pm_runtime_put(platform->dev); 243 pm_runtime_put(codec_dai->dev); 244 pm_runtime_put(cpu_dai->dev); 245 246 return ret; 247 } 248 249 /* 250 * Power down the audio subsystem pmdown_time msecs after close is called. 251 * This is to ensure there are no pops or clicks in between any music tracks 252 * due to DAPM power cycling. 253 */ 254 static void close_delayed_work(struct work_struct *work) 255 { 256 struct snd_soc_pcm_runtime *rtd = 257 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work); 258 struct snd_soc_dai *codec_dai = rtd->codec_dai; 259 260 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 261 262 pr_debug("pop wq checking: %s status: %s waiting: %s\n", 263 codec_dai->driver->playback.stream_name, 264 codec_dai->playback_active ? "active" : "inactive", 265 codec_dai->pop_wait ? "yes" : "no"); 266 267 /* are we waiting on this codec DAI stream */ 268 if (codec_dai->pop_wait == 1) { 269 codec_dai->pop_wait = 0; 270 snd_soc_dapm_stream_event(rtd, 271 codec_dai->driver->playback.stream_name, 272 SND_SOC_DAPM_STREAM_STOP); 273 } 274 275 mutex_unlock(&rtd->pcm_mutex); 276 } 277 278 /* 279 * Called by ALSA when a PCM substream is closed. Private data can be 280 * freed here. The cpu DAI, codec DAI, machine and platform are also 281 * shutdown. 282 */ 283 static int soc_pcm_close(struct snd_pcm_substream *substream) 284 { 285 struct snd_soc_pcm_runtime *rtd = substream->private_data; 286 struct snd_soc_platform *platform = rtd->platform; 287 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 288 struct snd_soc_dai *codec_dai = rtd->codec_dai; 289 struct snd_soc_codec *codec = rtd->codec; 290 291 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 292 293 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 294 cpu_dai->playback_active--; 295 codec_dai->playback_active--; 296 } else { 297 cpu_dai->capture_active--; 298 codec_dai->capture_active--; 299 } 300 301 cpu_dai->active--; 302 codec_dai->active--; 303 codec->active--; 304 305 /* clear the corresponding DAIs rate when inactive */ 306 if (!cpu_dai->active) 307 cpu_dai->rate = 0; 308 309 if (!codec_dai->active) 310 codec_dai->rate = 0; 311 312 /* Muting the DAC suppresses artifacts caused during digital 313 * shutdown, for example from stopping clocks. 314 */ 315 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 316 snd_soc_dai_digital_mute(codec_dai, 1); 317 318 if (cpu_dai->driver->ops->shutdown) 319 cpu_dai->driver->ops->shutdown(substream, cpu_dai); 320 321 if (codec_dai->driver->ops->shutdown) 322 codec_dai->driver->ops->shutdown(substream, codec_dai); 323 324 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown) 325 rtd->dai_link->ops->shutdown(substream); 326 327 if (platform->driver->ops && platform->driver->ops->close) 328 platform->driver->ops->close(substream); 329 cpu_dai->runtime = NULL; 330 331 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 332 if (codec->ignore_pmdown_time || 333 rtd->dai_link->ignore_pmdown_time) { 334 /* powered down playback stream now */ 335 snd_soc_dapm_stream_event(rtd, 336 codec_dai->driver->playback.stream_name, 337 SND_SOC_DAPM_STREAM_STOP); 338 } else { 339 /* start delayed pop wq here for playback streams */ 340 codec_dai->pop_wait = 1; 341 schedule_delayed_work(&rtd->delayed_work, 342 msecs_to_jiffies(rtd->pmdown_time)); 343 } 344 } else { 345 /* capture streams can be powered down now */ 346 snd_soc_dapm_stream_event(rtd, 347 codec_dai->driver->capture.stream_name, 348 SND_SOC_DAPM_STREAM_STOP); 349 } 350 351 mutex_unlock(&rtd->pcm_mutex); 352 353 pm_runtime_put(platform->dev); 354 pm_runtime_put(codec_dai->dev); 355 pm_runtime_put(cpu_dai->dev); 356 357 return 0; 358 } 359 360 /* 361 * Called by ALSA when the PCM substream is prepared, can set format, sample 362 * rate, etc. This function is non atomic and can be called multiple times, 363 * it can refer to the runtime info. 364 */ 365 static int soc_pcm_prepare(struct snd_pcm_substream *substream) 366 { 367 struct snd_soc_pcm_runtime *rtd = substream->private_data; 368 struct snd_soc_platform *platform = rtd->platform; 369 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 370 struct snd_soc_dai *codec_dai = rtd->codec_dai; 371 int ret = 0; 372 373 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 374 375 if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { 376 ret = rtd->dai_link->ops->prepare(substream); 377 if (ret < 0) { 378 printk(KERN_ERR "asoc: machine prepare error\n"); 379 goto out; 380 } 381 } 382 383 if (platform->driver->ops && platform->driver->ops->prepare) { 384 ret = platform->driver->ops->prepare(substream); 385 if (ret < 0) { 386 printk(KERN_ERR "asoc: platform prepare error\n"); 387 goto out; 388 } 389 } 390 391 if (codec_dai->driver->ops->prepare) { 392 ret = codec_dai->driver->ops->prepare(substream, codec_dai); 393 if (ret < 0) { 394 printk(KERN_ERR "asoc: codec DAI prepare error\n"); 395 goto out; 396 } 397 } 398 399 if (cpu_dai->driver->ops->prepare) { 400 ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); 401 if (ret < 0) { 402 printk(KERN_ERR "asoc: cpu DAI prepare error\n"); 403 goto out; 404 } 405 } 406 407 /* cancel any delayed stream shutdown that is pending */ 408 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 409 codec_dai->pop_wait) { 410 codec_dai->pop_wait = 0; 411 cancel_delayed_work(&rtd->delayed_work); 412 } 413 414 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 415 snd_soc_dapm_stream_event(rtd, 416 codec_dai->driver->playback.stream_name, 417 SND_SOC_DAPM_STREAM_START); 418 else 419 snd_soc_dapm_stream_event(rtd, 420 codec_dai->driver->capture.stream_name, 421 SND_SOC_DAPM_STREAM_START); 422 423 snd_soc_dai_digital_mute(codec_dai, 0); 424 425 out: 426 mutex_unlock(&rtd->pcm_mutex); 427 return ret; 428 } 429 430 /* 431 * Called by ALSA when the hardware params are set by application. This 432 * function can also be called multiple times and can allocate buffers 433 * (using snd_pcm_lib_* ). It's non-atomic. 434 */ 435 static int soc_pcm_hw_params(struct snd_pcm_substream *substream, 436 struct snd_pcm_hw_params *params) 437 { 438 struct snd_soc_pcm_runtime *rtd = substream->private_data; 439 struct snd_soc_platform *platform = rtd->platform; 440 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 441 struct snd_soc_dai *codec_dai = rtd->codec_dai; 442 int ret = 0; 443 444 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 445 446 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { 447 ret = rtd->dai_link->ops->hw_params(substream, params); 448 if (ret < 0) { 449 printk(KERN_ERR "asoc: machine hw_params failed\n"); 450 goto out; 451 } 452 } 453 454 if (codec_dai->driver->ops->hw_params) { 455 ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); 456 if (ret < 0) { 457 printk(KERN_ERR "asoc: can't set codec %s hw params\n", 458 codec_dai->name); 459 goto codec_err; 460 } 461 } 462 463 if (cpu_dai->driver->ops->hw_params) { 464 ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); 465 if (ret < 0) { 466 printk(KERN_ERR "asoc: interface %s hw params failed\n", 467 cpu_dai->name); 468 goto interface_err; 469 } 470 } 471 472 if (platform->driver->ops && platform->driver->ops->hw_params) { 473 ret = platform->driver->ops->hw_params(substream, params); 474 if (ret < 0) { 475 printk(KERN_ERR "asoc: platform %s hw params failed\n", 476 platform->name); 477 goto platform_err; 478 } 479 } 480 481 /* store the rate for each DAIs */ 482 cpu_dai->rate = params_rate(params); 483 codec_dai->rate = params_rate(params); 484 485 out: 486 mutex_unlock(&rtd->pcm_mutex); 487 return ret; 488 489 platform_err: 490 if (cpu_dai->driver->ops->hw_free) 491 cpu_dai->driver->ops->hw_free(substream, cpu_dai); 492 493 interface_err: 494 if (codec_dai->driver->ops->hw_free) 495 codec_dai->driver->ops->hw_free(substream, codec_dai); 496 497 codec_err: 498 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free) 499 rtd->dai_link->ops->hw_free(substream); 500 501 mutex_unlock(&rtd->pcm_mutex); 502 return ret; 503 } 504 505 /* 506 * Frees resources allocated by hw_params, can be called multiple times 507 */ 508 static int soc_pcm_hw_free(struct snd_pcm_substream *substream) 509 { 510 struct snd_soc_pcm_runtime *rtd = substream->private_data; 511 struct snd_soc_platform *platform = rtd->platform; 512 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 513 struct snd_soc_dai *codec_dai = rtd->codec_dai; 514 struct snd_soc_codec *codec = rtd->codec; 515 516 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 517 518 /* apply codec digital mute */ 519 if (!codec->active) 520 snd_soc_dai_digital_mute(codec_dai, 1); 521 522 /* free any machine hw params */ 523 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free) 524 rtd->dai_link->ops->hw_free(substream); 525 526 /* free any DMA resources */ 527 if (platform->driver->ops && platform->driver->ops->hw_free) 528 platform->driver->ops->hw_free(substream); 529 530 /* now free hw params for the DAIs */ 531 if (codec_dai->driver->ops->hw_free) 532 codec_dai->driver->ops->hw_free(substream, codec_dai); 533 534 if (cpu_dai->driver->ops->hw_free) 535 cpu_dai->driver->ops->hw_free(substream, cpu_dai); 536 537 mutex_unlock(&rtd->pcm_mutex); 538 return 0; 539 } 540 541 static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 542 { 543 struct snd_soc_pcm_runtime *rtd = substream->private_data; 544 struct snd_soc_platform *platform = rtd->platform; 545 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 546 struct snd_soc_dai *codec_dai = rtd->codec_dai; 547 int ret; 548 549 if (codec_dai->driver->ops->trigger) { 550 ret = codec_dai->driver->ops->trigger(substream, cmd, codec_dai); 551 if (ret < 0) 552 return ret; 553 } 554 555 if (platform->driver->ops && platform->driver->ops->trigger) { 556 ret = platform->driver->ops->trigger(substream, cmd); 557 if (ret < 0) 558 return ret; 559 } 560 561 if (cpu_dai->driver->ops->trigger) { 562 ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai); 563 if (ret < 0) 564 return ret; 565 } 566 return 0; 567 } 568 569 /* 570 * soc level wrapper for pointer callback 571 * If cpu_dai, codec_dai, platform driver has the delay callback, than 572 * the runtime->delay will be updated accordingly. 573 */ 574 static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) 575 { 576 struct snd_soc_pcm_runtime *rtd = substream->private_data; 577 struct snd_soc_platform *platform = rtd->platform; 578 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 579 struct snd_soc_dai *codec_dai = rtd->codec_dai; 580 struct snd_pcm_runtime *runtime = substream->runtime; 581 snd_pcm_uframes_t offset = 0; 582 snd_pcm_sframes_t delay = 0; 583 584 if (platform->driver->ops && platform->driver->ops->pointer) 585 offset = platform->driver->ops->pointer(substream); 586 587 if (cpu_dai->driver->ops->delay) 588 delay += cpu_dai->driver->ops->delay(substream, cpu_dai); 589 590 if (codec_dai->driver->ops->delay) 591 delay += codec_dai->driver->ops->delay(substream, codec_dai); 592 593 if (platform->driver->delay) 594 delay += platform->driver->delay(substream, codec_dai); 595 596 runtime->delay = delay; 597 598 return offset; 599 } 600 601 /* create a new pcm */ 602 int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 603 { 604 struct snd_soc_codec *codec = rtd->codec; 605 struct snd_soc_platform *platform = rtd->platform; 606 struct snd_soc_dai *codec_dai = rtd->codec_dai; 607 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 608 struct snd_pcm_ops *soc_pcm_ops = &rtd->ops; 609 struct snd_pcm *pcm; 610 char new_name[64]; 611 int ret = 0, playback = 0, capture = 0; 612 613 soc_pcm_ops->open = soc_pcm_open; 614 soc_pcm_ops->close = soc_pcm_close; 615 soc_pcm_ops->hw_params = soc_pcm_hw_params; 616 soc_pcm_ops->hw_free = soc_pcm_hw_free; 617 soc_pcm_ops->prepare = soc_pcm_prepare; 618 soc_pcm_ops->trigger = soc_pcm_trigger; 619 soc_pcm_ops->pointer = soc_pcm_pointer; 620 621 /* check client and interface hw capabilities */ 622 snprintf(new_name, sizeof(new_name), "%s %s-%d", 623 rtd->dai_link->stream_name, codec_dai->name, num); 624 625 if (codec_dai->driver->playback.channels_min) 626 playback = 1; 627 if (codec_dai->driver->capture.channels_min) 628 capture = 1; 629 630 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num,new_name); 631 ret = snd_pcm_new(rtd->card->snd_card, new_name, 632 num, playback, capture, &pcm); 633 if (ret < 0) { 634 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); 635 return ret; 636 } 637 638 /* DAPM dai link stream work */ 639 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 640 641 rtd->pcm = pcm; 642 pcm->private_data = rtd; 643 if (platform->driver->ops) { 644 soc_pcm_ops->mmap = platform->driver->ops->mmap; 645 soc_pcm_ops->pointer = platform->driver->ops->pointer; 646 soc_pcm_ops->ioctl = platform->driver->ops->ioctl; 647 soc_pcm_ops->copy = platform->driver->ops->copy; 648 soc_pcm_ops->silence = platform->driver->ops->silence; 649 soc_pcm_ops->ack = platform->driver->ops->ack; 650 soc_pcm_ops->page = platform->driver->ops->page; 651 } 652 653 if (playback) 654 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops); 655 656 if (capture) 657 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops); 658 659 if (platform->driver->pcm_new) { 660 ret = platform->driver->pcm_new(rtd); 661 if (ret < 0) { 662 pr_err("asoc: platform pcm constructor failed\n"); 663 return ret; 664 } 665 } 666 667 pcm->private_free = platform->driver->pcm_free; 668 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 669 cpu_dai->name); 670 return ret; 671 } 672