diff options
author | Simon Wilson <ksattic@gmail.com> | 2015-05-21 06:32:42 -0700 |
---|---|---|
committer | Simon Wilson <ksattic@gmail.com> | 2015-05-21 06:32:42 -0700 |
commit | 74a05da4f0650e0f395ab541dd6ef29e6b443376 (patch) | |
tree | 4ce6fbebb441c3992f6948420475c25aa8f4625c | |
parent | f2a7b6d3d81bd337a540d56704b4aaa7bdb046fe (diff) | |
parent | acc12b45388d204ab5be060f9393b32af2c341bc (diff) |
Merge pull request #58 from vinodkoul/tlv_support2
Tlv support2
-rw-r--r-- | mixer.c | 55 | ||||
-rw-r--r-- | tinymix.c | 47 |
2 files changed, 76 insertions, 26 deletions
@@ -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: @@ -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,21 +195,25 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control, printf(" (range %d->%d)", min, max); } } + + free(buf); + 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; - 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) @@ -271,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; } |