aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/skylake/skl-topology.c
diff options
context:
space:
mode:
authorJeeja KP <jeeja.kp@intel.com>2015-10-26 20:22:52 -0400
committerMark Brown <broonie@kernel.org>2015-11-16 05:08:09 -0500
commit8724ff17521a91a87971027cf78631030091bc52 (patch)
tree21866f58048449874c033eff6f0899d7ac17884a /sound/soc/intel/skylake/skl-topology.c
parentce1b5551a06af31a72feeb50c02a9fe22599926a (diff)
ASoC: Intel: Skylake: Add support for virtual dsp widgets
In SKL topology routes, some paths can be connected by a widget which are not a DSP FW widget and virtual with respect to firmware. In these case when module has to bind, then the virtual DSP modules needs to skipped till a actual DSP module is found which connects the pipelines. So we need to walk the graph and find a widget which is real in nature. This patch adds that support and splits skl_tplg_pga_dapm_pre_pmu_event() fn with parsing code to skl_tplg_bind_sinks() fn and call that recursively as well as while parsing The patch moves code a bit while splitting so diffstat doesn't tell real picture Signed-off-by: Jeeja KP <jeeja.kp@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/skylake/skl-topology.c')
-rw-r--r--sound/soc/intel/skylake/skl-topology.c133
1 files changed, 83 insertions, 50 deletions
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index abbf8e7eb3e7..0c6e7833e652 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -397,40 +397,24 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
397 return 0; 397 return 0;
398} 398}
399 399
400/* 400static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
401 * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA 401 struct skl *skl,
402 * we need to do following: 402 struct skl_module_cfg *src_mconfig)
403 * - Bind to sink pipeline
404 * Since the sink pipes can be running and we don't get mixer event on
405 * connect for already running mixer, we need to find the sink pipes
406 * here and bind to them. This way dynamic connect works.
407 * - Start sink pipeline, if not running
408 * - Then run current pipe
409 */
410static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
411 struct skl *skl)
412{ 403{
413 struct snd_soc_dapm_path *p; 404 struct snd_soc_dapm_path *p;
414 struct snd_soc_dapm_widget *source, *sink; 405 struct snd_soc_dapm_widget *sink = NULL;
415 struct skl_module_cfg *src_mconfig, *sink_mconfig; 406 struct skl_module_cfg *sink_mconfig;
416 struct skl_sst *ctx = skl->skl_sst; 407 struct skl_sst *ctx = skl->skl_sst;
417 int ret = 0; 408 int ret;
418
419 source = w;
420 src_mconfig = source->priv;
421 409
422 /* 410 snd_soc_dapm_widget_for_each_sink_path(w, p) {
423 * find which sink it is connected to, bind with the sink,
424 * if sink is not started, start sink pipe first, then start
425 * this pipe
426 */
427 snd_soc_dapm_widget_for_each_source_path(w, p) {
428 if (!p->connect) 411 if (!p->connect)
429 continue; 412 continue;
430 413
431 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name); 414 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name);
432 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name); 415 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
433 416
417 sink = p->sink;
434 /* 418 /*
435 * here we will check widgets in sink pipelines, so that 419 * here we will check widgets in sink pipelines, so that
436 * can be any widgets type and we are only interested if 420 * can be any widgets type and we are only interested if
@@ -440,7 +424,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
440 is_skl_dsp_widget_type(p->sink)) { 424 is_skl_dsp_widget_type(p->sink)) {
441 425
442 sink = p->sink; 426 sink = p->sink;
443 src_mconfig = source->priv;
444 sink_mconfig = sink->priv; 427 sink_mconfig = sink->priv;
445 428
446 /* Bind source to sink, mixin is always source */ 429 /* Bind source to sink, mixin is always source */
@@ -454,10 +437,43 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
454 if (ret) 437 if (ret)
455 return ret; 438 return ret;
456 } 439 }
457 break;
458 } 440 }
459 } 441 }
460 442
443 if (!sink)
444 return skl_tplg_bind_sinks(sink, skl, src_mconfig);
445
446 return 0;
447}
448
449/*
450 * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA
451 * we need to do following:
452 * - Bind to sink pipeline
453 * Since the sink pipes can be running and we don't get mixer event on
454 * connect for already running mixer, we need to find the sink pipes
455 * here and bind to them. This way dynamic connect works.
456 * - Start sink pipeline, if not running
457 * - Then run current pipe
458 */
459static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
460 struct skl *skl)
461{
462 struct skl_module_cfg *src_mconfig;
463 struct skl_sst *ctx = skl->skl_sst;
464 int ret = 0;
465
466 src_mconfig = w->priv;
467
468 /*
469 * find which sink it is connected to, bind with the sink,
470 * if sink is not started, start sink pipe first, then start
471 * this pipe
472 */
473 ret = skl_tplg_bind_sinks(w, skl, src_mconfig);
474 if (ret)
475 return ret;
476
461 /* Start source pipe last after starting all sinks */ 477 /* Start source pipe last after starting all sinks */
462 ret = skl_run_pipe(ctx, src_mconfig->pipe); 478 ret = skl_run_pipe(ctx, src_mconfig->pipe);
463 if (ret) 479 if (ret)
@@ -466,6 +482,38 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
466 return 0; 482 return 0;
467} 483}
468 484
485static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
486 struct snd_soc_dapm_widget *w, struct skl *skl)
487{
488 struct snd_soc_dapm_path *p;
489 struct snd_soc_dapm_widget *src_w = NULL;
490 struct skl_sst *ctx = skl->skl_sst;
491
492 snd_soc_dapm_widget_for_each_source_path(w, p) {
493 src_w = p->source;
494 if (!p->connect)
495 continue;
496
497 dev_dbg(ctx->dev, "sink widget=%s\n", w->name);
498 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
499
500 /*
501 * here we will check widgets in sink pipelines, so that can
502 * be any widgets type and we are only interested if they are
503 * ones used for SKL so check that first
504 */
505 if ((p->source->priv != NULL) &&
506 is_skl_dsp_widget_type(p->source)) {
507 return p->source;
508 }
509 }
510
511 if (src_w != NULL)
512 return skl_get_src_dsp_widget(src_w, skl);
513
514 return NULL;
515}
516
469/* 517/*
470 * in the Post-PMU event of mixer we need to do following: 518 * in the Post-PMU event of mixer we need to do following:
471 * - Check if this pipe is running 519 * - Check if this pipe is running
@@ -479,7 +527,6 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
479 struct skl *skl) 527 struct skl *skl)
480{ 528{
481 int ret = 0; 529 int ret = 0;
482 struct snd_soc_dapm_path *p;
483 struct snd_soc_dapm_widget *source, *sink; 530 struct snd_soc_dapm_widget *source, *sink;
484 struct skl_module_cfg *src_mconfig, *sink_mconfig; 531 struct skl_module_cfg *src_mconfig, *sink_mconfig;
485 struct skl_sst *ctx = skl->skl_sst; 532 struct skl_sst *ctx = skl->skl_sst;
@@ -493,32 +540,18 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
493 * one more sink before this sink got connected, Since source is 540 * one more sink before this sink got connected, Since source is
494 * started, bind this sink to source and start this pipe. 541 * started, bind this sink to source and start this pipe.
495 */ 542 */
496 snd_soc_dapm_widget_for_each_sink_path(w, p) { 543 source = skl_get_src_dsp_widget(w, skl);
497 if (!p->connect) 544 if (source != NULL) {
498 continue; 545 src_mconfig = source->priv;
499 546 sink_mconfig = sink->priv;
500 dev_dbg(ctx->dev, "sink widget=%s\n", w->name); 547 src_pipe_started = 1;
501 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
502 548
503 /* 549 /*
504 * here we will check widgets in sink pipelines, so that 550 * check pipe state, then no need to bind or start the
505 * can be any widgets type and we are only interested if 551 * pipe
506 * they are ones used for SKL so check that first
507 */ 552 */
508 if ((p->source->priv != NULL) && 553 if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
509 is_skl_dsp_widget_type(p->source)) { 554 src_pipe_started = 0;
510 source = p->source;
511 src_mconfig = source->priv;
512 sink_mconfig = sink->priv;
513 src_pipe_started = 1;
514
515 /*
516 * check pipe state, then no need to bind or start
517 * the pipe
518 */
519 if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
520 src_pipe_started = 0;
521 }
522 } 555 }
523 556
524 if (src_pipe_started) { 557 if (src_pipe_started) {