@@ -331,9 +331,9 @@ static int sof_setup_pipeline_connections(struct snd_sof_dev *sdev,
331331
332332 if (p -> sink -> dobj .private ) {
333333 /*
334- * skip routes between widgets belonging to the BE pipeline
334+ * skip routes with widgets belonging to the BE pipeline
335335 */
336- if (sof_is_widget_pipeline_be_managed (widget ) &&
336+ if (sof_is_widget_pipeline_be_managed (widget ) ||
337337 sof_is_widget_pipeline_be_managed (p -> sink ))
338338 continue ;
339339 ret = sof_route_setup (sdev , widget , p -> sink );
@@ -1026,6 +1026,32 @@ int sof_dai_get_tdm_slots(struct snd_soc_pcm_runtime *rtd)
10261026}
10271027EXPORT_SYMBOL (sof_dai_get_tdm_slots );
10281028
1029+ static struct snd_soc_dapm_widget * snd_sof_get_pipeline_source (struct snd_sof_pipeline * spipe ,
1030+ struct snd_soc_dapm_widget * w )
1031+ {
1032+ struct snd_soc_dapm_path * p ;
1033+
1034+ snd_soc_dapm_widget_for_each_source_path (w , p ) {
1035+ if (!p -> walking ) {
1036+ struct snd_soc_dapm_widget * wsource = p -> source ;
1037+ struct snd_sof_widget * source_swidget = wsource -> dobj .private ;
1038+ struct snd_soc_dapm_widget * source_widget ;
1039+
1040+ p -> walking = true;
1041+ if (source_swidget -> spipe != spipe ) {
1042+ p -> walking = false;
1043+ break ;
1044+ }
1045+
1046+ source_widget = snd_sof_get_pipeline_source (spipe , wsource );
1047+ p -> walking = false;
1048+ return source_widget ;
1049+ }
1050+ }
1051+
1052+ return w ;
1053+ }
1054+
10291055static int snd_sof_set_up_widgets_in_pipeline (struct snd_soc_dapm_widget * w ,
10301056 struct snd_sof_pipeline * spipe , int dir )
10311057{
@@ -1042,27 +1068,17 @@ static int snd_sof_set_up_widgets_in_pipeline(struct snd_soc_dapm_widget *w,
10421068 if (ret < 0 )
10431069 return ret ;
10441070
1045- if (dir == SNDRV_PCM_STREAM_PLAYBACK ) {
1046- snd_soc_dapm_widget_for_each_source_path (w , p ) {
1047- if (!p -> walking ) {
1048- p -> walking = true;
1071+ if (dir == SNDRV_PCM_STREAM_PLAYBACK && WIDGET_IS_DAI (swidget -> id ))
1072+ return 0 ;
10491073
1050- ret = snd_sof_set_up_widgets_in_pipeline (p -> source , spipe , dir );
1051- p -> walking = false;
1052- if (ret < 0 )
1053- goto err ;
1054- }
1055- }
1056- } else {
1057- snd_soc_dapm_widget_for_each_sink_path (w , p ) {
1058- if (!p -> walking ) {
1059- p -> walking = true;
1074+ snd_soc_dapm_widget_for_each_sink_path (w , p ) {
1075+ if (!p -> walking ) {
1076+ p -> walking = true;
10601077
1061- ret = snd_sof_set_up_widgets_in_pipeline (p -> sink , spipe , dir );
1062- p -> walking = false;
1063- if (ret < 0 )
1064- goto err ;
1065- }
1078+ ret = snd_sof_set_up_widgets_in_pipeline (p -> sink , spipe , dir );
1079+ p -> walking = false;
1080+ if (ret < 0 )
1081+ goto err ;
10661082 }
10671083 }
10681084
@@ -1185,15 +1201,19 @@ static int snd_sof_set_up_routes_in_pipeline(struct snd_soc_dapm_widget *w,
11851201 struct snd_soc_dapm_widget * wsource = p -> source ;
11861202 struct snd_sof_widget * source_swidget = wsource -> dobj .private ;
11871203
1188- if (source_swidget -> spipe != spipe )
1189- continue ;
1190-
11911204 p -> walking = true;
11921205
1193- ret = sof_route_setup (sdev , wsource , w );
1194- if (ret < 0 ) {
1206+ if (source_swidget -> use_count > 0 ) {
1207+ ret = sof_route_setup (sdev , wsource , w );
1208+ if (ret < 0 ) {
1209+ p -> walking = false;
1210+ return ret ;
1211+ }
1212+ }
1213+
1214+ if (source_swidget -> spipe != spipe ) {
11951215 p -> walking = false;
1196- return ret ;
1216+ continue ;
11971217 }
11981218
11991219 ret = snd_sof_set_up_routes_in_pipeline (wsource , spipe , dir );
@@ -1234,10 +1254,17 @@ int snd_sof_set_up_be_pipeline(struct snd_soc_dapm_widget *w, int dir)
12341254{
12351255 struct snd_sof_widget * swidget = w -> dobj .private ;
12361256 struct snd_sof_dev * sdev = widget_to_sdev (w );
1257+ struct snd_soc_dapm_widget * wsource ;
12371258 int ret ;
12381259
1260+ /* get the source widget for the BE pipeline */
1261+ if (dir == SNDRV_PCM_STREAM_PLAYBACK )
1262+ wsource = snd_sof_get_pipeline_source (swidget -> spipe , w );
1263+ else
1264+ wsource = w ;
1265+
12391266 /* set up the widgets in the BE pipeline */
1240- ret = snd_sof_set_up_widgets_in_pipeline (w , swidget -> spipe , dir );
1267+ ret = snd_sof_set_up_widgets_in_pipeline (wsource , swidget -> spipe , dir );
12411268 if (ret < 0 ) {
12421269 dev_err (sdev -> dev , "failed to set up widgets in the BE pipeline with DAI: %s\n" ,
12431270 w -> name );
0 commit comments