@@ -23,6 +23,13 @@ static bool disable_function_topology;
2323module_param (disable_function_topology , bool , 0444 );
2424MODULE_PARM_DESC (disable_function_topology , "Disable function topology loading" );
2525
26+ #define MAX_FEATURE_TPLG_COUNT 16
27+
28+ static char * feature_topologies [MAX_FEATURE_TPLG_COUNT ];
29+ static int feature_tplg_cnt ;
30+ module_param_array (feature_topologies , charp , & feature_tplg_cnt , 0444 );
31+ MODULE_PARM_DESC (index , "Topology list for virtual loop DAI link" );
32+
2633#define COMP_ID_UNASSIGNED 0xffffffff
2734/*
2835 * Constants used in the computation of linear volume gain
@@ -2590,6 +2597,50 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
25902597 }
25912598 }
25922599
2600+ /* Loading user defined topologies */
2601+ for (i = 0 ; i < feature_tplg_cnt ; i ++ ) {
2602+ const char * feature_topology = devm_kasprintf (scomp -> dev , GFP_KERNEL , "%s/%s" ,
2603+ tplg_filename_prefix ,
2604+ feature_topologies [i ]);
2605+
2606+ dev_info (scomp -> dev , "loading feature topology %d: %s\n" , i , feature_topology );
2607+ ret = request_firmware (& fw , feature_topology , scomp -> dev );
2608+ if (ret < 0 ) {
2609+ /*
2610+ * snd_soc_tplg_component_remove(scomp) will be called
2611+ * if snd_soc_tplg_component_load(scomp) failed and all
2612+ * objects in the scomp will be removed. No need to call
2613+ * snd_soc_tplg_component_remove(scomp) here.
2614+ */
2615+ dev_warn (scomp -> dev , "feature tplg request firmware %s failed err: %d\n" ,
2616+ feature_topologies [i ], ret );
2617+ /*
2618+ * We don't return error here because we can still have the basic
2619+ * audio feature when the function topology load complete. No need
2620+ * to convert the error code because we will get new 'ret' out of the
2621+ * loop.
2622+ */
2623+ continue ;
2624+ }
2625+
2626+ if (sdev -> dspless_mode_selected )
2627+ ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2628+ else
2629+ ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2630+
2631+ release_firmware (fw );
2632+
2633+ if (ret < 0 ) {
2634+ dev_err (scomp -> dev , "feature tplg %s component load failed %d\n" ,
2635+ feature_topologies [i ], ret );
2636+ /*
2637+ * We need to return error here because it may lead to kernel NULL pointer
2638+ * dereference if we continue the remaining tasks.
2639+ */
2640+ goto out ;
2641+ }
2642+ }
2643+
25932644 /* call sof_complete when topologies are loaded successfully */
25942645 ret = sof_complete (scomp );
25952646
0 commit comments