Skip to content

Commit 78e35b0

Browse files
fenugrectiwai
authored andcommitted
ALSA: usb-audio: clean up presonus s1810 consts
- Reorder some #define blocks - Document mixer/volume levels - Document some Ctl request fields (tag, len) - replace some magic numbers with macros No functional change intended. The information is based on reverse engineering. Signed-off-by: fenugrec <fenugrec@mail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20260111-preso_clean1-v2-2-44b4e5129a75@mail.com
1 parent 3ce0329 commit 78e35b0

1 file changed

Lines changed: 124 additions & 80 deletions

File tree

sound/usb/mixer_s1810c.c

Lines changed: 124 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@
2525
#include "helper.h"
2626
#include "mixer_s1810c.h"
2727

28-
#define SC1810C_CMD_REQ 160
29-
#define SC1810C_CMD_REQTYPE \
30-
(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT)
31-
#define SC1810C_CMD_F1 0x50617269
32-
#define SC1810C_CMD_F2 0x14
33-
3428
/*
3529
* DISCLAIMER: These are just guesses based on the
3630
* dumps I got.
@@ -42,9 +36,8 @@
4236
* * b selects an input channel (see below).
4337
* * c selects an output channel pair (see below).
4438
* * d selects left (0) or right (1) of that pair.
45-
* * e 0-> disconnect, 0x01000000-> connect,
46-
* 0x0109-> used for stereo-linking channels,
47-
* e is also used for setting volume levels
39+
* * e level : see MIXER_LEVEL_* defines below.
40+
* Also used for setting volume levels
4841
* in which case b is also set so I guess
4942
* this way it is possible to set the volume
5043
* level from the specified input to the
@@ -75,52 +68,98 @@
7568
* For output (0x65):
7669
* * b is the output channel (see above).
7770
* * c is zero.
78-
* * e I guess the same as with mixer except 0x0109
79-
* which I didn't see in my dumps.
71+
* * e I guess the same as with mixer
72+
*
73+
*/
74+
/** struct s1810c_ctl_packet - basic vendor request
75+
* @selector: device/mixer/output
76+
* @b: request-dependant field b
77+
* @tag: fixed value identifying type of request
78+
* @len: sizeof this struct - 8 (excludes first 2 fields)
79+
* i.e. for basic struct s1810c_ctl_packet: len is 5*4=0x14
80+
* @c: request-dependant field c
81+
* @d: request-dependant field d
82+
* @e: request-dependant field e
8083
*
81-
* The two fixed fields have the same values for
82-
* mixer and output but a different set for device.
84+
* See longer description above. This could be combined
85+
* (as a union?) with the longer struct s1810c_state_packet
8386
*/
8487
struct s1810c_ctl_packet {
85-
__le32 a;
88+
__le32 selector;
8689
__le32 b;
87-
__le32 fixed1;
88-
__le32 fixed2;
90+
__le32 tag;
91+
__le32 len;
8992
__le32 c;
9093
__le32 d;
9194
__le32 e;
9295
};
9396

97+
/** selectors for CMD request
98+
*/
99+
#define SC1810C_SEL_DEVICE 0
100+
#define SC1810C_SEL_MIXER 0x64
101+
#define SC1810C_SEL_OUTPUT 0x65
102+
103+
104+
/** control ids */
94105
#define SC1810C_CTL_LINE_SW 0
95106
#define SC1810C_CTL_MUTE_SW 1
96107
#define SC1824C_CTL_MONO_SW 2
97108
#define SC1810C_CTL_AB_SW 3
98109
#define SC1810C_CTL_48V_SW 4
99110

111+
/* USB Control (vendor) requests
112+
*/
113+
#define SC1810C_CMD_REQ 160
114+
#define SC1810C_CMD_REQTYPE \
115+
(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT)
116+
#define SC1810C_CMD_TAG 0x50617269
117+
#define SC1810C_CMD_LEN 0x14
118+
100119
#define SC1810C_SET_STATE_REQ 161
101120
#define SC1810C_SET_STATE_REQTYPE SC1810C_CMD_REQTYPE
102-
#define SC1810C_SET_STATE_F1 0x64656D73
103-
#define SC1810C_SET_STATE_F2 0xF4
121+
#define SC1810C_SET_STATE_TAG 0x64656D73
122+
#define SC1810C_SET_STATE_LEN 0xF4
104123

105124
#define SC1810C_GET_STATE_REQ 162
106125
#define SC1810C_GET_STATE_REQTYPE \
107126
(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN)
108-
#define SC1810C_GET_STATE_F1 SC1810C_SET_STATE_F1
109-
#define SC1810C_GET_STATE_F2 SC1810C_SET_STATE_F2
110-
111-
#define SC1810C_STATE_F1_IDX 2
112-
#define SC1810C_STATE_F2_IDX 3
127+
#define SC1810C_GET_STATE_TAG SC1810C_SET_STATE_TAG
128+
#define SC1810C_GET_STATE_LEN SC1810C_SET_STATE_LEN
129+
130+
/** Mixer levels normally range from 0 (off) to 0x0100 0000 (0 dB).
131+
* raw_level = 2^24 * 10^(db_level / 20), thus
132+
* -3dB = 0xb53bf0 (technically, half-power -3.01...dB would be 0xb504f3)
133+
* -96dB = 0x109
134+
* -99dB = 0xBC
135+
* PC software sliders cover -96 to +10dB (0x0329 8b08),
136+
* but the value 0 (-inf dB) can be used when e.g. Mixer Bypass is enabled.
137+
* Unclear what the hardware's maximum value is.
138+
*
139+
* Note, when a channel is panned to two channels (stereo),
140+
* the mixer level is set to slider value (by default -96dB) minus 3dB,
141+
* which explains the -99dB value seen in USB captures.
142+
*/
143+
#define MIXER_LEVEL_MUTE 0
144+
#define MIXER_LEVEL_N99DB 0xbc
145+
#define MIXER_LEVEL_N3DB 0xb53bf0
146+
#define MIXER_LEVEL_0DB 0x1000000
113147

114-
/*
148+
/**
115149
* This packet includes mixer volumes and
116150
* various other fields, it's an extended
117151
* version of ctl_packet, with a and b
118-
* being zero and different f1/f2.
152+
* being zero and different tag/length.
119153
*/
120154
struct s1810c_state_packet {
121155
__le32 fields[63];
122156
};
123157

158+
/** indices into s1810c_state_packet.fields[]
159+
*/
160+
#define SC1810C_STATE_TAG_IDX 2
161+
#define SC1810C_STATE_LEN_IDX 3
162+
124163
#define SC1810C_STATE_48V_SW 58
125164
#define SC1810C_STATE_LINE_SW 59
126165
#define SC1810C_STATE_MUTE_SW 60
@@ -134,16 +173,16 @@ struct s1810_mixer_state {
134173
};
135174

136175
static int
137-
snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 a,
176+
snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 sel,
138177
u32 b, u32 c, u32 d, u32 e)
139178
{
140179
struct s1810c_ctl_packet pkt = { 0 };
141180
int ret = 0;
142181

143-
pkt.fixed1 = __cpu_to_le32(SC1810C_CMD_F1);
144-
pkt.fixed2 = __cpu_to_le32(SC1810C_CMD_F2);
182+
pkt.tag = __cpu_to_le32(SC1810C_CMD_TAG);
183+
pkt.len = __cpu_to_le32(SC1810C_CMD_LEN);
145184

146-
pkt.a = __cpu_to_le32(a);
185+
pkt.selector = __cpu_to_le32(sel);
147186
pkt.b = __cpu_to_le32(b);
148187
pkt.c = __cpu_to_le32(c);
149188
pkt.d = __cpu_to_le32(d);
@@ -176,8 +215,8 @@ snd_sc1810c_get_status_field(struct usb_device *dev,
176215
struct s1810c_state_packet pkt_in = { { 0 } };
177216
int ret = 0;
178217

179-
pkt_out.fields[SC1810C_STATE_F1_IDX] = __cpu_to_le32(SC1810C_SET_STATE_F1);
180-
pkt_out.fields[SC1810C_STATE_F2_IDX] = __cpu_to_le32(SC1810C_SET_STATE_F2);
218+
pkt_out.fields[SC1810C_STATE_TAG_IDX] = __cpu_to_le32(SC1810C_SET_STATE_TAG);
219+
pkt_out.fields[SC1810C_STATE_LEN_IDX] = __cpu_to_le32(SC1810C_SET_STATE_LEN);
181220
ret = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
182221
SC1810C_SET_STATE_REQ,
183222
SC1810C_SET_STATE_REQTYPE,
@@ -216,8 +255,8 @@ static int snd_s1810c_init_mixer_maps(struct snd_usb_audio *chip)
216255
switch (chip->usb_id) {
217256
case USB_ID(0x194f, 0x010c): /* 1810c */
218257
/* Set initial volume levels ? */
219-
a = 0x64;
220-
e = 0xbc;
258+
a = SC1810C_SEL_MIXER;
259+
e = MIXER_LEVEL_N99DB;
221260
for (n = 0; n < 2; n++) {
222261
off = n * 18;
223262
for (b = off; b < 18 + off; b++) {
@@ -234,103 +273,102 @@ static int snd_s1810c_init_mixer_maps(struct snd_usb_audio *chip)
234273
* I noticed on UC that DAW channels have different
235274
* initial volumes, so this makes sense.
236275
*/
237-
e = 0xb53bf0;
276+
e = MIXER_LEVEL_N3DB;
238277
}
239278

240279
/* Connect analog outputs ? */
241-
a = 0x65;
242-
e = 0x01000000;
280+
a = SC1810C_SEL_OUTPUT;
243281
for (b = 1; b < 3; b++) {
244-
snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
245-
snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
282+
snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, MIXER_LEVEL_0DB);
283+
snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, MIXER_LEVEL_0DB);
246284
}
247-
snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, e);
248-
snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, e);
285+
snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, MIXER_LEVEL_0DB);
286+
snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, MIXER_LEVEL_0DB);
249287

250288
/* Set initial volume levels for S/PDIF mappings ? */
251-
a = 0x64;
252-
e = 0xbc;
289+
a = SC1810C_SEL_MIXER;
290+
e = MIXER_LEVEL_N99DB;
253291
c = 3;
254292
for (n = 0; n < 2; n++) {
255293
off = n * 18;
256294
for (b = off; b < 18 + off; b++) {
257295
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
258296
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
259297
}
260-
e = 0xb53bf0;
298+
e = MIXER_LEVEL_N3DB;
261299
}
262300

263301
/* Connect S/PDIF output ? */
264-
a = 0x65;
265-
e = 0x01000000;
266-
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
267-
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
302+
a = SC1810C_SEL_OUTPUT;
303+
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, MIXER_LEVEL_0DB);
304+
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, MIXER_LEVEL_0DB);
268305

269306
/* Connect all outputs (again) ? */
270-
a = 0x65;
271-
e = 0x01000000;
307+
a = SC1810C_SEL_OUTPUT;
272308
for (b = 0; b < 4; b++) {
273-
snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
274-
snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
309+
snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, MIXER_LEVEL_0DB);
310+
snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, MIXER_LEVEL_0DB);
275311
}
276312

277313
/* Basic routing to get sound out of the device */
278-
a = 0x64;
279-
e = 0x01000000;
314+
a = SC1810C_SEL_MIXER;
280315
for (c = 0; c < 4; c++) {
281316
for (b = 0; b < 36; b++) {
282317
if ((c == 0 && b == 18) || /* DAW1/2 -> Main */
283318
(c == 1 && b == 20) || /* DAW3/4 -> Line3/4 */
284319
(c == 2 && b == 22) || /* DAW4/5 -> Line5/6 */
285320
(c == 3 && b == 24)) { /* DAW5/6 -> S/PDIF */
286321
/* Left */
287-
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
288-
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
322+
snd_s1810c_send_ctl_packet(dev,
323+
a, b, c, 0, MIXER_LEVEL_0DB);
324+
snd_s1810c_send_ctl_packet(dev,
325+
a, b, c, 1, MIXER_LEVEL_MUTE);
289326
b++;
290327
/* Right */
291-
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
292-
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
328+
snd_s1810c_send_ctl_packet(dev,
329+
a, b, c, 0, MIXER_LEVEL_MUTE);
330+
snd_s1810c_send_ctl_packet(dev,
331+
a, b, c, 1, MIXER_LEVEL_0DB);
293332
} else {
294333
/* Leave the rest disconnected */
295-
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
296-
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
334+
snd_s1810c_send_ctl_packet(dev,
335+
a, b, c, 0, MIXER_LEVEL_MUTE);
336+
snd_s1810c_send_ctl_packet(dev,
337+
a, b, c, 1, MIXER_LEVEL_MUTE);
297338
}
298339
}
299340
}
300341

301342
/* Set initial volume levels for S/PDIF (again) ? */
302-
a = 0x64;
303-
e = 0xbc;
343+
a = SC1810C_SEL_MIXER;
344+
e = MIXER_LEVEL_N99DB;
304345
c = 3;
305346
for (n = 0; n < 2; n++) {
306347
off = n * 18;
307348
for (b = off; b < 18 + off; b++) {
308349
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
309350
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
310351
}
311-
e = 0xb53bf0;
352+
e = MIXER_LEVEL_N3DB;
312353
}
313354

314355
/* Connect S/PDIF outputs (again) ? */
315-
a = 0x65;
316-
e = 0x01000000;
317-
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
318-
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
356+
a = SC1810C_SEL_OUTPUT;
357+
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, MIXER_LEVEL_0DB);
358+
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, MIXER_LEVEL_0DB);
319359

320360
/* Again ? */
321-
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
322-
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
361+
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, MIXER_LEVEL_0DB);
362+
snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, MIXER_LEVEL_0DB);
323363
break;
324364

325365
case USB_ID(0x194f, 0x010d): /* 1824c */
326366
/* Set all output faders to unity gain */
327-
a = 0x65;
367+
a = SC1810C_SEL_OUTPUT;
328368
c = 0x00;
329-
e = 0x01000000;
330-
331369
for (b = 0; b < 9; b++) {
332-
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
333-
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
370+
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, MIXER_LEVEL_0DB);
371+
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, MIXER_LEVEL_0DB);
334372
}
335373

336374
/* Set
@@ -345,7 +383,7 @@ static int snd_s1810c_init_mixer_maps(struct snd_usb_audio *chip)
345383
* Daw 17 -> ADAT out 7, (left) Daw 18 -> ADAT out 8 (right)
346384
* Everything else muted
347385
*/
348-
a = 0x64;
386+
a = SC1810C_SEL_MIXER;
349387
/* The first Daw channel is channel 18 */
350388
left = 18;
351389

@@ -354,14 +392,20 @@ static int snd_s1810c_init_mixer_maps(struct snd_usb_audio *chip)
354392

355393
for (b = 0; b < 36; b++) {
356394
if (b == left) {
357-
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x01000000);
358-
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x00);
395+
snd_s1810c_send_ctl_packet(dev,
396+
a, b, c, 0, MIXER_LEVEL_0DB);
397+
snd_s1810c_send_ctl_packet(dev,
398+
a, b, c, 1, MIXER_LEVEL_MUTE);
359399
} else if (b == right) {
360-
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x00);
361-
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x01000000);
400+
snd_s1810c_send_ctl_packet(dev,
401+
a, b, c, 0, MIXER_LEVEL_MUTE);
402+
snd_s1810c_send_ctl_packet(dev,
403+
a, b, c, 1, MIXER_LEVEL_0DB);
362404
} else {
363-
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x00);
364-
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x00);
405+
snd_s1810c_send_ctl_packet(dev,
406+
a, b, c, 0, MIXER_LEVEL_MUTE);
407+
snd_s1810c_send_ctl_packet(dev,
408+
a, b, c, 1, MIXER_LEVEL_MUTE);
365409
}
366410
}
367411
left += 2;

0 commit comments

Comments
 (0)