@@ -567,7 +567,7 @@ static int sof_copy_tuples(struct snd_sof_dev *sdev, struct snd_soc_tplg_vendor_
567567 continue ;
568568
569569 tuples [* num_copied_tuples ].token = tokens [j ].token ;
570- tuples [* num_copied_tuples ].value .s = elem -> string ;
570+ tuples [* num_copied_tuples ].value .s = devm_kasprintf ( sdev -> dev , GFP_KERNEL , "%s" , elem -> string ) ;
571571 } else {
572572 struct snd_soc_tplg_vendor_value_elem * elem ;
573573
@@ -2280,7 +2280,7 @@ static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = {
22802280 {SOF_TPLG_KCTL_BYTES_VOLATILE_RO , snd_sof_bytes_ext_volatile_get },
22812281};
22822282
2283- static const struct snd_soc_tplg_ops sof_tplg_ops = {
2283+ static struct snd_soc_tplg_ops sof_tplg_ops = {
22842284 /* external kcontrol init - used for any driver specific init */
22852285 .control_load = sof_control_load ,
22862286 .control_unload = sof_control_unload ,
@@ -2303,7 +2303,7 @@ static const struct snd_soc_tplg_ops sof_tplg_ops = {
23032303 .link_unload = sof_link_unload ,
23042304
23052305 /* completion - called at completion of firmware loading */
2306- . complete = sof_complete ,
2306+ /* complete will be added in the last tplg ops */
23072307
23082308 /* manifest - optional to inform component of manifest */
23092309 .manifest = sof_manifest ,
@@ -2456,14 +2456,116 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
24562456 .bytes_ext_ops_count = ARRAY_SIZE (sof_dspless_bytes_ext_ops ),
24572457};
24582458
2459+ #define MAX_TPLG_NUM 5
2460+
2461+ enum tplg_device_id {
2462+ TPLG_DEVICE_SDW_JACK ,
2463+ TPLG_DEVICE_SDW_AMP ,
2464+ TPLG_DEVICE_SDW_MIC ,
2465+ TPLG_DEVICE_HOST_DMIC ,
2466+ TPLG_DEVICE_HDMI ,
2467+ };
2468+
2469+ struct topology_file {
2470+ char * device ;
2471+ char * file ;
2472+ int be_id ;
2473+ };
2474+
24592475int snd_sof_load_topology (struct snd_soc_component * scomp , const char * file )
24602476{
24612477 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
2478+ struct snd_sof_pdata * sof_pdata = sdev -> pdata ;
2479+ struct topology_file tplg_files [MAX_TPLG_NUM ];
2480+ struct snd_soc_dai_link * dai_link ;
2481+ char platform [4 ];
2482+ bool load_default_tplg = false;
2483+ unsigned long tplg_mask = 0 ;
24622484 const struct firmware * fw ;
2485+ int tplg_num = 0 ;
24632486 int ret ;
2487+ int i ;
24642488
24652489 dev_dbg (scomp -> dev , "loading topology:%s\n" , file );
24662490
2491+ sscanf (sof_pdata -> tplg_filename , "sof-%3s-*.tplg" , platform );
2492+
2493+ if (sdev -> pdata -> ipc_type == SOF_IPC_TYPE_3 )
2494+ goto legacy_tplg ;
2495+
2496+ for_each_card_prelinks (scomp -> card , i , dai_link ) {
2497+ dev_dbg (scomp -> dev , "dai_link %s id %d\n" , dai_link -> name , dai_link -> id );
2498+ if (strstr (dai_link -> name , "SimpleJack" )) {
2499+ if (tplg_mask & BIT (TPLG_DEVICE_SDW_JACK ))
2500+ continue ;
2501+ tplg_mask |= BIT (TPLG_DEVICE_SDW_JACK );
2502+ tplg_files [tplg_num ].device = "sdca-jack" ;
2503+ } else if (strstr (dai_link -> name , "SmartAmp" )) {
2504+ if (tplg_mask & BIT (TPLG_DEVICE_SDW_AMP ))
2505+ continue ;
2506+ tplg_mask |= BIT (TPLG_DEVICE_SDW_AMP );
2507+ tplg_files [tplg_num ].device = "sdca-amp" ;
2508+ } else if (strstr (dai_link -> name , "SmartMic" )) {
2509+ if (tplg_mask & BIT (TPLG_DEVICE_SDW_MIC ))
2510+ continue ;
2511+ tplg_mask |= BIT (TPLG_DEVICE_SDW_MIC );
2512+ tplg_files [tplg_num ].device = "sdca-mic" ;
2513+ } else if (strstr (dai_link -> name , "DMIC" )) {
2514+ if (tplg_mask & BIT (TPLG_DEVICE_HOST_DMIC ))
2515+ continue ;
2516+ tplg_mask |= BIT (TPLG_DEVICE_HOST_DMIC );
2517+ tplg_files [tplg_num ].device = "host-dmic" ;
2518+ } else if (strstr (dai_link -> name , "iDisp" )) {
2519+ if (tplg_mask & BIT (TPLG_DEVICE_HDMI ))
2520+ continue ;
2521+ tplg_mask |= BIT (TPLG_DEVICE_HDMI );
2522+ tplg_files [tplg_num ].device = "hdmi" ;
2523+ } else {
2524+ /* The dai link is not supported by sperated tplg yet */
2525+ load_default_tplg = true;
2526+ continue ;
2527+ }
2528+ tplg_files [tplg_num ].be_id = dai_link -> id ;
2529+ tplg_num ++ ;
2530+ }
2531+ dev_dbg (scomp -> dev , "tplg_mask %#lx tplg_num %d\n" , tplg_mask , tplg_num );
2532+
2533+ for (i = 0 ; i < tplg_num ; i ++ ) {
2534+ tplg_files [i ].file = devm_kasprintf (sdev -> dev , GFP_KERNEL ,
2535+ "%s/sof-%s-%s-id%d.tplg" ,
2536+ sof_pdata -> tplg_filename_prefix , platform ,
2537+ tplg_files [i ].device ,
2538+ tplg_files [i ].be_id );
2539+ ret = request_firmware (& fw , tplg_files [i ].file , scomp -> dev );
2540+ dev_dbg (scomp -> dev , "Requesting %d %s\n" , i , tplg_files [i ].file );
2541+ if (ret < 0 ) {
2542+ dev_warn (scomp -> dev , "error: tplg request firmware %s failed err: %d\n" ,
2543+ tplg_files [i ].file , ret );
2544+ dev_warn (scomp -> dev ,"Fail back to the default topology\n" );
2545+ goto legacy_tplg ;
2546+ }
2547+ /* set complete = sof_complete if it is the last topology */
2548+ if (!load_default_tplg && i == tplg_num - 1 )
2549+ sof_tplg_ops .complete = sof_complete ;
2550+ if (sdev -> dspless_mode_selected )
2551+ ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2552+ else
2553+ ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2554+
2555+ if (ret < 0 ) {
2556+ dev_err (scomp -> dev , "error: tplg component load failed %d\n" ,
2557+ ret );
2558+ release_firmware (fw );
2559+ return - EINVAL ;
2560+ }
2561+
2562+ release_firmware (fw );
2563+ }
2564+ /* Load topology successfully, goto out */
2565+ if (!load_default_tplg )
2566+ goto out ;
2567+
2568+ legacy_tplg :
24672569 ret = request_firmware (& fw , file , scomp -> dev );
24682570 if (ret < 0 ) {
24692571 dev_err (scomp -> dev , "error: tplg request firmware %s failed err: %d\n" ,
@@ -2473,6 +2575,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24732575 return ret ;
24742576 }
24752577
2578+ sof_tplg_ops .complete = sof_complete ;
24762579 if (sdev -> dspless_mode_selected )
24772580 ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
24782581 else
@@ -2486,6 +2589,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24862589
24872590 release_firmware (fw );
24882591
2592+ out :
24892593 if (ret >= 0 && sdev -> led_present )
24902594 ret = snd_ctl_led_request ();
24912595
0 commit comments