From f51c05bfaa7b98be049bb9e08c98b94346802a10 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 28 May 2012 13:40:33 +0100 Subject: mixer: Add mixer_ctl_{set,get}_bytes() For binary controls we don't want to go through mixer_ctl_{set,get}_value() as that will trigger many calls to our get()/put() callback in the kernel. Set the entire payload at once and trigger the get()/put() callback once. Signed-off-by: Dimitris Papastamos --- include/tinyalsa/asoundlib.h | 3 +++ mixer.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/tinyalsa/asoundlib.h b/include/tinyalsa/asoundlib.h index 5894257..bdb4b7a 100644 --- a/include/tinyalsa/asoundlib.h +++ b/include/tinyalsa/asoundlib.h @@ -30,6 +30,7 @@ #define ASOUNDLIB_H #include +#include #if defined(__cplusplus) extern "C" { @@ -193,7 +194,9 @@ int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id); int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent); int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id); +int mixer_ctl_get_bytes(struct mixer_ctl *ctl, void *data, size_t len); int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value); +int mixer_ctl_set_bytes(struct mixer_ctl *ctl, const void *data, size_t len); int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string); /* Determe range of integer mixer controls */ diff --git a/mixer.c b/mixer.c index 58d4fb5..f52bca9 100644 --- a/mixer.c +++ b/mixer.c @@ -317,6 +317,27 @@ int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id) return 0; } +int mixer_ctl_get_bytes(struct mixer_ctl *ctl, void *data, size_t len) +{ + struct snd_ctl_elem_value ev; + int ret; + + if (!ctl || (len > ctl->info->count) || !len || !data || + (ctl->info->type != SNDRV_CTL_ELEM_TYPE_BYTES)) + return -EINVAL; + + 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; + + memcpy(data, ev.value.bytes.data, len); + + return 0; +} + int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value) { struct snd_ctl_elem_value ev; @@ -351,6 +372,22 @@ int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value) return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); } +int mixer_ctl_set_bytes(struct mixer_ctl *ctl, const void *data, size_t len) +{ + struct snd_ctl_elem_value ev; + + if (!ctl || (len > ctl->info->count) || !len || !data || + (ctl->info->type != SNDRV_CTL_ELEM_TYPE_BYTES)) + return -EINVAL; + + memset(&ev, 0, sizeof(ev)); + ev.id.numid = ctl->info->id.numid; + + memcpy(ev.value.bytes.data, data, len); + + return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); +} + int mixer_ctl_get_range_min(struct mixer_ctl *ctl) { if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) -- cgit v1.2.3