aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Wilson <ksattic@gmail.com>2015-05-21 06:32:42 -0700
committerSimon Wilson <ksattic@gmail.com>2015-05-21 06:32:42 -0700
commit74a05da4f0650e0f395ab541dd6ef29e6b443376 (patch)
tree4ce6fbebb441c3992f6948420475c25aa8f4625c
parentf2a7b6d3d81bd337a540d56704b4aaa7bdb046fe (diff)
parentacc12b45388d204ab5be060f9393b32af2c341bc (diff)
Merge pull request #58 from vinodkoul/tlv_support2
Tlv support2
-rw-r--r--mixer.c55
-rw-r--r--tinymix.c47
2 files changed, 76 insertions, 26 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:
diff --git a/tinymix.c b/tinymix.c
index fa3defc..71dd206 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,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;
}