Re: [PATCH 0/5] ALSA: usb-audio: Audient iD14 MkI vendor controls
From: Will Porter
Date: Mon Oct 26 2026 - 17:46:01 EST
Hi Christian,
On Mon, Oct 26, 2026 at 07:36:24PM +0100, Christian Ruppert wrote:
> 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
Thanks for looking into this so closely, and for the fixes. I like
the idea of one driver, and I'd like to find out whether the iD line fits.
Your TLV in patch 4/4 is the same one I use for the iD14 matrix: same
unit 0x3C, s16 in 1/256 dB, -128 to +6 dB. That made me wonder whether
the iD14 matrix could use your MIXER type almost as it is. Its channel
number is input * 4 + output, so Main L/R and Cue L/R of each input
are adjacent, like your stereo pairs. Could we expose it as 28
controls with two values each, rather than my 56 single-value ones?
An input's level and pan in a mix set its L and R values together,
so a pair seems a natural fit. Does that look right to you?
> The only part which seems more problematic is probably FU12 which looks
> like it requires some custom logic and would still need actual code.
Agreed. I'd keep FU 12 as its own code.
A few questions about the rest:
1. Read before write. As I understand it, the put handlers in
mixer_evo.c read the value first to see if it changed. On the iD14,
GET stalls for mic boost, input polarity, optical mode and the iD
key function, so a put that reads first would fail there. Talkback
source always reads 0, so a read would hide real changes. Could
these write-only controls skip GET in both get and put, with get
returning the cached value? And could every put still send the
value, even when it matches the cache, so that "alsactl restore"
reaches a device that was reset?
2. The cache. My driver writes a known value at probe (off or none,
and for optical mode its measured power-on mode, S/PDIF) and
updates the cache only after a full-length write. If the probe
write fails, an enum reads "Unknown" and a switch reads off. Would
that approach work for you?
3. Control entries. The iD14 table uses 16 unit/selector pairs and
explicit control names, such as "Main Out L Source Playback Enum".
It also needs volumes in 1 dB steps (0..128, stored as s16
1/256 dB), a boost switch that writes 0x0a00 for on, and enums
that map items to device values, plus an "Other" item that only
get reports, for values outside the list. Would it make sense to
move the unit, selector and an optional full name into each control
entry, and add the new value formats (1 dB volumes, boost, enum)
as ctypes? Or would you structure it differently?
4. Checks. My helper returns -EIO on a short read or write, before
it decodes a value or updates the cache. My matrix put also rejects
values outside -128..+6 dB, and get clamps what it reads back.
Could the shared code keep these checks?
I don't have a firm view yet on which way is better. If the iD14
fits the table without many special cases, one driver seems clearly
worth it. If it needs a lot of per-device branches, two smaller files
might be easier to read and review. What do you think, now that you
have seen what the iD14 needs?
If we do combine them, the order I imagined is: your four fixes first,
then the rename to Audient, then the generic changes, then the iD14
tables on top as v2 of my series.
In that case, would you prefer to do the rename and the generic part
yourself? The rename would also touch MAINTAINERS; how would you like
to handle review of the iD14 parts? I can write the iD14 parts and
test them on my MkI. I don't have an EVO 4, so would you be able to
test that side? And which base should I work against, sound for-next
once your fixes are in? I'm also not sure how a combined change
should reach Takashi: as one series, or as two with a stated
dependency.
Thanks,
Will