@@ -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 ,
@@ -2488,34 +2490,82 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
24882490int snd_sof_load_topology (struct snd_soc_component * scomp , const char * file )
24892491{
24902492 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
2493+ struct snd_sof_pdata * sof_pdata = sdev -> pdata ;
2494+ const char * tplg_filename_prefix = sof_pdata -> tplg_filename_prefix ;
24912495 const struct firmware * fw ;
2496+ const char * * tplg_files ;
2497+ int tplg_cnt = 0 ;
24922498 int ret ;
2499+ int i ;
24932500
2494- dev_dbg (scomp -> dev , "loading topology:%s\n" , file );
2501+ tplg_files = kcalloc (scomp -> card -> num_links , sizeof (char * ), GFP_KERNEL );
2502+ if (!tplg_files )
2503+ return - ENOMEM ;
24952504
2496- ret = request_firmware (& fw , file , scomp -> dev );
2497- if (ret < 0 ) {
2498- dev_err (scomp -> dev , "error: tplg request firmware %s failed err: %d\n" ,
2499- file , ret );
2500- dev_err (scomp -> dev ,
2501- "you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n" );
2502- return ret ;
2505+ if (sof_pdata -> machine -> get_function_tplg_files ) {
2506+ tplg_cnt = sof_pdata -> machine -> get_function_tplg_files (scomp -> card ,
2507+ sof_pdata -> machine ,
2508+ tplg_filename_prefix ,
2509+ & tplg_files );
2510+ if (tplg_cnt < 0 ) {
2511+ kfree (tplg_files );
2512+ return tplg_cnt ;
2513+ }
25032514 }
25042515
2505- if (sdev -> dspless_mode_selected )
2506- ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2507- else
2508- ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2516+ /*
2517+ * The monolithic topology will be used if there is no get_function_tplg_files
2518+ * callback or the callback returns 0.
2519+ */
2520+ if (!tplg_cnt ) {
2521+ tplg_files [0 ] = file ;
2522+ tplg_cnt = 1 ;
2523+ dev_dbg (scomp -> dev , "loading topology: %s\n" , file );
2524+ } else {
2525+ dev_info (scomp -> dev , "Using function topologies instead %s\n" , file );
2526+ }
25092527
2510- if (ret < 0 )
2511- dev_err (scomp -> dev , "error: tplg component load failed %d\n" ,
2512- ret );
2528+ for (i = 0 ; i < tplg_cnt ; i ++ ) {
2529+ /* Only print the file names if the function topologies are used */
2530+ if (tplg_files [0 ] != file )
2531+ dev_info (scomp -> dev , "loading topology %d: %s\n" , i , tplg_files [i ]);
25132532
2514- release_firmware (fw );
2533+ ret = request_firmware (& fw , tplg_files [i ], scomp -> dev );
2534+ if (ret < 0 ) {
2535+ /*
2536+ * snd_soc_tplg_component_remove(scomp) will be called
2537+ * if snd_soc_tplg_component_load(scomp) failed and all
2538+ * objects in the scomp will be removed. No need to call
2539+ * snd_soc_tplg_component_remove(scomp) here.
2540+ */
2541+ dev_err (scomp -> dev , "tplg request firmware %s failed err: %d\n" ,
2542+ tplg_files [i ], ret );
2543+ goto out ;
2544+ }
25152545
2546+ if (sdev -> dspless_mode_selected )
2547+ ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2548+ else
2549+ ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2550+
2551+ release_firmware (fw );
2552+
2553+ if (ret < 0 ) {
2554+ dev_err (scomp -> dev , "tplg %s component load failed %d\n" ,
2555+ tplg_files [i ], ret );
2556+ goto out ;
2557+ }
2558+ }
2559+
2560+ /* call sof_complete when topologies are loaded successfully */
2561+ ret = sof_complete (scomp );
2562+
2563+ out :
25162564 if (ret >= 0 && sdev -> led_present )
25172565 ret = snd_ctl_led_request ();
25182566
2567+ kfree (tplg_files );
2568+
25192569 return ret ;
25202570}
25212571EXPORT_SYMBOL (snd_sof_load_topology );
0 commit comments