aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-pcm.c')
-rw-r--r--sound/soc/soc-pcm.c1246
1 files changed, 1216 insertions, 30 deletions
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 26a60b4061cf..458f116aa570 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -22,12 +22,37 @@
22#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <linux/export.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
28#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/soc-dpcm.h>
29#include <sound/initval.h> 31#include <sound/initval.h>
30 32
33#define DPCM_MAX_BE_USERS 8
34
35/* DPCM stream event, send event to FE and all active BEs. */
36static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
37 int event)
38{
39 struct snd_soc_dpcm *dpcm;
40
41 list_for_each_entry(dpcm, &fe->dpcm[dir].be_clients, list_be) {
42
43 struct snd_soc_pcm_runtime *be = dpcm->be;
44
45 dev_dbg(be->dev, "pm: BE %s event %d dir %d\n",
46 be->dai_link->name, event, dir);
47
48 snd_soc_dapm_stream_event(be, dir, event);
49 }
50
51 snd_soc_dapm_stream_event(fe, dir, event);
52
53 return 0;
54}
55
31static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, 56static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
32 struct snd_soc_dai *soc_dai) 57 struct snd_soc_dai *soc_dai)
33{ 58{
@@ -156,6 +181,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
156 } 181 }
157 } 182 }
158 183
184 /* Dynamic PCM DAI links compat checks use dynamic capabilities */
185 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm)
186 goto dynamic;
187
159 /* Check that the codec and cpu DAIs are compatible */ 188 /* Check that the codec and cpu DAIs are compatible */
160 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
161 runtime->hw.rate_min = 190 runtime->hw.rate_min =
@@ -248,6 +277,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
248 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 277 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
249 runtime->hw.rate_max); 278 runtime->hw.rate_max);
250 279
280dynamic:
251 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
252 cpu_dai->playback_active++; 282 cpu_dai->playback_active++;
253 codec_dai->playback_active++; 283 codec_dai->playback_active++;
@@ -633,6 +663,1025 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
633 return offset; 663 return offset;
634} 664}
635 665
666/* connect a FE and BE */
667static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
668 struct snd_soc_pcm_runtime *be, int stream)
669{
670 struct snd_soc_dpcm *dpcm;
671
672 /* only add new dpcms */
673 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
674 if (dpcm->be == be && dpcm->fe == fe)
675 return 0;
676 }
677
678 dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_KERNEL);
679 if (!dpcm)
680 return -ENOMEM;
681
682 dpcm->be = be;
683 dpcm->fe = fe;
684 be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
685 dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW;
686 list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients);
687 list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients);
688
689 dev_dbg(fe->dev, " connected new DPCM %s path %s %s %s\n",
690 stream ? "capture" : "playback", fe->dai_link->name,
691 stream ? "<-" : "->", be->dai_link->name);
692
693 return 1;
694}
695
696/* reparent a BE onto another FE */
697static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
698 struct snd_soc_pcm_runtime *be, int stream)
699{
700 struct snd_soc_dpcm *dpcm;
701 struct snd_pcm_substream *fe_substream, *be_substream;
702
703 /* reparent if BE is connected to other FEs */
704 if (!be->dpcm[stream].users)
705 return;
706
707 be_substream = snd_soc_dpcm_get_substream(be, stream);
708
709 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
710 if (dpcm->fe == fe)
711 continue;
712
713 dev_dbg(fe->dev, " reparent %s path %s %s %s\n",
714 stream ? "capture" : "playback",
715 dpcm->fe->dai_link->name,
716 stream ? "<-" : "->", dpcm->be->dai_link->name);
717
718 fe_substream = snd_soc_dpcm_get_substream(dpcm->fe, stream);
719 be_substream->runtime = fe_substream->runtime;
720 break;
721 }
722}
723
724/* disconnect a BE and FE */
725static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
726{
727 struct snd_soc_dpcm *dpcm, *d;
728
729 list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) {
730 dev_dbg(fe->dev, "BE %s disconnect check for %s\n",
731 stream ? "capture" : "playback",
732 dpcm->be->dai_link->name);
733
734 if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
735 continue;
736
737 dev_dbg(fe->dev, " freed DSP %s path %s %s %s\n",
738 stream ? "capture" : "playback", fe->dai_link->name,
739 stream ? "<-" : "->", dpcm->be->dai_link->name);
740
741 /* BEs still alive need new FE */
742 dpcm_be_reparent(fe, dpcm->be, stream);
743
744 list_del(&dpcm->list_be);
745 list_del(&dpcm->list_fe);
746 kfree(dpcm);
747 }
748}
749
750/* get BE for DAI widget and stream */
751static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
752 struct snd_soc_dapm_widget *widget, int stream)
753{
754 struct snd_soc_pcm_runtime *be;
755 int i;
756
757 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
758 for (i = 0; i < card->num_links; i++) {
759 be = &card->rtd[i];
760
761 if (be->cpu_dai->playback_widget == widget ||
762 be->codec_dai->playback_widget == widget)
763 return be;
764 }
765 } else {
766
767 for (i = 0; i < card->num_links; i++) {
768 be = &card->rtd[i];
769
770 if (be->cpu_dai->capture_widget == widget ||
771 be->codec_dai->capture_widget == widget)
772 return be;
773 }
774 }
775
776 dev_err(card->dev, "can't get %s BE for %s\n",
777 stream ? "capture" : "playback", widget->name);
778 return NULL;
779}
780
781static inline struct snd_soc_dapm_widget *
782 rtd_get_cpu_widget(struct snd_soc_pcm_runtime *rtd, int stream)
783{
784 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
785 return rtd->cpu_dai->playback_widget;
786 else
787 return rtd->cpu_dai->capture_widget;
788}
789
790static inline struct snd_soc_dapm_widget *
791 rtd_get_codec_widget(struct snd_soc_pcm_runtime *rtd, int stream)
792{
793 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
794 return rtd->codec_dai->playback_widget;
795 else
796 return rtd->codec_dai->capture_widget;
797}
798
799static int widget_in_list(struct snd_soc_dapm_widget_list *list,
800 struct snd_soc_dapm_widget *widget)
801{
802 int i;
803
804 for (i = 0; i < list->num_widgets; i++) {
805 if (widget == list->widgets[i])
806 return 1;
807 }
808
809 return 0;
810}
811
812static int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
813 int stream, struct snd_soc_dapm_widget_list **list_)
814{
815 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
816 struct snd_soc_dapm_widget_list *list;
817 int paths;
818
819 list = kzalloc(sizeof(struct snd_soc_dapm_widget_list) +
820 sizeof(struct snd_soc_dapm_widget *), GFP_KERNEL);
821 if (list == NULL)
822 return -ENOMEM;
823
824 /* get number of valid DAI paths and their widgets */
825 paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list);
826
827 dev_dbg(fe->dev, "found %d audio %s paths\n", paths,
828 stream ? "capture" : "playback");
829
830 *list_ = list;
831 return paths;
832}
833
834static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
835{
836 kfree(*list);
837}
838
839static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
840 struct snd_soc_dapm_widget_list **list_)
841{
842 struct snd_soc_dpcm *dpcm;
843 struct snd_soc_dapm_widget_list *list = *list_;
844 struct snd_soc_dapm_widget *widget;
845 int prune = 0;
846
847 /* Destroy any old FE <--> BE connections */
848 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
849
850 /* is there a valid CPU DAI widget for this BE */
851 widget = rtd_get_cpu_widget(dpcm->be, stream);
852
853 /* prune the BE if it's no longer in our active list */
854 if (widget && widget_in_list(list, widget))
855 continue;
856
857 /* is there a valid CODEC DAI widget for this BE */
858 widget = rtd_get_codec_widget(dpcm->be, stream);
859
860 /* prune the BE if it's no longer in our active list */
861 if (widget && widget_in_list(list, widget))
862 continue;
863
864 dev_dbg(fe->dev, "pruning %s BE %s for %s\n",
865 stream ? "capture" : "playback",
866 dpcm->be->dai_link->name, fe->dai_link->name);
867 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
868 dpcm->be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
869 prune++;
870 }
871
872 dev_dbg(fe->dev, "found %d old BE paths for pruning\n", prune);
873 return prune;
874}
875
876static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
877 struct snd_soc_dapm_widget_list **list_)
878{
879 struct snd_soc_card *card = fe->card;
880 struct snd_soc_dapm_widget_list *list = *list_;
881 struct snd_soc_pcm_runtime *be;
882 int i, new = 0, err;
883
884 /* Create any new FE <--> BE connections */
885 for (i = 0; i < list->num_widgets; i++) {
886
887 if (list->widgets[i]->id != snd_soc_dapm_dai)
888 continue;
889
890 /* is there a valid BE rtd for this widget */
891 be = dpcm_get_be(card, list->widgets[i], stream);
892 if (!be) {
893 dev_err(fe->dev, "no BE found for %s\n",
894 list->widgets[i]->name);
895 continue;
896 }
897
898 /* make sure BE is a real BE */
899 if (!be->dai_link->no_pcm)
900 continue;
901
902 /* don't connect if FE is not running */
903 if (!fe->dpcm[stream].runtime)
904 continue;
905
906 /* newly connected FE and BE */
907 err = dpcm_be_connect(fe, be, stream);
908 if (err < 0) {
909 dev_err(fe->dev, "can't connect %s\n",
910 list->widgets[i]->name);
911 break;
912 } else if (err == 0) /* already connected */
913 continue;
914
915 /* new */
916 be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
917 new++;
918 }
919
920 dev_dbg(fe->dev, "found %d new BE paths\n", new);
921 return new;
922}
923
924/*
925 * Find the corresponding BE DAIs that source or sink audio to this
926 * FE substream.
927 */
928static int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
929 int stream, struct snd_soc_dapm_widget_list **list, int new)
930{
931 if (new)
932 return dpcm_add_paths(fe, stream, list);
933 else
934 return dpcm_prune_paths(fe, stream, list);
935}
936
937static void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)
938{
939 struct snd_soc_dpcm *dpcm;
940
941 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
942 dpcm->be->dpcm[stream].runtime_update =
943 SND_SOC_DPCM_UPDATE_NO;
944}
945
946static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe,
947 int stream)
948{
949 struct snd_soc_dpcm *dpcm;
950
951 /* disable any enabled and non active backends */
952 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
953
954 struct snd_soc_pcm_runtime *be = dpcm->be;
955 struct snd_pcm_substream *be_substream =
956 snd_soc_dpcm_get_substream(be, stream);
957
958 if (be->dpcm[stream].users == 0)
959 dev_err(be->dev, "no users %s at close - state %d\n",
960 stream ? "capture" : "playback",
961 be->dpcm[stream].state);
962
963 if (--be->dpcm[stream].users != 0)
964 continue;
965
966 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
967 continue;
968
969 soc_pcm_close(be_substream);
970 be_substream->runtime = NULL;
971 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
972 }
973}
974
975static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
976{
977 struct snd_soc_dpcm *dpcm;
978 int err, count = 0;
979
980 /* only startup BE DAIs that are either sinks or sources to this FE DAI */
981 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
982
983 struct snd_soc_pcm_runtime *be = dpcm->be;
984 struct snd_pcm_substream *be_substream =
985 snd_soc_dpcm_get_substream(be, stream);
986
987 /* is this op for this BE ? */
988 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
989 continue;
990
991 /* first time the dpcm is open ? */
992 if (be->dpcm[stream].users == DPCM_MAX_BE_USERS)
993 dev_err(be->dev, "too many users %s at open %d\n",
994 stream ? "capture" : "playback",
995 be->dpcm[stream].state);
996
997 if (be->dpcm[stream].users++ != 0)
998 continue;
999
1000 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) &&
1001 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE))
1002 continue;
1003
1004 dev_dbg(be->dev, "dpcm: open BE %s\n", be->dai_link->name);
1005
1006 be_substream->runtime = be->dpcm[stream].runtime;
1007 err = soc_pcm_open(be_substream);
1008 if (err < 0) {
1009 dev_err(be->dev, "BE open failed %d\n", err);
1010 be->dpcm[stream].users--;
1011 if (be->dpcm[stream].users < 0)
1012 dev_err(be->dev, "no users %s at unwind %d\n",
1013 stream ? "capture" : "playback",
1014 be->dpcm[stream].state);
1015
1016 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1017 goto unwind;
1018 }
1019
1020 be->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
1021 count++;
1022 }
1023
1024 return count;
1025
1026unwind:
1027 /* disable any enabled and non active backends */
1028 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1029 struct snd_soc_pcm_runtime *be = dpcm->be;
1030 struct snd_pcm_substream *be_substream =
1031 snd_soc_dpcm_get_substream(be, stream);
1032
1033 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1034 continue;
1035
1036 if (be->dpcm[stream].users == 0)
1037 dev_err(be->dev, "no users %s at close %d\n",
1038 stream ? "capture" : "playback",
1039 be->dpcm[stream].state);
1040
1041 if (--be->dpcm[stream].users != 0)
1042 continue;
1043
1044 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
1045 continue;
1046
1047 soc_pcm_close(be_substream);
1048 be_substream->runtime = NULL;
1049 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1050 }
1051
1052 return err;
1053}
1054
1055void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
1056{
1057 struct snd_pcm_runtime *runtime = substream->runtime;
1058 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1059 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1060 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
1061
1062 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1063 runtime->hw.rate_min = cpu_dai_drv->playback.rate_min;
1064 runtime->hw.rate_max = cpu_dai_drv->playback.rate_max;
1065 runtime->hw.channels_min = cpu_dai_drv->playback.channels_min;
1066 runtime->hw.channels_max = cpu_dai_drv->playback.channels_max;
1067 runtime->hw.formats &= cpu_dai_drv->playback.formats;
1068 runtime->hw.rates = cpu_dai_drv->playback.rates;
1069 } else {
1070 runtime->hw.rate_min = cpu_dai_drv->capture.rate_min;
1071 runtime->hw.rate_max = cpu_dai_drv->capture.rate_max;
1072 runtime->hw.channels_min = cpu_dai_drv->capture.channels_min;
1073 runtime->hw.channels_max = cpu_dai_drv->capture.channels_max;
1074 runtime->hw.formats &= cpu_dai_drv->capture.formats;
1075 runtime->hw.rates = cpu_dai_drv->capture.rates;
1076 }
1077}
1078
1079static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
1080{
1081 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1082 struct snd_pcm_runtime *runtime = fe_substream->runtime;
1083 int stream = fe_substream->stream, ret = 0;
1084
1085 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1086
1087 ret = dpcm_be_dai_startup(fe, fe_substream->stream);
1088 if (ret < 0) {
1089 dev_err(fe->dev,"dpcm: failed to start some BEs %d\n", ret);
1090 goto be_err;
1091 }
1092
1093 dev_dbg(fe->dev, "dpcm: open FE %s\n", fe->dai_link->name);
1094
1095 /* start the DAI frontend */
1096 ret = soc_pcm_open(fe_substream);
1097 if (ret < 0) {
1098 dev_err(fe->dev,"dpcm: failed to start FE %d\n", ret);
1099 goto unwind;
1100 }
1101
1102 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
1103
1104 dpcm_set_fe_runtime(fe_substream);
1105 snd_pcm_limit_hw_rates(runtime);
1106
1107 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1108 return 0;
1109
1110unwind:
1111 dpcm_be_dai_startup_unwind(fe, fe_substream->stream);
1112be_err:
1113 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1114 return ret;
1115}
1116
1117static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
1118{
1119 struct snd_soc_dpcm *dpcm;
1120
1121 /* only shutdown BEs that are either sinks or sources to this FE DAI */
1122 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1123
1124 struct snd_soc_pcm_runtime *be = dpcm->be;
1125 struct snd_pcm_substream *be_substream =
1126 snd_soc_dpcm_get_substream(be, stream);
1127
1128 /* is this op for this BE ? */
1129 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1130 continue;
1131
1132 if (be->dpcm[stream].users == 0)
1133 dev_err(be->dev, "no users %s at close - state %d\n",
1134 stream ? "capture" : "playback",
1135 be->dpcm[stream].state);
1136
1137 if (--be->dpcm[stream].users != 0)
1138 continue;
1139
1140 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1141 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN))
1142 continue;
1143
1144 dev_dbg(be->dev, "dpcm: close BE %s\n",
1145 dpcm->fe->dai_link->name);
1146
1147 soc_pcm_close(be_substream);
1148 be_substream->runtime = NULL;
1149
1150 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1151 }
1152 return 0;
1153}
1154
1155static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
1156{
1157 struct snd_soc_pcm_runtime *fe = substream->private_data;
1158 int stream = substream->stream;
1159
1160 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1161
1162 /* shutdown the BEs */
1163 dpcm_be_dai_shutdown(fe, substream->stream);
1164
1165 dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name);
1166
1167 /* now shutdown the frontend */
1168 soc_pcm_close(substream);
1169
1170 /* run the stream event for each BE */
1171 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
1172
1173 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1174 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1175 return 0;
1176}
1177
1178static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
1179{
1180 struct snd_soc_dpcm *dpcm;
1181
1182 /* only hw_params backends that are either sinks or sources
1183 * to this frontend DAI */
1184 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1185
1186 struct snd_soc_pcm_runtime *be = dpcm->be;
1187 struct snd_pcm_substream *be_substream =
1188 snd_soc_dpcm_get_substream(be, stream);
1189
1190 /* is this op for this BE ? */
1191 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1192 continue;
1193
1194 /* only free hw when no longer used - check all FEs */
1195 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1196 continue;
1197
1198 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1199 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
1200 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1201 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1202 continue;
1203
1204 dev_dbg(be->dev, "dpcm: hw_free BE %s\n",
1205 dpcm->fe->dai_link->name);
1206
1207 soc_pcm_hw_free(be_substream);
1208
1209 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
1210 }
1211
1212 return 0;
1213}
1214
1215int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
1216{
1217 struct snd_soc_pcm_runtime *fe = substream->private_data;
1218 int err, stream = substream->stream;
1219
1220 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1221 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1222
1223 dev_dbg(fe->dev, "dpcm: hw_free FE %s\n", fe->dai_link->name);
1224
1225 /* call hw_free on the frontend */
1226 err = soc_pcm_hw_free(substream);
1227 if (err < 0)
1228 dev_err(fe->dev,"dpcm: hw_free FE %s failed\n",
1229 fe->dai_link->name);
1230
1231 /* only hw_params backends that are either sinks or sources
1232 * to this frontend DAI */
1233 err = dpcm_be_dai_hw_free(fe, stream);
1234
1235 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
1236 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1237
1238 mutex_unlock(&fe->card->mutex);
1239 return 0;
1240}
1241
1242static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream)
1243{
1244 struct snd_soc_dpcm *dpcm;
1245 int ret;
1246
1247 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1248
1249 struct snd_soc_pcm_runtime *be = dpcm->be;
1250 struct snd_pcm_substream *be_substream =
1251 snd_soc_dpcm_get_substream(be, stream);
1252
1253 /* is this op for this BE ? */
1254 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1255 continue;
1256
1257 /* only allow hw_params() if no connected FEs are running */
1258 if (!snd_soc_dpcm_can_be_params(fe, be, stream))
1259 continue;
1260
1261 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
1262 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1263 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE))
1264 continue;
1265
1266 dev_dbg(be->dev, "dpcm: hw_params BE %s\n",
1267 dpcm->fe->dai_link->name);
1268
1269 /* copy params for each dpcm */
1270 memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params,
1271 sizeof(struct snd_pcm_hw_params));
1272
1273 /* perform any hw_params fixups */
1274 if (be->dai_link->be_hw_params_fixup) {
1275 ret = be->dai_link->be_hw_params_fixup(be,
1276 &dpcm->hw_params);
1277 if (ret < 0) {
1278 dev_err(be->dev,
1279 "dpcm: hw_params BE fixup failed %d\n",
1280 ret);
1281 goto unwind;
1282 }
1283 }
1284
1285 ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params);
1286 if (ret < 0) {
1287 dev_err(dpcm->be->dev,
1288 "dpcm: hw_params BE failed %d\n", ret);
1289 goto unwind;
1290 }
1291
1292 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
1293 }
1294 return 0;
1295
1296unwind:
1297 /* disable any enabled and non active backends */
1298 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1299 struct snd_soc_pcm_runtime *be = dpcm->be;
1300 struct snd_pcm_substream *be_substream =
1301 snd_soc_dpcm_get_substream(be, stream);
1302
1303 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1304 continue;
1305
1306 /* only allow hw_free() if no connected FEs are running */
1307 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1308 continue;
1309
1310 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
1311 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1312 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1313 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1314 continue;
1315
1316 soc_pcm_hw_free(be_substream);
1317 }
1318
1319 return ret;
1320}
1321
1322int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream,
1323 struct snd_pcm_hw_params *params)
1324{
1325 struct snd_soc_pcm_runtime *fe = substream->private_data;
1326 int ret, stream = substream->stream;
1327
1328 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1329 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1330
1331 memcpy(&fe->dpcm[substream->stream].hw_params, params,
1332 sizeof(struct snd_pcm_hw_params));
1333 ret = dpcm_be_dai_hw_params(fe, substream->stream);
1334 if (ret < 0) {
1335 dev_err(fe->dev,"dpcm: hw_params BE failed %d\n", ret);
1336 goto out;
1337 }
1338
1339 dev_dbg(fe->dev, "dpcm: hw_params FE %s rate %d chan %x fmt %d\n",
1340 fe->dai_link->name, params_rate(params),
1341 params_channels(params), params_format(params));
1342
1343 /* call hw_params on the frontend */
1344 ret = soc_pcm_hw_params(substream, params);
1345 if (ret < 0) {
1346 dev_err(fe->dev,"dpcm: hw_params FE failed %d\n", ret);
1347 dpcm_be_dai_hw_free(fe, stream);
1348 } else
1349 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
1350
1351out:
1352 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1353 mutex_unlock(&fe->card->mutex);
1354 return ret;
1355}
1356
1357static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm,
1358 struct snd_pcm_substream *substream, int cmd)
1359{
1360 int ret;
1361
1362 dev_dbg(dpcm->be->dev, "dpcm: trigger BE %s cmd %d\n",
1363 dpcm->fe->dai_link->name, cmd);
1364
1365 ret = soc_pcm_trigger(substream, cmd);
1366 if (ret < 0)
1367 dev_err(dpcm->be->dev,"dpcm: trigger BE failed %d\n", ret);
1368
1369 return ret;
1370}
1371
1372int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd)
1373{
1374 struct snd_soc_dpcm *dpcm;
1375 int ret = 0;
1376
1377 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1378
1379 struct snd_soc_pcm_runtime *be = dpcm->be;
1380 struct snd_pcm_substream *be_substream =
1381 snd_soc_dpcm_get_substream(be, stream);
1382
1383 /* is this op for this BE ? */
1384 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1385 continue;
1386
1387 switch (cmd) {
1388 case SNDRV_PCM_TRIGGER_START:
1389 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
1390 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1391 continue;
1392
1393 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1394 if (ret)
1395 return ret;
1396
1397 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1398 break;
1399 case SNDRV_PCM_TRIGGER_RESUME:
1400 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
1401 continue;
1402
1403 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1404 if (ret)
1405 return ret;
1406
1407 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1408 break;
1409 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1410 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
1411 continue;
1412
1413 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1414 if (ret)
1415 return ret;
1416
1417 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1418 break;
1419 case SNDRV_PCM_TRIGGER_STOP:
1420 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
1421 continue;
1422
1423 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1424 continue;
1425
1426 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1427 if (ret)
1428 return ret;
1429
1430 be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
1431 break;
1432 case SNDRV_PCM_TRIGGER_SUSPEND:
1433 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)
1434 continue;
1435
1436 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1437 continue;
1438
1439 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1440 if (ret)
1441 return ret;
1442
1443 be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND;
1444 break;
1445 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1446 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
1447 continue;
1448
1449 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1450 continue;
1451
1452 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1453 if (ret)
1454 return ret;
1455
1456 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
1457 break;
1458 }
1459 }
1460
1461 return ret;
1462}
1463EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger);
1464
1465int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
1466{
1467 struct snd_soc_pcm_runtime *fe = substream->private_data;
1468 int stream = substream->stream, ret;
1469 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
1470
1471 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1472
1473 switch (trigger) {
1474 case SND_SOC_DPCM_TRIGGER_PRE:
1475 /* call trigger on the frontend before the backend. */
1476
1477 dev_dbg(fe->dev, "dpcm: pre trigger FE %s cmd %d\n",
1478 fe->dai_link->name, cmd);
1479
1480 ret = soc_pcm_trigger(substream, cmd);
1481 if (ret < 0) {
1482 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1483 goto out;
1484 }
1485
1486 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
1487 break;
1488 case SND_SOC_DPCM_TRIGGER_POST:
1489 /* call trigger on the frontend after the backend. */
1490
1491 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
1492 if (ret < 0) {
1493 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1494 goto out;
1495 }
1496
1497 dev_dbg(fe->dev, "dpcm: post trigger FE %s cmd %d\n",
1498 fe->dai_link->name, cmd);
1499
1500 ret = soc_pcm_trigger(substream, cmd);
1501 break;
1502 default:
1503 dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd,
1504 fe->dai_link->name);
1505 ret = -EINVAL;
1506 goto out;
1507 }
1508
1509 switch (cmd) {
1510 case SNDRV_PCM_TRIGGER_START:
1511 case SNDRV_PCM_TRIGGER_RESUME:
1512 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1513 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1514 break;
1515 case SNDRV_PCM_TRIGGER_STOP:
1516 case SNDRV_PCM_TRIGGER_SUSPEND:
1517 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1518 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
1519 break;
1520 }
1521
1522out:
1523 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1524 return ret;
1525}
1526
1527static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
1528{
1529 struct snd_soc_dpcm *dpcm;
1530 int ret = 0;
1531
1532 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1533
1534 struct snd_soc_pcm_runtime *be = dpcm->be;
1535 struct snd_pcm_substream *be_substream =
1536 snd_soc_dpcm_get_substream(be, stream);
1537
1538 /* is this op for this BE ? */
1539 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1540 continue;
1541
1542 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1543 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1544 continue;
1545
1546 dev_dbg(be->dev, "dpcm: prepare BE %s\n",
1547 dpcm->fe->dai_link->name);
1548
1549 ret = soc_pcm_prepare(be_substream);
1550 if (ret < 0) {
1551 dev_err(be->dev, "dpcm: backend prepare failed %d\n",
1552 ret);
1553 break;
1554 }
1555
1556 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
1557 }
1558 return ret;
1559}
1560
1561int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
1562{
1563 struct snd_soc_pcm_runtime *fe = substream->private_data;
1564 int stream = substream->stream, ret = 0;
1565
1566 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1567
1568 dev_dbg(fe->dev, "dpcm: prepare FE %s\n", fe->dai_link->name);
1569
1570 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1571
1572 /* there is no point preparing this FE if there are no BEs */
1573 if (list_empty(&fe->dpcm[stream].be_clients)) {
1574 dev_err(fe->dev, "dpcm: no backend DAIs enabled for %s\n",
1575 fe->dai_link->name);
1576 ret = -EINVAL;
1577 goto out;
1578 }
1579
1580 ret = dpcm_be_dai_prepare(fe, substream->stream);
1581 if (ret < 0)
1582 goto out;
1583
1584 /* call prepare on the frontend */
1585 ret = soc_pcm_prepare(substream);
1586 if (ret < 0) {
1587 dev_err(fe->dev,"dpcm: prepare FE %s failed\n",
1588 fe->dai_link->name);
1589 goto out;
1590 }
1591
1592 /* run the stream event for each BE */
1593 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
1594 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
1595
1596out:
1597 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1598 mutex_unlock(&fe->card->mutex);
1599
1600 return ret;
1601}
1602
1603
1604int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute)
1605{
1606 struct snd_soc_dpcm *dpcm;
1607 struct list_head *clients =
1608 &fe->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients;
1609
1610 list_for_each_entry(dpcm, clients, list_be) {
1611
1612 struct snd_soc_pcm_runtime *be = dpcm->be;
1613 struct snd_soc_dai *dai = be->codec_dai;
1614 struct snd_soc_dai_driver *drv = dai->driver;
1615
1616 if (be->dai_link->ignore_suspend)
1617 continue;
1618
1619 dev_dbg(be->dev, "BE digital mute %s\n", be->dai_link->name);
1620
1621 if (drv->ops->digital_mute && dai->playback_active)
1622 drv->ops->digital_mute(dai, mute);
1623 }
1624
1625 return 0;
1626}
1627
1628int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream)
1629{
1630 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1631 struct snd_soc_dpcm *dpcm;
1632 struct snd_soc_dapm_widget_list *list;
1633 int ret;
1634 int stream = fe_substream->stream;
1635
1636 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1637 fe->dpcm[stream].runtime = fe_substream->runtime;
1638
1639 if (dpcm_path_get(fe, stream, &list) <= 0) {
1640 dev_warn(fe->dev, "asoc: %s no valid %s route\n",
1641 fe->dai_link->name, stream ? "capture" : "playback");
1642 mutex_unlock(&fe->card->mutex);
1643 return -EINVAL;
1644 }
1645
1646 /* calculate valid and active FE <-> BE dpcms */
1647 dpcm_process_paths(fe, stream, &list, 1);
1648
1649 ret = dpcm_fe_dai_startup(fe_substream);
1650 if (ret < 0) {
1651 /* clean up all links */
1652 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
1653 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1654
1655 dpcm_be_disconnect(fe, stream);
1656 fe->dpcm[stream].runtime = NULL;
1657 }
1658
1659 dpcm_clear_pending_state(fe, stream);
1660 dpcm_path_put(&list);
1661 mutex_unlock(&fe->card->mutex);
1662 return ret;
1663}
1664
1665int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
1666{
1667 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1668 struct snd_soc_dpcm *dpcm;
1669 int stream = fe_substream->stream, ret;
1670
1671 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1672 ret = dpcm_fe_dai_shutdown(fe_substream);
1673
1674 /* mark FE's links ready to prune */
1675 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
1676 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1677
1678 dpcm_be_disconnect(fe, stream);
1679
1680 fe->dpcm[stream].runtime = NULL;
1681 mutex_unlock(&fe->card->mutex);
1682 return ret;
1683}
1684
636/* create a new pcm */ 1685/* create a new pcm */
637int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 1686int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
638{ 1687{
@@ -640,56 +1689,92 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
640 struct snd_soc_platform *platform = rtd->platform; 1689 struct snd_soc_platform *platform = rtd->platform;
641 struct snd_soc_dai *codec_dai = rtd->codec_dai; 1690 struct snd_soc_dai *codec_dai = rtd->codec_dai;
642 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1691 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
643 struct snd_pcm_ops *soc_pcm_ops = &rtd->ops;
644 struct snd_pcm *pcm; 1692 struct snd_pcm *pcm;
645 char new_name[64]; 1693 char new_name[64];
646 int ret = 0, playback = 0, capture = 0; 1694 int ret = 0, playback = 0, capture = 0;
647 1695
648 soc_pcm_ops->open = soc_pcm_open; 1696 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) {
649 soc_pcm_ops->close = soc_pcm_close; 1697 if (cpu_dai->driver->playback.channels_min)
650 soc_pcm_ops->hw_params = soc_pcm_hw_params; 1698 playback = 1;
651 soc_pcm_ops->hw_free = soc_pcm_hw_free; 1699 if (cpu_dai->driver->capture.channels_min)
652 soc_pcm_ops->prepare = soc_pcm_prepare; 1700 capture = 1;
653 soc_pcm_ops->trigger = soc_pcm_trigger; 1701 } else {
654 soc_pcm_ops->pointer = soc_pcm_pointer; 1702 if (codec_dai->driver->playback.channels_min)
655 1703 playback = 1;
656 /* check client and interface hw capabilities */ 1704 if (codec_dai->driver->capture.channels_min)
657 snprintf(new_name, sizeof(new_name), "%s %s-%d", 1705 capture = 1;
658 rtd->dai_link->stream_name, codec_dai->name, num); 1706 }
659 1707
660 if (codec_dai->driver->playback.channels_min) 1708 /* create the PCM */
661 playback = 1; 1709 if (rtd->dai_link->no_pcm) {
662 if (codec_dai->driver->capture.channels_min) 1710 snprintf(new_name, sizeof(new_name), "(%s)",
663 capture = 1; 1711 rtd->dai_link->stream_name);
664 1712
665 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num,new_name); 1713 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
666 ret = snd_pcm_new(rtd->card->snd_card, new_name, 1714 playback, capture, &pcm);
667 num, playback, capture, &pcm); 1715 } else {
1716 if (rtd->dai_link->dynamic)
1717 snprintf(new_name, sizeof(new_name), "%s (*)",
1718 rtd->dai_link->stream_name);
1719 else
1720 snprintf(new_name, sizeof(new_name), "%s %s-%d",
1721 rtd->dai_link->stream_name, codec_dai->name, num);
1722
1723 ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
1724 capture, &pcm);
1725 }
668 if (ret < 0) { 1726 if (ret < 0) {
669 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); 1727 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
670 return ret; 1728 return ret;
671 } 1729 }
1730 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name);
672 1731
673 /* DAPM dai link stream work */ 1732 /* DAPM dai link stream work */
674 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 1733 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
675 1734
676 rtd->pcm = pcm; 1735 rtd->pcm = pcm;
677 pcm->private_data = rtd; 1736 pcm->private_data = rtd;
1737
1738 if (rtd->dai_link->no_pcm) {
1739 if (playback)
1740 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
1741 if (capture)
1742 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
1743 goto out;
1744 }
1745
1746 /* ASoC PCM operations */
1747 if (rtd->dai_link->dynamic) {
1748 rtd->ops.open = dpcm_fe_dai_open;
1749 rtd->ops.hw_params = dpcm_fe_dai_hw_params;
1750 rtd->ops.prepare = dpcm_fe_dai_prepare;
1751 rtd->ops.trigger = dpcm_fe_dai_trigger;
1752 rtd->ops.hw_free = dpcm_fe_dai_hw_free;
1753 rtd->ops.close = dpcm_fe_dai_close;
1754 rtd->ops.pointer = soc_pcm_pointer;
1755 } else {
1756 rtd->ops.open = soc_pcm_open;
1757 rtd->ops.hw_params = soc_pcm_hw_params;
1758 rtd->ops.prepare = soc_pcm_prepare;
1759 rtd->ops.trigger = soc_pcm_trigger;
1760 rtd->ops.hw_free = soc_pcm_hw_free;
1761 rtd->ops.close = soc_pcm_close;
1762 rtd->ops.pointer = soc_pcm_pointer;
1763 }
1764
678 if (platform->driver->ops) { 1765 if (platform->driver->ops) {
679 soc_pcm_ops->mmap = platform->driver->ops->mmap; 1766 rtd->ops.ack = platform->driver->ops->ack;
680 soc_pcm_ops->pointer = platform->driver->ops->pointer; 1767 rtd->ops.copy = platform->driver->ops->copy;
681 soc_pcm_ops->ioctl = platform->driver->ops->ioctl; 1768 rtd->ops.silence = platform->driver->ops->silence;
682 soc_pcm_ops->copy = platform->driver->ops->copy; 1769 rtd->ops.page = platform->driver->ops->page;
683 soc_pcm_ops->silence = platform->driver->ops->silence; 1770 rtd->ops.mmap = platform->driver->ops->mmap;
684 soc_pcm_ops->ack = platform->driver->ops->ack;
685 soc_pcm_ops->page = platform->driver->ops->page;
686 } 1771 }
687 1772
688 if (playback) 1773 if (playback)
689 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops); 1774 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops);
690 1775
691 if (capture) 1776 if (capture)
692 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops); 1777 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
693 1778
694 if (platform->driver->pcm_new) { 1779 if (platform->driver->pcm_new) {
695 ret = platform->driver->pcm_new(rtd); 1780 ret = platform->driver->pcm_new(rtd);
@@ -700,7 +1785,108 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
700 } 1785 }
701 1786
702 pcm->private_free = platform->driver->pcm_free; 1787 pcm->private_free = platform->driver->pcm_free;
1788out:
703 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 1789 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
704 cpu_dai->name); 1790 cpu_dai->name);
705 return ret; 1791 return ret;
706} 1792}
1793
1794/* is the current PCM operation for this FE ? */
1795int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream)
1796{
1797 if (fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE)
1798 return 1;
1799 return 0;
1800}
1801EXPORT_SYMBOL_GPL(snd_soc_dpcm_fe_can_update);
1802
1803/* is the current PCM operation for this BE ? */
1804int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe,
1805 struct snd_soc_pcm_runtime *be, int stream)
1806{
1807 if ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) ||
1808 ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_BE) &&
1809 be->dpcm[stream].runtime_update))
1810 return 1;
1811 return 0;
1812}
1813EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_can_update);
1814
1815/* get the substream for this BE */
1816struct snd_pcm_substream *
1817 snd_soc_dpcm_get_substream(struct snd_soc_pcm_runtime *be, int stream)
1818{
1819 return be->pcm->streams[stream].substream;
1820}
1821EXPORT_SYMBOL_GPL(snd_soc_dpcm_get_substream);
1822
1823/* get the BE runtime state */
1824enum snd_soc_dpcm_state
1825 snd_soc_dpcm_be_get_state(struct snd_soc_pcm_runtime *be, int stream)
1826{
1827 return be->dpcm[stream].state;
1828}
1829EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_get_state);
1830
1831/* set the BE runtime state */
1832void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be,
1833 int stream, enum snd_soc_dpcm_state state)
1834{
1835 be->dpcm[stream].state = state;
1836}
1837EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_set_state);
1838
1839/*
1840 * We can only hw_free, stop, pause or suspend a BE DAI if any of it's FE
1841 * are not running, paused or suspended for the specified stream direction.
1842 */
1843int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
1844 struct snd_soc_pcm_runtime *be, int stream)
1845{
1846 struct snd_soc_dpcm *dpcm;
1847 int state;
1848
1849 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
1850
1851 if (dpcm->fe == fe)
1852 continue;
1853
1854 state = dpcm->fe->dpcm[stream].state;
1855 if (state == SND_SOC_DPCM_STATE_START ||
1856 state == SND_SOC_DPCM_STATE_PAUSED ||
1857 state == SND_SOC_DPCM_STATE_SUSPEND)
1858 return 0;
1859 }
1860
1861 /* it's safe to free/stop this BE DAI */
1862 return 1;
1863}
1864EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop);
1865
1866/*
1867 * We can only change hw params a BE DAI if any of it's FE are not prepared,
1868 * running, paused or suspended for the specified stream direction.
1869 */
1870int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
1871 struct snd_soc_pcm_runtime *be, int stream)
1872{
1873 struct snd_soc_dpcm *dpcm;
1874 int state;
1875
1876 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
1877
1878 if (dpcm->fe == fe)
1879 continue;
1880
1881 state = dpcm->fe->dpcm[stream].state;
1882 if (state == SND_SOC_DPCM_STATE_START ||
1883 state == SND_SOC_DPCM_STATE_PAUSED ||
1884 state == SND_SOC_DPCM_STATE_SUSPEND ||
1885 state == SND_SOC_DPCM_STATE_PREPARE)
1886 return 0;
1887 }
1888
1889 /* it's safe to change hw_params */
1890 return 1;
1891}
1892EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params);