@@ -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,117 @@ 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 * platform ;
2471+ char * device ;
2472+ char * file ;
2473+ int be_id ;
2474+ };
2475+
24592476int snd_sof_load_topology (struct snd_soc_component * scomp , const char * file )
24602477{
24612478 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
2479+ struct snd_sof_pdata * sof_pdata = sdev -> pdata ;
2480+ struct topology_file tplg_files [MAX_TPLG_NUM ];
2481+ struct snd_soc_dai_link * dai_link ;
2482+ char platform [4 ];
2483+ bool load_default_tplg = false;
2484+ unsigned long tplg_mask = 0 ;
24622485 const struct firmware * fw ;
2486+ int tplg_num = 0 ;
24632487 int ret ;
2488+ int i ;
24642489
24652490 dev_dbg (scomp -> dev , "loading topology:%s\n" , file );
24662491
2492+ sscanf (sof_pdata -> tplg_filename , "sof-%3s-*.tplg" , platform );
2493+
2494+ if (sdev -> pdata -> ipc_type == SOF_IPC_TYPE_3 )
2495+ goto legacy_tplg ;
2496+
2497+ for_each_card_prelinks (scomp -> card , i , dai_link ) {
2498+ dev_dbg (scomp -> dev , "dai_link %s id %d\n" , dai_link -> name , dai_link -> id );
2499+ if (strstr (dai_link -> name , "SimpleJack" )) {
2500+ if (tplg_mask & BIT (TPLG_DEVICE_SDW_JACK ))
2501+ continue ;
2502+ tplg_mask |= BIT (TPLG_DEVICE_SDW_JACK );
2503+ tplg_files [tplg_num ].device = "sdca-jack" ;
2504+ } else if (strstr (dai_link -> name , "SmartAmp" )) {
2505+ if (tplg_mask & BIT (TPLG_DEVICE_SDW_AMP ))
2506+ continue ;
2507+ tplg_mask |= BIT (TPLG_DEVICE_SDW_AMP );
2508+ tplg_files [tplg_num ].device = "sdca-amp" ;
2509+ } else if (strstr (dai_link -> name , "SmartMic" )) {
2510+ if (tplg_mask & BIT (TPLG_DEVICE_SDW_MIC ))
2511+ continue ;
2512+ tplg_mask |= BIT (TPLG_DEVICE_SDW_MIC );
2513+ tplg_files [tplg_num ].device = "sdca-mic" ;
2514+ } else if (strstr (dai_link -> name , "DMIC" )) {
2515+ if (tplg_mask & BIT (TPLG_DEVICE_HOST_DMIC ))
2516+ continue ;
2517+ tplg_mask |= BIT (TPLG_DEVICE_HOST_DMIC );
2518+ tplg_files [tplg_num ].device = "host-dmic" ;
2519+ } else if (strstr (dai_link -> name , "iDisp" )) {
2520+ if (tplg_mask & BIT (TPLG_DEVICE_HDMI ))
2521+ continue ;
2522+ tplg_mask |= BIT (TPLG_DEVICE_HDMI );
2523+ tplg_files [tplg_num ].device = "hdmi" ;
2524+ } else {
2525+ /* The dai link is not supported by sperated tplg yet */
2526+ load_default_tplg = true;
2527+ continue ;
2528+ }
2529+ tplg_files [tplg_num ].be_id = dai_link -> id ;
2530+ tplg_num ++ ;
2531+ }
2532+ dev_dbg (scomp -> dev , "tplg_mask %#lx tplg_num %d\n" , tplg_mask , tplg_num );
2533+
2534+ for (i = 0 ; i < tplg_num ; i ++ ) {
2535+ tplg_files [i ].file = devm_kasprintf (sdev -> dev , GFP_KERNEL ,
2536+ "%s/sof-%s-%s-id%d.tplg" ,
2537+ sof_pdata -> tplg_filename_prefix , platform ,
2538+ tplg_files [i ].device ,
2539+ tplg_files [i ].be_id );
2540+ ret = request_firmware (& fw , tplg_files [i ].file , scomp -> dev );
2541+ dev_dbg (scomp -> dev , "Requesting %d %s\n" , i , tplg_files [i ].file );
2542+ if (ret < 0 ) {
2543+ dev_warn (scomp -> dev , "error: tplg request firmware %s failed err: %d\n" ,
2544+ tplg_files [i ].file , ret );
2545+ dev_warn (scomp -> dev ,"Fail back to the default topology\n" );
2546+ goto legacy_tplg ;
2547+ }
2548+ /* set complete = sof_complete if it is the last topology */
2549+ if (!load_default_tplg && i == tplg_num - 1 )
2550+ sof_tplg_ops .complete = sof_complete ;
2551+ if (sdev -> dspless_mode_selected )
2552+ ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2553+ else
2554+ ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2555+
2556+ if (ret < 0 ) {
2557+ dev_err (scomp -> dev , "error: tplg component load failed %d\n" ,
2558+ ret );
2559+ release_firmware (fw );
2560+ return - EINVAL ;
2561+ }
2562+
2563+ release_firmware (fw );
2564+ }
2565+ /* Load topology successfully, goto out */
2566+ if (!load_default_tplg )
2567+ goto out ;
2568+
2569+ legacy_tplg :
24672570 ret = request_firmware (& fw , file , scomp -> dev );
24682571 if (ret < 0 ) {
24692572 dev_err (scomp -> dev , "error: tplg request firmware %s failed err: %d\n" ,
@@ -2473,6 +2576,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24732576 return ret ;
24742577 }
24752578
2579+ sof_tplg_ops .complete = sof_complete ;
24762580 if (sdev -> dspless_mode_selected )
24772581 ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
24782582 else
@@ -2486,6 +2590,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24862590
24872591 release_firmware (fw );
24882592
2593+ out :
24892594 if (ret >= 0 && sdev -> led_present )
24902595 ret = snd_ctl_led_request ();
24912596
0 commit comments