From: Will Porter <mrwillporter@gmail.com>
To: Christian Ruppert <arc@gmx.li>
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: [RFC PATCH 15/16] ALSA: mixer_audient: Add Audient iD14 MkI controls
Date: Fri, 6 Nov 2026 10:31:28 -0600 [thread overview]
Message-ID: <20261106163129.1006907-16-mrwillporter@gmail.com> (raw)
In-Reply-To: <20261106163129.1006907-1-mrwillporter@gmail.com>
The iD14 MkI (2708:0002) has its monitor controller on extension unit
54 and its output routing on extension unit 51. The headphone level is
on feature unit 10 (CN 3-4, which the descriptor does not declare).
The mixer is mixer unit 60. The generic driver cannot find the vendor
controls and creates wrong controls for mixer unit 60 and feature unit
11. Add the MkI as a device with these tables. Apart from the tables
and their macros, the patch adds the device ID, its case in
mixer_quirks.c and the map entries that hide the generic controls.
Monitor and routing controls: speaker volume, cut, dim, dim level,
mono, mono mode, polarity, talkback, headphone volume and mute, and
one routing selector per output channel. All of them read the device
on every get: the front panel knob changes the volumes and the cut and
mute states.
The volumes are s16 values in 1/256 dB from -128 to 0 dB, in the 1 dB
steps of the knob. -128 dB does not mute the headphones, so the TLV
does not declare a mute.
DAW Thru plays the USB stream past the monitor controller, so the main
output selectors name it "DAW Thru (full scale)". The headphone volume
and mute still act on every headphone source, so the headphone
selectors name it "DAW Thru".
Mixer matrix: mixer unit 60 mixes 14 inputs (Mic 1-2, Digi 1-8, DAW
1-4) into four outputs (Main L/R, Cue L/R), CN = input * 4 + output.
GET RANGE reports -127 to 0 dB in 1 dB steps, so the generic driver
creates four "Analogue 4 Volume" controls with values from 0 to 127.
The crosspoints take -128 dB (mute) to +6 dB in 1/256 dB steps, as on
the EVO4, so they use the same control type. Add one stereo control
per input and output pair: "Mix Main <input> Playback Volume" and "Mix
Cue <input> Playback Volume". Hide the generic controls in the MkI
map. The driver reads each crosspoint at probe and writes nothing to
the mixer.
Write-only controls: some MkI controls cannot be read back:
- GET stalls for the input gain boost and polarity (feature unit 11),
the iD key function and the digital input mode.
- GET of the talkback source answers 0, whatever value a SET wrote.
For FU 11 the generic driver creates "Input Gain Control" and "Phase
Inverter Control" and logs "cannot get min/max values". Add:
- Mic 1/2 Boost Capture Switch (+10 dB)
- Mic 1/2 and Digi 1/2 Polarity Invert Capture Switch
- iD Key Function Playback Enum (ScrollControl, Mono, Mono + Polarity,
Dim, Talkback)
- Talkback Source Capture Enum (None, Mic 1-2, Digi 1-8)
- Digital In Mode Capture Enum (ADAT, S/PDIF)
and hide the generic FU 11 controls in the MkI map. The device refuses
polarity on Digi 3-8 with EPIPE, in ADAT and in S/PDIF mode, so Digi
3-8 have no polarity control.
These controls use the cache, init and force-set flags: they show the
last value written, every put sends its value, and the probe writes
each one once so that the value shown is true:
- boost and polarity off, iD key ScrollControl, talkback source None
- S/PDIF: the MkI's measured power-on mode
If a probe write fails, the card still registers: the control shows
"Unknown" (or off) until a put succeeds.
The probe write replaces any value the device kept. On mains power the
device keeps its values across a replug, so the controls return to the
probe values until alsactl restore runs.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Will Porter <mrwillporter@gmail.com>
---
sound/usb/mixer_audient.c | 313 ++++++++++++++++++++++++++++++++++++++
sound/usb/mixer_audient.h | 1 +
sound/usb/mixer_maps.c | 2 +
sound/usb/mixer_quirks.c | 3 +
4 files changed, 319 insertions(+)
diff --git a/sound/usb/mixer_audient.c b/sound/usb/mixer_audient.c
index 3e6cd8981b4f..ad39d17c0b5e 100644
--- a/sound/usb/mixer_audient.c
+++ b/sound/usb/mixer_audient.c
@@ -3,6 +3,10 @@
* Audient driver for ALSA
* Copyright (C) 2026 Christian Ruppert <arc@gmx.li>
*
+ * Supported models: EVO4 (2708:0006), iD14 MkI (2708:0002).
+ * The iD14 MkII and other iD models keep the generic driver: their units
+ * may differ.
+ *
* EVO4 support is based on the work of Ivan Hazucha for audient-evo-py.
* https://github.com/vanzaho/audient-evo-py/
*/
@@ -10,6 +14,7 @@
#include <asm/byteorder.h>
#include <linux/usb.h>
+#include <linux/usb/audio.h>
#include <linux/usb/audio-v2.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -31,6 +36,25 @@ enum snd_audient_type {
SND_AUDIENT_TYPE_MUTE,
SND_AUDIENT_TYPE_MUTE_OUT,
SND_AUDIENT_TYPE_MIXER,
+ SND_AUDIENT_TYPE_ID14_MON_VOLUME,
+ SND_AUDIENT_TYPE_ID14_MON_CUT,
+ SND_AUDIENT_TYPE_ID14_MON_DIM,
+ SND_AUDIENT_TYPE_ID14_MON_DIM_LEVEL,
+ SND_AUDIENT_TYPE_ID14_MON_MONO,
+ SND_AUDIENT_TYPE_ID14_MON_MONO_MODE,
+ SND_AUDIENT_TYPE_ID14_MON_POLARITY,
+ SND_AUDIENT_TYPE_ID14_MON_TALKBACK,
+ SND_AUDIENT_TYPE_ID14_HP_VOLUME,
+ SND_AUDIENT_TYPE_ID14_HP_MUTE,
+ SND_AUDIENT_TYPE_ID14_ROUTE_MAIN_L,
+ SND_AUDIENT_TYPE_ID14_ROUTE_MAIN_R,
+ SND_AUDIENT_TYPE_ID14_ROUTE_HP_L,
+ SND_AUDIENT_TYPE_ID14_ROUTE_HP_R,
+ SND_AUDIENT_TYPE_ID14_IN_BOOST,
+ SND_AUDIENT_TYPE_ID14_IN_POLARITY,
+ SND_AUDIENT_TYPE_ID14_MON_ID_KEY,
+ SND_AUDIENT_TYPE_ID14_MON_TALKBACK_SRC,
+ SND_AUDIENT_TYPE_ID14_OPTICAL_MODE,
SND_AUDIENT_TYPE_NCTYPES
};
@@ -63,6 +87,151 @@ struct snd_audient_enum {
}; \
static_assert(ARRAY_SIZE(texts_) == ARRAY_SIZE(name##_values) + 1)
+/*
+ * iD14 MkI units. The monitor controller, output routing, headphone level,
+ * input options and the mixer sit on extension units and on feature units
+ * whose descriptors declare no controls; the generic driver cannot find them.
+ */
+#define ID14_IT_DIGITAL 0x01 /* input terminal: optical and coaxial */
+#define ID14_FU_OUT 0x0a /* before the outputs: CN 3-4 headphones */
+#define ID14_FU_IN 0x0b /* inputs: CN 1-2 Mic, 3-10 Digi */
+#define ID14_FU_MIX 0x0c /* after the mixer: CN 1-2 Main, 3-4 Cue */
+#define ID14_ROUTE 0x33 /* routing XU: CN = destination */
+#define ID14_MON 0x36 /* monitor controller XU */
+
+/* Monitor controller selectors */
+#define ID14_MON_MONO 0x00
+#define ID14_MON_MONO_MODE 0x01
+#define ID14_MON_POLARITY 0x03
+#define ID14_MON_CUT 0x04
+#define ID14_MON_DIM 0x05
+#define ID14_MON_DIM_LEVEL 0x06 /* s16, 1/256 dB */
+#define ID14_MON_TALKBACK 0x07
+#define ID14_MON_TALKBACK_SRC 0x08 /* GET always returns 0 */
+#define ID14_MON_ID_KEY 0x10 /* u16: the selector the iD key toggles */
+#define ID14_MON_VOLUME 0x12 /* s16, 1/256 dB; the knob also sets it */
+
+#define ID14_IN_BOOST 0x0b /* s16: 0x0a00 = +10 dB, 0 = off */
+#define ID14_IN_POLARITY 0x0d
+#define ID14_IT_OPTICAL_MODE 0x00 /* u32: 0 ADAT, 1 S/PDIF */
+
+#define ID14_ROUTE_SOURCE 0x06 /* u8: source of the destination */
+
+/*
+ * iD14 volumes: s16 in 1/256 dB, -128 ... 0 dB, in the 1 dB steps of the
+ * front panel knob. Control value 0 is -128 dB, 128 is 0 dB. -128 dB is not
+ * a mute: on the headphones the level stops falling at a small residual.
+ */
+static const DECLARE_TLV_DB_SCALE(snd_audient_tlv_id14_vol, -12800, 100, 0);
+
+/* Mono mode: one-speaker sum (Left, Right) or phantom centre */
+static const char *const snd_audient_id14_mono_mode_texts[] = {
+ "Left", "Centre", "Right", "Other",
+};
+SND_AUDIENT_ENUM(snd_audient_id14_mono_mode,
+ snd_audient_id14_mono_mode_texts, 1, 0, 2);
+
+/*
+ * Output routing. Main Mix is 0x14/0x15 on the main outputs and 0x18/0x19
+ * on the headphones; DAW Thru on destination n plays DAW n + 1. DAW Thru
+ * bypasses the monitor controller (speaker volume, cut and dim), so the
+ * main outputs play the USB stream at full scale. The headphone volume and
+ * mute still act on every headphone source.
+ */
+static const char *const snd_audient_id14_route_main_texts[] = {
+ "Main Mix", "Cue Mix", "DAW Thru (full scale)", "Other",
+};
+static const char *const snd_audient_id14_route_hp_texts[] = {
+ "Main Mix", "Cue Mix", "DAW Thru", "Other",
+};
+SND_AUDIENT_ENUM(snd_audient_id14_route_main_l,
+ snd_audient_id14_route_main_texts, 0x14, 0x10, 0x00);
+SND_AUDIENT_ENUM(snd_audient_id14_route_main_r,
+ snd_audient_id14_route_main_texts, 0x15, 0x11, 0x01);
+SND_AUDIENT_ENUM(snd_audient_id14_route_hp_l,
+ snd_audient_id14_route_hp_texts, 0x18, 0x10, 0x02);
+SND_AUDIENT_ENUM(snd_audient_id14_route_hp_r,
+ snd_audient_id14_route_hp_texts, 0x19, 0x11, 0x03);
+
+/*
+ * iD key function: the value is the monitor controller selector the key
+ * toggles. ScrollControl (0xffff) toggles nothing: the knob then scrolls
+ * through the HID interface. The last item of a write-only enum shows a
+ * value that is not known.
+ */
+static const char *const snd_audient_id14_id_key_texts[] = {
+ "ScrollControl", "Mono", "Mono + Polarity", "Dim", "Talkback",
+ "Unknown",
+};
+SND_AUDIENT_ENUM(snd_audient_id14_id_key, snd_audient_id14_id_key_texts,
+ 0xffff, ID14_MON_MONO, ID14_MON_POLARITY, ID14_MON_DIM,
+ ID14_MON_TALKBACK);
+
+/* Talkback source: the routing source number of the input; none = 0xff */
+static const char *const snd_audient_id14_talkback_texts[] = {
+ "None", "Mic 1", "Mic 2", "Digi 1", "Digi 2", "Digi 3", "Digi 4",
+ "Digi 5", "Digi 6", "Digi 7", "Digi 8", "Unknown",
+};
+SND_AUDIENT_ENUM(snd_audient_id14_talkback, snd_audient_id14_talkback_texts,
+ 0xff, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+
+static const char *const snd_audient_id14_optical_texts[] = {
+ "ADAT", "S/PDIF", "Unknown",
+};
+SND_AUDIENT_ENUM(snd_audient_id14_optical, snd_audient_id14_optical_texts,
+ 0, 1);
+
+/*
+ * Write-only: GET stalls or does not report writes. Show the last value
+ * written, write the init value at probe, and send every put.
+ */
+#define ID14_WO (SND_AUDIENT_CTYPE_FLAGS_CACHE \
+ | SND_AUDIENT_CTYPE_FLAGS_FORCE_SET \
+ | SND_AUDIENT_CTYPE_FLAGS_INIT_HW)
+
+#define ID14_BOOL(unit_, sel_) \
+ { \
+ .type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, \
+ .len = 1, \
+ .min.integer = 0, \
+ .max.integer = 1, \
+ .unit = (unit_), \
+ .sel = (sel_), \
+ }
+
+/* 1 = cut or mute: shown as a switch that is off */
+#define ID14_BOOL_INV(unit_, sel_) \
+ { \
+ .type = SNDRV_CTL_ELEM_TYPE_BOOLEAN, \
+ .len = 1, \
+ .min.integer = 1, \
+ .max.integer = 0, \
+ .unit = (unit_), \
+ .sel = (sel_), \
+ }
+
+#define ID14_VOLUME(unit_, sel_) \
+ { \
+ .type = SNDRV_CTL_ELEM_TYPE_INTEGER, \
+ .flags = SND_AUDIENT_CTYPE_FLAGS_SIGNED, \
+ .len = 2, \
+ .min.integer = -128 * 256, \
+ .max.integer = 0, \
+ .res = 256, \
+ .tlv = snd_audient_tlv_id14_vol, \
+ .unit = (unit_), \
+ .sel = (sel_), \
+ }
+
+#define ID14_ENUM(unit_, sel_, len_, enum_) \
+ { \
+ .type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, \
+ .len = (len_), \
+ .enumeration = &(enum_), \
+ .unit = (unit_), \
+ .sel = (sel_), \
+ }
+
static const struct snd_audient_ctrl_type {
snd_ctl_elem_type_t type;
unsigned long flags;
@@ -124,6 +293,88 @@ static const struct snd_audient_ctrl_type {
.sel = 0x01,
.tlv = snd_audient_tlv_mixer,
},
+ [SND_AUDIENT_TYPE_ID14_MON_VOLUME] =
+ ID14_VOLUME(ID14_MON, ID14_MON_VOLUME),
+ [SND_AUDIENT_TYPE_ID14_MON_CUT] =
+ ID14_BOOL_INV(ID14_MON, ID14_MON_CUT),
+ [SND_AUDIENT_TYPE_ID14_MON_DIM] =
+ ID14_BOOL(ID14_MON, ID14_MON_DIM),
+ [SND_AUDIENT_TYPE_ID14_MON_DIM_LEVEL] =
+ ID14_VOLUME(ID14_MON, ID14_MON_DIM_LEVEL),
+ [SND_AUDIENT_TYPE_ID14_MON_MONO] =
+ ID14_BOOL(ID14_MON, ID14_MON_MONO),
+ [SND_AUDIENT_TYPE_ID14_MON_MONO_MODE] =
+ ID14_ENUM(ID14_MON, ID14_MON_MONO_MODE, 1,
+ snd_audient_id14_mono_mode),
+ [SND_AUDIENT_TYPE_ID14_MON_POLARITY] =
+ ID14_BOOL(ID14_MON, ID14_MON_POLARITY),
+ [SND_AUDIENT_TYPE_ID14_MON_TALKBACK] =
+ ID14_BOOL(ID14_MON, ID14_MON_TALKBACK),
+ [SND_AUDIENT_TYPE_ID14_HP_VOLUME] =
+ ID14_VOLUME(ID14_FU_OUT, UAC_FU_VOLUME),
+ [SND_AUDIENT_TYPE_ID14_HP_MUTE] =
+ ID14_BOOL_INV(ID14_FU_OUT, UAC_FU_MUTE),
+ [SND_AUDIENT_TYPE_ID14_ROUTE_MAIN_L] =
+ ID14_ENUM(ID14_ROUTE, ID14_ROUTE_SOURCE, 1,
+ snd_audient_id14_route_main_l),
+ [SND_AUDIENT_TYPE_ID14_ROUTE_MAIN_R] =
+ ID14_ENUM(ID14_ROUTE, ID14_ROUTE_SOURCE, 1,
+ snd_audient_id14_route_main_r),
+ [SND_AUDIENT_TYPE_ID14_ROUTE_HP_L] =
+ ID14_ENUM(ID14_ROUTE, ID14_ROUTE_SOURCE, 1,
+ snd_audient_id14_route_hp_l),
+ [SND_AUDIENT_TYPE_ID14_ROUTE_HP_R] =
+ ID14_ENUM(ID14_ROUTE, ID14_ROUTE_SOURCE, 1,
+ snd_audient_id14_route_hp_r),
+ /* the documented boost is a fixed +10 dB */
+ [SND_AUDIENT_TYPE_ID14_IN_BOOST] = {
+ .type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+ .flags = ID14_WO,
+ .len = 2,
+ .min.integer = 0,
+ .max.integer = 10 * 256,
+ .init = 0,
+ .unit = ID14_FU_IN,
+ .sel = ID14_IN_BOOST,
+ },
+ [SND_AUDIENT_TYPE_ID14_IN_POLARITY] = {
+ .type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+ .flags = ID14_WO,
+ .len = 1,
+ .min.integer = 0,
+ .max.integer = 1,
+ .init = 0,
+ .unit = ID14_FU_IN,
+ .sel = ID14_IN_POLARITY,
+ },
+ [SND_AUDIENT_TYPE_ID14_MON_ID_KEY] = {
+ .type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+ .flags = ID14_WO,
+ .len = 2,
+ .init = 0xffff, /* ScrollControl */
+ .enumeration = &snd_audient_id14_id_key,
+ .unit = ID14_MON,
+ .sel = ID14_MON_ID_KEY,
+ },
+ [SND_AUDIENT_TYPE_ID14_MON_TALKBACK_SRC] = {
+ .type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+ .flags = ID14_WO,
+ .len = 1,
+ .init = 0xff, /* None */
+ .enumeration = &snd_audient_id14_talkback,
+ .unit = ID14_MON,
+ .sel = ID14_MON_TALKBACK_SRC,
+ },
+ /* the power-on mode is S/PDIF */
+ [SND_AUDIENT_TYPE_ID14_OPTICAL_MODE] = {
+ .type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+ .flags = ID14_WO,
+ .len = 4,
+ .init = 1, /* S/PDIF */
+ .enumeration = &snd_audient_id14_optical,
+ .unit = ID14_IT_DIGITAL,
+ .sel = ID14_IT_OPTICAL_MODE,
+ },
};
@@ -184,6 +435,62 @@ static const char *const snd_audient_evo4_matrix[] = {
NULL
};
+#define ID14_CTRL(name_, type_, offs_, chans_) \
+ { \
+ .name = (name_), \
+ .type = SND_AUDIENT_TYPE_ID14_##type_, \
+ .channels = (chans_), \
+ .hwchannels = (chans_), \
+ .val_offs = (offs_), \
+ }
+
+static const struct snd_audient_ctrl snd_audient_id14_mk1_controls[] = {
+ ID14_CTRL("Monitor Speaker Playback Volume", MON_VOLUME, 0, 1),
+ ID14_CTRL("Monitor Speaker Playback Switch", MON_CUT, 0, 1),
+ ID14_CTRL("Monitor Dim Playback Switch", MON_DIM, 0, 1),
+ ID14_CTRL("Monitor Dim Level Playback Volume", MON_DIM_LEVEL, 0, 1),
+ ID14_CTRL("Monitor Mono Playback Switch", MON_MONO, 0, 1),
+ ID14_CTRL("Monitor Mono Mode Playback Enum", MON_MONO_MODE, 0, 1),
+ ID14_CTRL("Monitor Polarity Invert Playback Switch", MON_POLARITY, 0, 1),
+ ID14_CTRL("Monitor Headphone Playback Volume", HP_VOLUME, 3, 2),
+ ID14_CTRL("Monitor Headphone Playback Switch", HP_MUTE, 3, 2),
+ ID14_CTRL("Talkback Playback Switch", MON_TALKBACK, 0, 1),
+ ID14_CTRL("Main Out L Source Playback Enum", ROUTE_MAIN_L, 0, 1),
+ ID14_CTRL("Main Out R Source Playback Enum", ROUTE_MAIN_R, 1, 1),
+ ID14_CTRL("Headphone L Source Playback Enum", ROUTE_HP_L, 2, 1),
+ ID14_CTRL("Headphone R Source Playback Enum", ROUTE_HP_R, 3, 1),
+ ID14_CTRL("Mic 1 Boost Capture Switch", IN_BOOST, 1, 1),
+ ID14_CTRL("Mic 2 Boost Capture Switch", IN_BOOST, 2, 1),
+ ID14_CTRL("Mic 1 Polarity Invert Capture Switch", IN_POLARITY, 1, 1),
+ ID14_CTRL("Mic 2 Polarity Invert Capture Switch", IN_POLARITY, 2, 1),
+ /* Digi 3-8 refuse polarity (CN 5-10 stall) */
+ ID14_CTRL("Digi 1 Polarity Invert Capture Switch", IN_POLARITY, 3, 1),
+ ID14_CTRL("Digi 2 Polarity Invert Capture Switch", IN_POLARITY, 4, 1),
+ ID14_CTRL("iD Key Function Playback Enum", MON_ID_KEY, 0, 1),
+ ID14_CTRL("Talkback Source Capture Enum", MON_TALKBACK_SRC, 0, 1),
+ ID14_CTRL("Digital In Mode Capture Enum", OPTICAL_MODE, 0, 1),
+ { 0 }, /* sentinel */
+};
+
+/*
+ * iD14 MkI mixer: unit 60, 14 inputs x 4 outputs, CN = input * 4 + output
+ * (outputs Main L, Main R, Cue L, Cue R). Each input has a Main and a Cue
+ * pair, so with 2 channels per element, element n starts at CN 2 * n.
+ */
+#define ID14_MIX(in) "Mix Main " in " Playback Volume", \
+ "Mix Cue " in " Playback Volume"
+
+static const char *const snd_audient_id14_mk1_matrix[] = {
+ ID14_MIX("Mic 1"), ID14_MIX("Mic 2"),
+ ID14_MIX("Digi 1"), ID14_MIX("Digi 2"),
+ ID14_MIX("Digi 3"), ID14_MIX("Digi 4"),
+ ID14_MIX("Digi 5"), ID14_MIX("Digi 6"),
+ ID14_MIX("Digi 7"), ID14_MIX("Digi 8"),
+ ID14_MIX("DAW 1"), ID14_MIX("DAW 2"),
+ ID14_MIX("DAW 3"), ID14_MIX("DAW 4"),
+ NULL
+};
+
static const struct audient_devinfo {
u32 usb_id;
const struct snd_audient_ctrl *controls;
@@ -196,6 +503,12 @@ static const struct audient_devinfo {
.matrix_names = snd_audient_evo4_matrix,
.matrix_channels = 2,
},
+ {
+ .usb_id = USB_ID(USB_AUDIENT_VID, USB_ID14_MK1_PID),
+ .controls = snd_audient_id14_mk1_controls,
+ .matrix_names = snd_audient_id14_mk1_matrix,
+ .matrix_channels = 2,
+ },
{ 0 } /* sentinel */
};
diff --git a/sound/usb/mixer_audient.h b/sound/usb/mixer_audient.h
index db4f31e02b5e..5d705ffe2cfa 100644
--- a/sound/usb/mixer_audient.h
+++ b/sound/usb/mixer_audient.h
@@ -6,6 +6,7 @@
#define USB_AUDIENT_VID (0x2708)
#define USB_EVO4_PID (0x0006)
+#define USB_ID14_MK1_PID (0x0002)
int snd_audient_controls_create(struct usb_mixer_interface *mixer);
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
index 7795a5fbe382..30673bbbf762 100644
--- a/sound/usb/mixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -528,7 +528,9 @@ static const struct usbmix_name_map audient_id14_map[] = {
/* Audient iD14 MkI: model-specific control map. */
static const struct usbmix_name_map audient_id14_mk1_map[] = {
+ { 11, NULL }, /* FU, see mixer_audient.c */
{ 12, "Monitor Mix Playback" }, /* FU, partial coverage */
+ { 60, NULL }, /* MU, see mixer_audient.c */
{}
};
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index af53c5c20e65..41d559d639d2 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -4543,6 +4543,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
case USB_ID(USB_AUDIENT_VID, USB_EVO4_PID): /* Audient EVO 4 */
err = snd_audient_controls_create(mixer);
break;
+ case USB_ID(USB_AUDIENT_VID, USB_ID14_MK1_PID): /* Audient iD14 MkI */
+ err = snd_audient_controls_create(mixer);
+ break;
case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */
err = snd_soundblaster_e1_switch_create(mixer);
--
2.47.3
next prev parent reply other threads:[~2026-11-06 16:32 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-19 23:01 [PATCH 0/5] ALSA: usb-audio: Audient iD14 MkI vendor controls 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
2026-10-26 21:44 ` Will Porter
2026-10-27 6:35 ` Takashi Iwai
2026-10-27 23:21 ` Christian Ruppert
2026-10-28 2:36 ` Will Porter
2026-11-01 0:00 ` [RFC PATCH 00/11] " Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 01/11] ALSA: rename mixer_evo to mixer_audient Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 02/11] ALSA: mixer_audient: explicitly define full control names Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 03/11] ALSA: mixer_audient: clarify USB control message definition Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 04/11] ALSA: mixer_audient: Add length check to USB transfer Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 05/11] ALSA: mixer_audient: make USB control transfer size configurable Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 06/11] ALSA: mixer_audient: Allow arbitrary boolean control values Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 07/11] ALSA: mixer_audient: Add integer range checks Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 08/11] ALSA: mixer_audient: Add control initialization at probe Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 09/11] ALSA: mixer_audient: Add readback-free parameter set Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 10/11] ALSA: mixer_audient: add control value caching Christian Ruppert
2026-11-01 0:00 ` [RFC PATCH 11/11] ALSA: mixer_audient: Create matrix programmatically Christian Ruppert
2026-11-01 17:35 ` [RFC PATCH 00/11] Re: ALSA: usb-audio: Audient iD14 MkI vendor controls Will Porter
2026-11-02 0:32 ` [RFC V2 PATCH 00/11] Re: ALSA: usb-audio: Audient iD14 MkI vendor Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 01/11] ALSA: rename mixer_evo to mixer_audient Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 02/11] ALSA: mixer_audient: explicitly define full control names Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 03/11] ALSA: mixer_audient: clarify USB control message definition Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 04/11] ALSA: mixer_audient: Add length check to USB transfer Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 05/11] ALSA: mixer_audient: make USB control transfer size configurable Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 06/11] ALSA: mixer_audient: Allow arbitrary boolean control values Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 07/11] ALSA: mixer_audient: Add integer range checks Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 08/11] ALSA: mixer_audient: Add control initialization at probe Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 09/11] ALSA: mixer_audient: Add readback-free parameter set Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 10/11] ALSA: mixer_audient: add control value caching Christian Ruppert
2026-11-02 0:32 ` [RFC V2 PATCH 11/11] ALSA: mixer_audient: Create matrix programmatically Christian Ruppert
2026-11-03 2:45 ` [RFC V2 PATCH 00/11] Re: ALSA: usb-audio: Audient iD14 MkI vendor Will Porter
2026-11-03 23:01 ` Christian Ruppert
2026-11-06 16:31 ` [RFC PATCH 00/16] ALSA: usb-audio: Audient driver and iD14 MkI support Will Porter
2026-11-06 16:31 ` [RFC PATCH 01/16] ALSA: rename mixer_evo to mixer_audient Will Porter
2026-11-06 16:31 ` [RFC PATCH 02/16] ALSA: mixer_audient: explicitly define full control names Will Porter
2026-11-06 16:31 ` [RFC PATCH 03/16] ALSA: mixer_audient: clarify USB control message definition Will Porter
2026-11-06 16:31 ` [RFC PATCH 04/16] ALSA: mixer_audient: Add length check to USB transfer Will Porter
2026-11-06 16:31 ` [RFC PATCH 05/16] ALSA: mixer_audient: make USB control transfer size configurable Will Porter
2026-11-06 16:31 ` [RFC PATCH 06/16] ALSA: mixer_audient: Allow arbitrary boolean control values Will Porter
2026-11-06 16:31 ` [RFC PATCH 07/16] ALSA: mixer_audient: Add integer range checks Will Porter
2026-11-06 16:31 ` [RFC PATCH 08/16] ALSA: mixer_audient: Add control initialization at probe Will Porter
2026-11-06 16:31 ` [RFC PATCH 09/16] ALSA: mixer_audient: Add readback-free parameter set Will Porter
2026-11-06 16:31 ` [RFC PATCH 10/16] ALSA: mixer_audient: add control value caching Will Porter
2026-11-06 16:31 ` [RFC PATCH 11/16] ALSA: mixer_audient: Create matrix programmatically Will Porter
2026-11-06 16:31 ` [RFC PATCH 12/16] ALSA: mixer_audient: Add a step size to integer controls Will Porter
2026-11-06 16:31 ` [RFC PATCH 13/16] ALSA: mixer_audient: Add enumerated controls Will Porter
2026-11-06 16:31 ` [RFC PATCH 14/16] ALSA: usb-audio: Give the Audient iD14 MkI its own mixer map Will Porter
2026-11-06 16:31 ` Will Porter [this message]
2026-11-06 16:31 ` [RFC PATCH 16/16] ALSA: mixer_audient: Replace the Audient iD14 MkI FU 12 control Will Porter
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=20261106163129.1006907-16-mrwillporter@gmail.com \
--to=mrwillporter@gmail.com \
--cc=arc@gmx.li \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--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®