soc-pcm.c (4f2bd18b191a10660782f2f1ccc989b000b2be63) soc-pcm.c (4febced15ac8ddb9cf3e603edb111842e4863d9a)
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 *

--- 434 unchanged lines hidden (view full) ---

443 snd_pcm_limit_hw_rates(runtime);
444
445 hw->rate_min = max(hw->rate_min, cpu_stream->rate_min);
446 hw->rate_min = max(hw->rate_min, rate_min);
447 hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max);
448 hw->rate_max = min_not_zero(hw->rate_max, rate_max);
449}
450
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 *

--- 434 unchanged lines hidden (view full) ---

443 snd_pcm_limit_hw_rates(runtime);
444
445 hw->rate_min = max(hw->rate_min, cpu_stream->rate_min);
446 hw->rate_min = max(hw->rate_min, rate_min);
447 hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max);
448 hw->rate_max = min_not_zero(hw->rate_max, rate_max);
449}
450
451static int soc_pcm_components_close(struct snd_pcm_substream *substream,
452 struct snd_soc_component *last)
453{
454 struct snd_soc_pcm_runtime *rtd = substream->private_data;
455 struct snd_soc_rtdcom_list *rtdcom;
456 struct snd_soc_component *component;
457
458 for_each_rtdcom(rtd, rtdcom) {
459 component = rtdcom->component;
460
461 if (component == last)
462 break;
463
464 if (!component->driver->ops ||
465 !component->driver->ops->close)
466 continue;
467
468 component->driver->ops->close(substream);
469 }
470
471 return 0;
472}
473
474/*
475 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
476 * then initialized and any private data can be allocated. This also calls
477 * startup for the cpu DAI, component, machine and codec DAI.
478 */
479static int soc_pcm_open(struct snd_pcm_substream *substream)
480{
481 struct snd_soc_pcm_runtime *rtd = substream->private_data;
482 struct snd_pcm_runtime *runtime = substream->runtime;
483 struct snd_soc_component *component;
484 struct snd_soc_rtdcom_list *rtdcom;
485 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
486 struct snd_soc_dai *codec_dai;
487 const char *codec_dai_name = "multicodec";
451/*
452 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
453 * then initialized and any private data can be allocated. This also calls
454 * startup for the cpu DAI, component, machine and codec DAI.
455 */
456static int soc_pcm_open(struct snd_pcm_substream *substream)
457{
458 struct snd_soc_pcm_runtime *rtd = substream->private_data;
459 struct snd_pcm_runtime *runtime = substream->runtime;
460 struct snd_soc_component *component;
461 struct snd_soc_rtdcom_list *rtdcom;
462 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
463 struct snd_soc_dai *codec_dai;
464 const char *codec_dai_name = "multicodec";
488 int i, ret = 0;
465 int i, ret = 0, __ret;
489
490 pinctrl_pm_select_default_state(cpu_dai->dev);
491 for (i = 0; i < rtd->num_codecs; i++)
492 pinctrl_pm_select_default_state(rtd->codec_dais[i]->dev);
493
494 for_each_rtdcom(rtd, rtdcom) {
495 component = rtdcom->component;
496

--- 7 unchanged lines hidden (view full) ---

504 ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
505 if (ret < 0) {
506 dev_err(cpu_dai->dev, "ASoC: can't open interface"
507 " %s: %d\n", cpu_dai->name, ret);
508 goto out;
509 }
510 }
511
466
467 pinctrl_pm_select_default_state(cpu_dai->dev);
468 for (i = 0; i < rtd->num_codecs; i++)
469 pinctrl_pm_select_default_state(rtd->codec_dais[i]->dev);
470
471 for_each_rtdcom(rtd, rtdcom) {
472 component = rtdcom->component;
473

--- 7 unchanged lines hidden (view full) ---

481 ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
482 if (ret < 0) {
483 dev_err(cpu_dai->dev, "ASoC: can't open interface"
484 " %s: %d\n", cpu_dai->name, ret);
485 goto out;
486 }
487 }
488
489 ret = 0;
512 for_each_rtdcom(rtd, rtdcom) {
513 component = rtdcom->component;
514
515 if (!component->driver->ops ||
516 !component->driver->ops->open)
517 continue;
518
490 for_each_rtdcom(rtd, rtdcom) {
491 component = rtdcom->component;
492
493 if (!component->driver->ops ||
494 !component->driver->ops->open)
495 continue;
496
519 ret = component->driver->ops->open(substream);
520 if (ret < 0) {
497 __ret = component->driver->ops->open(substream);
498 if (__ret < 0) {
521 dev_err(component->dev,
522 "ASoC: can't open component %s: %d\n",
499 dev_err(component->dev,
500 "ASoC: can't open component %s: %d\n",
523 component->name, ret);
524 goto component_err;
501 component->name, __ret);
502 ret = __ret;
525 }
526 }
503 }
504 }
527 component = NULL;
505 if (ret < 0)
506 goto component_err;
528
529 for (i = 0; i < rtd->num_codecs; i++) {
530 codec_dai = rtd->codec_dais[i];
531 if (codec_dai->driver->ops->startup) {
532 ret = codec_dai->driver->ops->startup(substream,
533 codec_dai);
534 if (ret < 0) {
535 dev_err(codec_dai->dev,

--- 92 unchanged lines hidden (view full) ---

628codec_dai_err:
629 while (--i >= 0) {
630 codec_dai = rtd->codec_dais[i];
631 if (codec_dai->driver->ops->shutdown)
632 codec_dai->driver->ops->shutdown(substream, codec_dai);
633 }
634
635component_err:
507
508 for (i = 0; i < rtd->num_codecs; i++) {
509 codec_dai = rtd->codec_dais[i];
510 if (codec_dai->driver->ops->startup) {
511 ret = codec_dai->driver->ops->startup(substream,
512 codec_dai);
513 if (ret < 0) {
514 dev_err(codec_dai->dev,

--- 92 unchanged lines hidden (view full) ---

607codec_dai_err:
608 while (--i >= 0) {
609 codec_dai = rtd->codec_dais[i];
610 if (codec_dai->driver->ops->shutdown)
611 codec_dai->driver->ops->shutdown(substream, codec_dai);
612 }
613
614component_err:
636 soc_pcm_components_close(substream, component);
615 for_each_rtdcom(rtd, rtdcom) {
616 component = rtdcom->component;
637
617
618 if (!component->driver->ops ||
619 !component->driver->ops->close)
620 continue;
621
622 component->driver->ops->close(substream);
623 }
624
638 if (cpu_dai->driver->ops->shutdown)
639 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
640out:
641 mutex_unlock(&rtd->pcm_mutex);
642
643 for_each_rtdcom(rtd, rtdcom) {
644 component = rtdcom->component;
645

--- 76 unchanged lines hidden (view full) ---

722 codec_dai = rtd->codec_dais[i];
723 if (codec_dai->driver->ops->shutdown)
724 codec_dai->driver->ops->shutdown(substream, codec_dai);
725 }
726
727 if (rtd->dai_link->ops->shutdown)
728 rtd->dai_link->ops->shutdown(substream);
729
625 if (cpu_dai->driver->ops->shutdown)
626 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
627out:
628 mutex_unlock(&rtd->pcm_mutex);
629
630 for_each_rtdcom(rtd, rtdcom) {
631 component = rtdcom->component;
632

--- 76 unchanged lines hidden (view full) ---

709 codec_dai = rtd->codec_dais[i];
710 if (codec_dai->driver->ops->shutdown)
711 codec_dai->driver->ops->shutdown(substream, codec_dai);
712 }
713
714 if (rtd->dai_link->ops->shutdown)
715 rtd->dai_link->ops->shutdown(substream);
716
730 soc_pcm_components_close(substream, NULL);
717 for_each_rtdcom(rtd, rtdcom) {
718 component = rtdcom->component;
731
719
720 if (!component->driver->ops ||
721 !component->driver->ops->close)
722 continue;
723
724 component->driver->ops->close(substream);
725 }
726
732 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
733 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
734 /* powered down playback stream now */
735 snd_soc_dapm_stream_event(rtd,
736 SNDRV_PCM_STREAM_PLAYBACK,
737 SND_SOC_DAPM_STREAM_STOP);
738 } else {
739 /* start delayed pop wq here for playback streams */

--- 134 unchanged lines hidden (view full) ---

874 dai->name, ret);
875 return ret;
876 }
877 }
878
879 return 0;
880}
881
727 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
728 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
729 /* powered down playback stream now */
730 snd_soc_dapm_stream_event(rtd,
731 SNDRV_PCM_STREAM_PLAYBACK,
732 SND_SOC_DAPM_STREAM_STOP);
733 } else {
734 /* start delayed pop wq here for playback streams */

--- 134 unchanged lines hidden (view full) ---

869 dai->name, ret);
870 return ret;
871 }
872 }
873
874 return 0;
875}
876
882static int soc_pcm_components_hw_free(struct snd_pcm_substream *substream,
883 struct snd_soc_component *last)
884{
885 struct snd_soc_pcm_runtime *rtd = substream->private_data;
886 struct snd_soc_rtdcom_list *rtdcom;
887 struct snd_soc_component *component;
888
889 for_each_rtdcom(rtd, rtdcom) {
890 component = rtdcom->component;
891
892 if (component == last)
893 break;
894
895 if (!component->driver->ops ||
896 !component->driver->ops->hw_free)
897 continue;
898
899 component->driver->ops->hw_free(substream);
900 }
901
902 return 0;
903}
904
905/*
906 * Called by ALSA when the hardware params are set by application. This
907 * function can also be called multiple times and can allocate buffers
908 * (using snd_pcm_lib_* ). It's non-atomic.
909 */
910static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
911 struct snd_pcm_hw_params *params)
912{
913 struct snd_soc_pcm_runtime *rtd = substream->private_data;
914 struct snd_soc_component *component;
915 struct snd_soc_rtdcom_list *rtdcom;
916 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
877/*
878 * Called by ALSA when the hardware params are set by application. This
879 * function can also be called multiple times and can allocate buffers
880 * (using snd_pcm_lib_* ). It's non-atomic.
881 */
882static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
883 struct snd_pcm_hw_params *params)
884{
885 struct snd_soc_pcm_runtime *rtd = substream->private_data;
886 struct snd_soc_component *component;
887 struct snd_soc_rtdcom_list *rtdcom;
888 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
917 int i, ret = 0;
889 int i, ret = 0, __ret;
918
919 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
920 if (rtd->dai_link->ops->hw_params) {
921 ret = rtd->dai_link->ops->hw_params(substream, params);
922 if (ret < 0) {
923 dev_err(rtd->card->dev, "ASoC: machine hw_params"
924 " failed: %d\n", ret);
925 goto out;

--- 41 unchanged lines hidden (view full) ---

967 codec_dai->sample_bits = snd_pcm_format_physical_width(
968 params_format(&codec_params));
969 }
970
971 ret = soc_dai_hw_params(substream, params, cpu_dai);
972 if (ret < 0)
973 goto interface_err;
974
890
891 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
892 if (rtd->dai_link->ops->hw_params) {
893 ret = rtd->dai_link->ops->hw_params(substream, params);
894 if (ret < 0) {
895 dev_err(rtd->card->dev, "ASoC: machine hw_params"
896 " failed: %d\n", ret);
897 goto out;

--- 41 unchanged lines hidden (view full) ---

939 codec_dai->sample_bits = snd_pcm_format_physical_width(
940 params_format(&codec_params));
941 }
942
943 ret = soc_dai_hw_params(substream, params, cpu_dai);
944 if (ret < 0)
945 goto interface_err;
946
947 ret = 0;
975 for_each_rtdcom(rtd, rtdcom) {
976 component = rtdcom->component;
977
978 if (!component->driver->ops ||
979 !component->driver->ops->hw_params)
980 continue;
981
948 for_each_rtdcom(rtd, rtdcom) {
949 component = rtdcom->component;
950
951 if (!component->driver->ops ||
952 !component->driver->ops->hw_params)
953 continue;
954
982 ret = component->driver->ops->hw_params(substream, params);
983 if (ret < 0) {
955 __ret = component->driver->ops->hw_params(substream, params);
956 if (__ret < 0) {
984 dev_err(component->dev,
985 "ASoC: %s hw params failed: %d\n",
957 dev_err(component->dev,
958 "ASoC: %s hw params failed: %d\n",
986 component->name, ret);
987 goto component_err;
959 component->name, __ret);
960 ret = __ret;
988 }
989 }
961 }
962 }
990 component = NULL;
963 if (ret < 0)
964 goto component_err;
991
992 /* store the parameters for each DAIs */
993 cpu_dai->rate = params_rate(params);
994 cpu_dai->channels = params_channels(params);
995 cpu_dai->sample_bits =
996 snd_pcm_format_physical_width(params_format(params));
997
998 ret = soc_pcm_params_symmetry(substream, params);
999 if (ret)
1000 goto component_err;
1001out:
1002 mutex_unlock(&rtd->pcm_mutex);
1003 return ret;
1004
1005component_err:
965
966 /* store the parameters for each DAIs */
967 cpu_dai->rate = params_rate(params);
968 cpu_dai->channels = params_channels(params);
969 cpu_dai->sample_bits =
970 snd_pcm_format_physical_width(params_format(params));
971
972 ret = soc_pcm_params_symmetry(substream, params);
973 if (ret)
974 goto component_err;
975out:
976 mutex_unlock(&rtd->pcm_mutex);
977 return ret;
978
979component_err:
1006 soc_pcm_components_hw_free(substream, component);
980 for_each_rtdcom(rtd, rtdcom) {
981 component = rtdcom->component;
1007
982
983 if (!component->driver->ops ||
984 !component->driver->ops->hw_free)
985 continue;
986
987 component->driver->ops->hw_free(substream);
988 }
989
1008 if (cpu_dai->driver->ops->hw_free)
1009 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
1010
1011interface_err:
1012 i = rtd->num_codecs;
1013
1014codec_err:
1015 while (--i >= 0) {

--- 11 unchanged lines hidden (view full) ---

1027}
1028
1029/*
1030 * Frees resources allocated by hw_params, can be called multiple times
1031 */
1032static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
1033{
1034 struct snd_soc_pcm_runtime *rtd = substream->private_data;
990 if (cpu_dai->driver->ops->hw_free)
991 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
992
993interface_err:
994 i = rtd->num_codecs;
995
996codec_err:
997 while (--i >= 0) {

--- 11 unchanged lines hidden (view full) ---

1009}
1010
1011/*
1012 * Frees resources allocated by hw_params, can be called multiple times
1013 */
1014static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
1015{
1016 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1017 struct snd_soc_component *component;
1018 struct snd_soc_rtdcom_list *rtdcom;
1035 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1036 struct snd_soc_dai *codec_dai;
1037 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
1038 int i;
1039
1040 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
1041
1042 /* clear the corresponding DAIs parameters when going to be inactive */

--- 20 unchanged lines hidden (view full) ---

1063 substream->stream);
1064 }
1065
1066 /* free any machine hw params */
1067 if (rtd->dai_link->ops->hw_free)
1068 rtd->dai_link->ops->hw_free(substream);
1069
1070 /* free any component resources */
1019 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1020 struct snd_soc_dai *codec_dai;
1021 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
1022 int i;
1023
1024 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
1025
1026 /* clear the corresponding DAIs parameters when going to be inactive */

--- 20 unchanged lines hidden (view full) ---

1047 substream->stream);
1048 }
1049
1050 /* free any machine hw params */
1051 if (rtd->dai_link->ops->hw_free)
1052 rtd->dai_link->ops->hw_free(substream);
1053
1054 /* free any component resources */
1071 soc_pcm_components_hw_free(substream, NULL);
1055 for_each_rtdcom(rtd, rtdcom) {
1056 component = rtdcom->component;
1072
1057
1058 if (!component->driver->ops ||
1059 !component->driver->ops->hw_free)
1060 continue;
1061
1062 component->driver->ops->hw_free(substream);
1063 }
1064
1073 /* now free hw params for the DAIs */
1074 for (i = 0; i < rtd->num_codecs; i++) {
1075 codec_dai = rtd->codec_dais[i];
1076 if (codec_dai->driver->ops->hw_free)
1077 codec_dai->driver->ops->hw_free(substream, codec_dai);
1078 }
1079
1080 if (cpu_dai->driver->ops->hw_free)

--- 616 unchanged lines hidden (view full) ---

1697
1698 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1699 struct snd_soc_pcm_runtime *be = dpcm->be;
1700 struct snd_soc_dai_driver *codec_dai_drv;
1701 struct snd_soc_pcm_stream *codec_stream;
1702 int i;
1703
1704 for (i = 0; i < be->num_codecs; i++) {
1065 /* now free hw params for the DAIs */
1066 for (i = 0; i < rtd->num_codecs; i++) {
1067 codec_dai = rtd->codec_dais[i];
1068 if (codec_dai->driver->ops->hw_free)
1069 codec_dai->driver->ops->hw_free(substream, codec_dai);
1070 }
1071
1072 if (cpu_dai->driver->ops->hw_free)

--- 616 unchanged lines hidden (view full) ---

1689
1690 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1691 struct snd_soc_pcm_runtime *be = dpcm->be;
1692 struct snd_soc_dai_driver *codec_dai_drv;
1693 struct snd_soc_pcm_stream *codec_stream;
1694 int i;
1695
1696 for (i = 0; i < be->num_codecs; i++) {
1697 /*
1698 * Skip CODECs which don't support the current stream
1699 * type. See soc_pcm_init_runtime_hw() for more details
1700 */
1701 if (!snd_soc_dai_stream_valid(be->codec_dais[i],
1702 stream))
1703 continue;
1704
1705 codec_dai_drv = be->codec_dais[i]->driver;
1706 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1707 codec_stream = &codec_dai_drv->playback;
1708 else
1709 codec_stream = &codec_dai_drv->capture;
1710
1711 formats &= codec_stream->formats;
1712 }
1713 }
1714
1715 return formats;
1716}
1717
1705 codec_dai_drv = be->codec_dais[i]->driver;
1706 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1707 codec_stream = &codec_dai_drv->playback;
1708 else
1709 codec_stream = &codec_dai_drv->capture;
1710
1711 formats &= codec_stream->formats;
1712 }
1713 }
1714
1715 return formats;
1716}
1717
1718static void dpcm_runtime_base_chan(struct snd_pcm_substream *substream,
1719 unsigned int *channels_min,
1720 unsigned int *channels_max)
1721{
1722 struct snd_soc_pcm_runtime *fe = substream->private_data;
1723 struct snd_soc_dpcm *dpcm;
1724 int stream = substream->stream;
1725
1726 if (!fe->dai_link->dpcm_merged_chan)
1727 return;
1728
1729 *channels_min = 0;
1730 *channels_max = UINT_MAX;
1731
1732 /*
1733 * It returns merged BE codec channel;
1734 * if FE want to use it (= dpcm_merged_chan)
1735 */
1736
1737 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1738 struct snd_soc_pcm_runtime *be = dpcm->be;
1739 struct snd_soc_dai_driver *cpu_dai_drv = be->cpu_dai->driver;
1740 struct snd_soc_dai_driver *codec_dai_drv;
1741 struct snd_soc_pcm_stream *codec_stream;
1742 struct snd_soc_pcm_stream *cpu_stream;
1743
1744 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1745 cpu_stream = &cpu_dai_drv->playback;
1746 else
1747 cpu_stream = &cpu_dai_drv->capture;
1748
1749 *channels_min = max(*channels_min, cpu_stream->channels_min);
1750 *channels_max = min(*channels_max, cpu_stream->channels_max);
1751
1752 /*
1753 * chan min/max cannot be enforced if there are multiple CODEC
1754 * DAIs connected to a single CPU DAI, use CPU DAI's directly
1755 */
1756 if (be->num_codecs == 1) {
1757 codec_dai_drv = be->codec_dais[0]->driver;
1758
1759 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1760 codec_stream = &codec_dai_drv->playback;
1761 else
1762 codec_stream = &codec_dai_drv->capture;
1763
1764 *channels_min = max(*channels_min,
1765 codec_stream->channels_min);
1766 *channels_max = min(*channels_max,
1767 codec_stream->channels_max);
1768 }
1769 }
1770}
1771
1772static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
1773{
1774 struct snd_pcm_runtime *runtime = substream->runtime;
1775 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1776 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1777 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
1778 u64 format = dpcm_runtime_base_format(substream);
1718static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
1719{
1720 struct snd_pcm_runtime *runtime = substream->runtime;
1721 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1722 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1723 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
1724 u64 format = dpcm_runtime_base_format(substream);
1779 unsigned int channels_min = 0, channels_max = UINT_MAX;
1780
1781 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1782 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback, format);
1783 else
1784 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture, format);
1725
1726 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1727 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback, format);
1728 else
1729 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture, format);
1785
1786 dpcm_runtime_base_chan(substream, &channels_min, &channels_max);
1787
1788 runtime->hw.channels_min = max(channels_min, runtime->hw.channels_min);
1789 runtime->hw.channels_max = min(channels_max, runtime->hw.channels_max);
1790}
1791
1792static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd);
1793
1794/* Set FE's runtime_update state; the state is protected via PCM stream lock
1795 * for avoiding the race with trigger callback.
1796 * If the state is unset and a trigger is pending while the previous operation,
1797 * process the pending trigger action here.

--- 808 unchanged lines hidden (view full) ---

2606 ret = dpcm_run_update_shutdown(fe, stream);
2607 if (ret < 0)
2608 dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n");
2609 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
2610
2611 return ret;
2612}
2613
1730}
1731
1732static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd);
1733
1734/* Set FE's runtime_update state; the state is protected via PCM stream lock
1735 * for avoiding the race with trigger callback.
1736 * If the state is unset and a trigger is pending while the previous operation,
1737 * process the pending trigger action here.

--- 808 unchanged lines hidden (view full) ---

2546 ret = dpcm_run_update_shutdown(fe, stream);
2547 if (ret < 0)
2548 dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n");
2549 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
2550
2551 return ret;
2552}
2553
2614static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
2554/* Called by DAPM mixer/mux changes to update audio routing between PCMs and
2555 * any DAI links.
2556 */
2557int soc_dpcm_runtime_update(struct snd_soc_card *card)
2615{
2558{
2616 struct snd_soc_dapm_widget_list *list;
2617 int count, paths;
2559 struct snd_soc_pcm_runtime *fe;
2560 int old, new, paths;
2618
2561
2619 if (!fe->dai_link->dynamic)
2620 return 0;
2562 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
2563 list_for_each_entry(fe, &card->rtd_list, list) {
2564 struct snd_soc_dapm_widget_list *list;
2621
2565
2622 /* only check active links */
2623 if (!fe->cpu_dai->active)
2624 return 0;
2566 /* make sure link is FE */
2567 if (!fe->dai_link->dynamic)
2568 continue;
2625
2569
2626 /* DAPM sync will call this to update DSP paths */
2627 dev_dbg(fe->dev, "ASoC: DPCM %s runtime update for FE %s\n",
2628 new ? "new" : "old", fe->dai_link->name);
2570 /* only check active links */
2571 if (!fe->cpu_dai->active)
2572 continue;
2629
2573
2630 /* skip if FE doesn't have playback capability */
2631 if (!fe->cpu_dai->driver->playback.channels_min ||
2632 !fe->codec_dai->driver->playback.channels_min)
2633 goto capture;
2574 /* DAPM sync will call this to update DSP paths */
2575 dev_dbg(fe->dev, "ASoC: DPCM runtime update for FE %s\n",
2576 fe->dai_link->name);
2634
2577
2635 /* skip if FE isn't currently playing */
2636 if (!fe->cpu_dai->playback_active || !fe->codec_dai->playback_active)
2637 goto capture;
2578 /* skip if FE doesn't have playback capability */
2579 if (!fe->cpu_dai->driver->playback.channels_min
2580 || !fe->codec_dai->driver->playback.channels_min)
2581 goto capture;
2638
2582
2639 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list);
2640 if (paths < 0) {
2641 dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
2642 fe->dai_link->name, "playback");
2643 return paths;
2644 }
2583 /* skip if FE isn't currently playing */
2584 if (!fe->cpu_dai->playback_active
2585 || !fe->codec_dai->playback_active)
2586 goto capture;
2645
2587
2646 /* update any playback paths */
2647 count = dpcm_process_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, &list, new);
2648 if (count) {
2649 if (new)
2588 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list);
2589 if (paths < 0) {
2590 dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
2591 fe->dai_link->name, "playback");
2592 mutex_unlock(&card->mutex);
2593 return paths;
2594 }
2595
2596 /* update any new playback paths */
2597 new = dpcm_process_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, &list, 1);
2598 if (new) {
2650 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_PLAYBACK);
2599 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_PLAYBACK);
2651 else
2600 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_PLAYBACK);
2601 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK);
2602 }
2603
2604 /* update any old playback paths */
2605 old = dpcm_process_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, &list, 0);
2606 if (old) {
2652 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_PLAYBACK);
2607 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_PLAYBACK);
2608 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_PLAYBACK);
2609 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK);
2610 }
2653
2611
2654 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_PLAYBACK);
2655 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK);
2656 }
2657
2658 dpcm_path_put(&list);
2659
2612 dpcm_path_put(&list);
2660capture:
2613capture:
2661 /* skip if FE doesn't have capture capability */
2662 if (!fe->cpu_dai->driver->capture.channels_min ||
2663 !fe->codec_dai->driver->capture.channels_min)
2664 return 0;
2614 /* skip if FE doesn't have capture capability */
2615 if (!fe->cpu_dai->driver->capture.channels_min
2616 || !fe->codec_dai->driver->capture.channels_min)
2617 continue;
2665
2618
2666 /* skip if FE isn't currently capturing */
2667 if (!fe->cpu_dai->capture_active || !fe->codec_dai->capture_active)
2668 return 0;
2619 /* skip if FE isn't currently capturing */
2620 if (!fe->cpu_dai->capture_active
2621 || !fe->codec_dai->capture_active)
2622 continue;
2669
2623
2670 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list);
2671 if (paths < 0) {
2672 dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
2673 fe->dai_link->name, "capture");
2674 return paths;
2675 }
2624 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list);
2625 if (paths < 0) {
2626 dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
2627 fe->dai_link->name, "capture");
2628 mutex_unlock(&card->mutex);
2629 return paths;
2630 }
2676
2631
2677 /* update any old capture paths */
2678 count = dpcm_process_paths(fe, SNDRV_PCM_STREAM_CAPTURE, &list, new);
2679 if (count) {
2680 if (new)
2632 /* update any new capture paths */
2633 new = dpcm_process_paths(fe, SNDRV_PCM_STREAM_CAPTURE, &list, 1);
2634 if (new) {
2681 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_CAPTURE);
2635 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_CAPTURE);
2682 else
2636 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_CAPTURE);
2637 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE);
2638 }
2639
2640 /* update any old capture paths */
2641 old = dpcm_process_paths(fe, SNDRV_PCM_STREAM_CAPTURE, &list, 0);
2642 if (old) {
2683 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_CAPTURE);
2643 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_CAPTURE);
2644 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_CAPTURE);
2645 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE);
2646 }
2684
2647
2685 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_CAPTURE);
2686 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE);
2648 dpcm_path_put(&list);
2687 }
2688
2649 }
2650
2689 dpcm_path_put(&list);
2690
2651 mutex_unlock(&card->mutex);
2691 return 0;
2692}
2652 return 0;
2653}
2693
2694/* Called by DAPM mixer/mux changes to update audio routing between PCMs and
2695 * any DAI links.
2696 */
2697int soc_dpcm_runtime_update(struct snd_soc_card *card)
2698{
2699 struct snd_soc_pcm_runtime *fe;
2700 int ret = 0;
2701
2702 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
2703 /* shutdown all old paths first */
2704 list_for_each_entry(fe, &card->rtd_list, list) {
2705 ret = soc_dpcm_fe_runtime_update(fe, 0);
2706 if (ret)
2707 goto out;
2708 }
2709
2710 /* bring new paths up */
2711 list_for_each_entry(fe, &card->rtd_list, list) {
2712 ret = soc_dpcm_fe_runtime_update(fe, 1);
2713 if (ret)
2714 goto out;
2715 }
2716
2717out:
2718 mutex_unlock(&card->mutex);
2719 return ret;
2720}
2721int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute)
2722{
2723 struct snd_soc_dpcm *dpcm;
2724 struct list_head *clients =
2725 &fe->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients;
2726
2727 list_for_each_entry(dpcm, clients, list_be) {
2728

--- 618 unchanged lines hidden ---
2654int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute)
2655{
2656 struct snd_soc_dpcm *dpcm;
2657 struct list_head *clients =
2658 &fe->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients;
2659
2660 list_for_each_entry(dpcm, clients, list_be) {
2661

--- 618 unchanged lines hidden ---