From 45b2d047b8c2f4d9d1d87244f7f981db8234c906 Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Mon, 18 Aug 2014 15:39:36 +0530 Subject: mixer: add support for TLV based byte controls Add tinyasla support for bytes controls with TLV type Signed-off-by: Mythri P K Signed-off-by: Samreen Nilofer Signed-off-by: Vinod Koul --- mixer.c | 55 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/mixer.c b/mixer.c index 78b1a12..73ae6da 100644 --- a/mixer.c +++ b/mixer.c @@ -331,7 +331,7 @@ int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id) int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count) { struct snd_ctl_elem_value ev; - int ret; + int ret = 0; size_t size; void *source; @@ -341,21 +341,41 @@ int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count) memset(&ev, 0, sizeof(ev)); ev.id.numid = ctl->info->id.numid; - ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev); - if (ret < 0) - return ret; - switch (ctl->info->type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_INTEGER: + ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev); + if (ret < 0) + return ret; size = sizeof(ev.value.integer.value[0]); source = ev.value.integer.value; break; case SNDRV_CTL_ELEM_TYPE_BYTES: - size = sizeof(ev.value.bytes.data[0]); - source = ev.value.bytes.data; - break; + /* check if this is new bytes TLV */ + if (ctl->info->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) { + struct snd_ctl_tlv *tlv; + int ret; + + tlv = calloc(1, sizeof(*tlv) + count); + tlv->numid = ctl->info->id.numid; + tlv->length = count; + ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_TLV_READ, tlv); + + source = tlv->tlv; + memcpy(array, source, count); + + free(tlv); + + return ret; + } else { + ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev); + if (ret < 0) + return ret; + size = sizeof(ev.value.bytes.data[0]); + source = ev.value.bytes.data; + break; + } default: return -EINVAL; @@ -429,8 +449,23 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) break; case SNDRV_CTL_ELEM_TYPE_BYTES: - size = sizeof(ev.value.bytes.data[0]); - dest = ev.value.bytes.data; + /* check if this is new bytes TLV */ + if (ctl->info->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) { + struct snd_ctl_tlv *tlv; + int ret = 0; + tlv = calloc(1, sizeof(*tlv) + count); + tlv->numid = ctl->info->id.numid; + tlv->length = count; + memcpy(tlv->tlv, array, count); + + ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_TLV_WRITE, tlv); + free(tlv); + + return ret; + } else { + size = sizeof(ev.value.bytes.data[0]); + dest = ev.value.bytes.data; + } break; default: -- cgit v1.2.3 From 7cab1ef96b60a7b16120cad230afb279329a01a1 Mon Sep 17 00:00:00 2001 From: Samreen Nilofer Date: Thu, 2 Apr 2015 11:57:29 +0530 Subject: tinymix: Support more that 512 bytes in byte control The set/get byte control support more than 512 bytes. This is utilized by tlv type controls. Signed-off-by: Samreen Nilofer Signed-off-by: Vinod Koul --- tinymix.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/tinymix.c b/tinymix.c index fa3defc..dcc985f 100644 --- a/tinymix.c +++ b/tinymix.c @@ -131,7 +131,7 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control, unsigned int i; int min, max; int ret; - char buf[512] = { 0 }; + char *buf = NULL; size_t len; if (isdigit(control[0])) @@ -148,14 +148,18 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control, num_values = mixer_ctl_get_num_values(ctl); if (type == MIXER_CTL_TYPE_BYTE) { - len = num_values; - if (len > sizeof(buf)) { - fprintf(stderr, "Truncating get to %zu bytes\n", sizeof(buf)); - len = sizeof(buf); + + buf = calloc(1, num_values); + if (buf == NULL) { + fprintf(stderr, "Failed to alloc mem for bytes %d\n", num_values); + return; } + + len = num_values; ret = mixer_ctl_get_array(ctl, buf, len); if (ret < 0) { fprintf(stderr, "Failed to mixer_ctl_get_array\n"); + free(buf); return; } } @@ -191,6 +195,9 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control, printf(" (range %d->%d)", min, max); } } + + free(buf); + printf("\n"); } @@ -198,14 +205,15 @@ static void tinymix_set_byte_ctl(struct mixer_ctl *ctl, const char *control, char **values, unsigned int num_values) { int ret; - char buf[512] = { 0 }; + char *buf; char *end; - int i; + unsigned int i; long n; - if (num_values > sizeof(buf)) { - fprintf(stderr, "Truncating set to %zu bytes\n", sizeof(buf)); - num_values = sizeof(buf); + buf = calloc(1, num_values); + if (buf == NULL) { + fprintf(stderr, "set_byte_ctl: Failed to alloc mem for bytes %d\n", num_values); + exit(EXIT_FAILURE); } for (i = 0; i < num_values; i++) { @@ -213,17 +221,17 @@ static void tinymix_set_byte_ctl(struct mixer_ctl *ctl, const char *control, n = strtol(values[i], &end, 0); if (*end) { fprintf(stderr, "%s not an integer\n", values[i]); - exit(EXIT_FAILURE); + goto fail; } if (errno) { fprintf(stderr, "strtol: %s: %s\n", values[i], strerror(errno)); - exit(EXIT_FAILURE); + goto fail; } if (n < 0 || n > 0xff) { fprintf(stderr, "%s should be between [0, 0xff]\n", values[i]); - exit(EXIT_FAILURE); + goto fail; } buf[i] = n; } @@ -231,8 +239,15 @@ static void tinymix_set_byte_ctl(struct mixer_ctl *ctl, const char *control, ret = mixer_ctl_set_array(ctl, buf, num_values); if (ret < 0) { fprintf(stderr, "Failed to set binary control\n"); - exit(EXIT_FAILURE); + goto fail; } + + free(buf); + return; + +fail: + free(buf); + exit(EXIT_FAILURE); } static int is_int(char *value) -- cgit v1.2.3 From acc12b45388d204ab5be060f9393b32af2c341bc Mon Sep 17 00:00:00 2001 From: Samreen Nilofer Date: Thu, 2 Apr 2015 11:59:08 +0530 Subject: tinymix: Remove the unused parameter from tinymix_set_byte_ctl() The control pointer is not used in the tinymix_set_byte_ctl(), hence removing it. Signed-off-by: Samreen Nilofer Signed-off-by: Vinod Koul --- tinymix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tinymix.c b/tinymix.c index dcc985f..71dd206 100644 --- a/tinymix.c +++ b/tinymix.c @@ -201,7 +201,7 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control, printf("\n"); } -static void tinymix_set_byte_ctl(struct mixer_ctl *ctl, const char *control, +static void tinymix_set_byte_ctl(struct mixer_ctl *ctl, char **values, unsigned int num_values) { int ret; @@ -286,7 +286,7 @@ static void tinymix_set_value(struct mixer *mixer, const char *control, num_ctl_values = mixer_ctl_get_num_values(ctl); if (type == MIXER_CTL_TYPE_BYTE) { - tinymix_set_byte_ctl(ctl, control, values, num_values); + tinymix_set_byte_ctl(ctl, values, num_values); return; } -- cgit v1.2.3