From: mengdong.lin@linux.intel.com
To: alsa-devel@alsa-project.org
Cc: Mengdong Lin <mengdong.lin@linux.intel.com>,
tiwai@suse.de, mengdong.lin@intel.com,
liam.r.girdwood@linux.intel.com, vinod.koul@intel.com,
broonie@kernel.org
Subject: [PATCH v2 2/3] ucm: Parse sequence of component devices
Date: Fri, 18 Nov 2016 13:28:04 +0800 [thread overview]
Message-ID: <7efc58e307fce50c6db6326e5e25dfe8403c11a6.1479446217.git.mengdong.lin@linux.intel.com> (raw)
In-Reply-To: <cover.1479446217.git.mengdong.lin@linux.intel.com>
From: Mengdong Lin <mengdong.lin@linux.intel.com>
A machine device's sequence can enable or disable a component device by
keyword 'enadev' and 'disdev' followed the name of the component device.
UCM sequence parser will find the component device and mark if its enable
or disable sequence is needed by the parent, the machine device.
New element type and struct are defined for the sequence of a component
device. Component devices will be removed from the machine device list
'device_list' of a verb, since we don't want to expose them to audio
servers with original API to list devices for backward compatibility.
A new list 'cmpt_device_list' is used for the component devices of a verb.
Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com>
diff --git a/src/ucm/parser.c b/src/ucm/parser.c
index 5c99ab4..c98373a 100644
--- a/src/ucm/parser.c
+++ b/src/ucm/parser.c
@@ -254,6 +254,82 @@ static int parse_device_list(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
return 0;
}
+/* Find a component device by its name, and remove it from machine device
+ * list.
+ *
+ * Component devices are defined by machine components (usually off-soc
+ * codes or DSP embeded in SoC). Since alsaconf imports their configuration
+ * files automatically, we don't know which devices are component devices
+ * until they are referenced by a machine device sequence. So here when we
+ * find a referenced device, we move it from the machine device list to the
+ * component device list. Component devices will not be exposed to applications
+ * by the original API to list devices for backward compatibility. So sound
+ * servers can only see the machine devices.
+ */
+struct use_case_device *find_component_dev(snd_use_case_mgr_t *uc_mgr,
+ const char *name)
+{
+ struct list_head *pos, *posdev, *_posdev;
+ struct use_case_verb *verb;
+ struct use_case_device *dev;
+
+ list_for_each(pos, &uc_mgr->verb_list) {
+ verb = list_entry(pos, struct use_case_verb, list);
+
+ /* search in the component device list */
+ list_for_each(posdev, &verb->cmpt_device_list) {
+ dev = list_entry(posdev, struct use_case_device, list);
+ if (!strcmp(dev->name, name))
+ return dev;
+ }
+
+ /* search the machine device list */
+ list_for_each_safe(posdev, _posdev, &verb->device_list) {
+ dev = list_entry(posdev, struct use_case_device, list);
+ if (!strcmp(dev->name, name)) {
+ /* find the component device, move it from the
+ * machine device list to the component device
+ * list.
+ */
+ list_del(&dev->list);
+ list_add_tail(&dev->list,
+ &verb->cmpt_device_list);
+ return dev;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/* parse sequence of a component device
+ *
+ * This function will find the component device and mark if its enable or
+ * disable sequence is needed by its parenet device.
+ */
+static int parse_component_seq(snd_use_case_mgr_t *uc_mgr,
+ snd_config_t *n, int enable,
+ struct component_sequence *cmpt_seq)
+{
+ const char *val;
+ int err;
+
+ err = snd_config_get_string(n, &val);
+ if (err < 0)
+ return err;
+
+ cmpt_seq->device = find_component_dev(uc_mgr, val);
+ if (!cmpt_seq->device) {
+ uc_error("error: Cannot find component device %s", val);
+ return -EINVAL;
+ }
+
+ /* Parent needs its enable or disable sequence */
+ cmpt_seq->enable = enable;
+
+ return 0;
+}
+
/*
* Parse sequences.
*
@@ -263,12 +339,16 @@ static int parse_device_list(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
* cset "element_id_syntax value_syntax"
* usleep time
* exec "any unix command with arguments"
+ * enadev "component device name"
+ * disdev "component device name"
*
* e.g.
* cset "name='Master Playback Switch' 0,0"
* cset "iface=PCM,name='Disable HDMI',index=1 0"
+ * enadev "rt286:Headphones"
+ * disdev "rt286:Speaker"
*/
-static int parse_sequence(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
+static int parse_sequence(snd_use_case_mgr_t *uc_mgr,
struct list_head *base,
snd_config_t *cfg)
{
@@ -325,6 +405,30 @@ static int parse_sequence(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
continue;
}
+ if (strcmp(cmd, "enadev") == 0) {
+ /* need to enable a component device */
+ curr->type = SEQUENCE_ELEMENT_TYPE_CMPT_SEQ;
+ err = parse_component_seq(uc_mgr, n, 1,
+ &curr->data.cmpt_seq);
+ if (err < 0) {
+ uc_error("error: enadev requires a valid device!");
+ return err;
+ }
+ continue;
+ }
+
+ if (strcmp(cmd, "disdev") == 0) {
+ /* need to disable a component device */
+ curr->type = SEQUENCE_ELEMENT_TYPE_CMPT_SEQ;
+ err = parse_component_seq(uc_mgr, n, 0,
+ &curr->data.cmpt_seq);
+ if (err < 0) {
+ uc_error("error: disdev requires a valid device!");
+ return err;
+ }
+ continue;
+ }
+
if (strcmp(cmd, "cset-bin-file") == 0) {
curr->type = SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE;
err = parse_string(n, &curr->data.cset);
@@ -957,6 +1061,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
INIT_LIST_HEAD(&verb->disable_list);
INIT_LIST_HEAD(&verb->transition_list);
INIT_LIST_HEAD(&verb->device_list);
+ INIT_LIST_HEAD(&verb->cmpt_device_list);
INIT_LIST_HEAD(&verb->modifier_list);
INIT_LIST_HEAD(&verb->value_list);
list_add_tail(&verb->list, &uc_mgr->verb_list);
diff --git a/src/ucm/ucm_local.h b/src/ucm/ucm_local.h
index b89de2a..3bfdd67 100644
--- a/src/ucm/ucm_local.h
+++ b/src/ucm/ucm_local.h
@@ -49,6 +49,7 @@
#define SEQUENCE_ELEMENT_TYPE_EXEC 4
#define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE 5
#define SEQUENCE_ELEMENT_TYPE_CSET_TLV 6
+#define SEQUENCE_ELEMENT_TYPE_CMPT_SEQ 7
struct ucm_value {
struct list_head list;
@@ -56,6 +57,12 @@ struct ucm_value {
char *data;
};
+/* sequence of a component device */
+struct component_sequence {
+ struct use_case_device *device; /* component device */
+ int enable; /* flag to choose enable or disable list of the device */
+};
+
struct sequence_element {
struct list_head list;
unsigned int type;
@@ -64,6 +71,7 @@ struct sequence_element {
char *cdev;
char *cset;
char *exec;
+ struct component_sequence cmpt_seq; /* component sequence */
} data;
};
@@ -167,6 +175,9 @@ struct use_case_verb {
/* hardware devices that can be used with this use case */
struct list_head device_list;
+ /* component device list */
+ struct list_head cmpt_device_list;
+
/* modifiers that can be used with this use case */
struct list_head modifier_list;
diff --git a/src/ucm/utils.c b/src/ucm/utils.c
index 45307b0..0fba85a 100644
--- a/src/ucm/utils.c
+++ b/src/ucm/utils.c
@@ -210,6 +210,7 @@ void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr)
uc_mgr_free_transition(&verb->transition_list);
uc_mgr_free_value(&verb->value_list);
uc_mgr_free_device(&verb->device_list);
+ uc_mgr_free_device(&verb->cmpt_device_list);
uc_mgr_free_modifier(&verb->modifier_list);
list_del(&verb->list);
free(verb);
--
2.7.4
next prev parent reply other threads:[~2016-11-18 5:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-18 5:27 [PATCH v2 0/3] ucm: Add support for component devices mengdong.lin
2016-11-18 5:27 ` [PATCH v2 1/3] ucm: Skip component directories when scanning sound card configuration files mengdong.lin
2016-11-18 5:28 ` mengdong.lin [this message]
2016-11-18 5:28 ` [PATCH v2 3/3] ucm: Execute sequence of component devices mengdong.lin
2016-11-24 12:03 ` [RESEND PATCH " Liam Girdwood
2016-11-28 3:12 ` Lin, Mengdong
2017-01-18 4:00 ` [PATCH v2 0/3] ucm: Add support for " Lin, Mengdong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7efc58e307fce50c6db6326e5e25dfe8403c11a6.1479446217.git.mengdong.lin@linux.intel.com \
--to=mengdong.lin@linux.intel.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=liam.r.girdwood@linux.intel.com \
--cc=mengdong.lin@intel.com \
--cc=tiwai@suse.de \
--cc=vinod.koul@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).