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.
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
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 */
8487struct 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 */
120154struct 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
136175static 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