@@ -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,81 @@ 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: %s\n" , file );
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+ /* Only print the file names if the function topologies are used */
2519+ if (tplg_files [0 ] != file )
2520+ dev_info (scomp -> dev , "loading topology %d: %s\n" , i , tplg_files [i ]);
25022521
2503- release_firmware (fw );
2522+ ret = request_firmware (& fw , tplg_files [i ], scomp -> dev );
2523+ if (ret < 0 ) {
2524+ /*
2525+ * snd_soc_tplg_component_remove(scomp) will be called
2526+ * if snd_soc_tplg_component_load(scomp) failed and all
2527+ * objects in the scomp will be removed. No need to call
2528+ * snd_soc_tplg_component_remove(scomp) here.
2529+ */
2530+ dev_err (scomp -> dev , "tplg request firmware %s failed err: %d\n" ,
2531+ tplg_files [i ], ret );
2532+ goto out ;
2533+ }
25042534
2535+ if (sdev -> dspless_mode_selected )
2536+ ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2537+ else
2538+ ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2539+
2540+ release_firmware (fw );
2541+
2542+ if (ret < 0 ) {
2543+ dev_err (scomp -> dev , "tplg %s component load failed %d\n" , tplg_files [i ], ret );
2544+ goto out ;
2545+ }
2546+ }
2547+
2548+ /* call sof_complete when topologies are loaded successfully */
2549+ ret = sof_complete (scomp );
2550+
2551+ out :
25052552 if (ret >= 0 && sdev -> led_present )
25062553 ret = snd_ctl_led_request ();
25072554
2555+ kfree (tplg_files );
2556+
25082557 return ret ;
25092558}
25102559EXPORT_SYMBOL (snd_sof_load_topology );
0 commit comments