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 <dp@opensource.wolfsonmicro.com>
This commit is contained in:
Dimitris Papastamos
2012-05-28 13:40:33 +01:00
parent fcf66ab156
commit f51c05bfaa
2 changed files with 40 additions and 0 deletions
+3
View File
@@ -30,6 +30,7 @@
#define ASOUNDLIB_H
#include <sys/time.h>
#include <stddef.h>
#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 */
+37
View File
@@ -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))