@@ -2320,8 +2320,10 @@ static const struct snd_soc_tplg_ops sof_tplg_ops = {
23202320 .link_load = sof_link_load ,
23212321 .link_unload = sof_link_unload ,
23222322
2323- /* completion - called at completion of firmware loading */
2324- .complete = sof_complete ,
2323+ /*
2324+ * No need to set the complete callback. sof_complete will be called explicitly after
2325+ * topology loading is complete.
2326+ */
23252327
23262328 /* manifest - optional to inform component of manifest */
23272329 .manifest = sof_manifest ,
@@ -2477,34 +2479,80 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
24772479int snd_sof_load_topology (struct snd_soc_component * scomp , const char * file )
24782480{
24792481 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
2482+ struct snd_sof_pdata * sof_pdata = sdev -> pdata ;
2483+ const char * tplg_filename_prefix = sof_pdata -> tplg_filename_prefix ;
24802484 const struct firmware * fw ;
2485+ const char * * tplg_files ;
2486+ int tplg_cnt = 0 ;
24812487 int ret ;
2488+ int i ;
24822489
2483- dev_dbg (scomp -> dev , "loading topology:%s\n" , file );
2490+ tplg_files = kcalloc (scomp -> card -> num_links , sizeof (char * ), GFP_KERNEL );
2491+ if (!tplg_files )
2492+ return - ENOMEM ;
24842493
2485- ret = request_firmware (& fw , file , scomp -> dev );
2486- if (ret < 0 ) {
2487- dev_err (scomp -> dev , "error: tplg request firmware %s failed err: %d\n" ,
2488- file , ret );
2489- dev_err (scomp -> dev ,
2490- "you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n" );
2491- return ret ;
2494+ if (sof_pdata -> machine -> get_function_tplg_files ) {
2495+ tplg_cnt = sof_pdata -> machine -> get_function_tplg_files (scomp -> card ,
2496+ sof_pdata -> machine ,
2497+ tplg_filename_prefix ,
2498+ & tplg_files );
2499+ if (tplg_cnt < 0 ) {
2500+ kfree (tplg_files );
2501+ return tplg_cnt ;
2502+ }
24922503 }
24932504
2494- if (sdev -> dspless_mode_selected )
2495- ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2496- else
2497- ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2505+ /*
2506+ * The monolithic topology will be used if there is no get_function_tplg_files
2507+ * callback or the callback returns 0.
2508+ */
2509+ if (!tplg_cnt ) {
2510+ tplg_files [0 ] = file ;
2511+ tplg_cnt = 1 ;
2512+ dev_dbg (scomp -> dev , "loading topology %d: %s\n" , i , tplg_files [i ]);
2513+ } else {
2514+ dev_info (scomp -> dev , "Using function topologies instead %s\n" , file );
2515+ }
24982516
2499- if ( ret < 0 )
2500- dev_err ( scomp -> dev , "error: tplg component load failed %d\n" ,
2501- ret );
2517+ for ( i = 0 ; i < tplg_cnt ; i ++ ) {
2518+ if ( tplg_files [ 0 ] != file )
2519+ dev_info ( scomp -> dev , "loading topology %d: %s\n" , i , tplg_files [ i ] );
25022520
2503- release_firmware (fw );
2521+ ret = request_firmware (& fw , tplg_files [i ], scomp -> dev );
2522+ if (ret < 0 ) {
2523+ /*
2524+ * snd_soc_tplg_component_remove(scomp) will be called
2525+ * if snd_soc_tplg_component_load(scomp) failed and all
2526+ * objects in the scomp will be removed. No need to call
2527+ * snd_soc_tplg_component_remove(scomp) here.
2528+ */
2529+ dev_err (scomp -> dev , "tplg request firmware %s failed err: %d\n" ,
2530+ tplg_files [i ], ret );
2531+ goto out ;
2532+ }
25042533
2534+ if (sdev -> dspless_mode_selected )
2535+ ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2536+ else
2537+ ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2538+
2539+ release_firmware (fw );
2540+
2541+ if (ret < 0 ) {
2542+ dev_err (scomp -> dev , "tplg %s component load failed %d\n" , tplg_files [i ], ret );
2543+ goto out ;
2544+ }
2545+ }
2546+
2547+ /* call sof_complete when topologies are loaded successfully */
2548+ ret = sof_complete (scomp );
2549+
2550+ out :
25052551 if (ret >= 0 && sdev -> led_present )
25062552 ret = snd_ctl_led_request ();
25072553
2554+ kfree (tplg_files );
2555+
25082556 return ret ;
25092557}
25102558EXPORT_SYMBOL (snd_sof_load_topology );
0 commit comments