1313#include <linux/errno.h>
1414#include <linux/firmware.h>
1515#include <linux/workqueue.h>
16+ #include <sound/soc_sdw_utils.h>
1617#include <sound/tlv.h>
1718#include <uapi/sound/sof/tokens.h>
1819#include "sof-priv.h"
@@ -2286,7 +2287,7 @@ static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = {
22862287 {SOF_TPLG_KCTL_BYTES_VOLATILE_RO , snd_sof_bytes_ext_volatile_get },
22872288};
22882289
2289- static const struct snd_soc_tplg_ops sof_tplg_ops = {
2290+ static struct snd_soc_tplg_ops sof_tplg_ops = {
22902291 /* external kcontrol init - used for any driver specific init */
22912292 .control_load = sof_control_load ,
22922293 .control_unload = sof_control_unload ,
@@ -2309,7 +2310,7 @@ static const struct snd_soc_tplg_ops sof_tplg_ops = {
23092310 .link_unload = sof_link_unload ,
23102311
23112312 /* completion - called at completion of firmware loading */
2312- . complete = sof_complete ,
2313+ /* complete will be added in the last tplg ops */
23132314
23142315 /* manifest - optional to inform component of manifest */
23152316 .manifest = sof_manifest ,
@@ -2462,14 +2463,138 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
24622463 .bytes_ext_ops_count = ARRAY_SIZE (sof_dspless_bytes_ext_ops ),
24632464};
24642465
2466+ #define MAX_TPLG_NUM 5
2467+
2468+ enum tplg_device_id {
2469+ TPLG_DEVICE_SDW_JACK ,
2470+ TPLG_DEVICE_SDW_AMP ,
2471+ TPLG_DEVICE_SDW_MIC ,
2472+ TPLG_DEVICE_HOST_DMIC ,
2473+ TPLG_DEVICE_HDMI ,
2474+ };
2475+
2476+ struct topology_file {
2477+ char * device ;
2478+ char * file ;
2479+ int be_id ;
2480+ };
2481+
24652482int snd_sof_load_topology (struct snd_soc_component * scomp , const char * file )
24662483{
24672484 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
2485+ struct snd_sof_pdata * sof_pdata = sdev -> pdata ;
2486+ struct topology_file tplg_files [MAX_TPLG_NUM ];
2487+ struct snd_soc_dai_link * dai_link ;
2488+ char platform [4 ];
2489+ bool load_default_tplg = false;
2490+ unsigned long tplg_mask = 0 ;
24682491 const struct firmware * fw ;
2492+ int tplg_num = 0 ;
2493+ int tplg_dev ;
24692494 int ret ;
2495+ int i ;
24702496
24712497 dev_dbg (scomp -> dev , "loading topology:%s\n" , file );
24722498
2499+ sscanf (sof_pdata -> tplg_filename , "sof-%3s-*.tplg" , platform );
2500+
2501+ if (sdev -> pdata -> ipc_type == SOF_IPC_TYPE_3 )
2502+ goto legacy_tplg ;
2503+
2504+ for_each_card_prelinks (scomp -> card , i , dai_link ) {
2505+ char * tplg_device ;
2506+
2507+ dev_dbg (scomp -> dev , "dai_link %s id %d\n" , dai_link -> name , dai_link -> id );
2508+ if (strstr (dai_link -> name , "SimpleJack" )) {
2509+ tplg_dev = TPLG_DEVICE_SDW_JACK ;
2510+ tplg_device = "sdca-jack" ;
2511+ } else if (strstr (dai_link -> name , "SmartAmp" )) {
2512+ tplg_dev = TPLG_DEVICE_SDW_AMP ;
2513+ tplg_device = "sdca-amp" ;
2514+ } else if (strstr (dai_link -> name , "SmartMic" )) {
2515+ tplg_dev |= TPLG_DEVICE_SDW_MIC ;
2516+ tplg_device = "sdca-mic" ;
2517+ } else if (strstr (dai_link -> name , "SDW" )) {
2518+ int sdw_link ;
2519+
2520+ sscanf (dai_link -> name , "SDW%d" , & sdw_link );
2521+ /* detect SDW device by dai_link id */
2522+ switch (dai_link -> id ) {
2523+ case SOC_SDW_JACK_OUT_DAI_ID :
2524+ case SOC_SDW_JACK_IN_DAI_ID :
2525+ tplg_dev = TPLG_DEVICE_SDW_JACK ;
2526+ tplg_device = devm_kasprintf (sdev -> dev , GFP_KERNEL ,
2527+ "sdw%d-jack" , sdw_link );
2528+ break ;
2529+ case SOC_SDW_AMP_OUT_DAI_ID :
2530+ case SOC_SDW_AMP_IN_DAI_ID :
2531+ tplg_dev = TPLG_DEVICE_SDW_AMP ;
2532+ tplg_device = devm_kasprintf (sdev -> dev , GFP_KERNEL ,
2533+ "sdw%d-amp" , sdw_link );
2534+ break ;
2535+ case SOC_SDW_DMIC_DAI_ID :
2536+ tplg_dev = TPLG_DEVICE_SDW_MIC ;
2537+ tplg_device = devm_kasprintf (sdev -> dev , GFP_KERNEL ,
2538+ "sdw%d-mic" , sdw_link );
2539+ break ;
2540+
2541+ }
2542+ } else if (strstr (dai_link -> name , "DMIC" )) {
2543+ tplg_mask = TPLG_DEVICE_HOST_DMIC ;
2544+ tplg_device = "host-dmic" ;
2545+ } else if (strstr (dai_link -> name , "iDisp" )) {
2546+ tplg_dev = TPLG_DEVICE_HDMI ;
2547+ tplg_device = "hdmi" ;
2548+ } else {
2549+ /* The dai link is not supported by sperated tplg yet */
2550+ load_default_tplg = true;
2551+ continue ;
2552+ }
2553+ if (tplg_mask & BIT (tplg_dev ))
2554+ continue ;
2555+ tplg_mask |= BIT (tplg_dev );
2556+ tplg_files [tplg_num ].be_id = dai_link -> id ;
2557+ tplg_files [tplg_num ].device = tplg_device ;
2558+ tplg_num ++ ;
2559+ }
2560+ dev_dbg (scomp -> dev , "tplg_mask %#lx tplg_num %d\n" , tplg_mask , tplg_num );
2561+
2562+ for (i = 0 ; i < tplg_num ; i ++ ) {
2563+ tplg_files [i ].file = devm_kasprintf (sdev -> dev , GFP_KERNEL ,
2564+ "%s/sof-%s-%s-id%d.tplg" ,
2565+ sof_pdata -> tplg_filename_prefix , platform ,
2566+ tplg_files [i ].device ,
2567+ tplg_files [i ].be_id );
2568+ ret = request_firmware (& fw , tplg_files [i ].file , scomp -> dev );
2569+ dev_dbg (scomp -> dev , "Requesting %d %s\n" , i , tplg_files [i ].file );
2570+ if (ret < 0 ) {
2571+ dev_warn (scomp -> dev , "error: tplg request firmware %s failed err: %d\n" ,
2572+ tplg_files [i ].file , ret );
2573+ dev_warn (scomp -> dev ,"Fail back to the default topology\n" );
2574+ goto legacy_tplg ;
2575+ }
2576+ /* set complete = sof_complete if it is the last topology */
2577+ if (!load_default_tplg && i == tplg_num - 1 )
2578+ sof_tplg_ops .complete = sof_complete ;
2579+ if (sdev -> dspless_mode_selected )
2580+ ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
2581+ else
2582+ ret = snd_soc_tplg_component_load (scomp , & sof_tplg_ops , fw );
2583+
2584+ if (ret < 0 ) {
2585+ dev_err (scomp -> dev , "error: tplg component load failed %d\n" ,
2586+ ret );
2587+ release_firmware (fw );
2588+ return - EINVAL ;
2589+ }
2590+
2591+ release_firmware (fw );
2592+ }
2593+ /* Load topology successfully, goto out */
2594+ if (!load_default_tplg )
2595+ goto out ;
2596+
2597+ legacy_tplg :
24732598 ret = request_firmware (& fw , file , scomp -> dev );
24742599 if (ret < 0 ) {
24752600 dev_err (scomp -> dev , "error: tplg request firmware %s failed err: %d\n" ,
@@ -2479,6 +2604,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24792604 return ret ;
24802605 }
24812606
2607+ sof_tplg_ops .complete = sof_complete ;
24822608 if (sdev -> dspless_mode_selected )
24832609 ret = snd_soc_tplg_component_load (scomp , & sof_dspless_tplg_ops , fw );
24842610 else
@@ -2492,6 +2618,7 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
24922618
24932619 release_firmware (fw );
24942620
2621+ out :
24952622 if (ret >= 0 && sdev -> led_present )
24962623 ret = snd_ctl_led_request ();
24972624
0 commit comments