@@ -1073,7 +1073,11 @@ static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list,
1073
1073
*/
1074
1074
static __always_inline int is_connected_ep (struct snd_soc_dapm_widget * widget ,
1075
1075
struct list_head * list , enum snd_soc_dapm_direction dir ,
1076
- int (* fn )(struct snd_soc_dapm_widget * , struct list_head * ))
1076
+ int (* fn )(struct snd_soc_dapm_widget * , struct list_head * ,
1077
+ bool (* custom_stop_condition )(struct snd_soc_dapm_widget * ,
1078
+ enum snd_soc_dapm_direction )),
1079
+ bool (* custom_stop_condition )(struct snd_soc_dapm_widget * ,
1080
+ enum snd_soc_dapm_direction ))
1077
1081
{
1078
1082
enum snd_soc_dapm_direction rdir = SND_SOC_DAPM_DIR_REVERSE (dir );
1079
1083
struct snd_soc_dapm_path * path ;
@@ -1088,6 +1092,9 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
1088
1092
if (list )
1089
1093
list_add_tail (& widget -> work_list , list );
1090
1094
1095
+ if (custom_stop_condition && custom_stop_condition (widget , dir ))
1096
+ return con ;
1097
+
1091
1098
if ((widget -> is_ep & SND_SOC_DAPM_DIR_TO_EP (dir )) && widget -> connected ) {
1092
1099
widget -> endpoints [dir ] = snd_soc_dapm_suspend_check (widget );
1093
1100
return widget -> endpoints [dir ];
@@ -1106,7 +1113,7 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
1106
1113
1107
1114
if (path -> connect ) {
1108
1115
path -> walking = 1 ;
1109
- con += fn (path -> node [dir ], list );
1116
+ con += fn (path -> node [dir ], list , custom_stop_condition );
1110
1117
path -> walking = 0 ;
1111
1118
}
1112
1119
}
@@ -1119,39 +1126,62 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
1119
1126
/*
1120
1127
* Recursively check for a completed path to an active or physically connected
1121
1128
* output widget. Returns number of complete paths.
1129
+ *
1130
+ * Optionally, can be supplied with a function acting as a stopping condition.
1131
+ * This function takes the dapm widget currently being examined and the walk
1132
+ * direction as an arguments, it should return true if the walk should be
1133
+ * stopped and false otherwise.
1122
1134
*/
1123
1135
static int is_connected_output_ep (struct snd_soc_dapm_widget * widget ,
1124
- struct list_head * list )
1136
+ struct list_head * list ,
1137
+ bool (* custom_stop_condition )(struct snd_soc_dapm_widget * i ,
1138
+ enum snd_soc_dapm_direction ))
1125
1139
{
1126
1140
return is_connected_ep (widget , list , SND_SOC_DAPM_DIR_OUT ,
1127
- is_connected_output_ep );
1141
+ is_connected_output_ep , custom_stop_condition );
1128
1142
}
1129
1143
1130
1144
/*
1131
1145
* Recursively check for a completed path to an active or physically connected
1132
1146
* input widget. Returns number of complete paths.
1147
+ *
1148
+ * Optionally, can be supplied with a function acting as a stopping condition.
1149
+ * This function takes the dapm widget currently being examined and the walk
1150
+ * direction as an arguments, it should return true if the walk should be
1151
+ * stopped and false otherwise.
1133
1152
*/
1134
1153
static int is_connected_input_ep (struct snd_soc_dapm_widget * widget ,
1135
- struct list_head * list )
1154
+ struct list_head * list ,
1155
+ bool (* custom_stop_condition )(struct snd_soc_dapm_widget * i ,
1156
+ enum snd_soc_dapm_direction ))
1136
1157
{
1137
1158
return is_connected_ep (widget , list , SND_SOC_DAPM_DIR_IN ,
1138
- is_connected_input_ep );
1159
+ is_connected_input_ep , custom_stop_condition );
1139
1160
}
1140
1161
1141
1162
/**
1142
1163
* snd_soc_dapm_get_connected_widgets - query audio path and it's widgets.
1143
1164
* @dai: the soc DAI.
1144
1165
* @stream: stream direction.
1145
1166
* @list: list of active widgets for this stream.
1167
+ * @custom_stop_condition: (optional) a function meant to stop the widget graph
1168
+ * walk based on custom logic.
1146
1169
*
1147
1170
* Queries DAPM graph as to whether an valid audio stream path exists for
1148
1171
* the initial stream specified by name. This takes into account
1149
1172
* current mixer and mux kcontrol settings. Creates list of valid widgets.
1150
1173
*
1174
+ * Optionally, can be supplied with a function acting as a stopping condition.
1175
+ * This function takes the dapm widget currently being examined and the walk
1176
+ * direction as an arguments, it should return true if the walk should be
1177
+ * stopped and false otherwise.
1178
+ *
1151
1179
* Returns the number of valid paths or negative error.
1152
1180
*/
1153
1181
int snd_soc_dapm_dai_get_connected_widgets (struct snd_soc_dai * dai , int stream ,
1154
- struct snd_soc_dapm_widget_list * * list )
1182
+ struct snd_soc_dapm_widget_list * * list ,
1183
+ bool (* custom_stop_condition )(struct snd_soc_dapm_widget * ,
1184
+ enum snd_soc_dapm_direction ))
1155
1185
{
1156
1186
struct snd_soc_card * card = dai -> component -> card ;
1157
1187
struct snd_soc_dapm_widget * w ;
@@ -1171,9 +1201,11 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
1171
1201
}
1172
1202
1173
1203
if (stream == SNDRV_PCM_STREAM_PLAYBACK )
1174
- paths = is_connected_output_ep (dai -> playback_widget , & widgets );
1204
+ paths = is_connected_output_ep (dai -> playback_widget , & widgets ,
1205
+ custom_stop_condition );
1175
1206
else
1176
- paths = is_connected_input_ep (dai -> capture_widget , & widgets );
1207
+ paths = is_connected_input_ep (dai -> capture_widget , & widgets ,
1208
+ custom_stop_condition );
1177
1209
1178
1210
/* Drop starting point */
1179
1211
list_del (widgets .next );
@@ -1268,8 +1300,8 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
1268
1300
1269
1301
DAPM_UPDATE_STAT (w , power_checks );
1270
1302
1271
- in = is_connected_input_ep (w , NULL );
1272
- out = is_connected_output_ep (w , NULL );
1303
+ in = is_connected_input_ep (w , NULL , NULL );
1304
+ out = is_connected_output_ep (w , NULL , NULL );
1273
1305
return out != 0 && in != 0 ;
1274
1306
}
1275
1307
@@ -1928,8 +1960,8 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1928
1960
in = 0 ;
1929
1961
out = 0 ;
1930
1962
} else {
1931
- in = is_connected_input_ep (w , NULL );
1932
- out = is_connected_output_ep (w , NULL );
1963
+ in = is_connected_input_ep (w , NULL , NULL );
1964
+ out = is_connected_output_ep (w , NULL , NULL );
1933
1965
}
1934
1966
1935
1967
ret = snprintf (buf , PAGE_SIZE , "%s: %s%s in %d out %d" ,
0 commit comments