From: Christian Ruppert <arc@gmx.li>
To: Will Porter <mrwillporter@gmail.com>
Cc: Takashi Iwai <tiwai@suse.com>, Jaroslav Kysela <perex@perex.cz>,
linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
Neil Andrews <neil@androos.io>
Subject: Re: [PATCH 0/5] ALSA: usb-audio: Audient iD14 MkI vendor controls
Date: Mon, 26 Oct 2026 19:36:24 +0100 [thread overview]
Message-ID: <at-dpPOGs2zD2fuL@khmer.arcnet> (raw)
In-Reply-To: <20261019230159.834954-1-mrwillporter@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 6569 bytes --]
Hi Will,
On Mon, Oct 19, 2026 at 06:01:54PM -0500, Will Porter wrote:
> [...]
>
> sound for-next also has mixer_evo.c for the Audient EVO 4 (2708:0006).
> EVO and iD are separate Audient product lines. The iD14 MkI uses other
> units and a larger control set: a monitor controller, output routing, a
> 14 x 4 mixer and write-only controls. So this series keeps the iD line
> in its own file.
>
> [...]
I took a look at this question and it seems like we can share the majority
of code in the EVO driver by complementing it with the following features:
- variable width read/write
- caching of write-only values
- enum data type
Most of these changes should be trivial as the EVO driver controls are
also structured in tabular form and the driver was intended from the start
to be extensible to the evo8 and possibly other hardware. See below diff
for an example of how to support the first point (just to illustrate these
changes are minor, others should be of similar extent, not properly tested
so use with caution).
Adding those features should allow to simply add a new table (allocated at
probe time for WO caching) with entries for most id14 controls. The only
part which seems more problematic is probably FU12 which looks like it
requires some custom logic and would still need actual code.
Happy to support a common driver activity and rename everything to audient
if you think this makes sense in order to reduce code size but no problem
if you think this is too complex to manage, up to you.
Christian
diff --git a/sound/usb/mixer_evo.c b/sound/usb/mixer_evo.c
index c327b82c8d2d..92f3c6d108a9 100644
--- a/sound/usb/mixer_evo.c
+++ b/sound/usb/mixer_evo.c
@@ -31,9 +31,13 @@ enum snd_evo_type {
SND_EVO_TYPE_NCTYPES
};
+#define SND_EVO_CTRL_FLAGS_SIGNED (1L<<0)
+#define SND_EVO_CTRL_FLAGS_INVERT (1L<<1)
+
static const struct snd_evo_ctrl_type {
snd_ctl_elem_type_t type;
- bool invert;
+ unsigned long width;
+ unsigned long flags;
union {
int integer;
} min;
@@ -45,6 +49,7 @@ static const struct snd_evo_ctrl_type {
} snd_evo_ctypes[SND_EVO_TYPE_NCTYPES] = {
[SND_EVO_TYPE_MONITOR] = {
.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+ .width = 2,
.min.integer = 0,
.max.integer = 127,
.wValue = 0x0000,
@@ -52,7 +57,7 @@ static const struct snd_evo_ctrl_type {
},
[SND_EVO_TYPE_PHANTOM] = {
.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
- .invert = false,
+ .width = 4,
.min.integer = 0,
.max.integer = 1,
.wValue = 0x0000,
@@ -60,7 +65,8 @@ static const struct snd_evo_ctrl_type {
},
[SND_EVO_TYPE_MUTE] = {
.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
- .invert = true,
+ .width = 4,
+ .flags = SND_EVO_CTRL_FLAGS_INVERT,
.min.integer = 0,
.max.integer = 1,
.wValue = 0x0200,
@@ -68,7 +74,8 @@ static const struct snd_evo_ctrl_type {
},
[SND_EVO_TYPE_MUTE_OUT] = {
.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
- .invert = true,
+ .width = 4,
+ .flags = SND_EVO_CTRL_FLAGS_INVERT,
.min.integer = 0,
.max.integer = 1,
.wValue = 0x0100,
@@ -76,6 +83,8 @@ static const struct snd_evo_ctrl_type {
},
[SND_EVO_TYPE_MIXER] = {
.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+ .width = 2,
+ .flags = SND_EVO_CTRL_FLAGS_SIGNED,
.min.integer = -128 * 256,
.max.integer = 6 * 256,
.wValue = 0x0100,
@@ -280,24 +289,24 @@ static int snd_ctl_evo_boolean_get(struct snd_kcontrol *kctl,
int i;
for (i = 0; i < hwchan; i++) {
- u32 buf;
+ u32 buf = 0;
int ret;
ret = snd_evo_get_cur(mixer, value + i, index,
- &buf, sizeof(buf));
+ &buf, ctype->width);
if (ret < 0)
return ret;
ctl_val->value.integer.value[i] = le32_to_cpu(buf) ? 1 : 0;
- if (ctype->invert)
+ if (ctype->flags & SND_EVO_CTRL_FLAGS_INVERT)
ctl_val->value.integer.value[i] ^= 0x1;
}
for (; i < nchan; i++)
- ctl_val->value.integer.value[i] = ctype->invert
- ? ctype->max.integer
- : ctype->min.integer;
+ ctl_val->value.integer.value[i]
+ = (ctype->flags & SND_EVO_CTRL_FLAGS_INVERT)
+ ? ctype->max.integer : ctype->min.integer;
return 0;
}
@@ -317,15 +326,15 @@ static int snd_ctl_evo_boolean_set(struct snd_kcontrol *kctl,
int i;
for (i = 0; i < hwchan; i++) {
- u32 rbuf;
+ u32 rbuf = 0;
u32 buf = cpu_to_le32(ctl_val->value.integer.value[i] ? 1 : 0);
int ret;
- if (ctype->invert)
+ if (ctype->flags & SND_EVO_CTRL_FLAGS_INVERT)
buf ^= 0x1;
ret = snd_evo_get_cur(mixer, value + i, index,
- &rbuf, sizeof(rbuf));
+ &rbuf, ctype->width);
if (ret < 0)
return ret;
@@ -333,7 +342,7 @@ static int snd_ctl_evo_boolean_set(struct snd_kcontrol *kctl,
changed = 1;
ret = snd_evo_set_cur(mixer, value + i, index,
- &buf, sizeof(buf));
+ &buf, ctype->width);
if (ret < 0)
return ret;
}
@@ -342,6 +351,19 @@ static int snd_ctl_evo_boolean_set(struct snd_kcontrol *kctl,
return changed;
}
+static inline long buf2cpu(const struct snd_evo_ctrl_type *const ctype, u32 in)
+{
+ const u32 u = le32_to_cpu(in);
+
+ if (ctype->flags & SND_EVO_CTRL_FLAGS_SIGNED) {
+ const int sh = 32 - ctype->width * 8;
+ const s32 s = u << sh;
+
+ return s >> sh;
+ } else
+ return u;
+}
+
static int snd_ctl_evo_integer_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ctl_val)
{
@@ -357,16 +379,16 @@ static int snd_ctl_evo_integer_get(struct snd_kcontrol *kctl,
int i;
for (i = 0; i < hwchan; i++) {
- u16 buf;
- s16 val;
+ u32 buf = 0;
+ s32 val;
int ret;
ret = snd_evo_get_cur(mixer, value + i, index,
- &buf, sizeof(buf));
+ &buf, ctype->width);
if (ret < 0)
return ret;
- val = le16_to_cpu(buf);
+ val = buf2cpu(ctype, buf);
ctl_val->value.integer.value[i] = val;
}
@@ -391,16 +413,16 @@ static int snd_ctl_evo_integer_set(struct snd_kcontrol *kctl,
int i;
for (i = 0; i < hwchan; i++) {
- s16 rbuf;
- s16 buf = cpu_to_le16(ctl_val->value.integer.value[i]);
+ s32 rbuf = 0;
+ s32 buf = cpu_to_le32(ctl_val->value.integer.value[i]);
int ret;
ret = snd_evo_get_cur(mixer, value + i, index,
- &rbuf, sizeof(rbuf));
+ &rbuf, ctype->width);
if (ret < 0)
return ret;
- if (rbuf != buf) {
+ if (buf2cpu(ctype, rbuf) != ctl_val->value.integer.value[i]) {
changed = 1;
ret = snd_evo_set_cur(mixer, value + i, index,
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 870 bytes --]
next prev parent reply other threads:[~2026-10-26 18:36 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-19 23:01 Will Porter
2026-10-19 23:01 ` [PATCH 1/5] ALSA: usb-audio: Give the Audient iD14 MkI its own mixer map Will Porter
2026-10-19 23:01 ` [PATCH 2/5] ALSA: usb-audio: Add Audient iD14 MkI monitor and routing controls Will Porter
2026-10-19 23:01 ` [PATCH 3/5] ALSA: usb-audio: Add Audient iD14 MkI mixer matrix Will Porter
2026-10-19 23:01 ` [PATCH 4/5] ALSA: usb-audio: Add Audient iD14 MkI write-only controls Will Porter
2026-10-19 23:01 ` [PATCH 5/5] ALSA: usb-audio: Replace the Audient iD14 MkI FU 12 control Will Porter
2026-10-20 13:10 ` [PATCH 0/5] ALSA: usb-audio: Audient iD14 MkI vendor controls Takashi Iwai
2026-10-26 18:36 ` Christian Ruppert [this message]
2026-10-26 21:44 ` Will Porter
2026-10-27 6:35 ` Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=at-dpPOGs2zD2fuL@khmer.arcnet \
--to=arc@gmx.li \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=mrwillporter@gmail.com \
--cc=neil@androos.io \
--cc=perex@perex.cz \
--cc=tiwai@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®