From: Hsin-Yu Chao <hychao@chromium.org>
To: alsa-devel@alsa-project.org
Cc: vinod.koul@intel.com, dgreid@chromium.org,
Hsin-Yu Chao <hychao@chromium.org>
Subject: [PATCH v2] ucm: add cset-tlv
Date: Wed, 23 Mar 2016 17:16:42 +0800 [thread overview]
Message-ID: <1458724602-5618-1-git-send-email-hychao@chromium.org> (raw)
This patch enables UCM to set a file in TLV format to kcontrol by:
cset-tlv "name='<kcontrol-name>' <path-to-file>"
This new 'cset-tlv' command will be used to write audio DSP to
specific alsa control, where the driver expectes a file in TLV
format.
Signed-off-by: Hsin-Yu Chao <hychao@chromium.org>
---
src/ucm/main.c | 91 +++++++++++++++++++++++++++++++++++++++++++++--------
src/ucm/parser.c | 10 ++++++
src/ucm/ucm_local.h | 1 +
3 files changed, 89 insertions(+), 13 deletions(-)
diff --git a/src/ucm/main.c b/src/ucm/main.c
index 7e44603..c6bbf27 100644
--- a/src/ucm/main.c
+++ b/src/ucm/main.c
@@ -161,6 +161,54 @@ static int open_ctl(snd_use_case_mgr_t *uc_mgr,
return 0;
}
+static int read_tlv_file(char **res,
+ const char *filepath)
+{
+ int err = 0;
+ int fd;
+ struct stat st;
+ size_t sz;
+ ssize_t sz_read;
+ unsigned int *tlv;
+
+ fd = open(filepath, O_RDONLY);
+ if (fd < 0) {
+ err = -errno;
+ return err;
+ }
+ if (stat(filepath, &st) == -1) {
+ err = -errno;
+ goto __fail;
+ }
+ sz = st.st_size;
+ if (sz > 1024 * 1024 || sz < 8) {
+ uc_error("unsupported file size");
+ goto __fail;
+ }
+ *res = malloc(sz);
+ if (res == NULL) {
+ err = -ENOMEM;
+ goto __fail;
+ }
+ sz_read = read(fd, *res, sz);
+ if (sz_read < 0 || (size_t)sz_read != sz) {
+ err = -errno;
+ free(*res);
+ *res = NULL;
+ }
+ /* Check if the tlv file specifies valid size. */
+ tlv = (unsigned int *)(*res);
+ if (tlv[1] + 2 * sizeof(unsigned int) != sz) {
+ uc_error("Invalid tlv size");
+ free(*res);
+ *res = NULL;
+ }
+
+ __fail:
+ close(fd);
+ return err;
+}
+
static int binary_file_parse(snd_ctl_elem_value_t *dst,
snd_ctl_elem_info_t *info,
const char *filepath)
@@ -226,6 +274,7 @@ static int execute_cset(snd_ctl_t *ctl, const char *cset, unsigned int type)
snd_ctl_elem_id_t *id;
snd_ctl_elem_value_t *value;
snd_ctl_elem_info_t *info;
+ char *res = NULL;
snd_ctl_elem_id_malloc(&id);
snd_ctl_elem_value_malloc(&value);
@@ -241,23 +290,36 @@ static int execute_cset(snd_ctl_t *ctl, const char *cset, unsigned int type)
err = -EINVAL;
goto __fail;
}
- snd_ctl_elem_value_set_id(value, id);
snd_ctl_elem_info_set_id(info, id);
- err = snd_ctl_elem_read(ctl, value);
- if (err < 0)
- goto __fail;
err = snd_ctl_elem_info(ctl, info);
if (err < 0)
goto __fail;
- if (type == SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE)
- err = binary_file_parse(value, info, pos);
- else
- err = snd_ctl_ascii_value_parse(ctl, value, info, pos);
- if (err < 0)
- goto __fail;
- err = snd_ctl_elem_write(ctl, value);
- if (err < 0)
- goto __fail;
+ if (type == SEQUENCE_ELEMENT_TYPE_CSET_TLV) {
+ if (!snd_ctl_elem_info_is_tlv_writable(info)) {
+ err = -EINVAL;
+ goto __fail;
+ }
+ err = read_tlv_file(&res, pos);
+ if (err < 0)
+ goto __fail;
+ err = snd_ctl_elem_tlv_write(ctl, id, (unsigned int *)res);
+ if (err < 0)
+ goto __fail;
+ } else {
+ snd_ctl_elem_value_set_id(value, id);
+ err = snd_ctl_elem_read(ctl, value);
+ if (err < 0)
+ goto __fail;
+ if (type == SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE)
+ err = binary_file_parse(value, info, pos);
+ else
+ err = snd_ctl_ascii_value_parse(ctl, value, info, pos);
+ if (err < 0)
+ goto __fail;
+ err = snd_ctl_elem_write(ctl, value);
+ if (err < 0)
+ goto __fail;
+ }
err = 0;
__fail:
if (id != NULL)
@@ -266,6 +328,8 @@ static int execute_cset(snd_ctl_t *ctl, const char *cset, unsigned int type)
free(value);
if (info != NULL)
free(info);
+ if (res != NULL)
+ free(res);
return err;
}
@@ -298,6 +362,7 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
break;
case SEQUENCE_ELEMENT_TYPE_CSET:
case SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE:
+ case SEQUENCE_ELEMENT_TYPE_CSET_TLV:
if (cdev == NULL) {
char *playback_ctl = NULL;
char *capture_ctl = NULL;
diff --git a/src/ucm/parser.c b/src/ucm/parser.c
index 9e1cb41..d781e1b 100644
--- a/src/ucm/parser.c
+++ b/src/ucm/parser.c
@@ -316,6 +316,16 @@ static int parse_sequence(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
continue;
}
+ if (strcmp(cmd, "cset-tlv") == 0) {
+ curr->type = SEQUENCE_ELEMENT_TYPE_CSET_TLV;
+ err = parse_string(n, &curr->data.cset);
+ if (err < 0) {
+ uc_error("error: cset-tlv requires a string!");
+ return err;
+ }
+ continue;
+ }
+
if (strcmp(cmd, "usleep") == 0) {
curr->type = SEQUENCE_ELEMENT_TYPE_SLEEP;
err = snd_config_get_integer(n, &curr->data.sleep);
diff --git a/src/ucm/ucm_local.h b/src/ucm/ucm_local.h
index 3a5d2c2..b89de2a 100644
--- a/src/ucm/ucm_local.h
+++ b/src/ucm/ucm_local.h
@@ -48,6 +48,7 @@
#define SEQUENCE_ELEMENT_TYPE_SLEEP 3
#define SEQUENCE_ELEMENT_TYPE_EXEC 4
#define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE 5
+#define SEQUENCE_ELEMENT_TYPE_CSET_TLV 6
struct ucm_value {
struct list_head list;
--
2.1.2
reply other threads:[~2016-03-23 9:16 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=1458724602-5618-1-git-send-email-hychao@chromium.org \
--to=hychao@chromium.org \
--cc=alsa-devel@alsa-project.org \
--cc=dgreid@chromium.org \
--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).