diff --git a/src/ucm/parser.c b/src/ucm/parser.c
index 3b42e31..4ea1b3f 100644
--- a/src/ucm/parser.c
+++ b/src/ucm/parser.c
@@ -55,6 +55,9 @@ static const char * const component_dir[] = {
 	NULL,		/* terminator */
 };
 
+static int filename_filter(const struct dirent *dirent);
+static int is_component_directory(const char *dir);
+
 static int parse_sequence(snd_use_case_mgr_t *uc_mgr,
 			  struct list_head *base,
 			  snd_config_t *cfg);
@@ -1328,6 +1331,66 @@ static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
 	return 0;
 }
 
+/* find the card in the local machine and store the card long name */
+static int get_card_long_name(snd_use_case_mgr_t *mgr)
+{
+	const char *card_name = mgr->card_name;
+	snd_ctl_t *handle;
+	int card, err;
+	snd_ctl_card_info_t *info;
+	const char *_name, *_long_name;
+
+	snd_ctl_card_info_alloca(&info);
+
+	card = -1;
+	if (snd_card_next(&card) < 0 || card < 0) {
+		uc_error("no soundcards found...");
+		return -1;
+	}
+
+	while (card >= 0) {
+		char name[32];
+
+		sprintf(name, "hw:%d", card);
+		err = snd_ctl_open(&handle, name, 0);
+		if (err < 0) {
+			uc_error("control open (%i): %s", card,
+				 snd_strerror(err));
+			goto next_card;
+		}
+
+		err = snd_ctl_card_info(handle, info);
+		if (err < 0) {
+			uc_error("control hardware info (%i): %s", card,
+				 snd_strerror(err));
+			snd_ctl_close(handle);
+			goto next_card;
+		}
+
+		/* Find the local card by comparing the given name with the
+		 * card short name and long name. The given card name may be
+		 * either a short name or long name, because users may open
+		 * the card by either of the two names.
+		 */
+		_name = snd_ctl_card_info_get_name(info);
+		_long_name = snd_ctl_card_info_get_longname(info);
+		if (!strcmp(card_name, _name)
+		    || !strcmp(card_name, _long_name)) {
+			strcpy(mgr->card_long_name, _long_name);
+			snd_ctl_close(handle);
+			return 0;
+		}
+
+		snd_ctl_close(handle);
+next_card:
+		if (snd_card_next(&card) < 0) {
+			uc_error("snd_card_next");
+			break;
+		}
+	}
+
+	return -1;
+}
 static int load_master_config(const char *card_name, snd_config_t **cfg)
 {
 	char filename[MAX_FILE];
@@ -1355,15 +1418,43 @@ static int load_master_config(const char *card_name, snd_config_t **cfg)
 	return 0;
 }
 
-/* load master use case file for sound card */
+/* load master use case file for sound card
+ *
+ * The same ASoC machine driver can be shared by many different devices.
+ * For user space to differentiate them and get the best device-specific
+ * configuration, ASoC machine drivers may use the DMI info
+ * (vendor-product-version-board) as the card long name. And user space can
+ * define configuration files like longname\longname.conf for a specific device.
+ *
+ * This function will try to find the card in the local machine and get its
+ * long name, then load the file longname\longname.conf to get the best
+ * device-specific configuration. If the card is not found in the local
+ * machine or the device-specific file is not available, fall back to load
+ * the default configuration file name\name.conf.
+ */
 int uc_mgr_import_master_config(snd_use_case_mgr_t *uc_mgr)
 {
 	snd_config_t *cfg;
 	int err;
 
-	err = load_master_config(uc_mgr->card_name, &cfg);
-	if (err < 0)
-		return err;
+	err = get_card_long_name(uc_mgr);
+	if (err == 0)	/* load file that maches the card long name */
+		err = load_master_config(uc_mgr->card_long_name, &cfg);
+
+	if (err == 0) {
+		/* got device-specific file that matches the card long name */
+		strcpy(uc_mgr->conf_file_name, uc_mgr->card_long_name);
+	} else {
+		/* Fall back to the file that maches the given card name,
+		 * either short name or long name (users may open a card by
+		 * its name or long name).
+		 */
+		err = load_master_config(uc_mgr->card_name, &cfg);
+		if (err < 0)
+			return err;
+		strcpy(uc_mgr->conf_file_name, uc_mgr->card_name);
+	}
+
 	err = parse_master_file(uc_mgr, cfg);
 	snd_config_delete(cfg);
 	if (err < 0)
diff --git a/src/ucm/ucm_local.h b/src/ucm/ucm_local.h
index e41aafa..299a5b9 100644
--- a/src/ucm/ucm_local.h
+++ b/src/ucm/ucm_local.h
@@ -191,6 +191,8 @@ struct use_case_verb {
  */
 struct snd_use_case_mgr {
 	char *card_name;
+	char card_long_name[MAX_CARD_LONG_NAME];
+	char conf_file_name[MAX_CARD_LONG_NAME];
 	char *comment;
 
 	/* use case verb, devices and modifier configs parsed from files */
