@@ -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
@@ -2592,6 +2599,50 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
25922599 }
25932600 }
25942601
2602+ /* Loading user defined topologies */
2603+ for (i = 0 ; i < feature_tplg_cnt ; i ++ ) {
2604+ const char * feature_topology = devm_kasprintf (scomp -> dev , GFP_KERNEL , "%s/%s" ,
2605+ tplg_filename_prefix ,
2606+ feature_topologies [i ]);
2607+
2608+ dev_info (scomp -> dev , "loading feature topology %d: %s\n" , i , feature_topology );
2609+ ret = request_firmware (& fw , feature_topology , scomp -> dev );
2610+ if (ret < 0 ) {
2611+ /*
2612+ * snd_soc_tplg_component_remove(scomp) will be called
2613+ * if snd_soc_tplg_component_load(scomp) failed and all
2614+ * objects in the scomp will be removed. No need to call
2615+ * snd_soc_tplg_component_remove(scomp) here.
2616+ */
2617+ dev_warn (scomp -> dev , "feature tplg request firmware %s failed err: %d\n" ,
2618+ feature_topologies [i ], ret );
2619+ /*
2620+ * We don't return error here because we can still have the basic
2621+ * audio feature when the function topology load complete. No need
2622+ * to convert the error code because we will get new 'ret' out of the
2623+ * loop.
2624+ */
2625+ continue ;
2626+ }
2627+
2628+ if (sdev -> dspless_mode_selected )
2629+ ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2630+ else
2631+ ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2632+
2633+ release_firmware (fw );
2634+
2635+ if (ret < 0 ) {
2636+ dev_err (scomp -> dev , "feature tplg %s component load failed %d\n" ,
2637+ feature_topologies [i ], ret );
2638+ /*
2639+ * We need to return error here because it may lead to kernel NULL pointer
2640+ * dereference if we continue the remaining tasks.
2641+ */
2642+ goto out ;
2643+ }
2644+ }
2645+
25952646 /* call sof_complete when topologies are loaded successfully */
25962647 ret = sof_complete (scomp );
25972648
0 commit comments