Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

fenugrec and committed by
Takashi Iwai
78e35b01 3ce03297

+123 -79
+123 -79
sound/usb/mixer_s1810c.c
··· 25 25 #include "helper.h" 26 26 #include "mixer_s1810c.h" 27 27 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 - 34 28 /* 35 29 * DISCLAIMER: These are just guesses based on the 36 30 * dumps I got. ··· 36 42 * * b selects an input channel (see below). 37 43 * * c selects an output channel pair (see below). 38 44 * * d selects left (0) or right (1) of that pair. 39 - * * e 0-> disconnect, 0x01000000-> connect, 40 - * 0x0109-> used for stereo-linking channels, 41 - * e is also used for setting volume levels 45 + * * e level : see MIXER_LEVEL_* defines below. 46 + * Also used for setting volume levels 42 47 * in which case b is also set so I guess 43 48 * this way it is possible to set the volume 44 49 * level from the specified input to the ··· 68 75 * For output (0x65): 69 76 * * b is the output channel (see above). 70 77 * * c is zero. 71 - * * e I guess the same as with mixer except 0x0109 72 - * which I didn't see in my dumps. 78 + * * e I guess the same as with mixer 73 79 * 74 - * The two fixed fields have the same values for 75 - * mixer and output but a different set for device. 80 + */ 81 + /** struct s1810c_ctl_packet - basic vendor request 82 + * @selector: device/mixer/output 83 + * @b: request-dependant field b 84 + * @tag: fixed value identifying type of request 85 + * @len: sizeof this struct - 8 (excludes first 2 fields) 86 + * i.e. for basic struct s1810c_ctl_packet: len is 5*4=0x14 87 + * @c: request-dependant field c 88 + * @d: request-dependant field d 89 + * @e: request-dependant field e 90 + * 91 + * See longer description above. This could be combined 92 + * (as a union?) with the longer struct s1810c_state_packet 76 93 */ 77 94 struct s1810c_ctl_packet { 78 - __le32 a; 95 + __le32 selector; 79 96 __le32 b; 80 - __le32 fixed1; 81 - __le32 fixed2; 97 + __le32 tag; 98 + __le32 len; 82 99 __le32 c; 83 100 __le32 d; 84 101 __le32 e; 85 102 }; 86 103 104 + /** selectors for CMD request 105 + */ 106 + #define SC1810C_SEL_DEVICE 0 107 + #define SC1810C_SEL_MIXER 0x64 108 + #define SC1810C_SEL_OUTPUT 0x65 109 + 110 + 111 + /** control ids */ 87 112 #define SC1810C_CTL_LINE_SW 0 88 113 #define SC1810C_CTL_MUTE_SW 1 89 114 #define SC1824C_CTL_MONO_SW 2 90 115 #define SC1810C_CTL_AB_SW 3 91 116 #define SC1810C_CTL_48V_SW 4 92 117 118 + /* USB Control (vendor) requests 119 + */ 120 + #define SC1810C_CMD_REQ 160 121 + #define SC1810C_CMD_REQTYPE \ 122 + (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT) 123 + #define SC1810C_CMD_TAG 0x50617269 124 + #define SC1810C_CMD_LEN 0x14 125 + 93 126 #define SC1810C_SET_STATE_REQ 161 94 127 #define SC1810C_SET_STATE_REQTYPE SC1810C_CMD_REQTYPE 95 - #define SC1810C_SET_STATE_F1 0x64656D73 96 - #define SC1810C_SET_STATE_F2 0xF4 128 + #define SC1810C_SET_STATE_TAG 0x64656D73 129 + #define SC1810C_SET_STATE_LEN 0xF4 97 130 98 131 #define SC1810C_GET_STATE_REQ 162 99 132 #define SC1810C_GET_STATE_REQTYPE \ 100 133 (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN) 101 - #define SC1810C_GET_STATE_F1 SC1810C_SET_STATE_F1 102 - #define SC1810C_GET_STATE_F2 SC1810C_SET_STATE_F2 134 + #define SC1810C_GET_STATE_TAG SC1810C_SET_STATE_TAG 135 + #define SC1810C_GET_STATE_LEN SC1810C_SET_STATE_LEN 103 136 104 - #define SC1810C_STATE_F1_IDX 2 105 - #define SC1810C_STATE_F2_IDX 3 137 + /** Mixer levels normally range from 0 (off) to 0x0100 0000 (0 dB). 138 + * raw_level = 2^24 * 10^(db_level / 20), thus 139 + * -3dB = 0xb53bf0 (technically, half-power -3.01...dB would be 0xb504f3) 140 + * -96dB = 0x109 141 + * -99dB = 0xBC 142 + * PC software sliders cover -96 to +10dB (0x0329 8b08), 143 + * but the value 0 (-inf dB) can be used when e.g. Mixer Bypass is enabled. 144 + * Unclear what the hardware's maximum value is. 145 + * 146 + * Note, when a channel is panned to two channels (stereo), 147 + * the mixer level is set to slider value (by default -96dB) minus 3dB, 148 + * which explains the -99dB value seen in USB captures. 149 + */ 150 + #define MIXER_LEVEL_MUTE 0 151 + #define MIXER_LEVEL_N99DB 0xbc 152 + #define MIXER_LEVEL_N3DB 0xb53bf0 153 + #define MIXER_LEVEL_0DB 0x1000000 106 154 107 - /* 155 + /** 108 156 * This packet includes mixer volumes and 109 157 * various other fields, it's an extended 110 158 * version of ctl_packet, with a and b 111 - * being zero and different f1/f2. 159 + * being zero and different tag/length. 112 160 */ 113 161 struct s1810c_state_packet { 114 162 __le32 fields[63]; 115 163 }; 164 + 165 + /** indices into s1810c_state_packet.fields[] 166 + */ 167 + #define SC1810C_STATE_TAG_IDX 2 168 + #define SC1810C_STATE_LEN_IDX 3 116 169 117 170 #define SC1810C_STATE_48V_SW 58 118 171 #define SC1810C_STATE_LINE_SW 59 ··· 173 134 }; 174 135 175 136 static int 176 - snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 a, 137 + snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 sel, 177 138 u32 b, u32 c, u32 d, u32 e) 178 139 { 179 140 struct s1810c_ctl_packet pkt = { 0 }; 180 141 int ret = 0; 181 142 182 - pkt.fixed1 = __cpu_to_le32(SC1810C_CMD_F1); 183 - pkt.fixed2 = __cpu_to_le32(SC1810C_CMD_F2); 143 + pkt.tag = __cpu_to_le32(SC1810C_CMD_TAG); 144 + pkt.len = __cpu_to_le32(SC1810C_CMD_LEN); 184 145 185 - pkt.a = __cpu_to_le32(a); 146 + pkt.selector = __cpu_to_le32(sel); 186 147 pkt.b = __cpu_to_le32(b); 187 148 pkt.c = __cpu_to_le32(c); 188 149 pkt.d = __cpu_to_le32(d); ··· 215 176 struct s1810c_state_packet pkt_in = { { 0 } }; 216 177 int ret = 0; 217 178 218 - pkt_out.fields[SC1810C_STATE_F1_IDX] = __cpu_to_le32(SC1810C_SET_STATE_F1); 219 - pkt_out.fields[SC1810C_STATE_F2_IDX] = __cpu_to_le32(SC1810C_SET_STATE_F2); 179 + pkt_out.fields[SC1810C_STATE_TAG_IDX] = __cpu_to_le32(SC1810C_SET_STATE_TAG); 180 + pkt_out.fields[SC1810C_STATE_LEN_IDX] = __cpu_to_le32(SC1810C_SET_STATE_LEN); 220 181 ret = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 221 182 SC1810C_SET_STATE_REQ, 222 183 SC1810C_SET_STATE_REQTYPE, ··· 255 216 switch (chip->usb_id) { 256 217 case USB_ID(0x194f, 0x010c): /* 1810c */ 257 218 /* Set initial volume levels ? */ 258 - a = 0x64; 259 - e = 0xbc; 219 + a = SC1810C_SEL_MIXER; 220 + e = MIXER_LEVEL_N99DB; 260 221 for (n = 0; n < 2; n++) { 261 222 off = n * 18; 262 223 for (b = off; b < 18 + off; b++) { ··· 273 234 * I noticed on UC that DAW channels have different 274 235 * initial volumes, so this makes sense. 275 236 */ 276 - e = 0xb53bf0; 237 + e = MIXER_LEVEL_N3DB; 277 238 } 278 239 279 240 /* Connect analog outputs ? */ 280 - a = 0x65; 281 - e = 0x01000000; 241 + a = SC1810C_SEL_OUTPUT; 282 242 for (b = 1; b < 3; b++) { 283 - snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e); 284 - snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e); 243 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, MIXER_LEVEL_0DB); 244 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, MIXER_LEVEL_0DB); 285 245 } 286 - snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, e); 287 - snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, e); 246 + snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, MIXER_LEVEL_0DB); 247 + snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, MIXER_LEVEL_0DB); 288 248 289 249 /* Set initial volume levels for S/PDIF mappings ? */ 290 - a = 0x64; 291 - e = 0xbc; 250 + a = SC1810C_SEL_MIXER; 251 + e = MIXER_LEVEL_N99DB; 292 252 c = 3; 293 253 for (n = 0; n < 2; n++) { 294 254 off = n * 18; ··· 295 257 snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e); 296 258 snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e); 297 259 } 298 - e = 0xb53bf0; 260 + e = MIXER_LEVEL_N3DB; 299 261 } 300 262 301 263 /* Connect S/PDIF output ? */ 302 - a = 0x65; 303 - e = 0x01000000; 304 - snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e); 305 - snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e); 264 + a = SC1810C_SEL_OUTPUT; 265 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, MIXER_LEVEL_0DB); 266 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, MIXER_LEVEL_0DB); 306 267 307 268 /* Connect all outputs (again) ? */ 308 - a = 0x65; 309 - e = 0x01000000; 269 + a = SC1810C_SEL_OUTPUT; 310 270 for (b = 0; b < 4; b++) { 311 - snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e); 312 - snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e); 271 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, MIXER_LEVEL_0DB); 272 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, MIXER_LEVEL_0DB); 313 273 } 314 274 315 275 /* Basic routing to get sound out of the device */ 316 - a = 0x64; 317 - e = 0x01000000; 276 + a = SC1810C_SEL_MIXER; 318 277 for (c = 0; c < 4; c++) { 319 278 for (b = 0; b < 36; b++) { 320 279 if ((c == 0 && b == 18) || /* DAW1/2 -> Main */ ··· 319 284 (c == 2 && b == 22) || /* DAW4/5 -> Line5/6 */ 320 285 (c == 3 && b == 24)) { /* DAW5/6 -> S/PDIF */ 321 286 /* Left */ 322 - snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e); 323 - snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0); 287 + snd_s1810c_send_ctl_packet(dev, 288 + a, b, c, 0, MIXER_LEVEL_0DB); 289 + snd_s1810c_send_ctl_packet(dev, 290 + a, b, c, 1, MIXER_LEVEL_MUTE); 324 291 b++; 325 292 /* Right */ 326 - snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0); 327 - snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e); 293 + snd_s1810c_send_ctl_packet(dev, 294 + a, b, c, 0, MIXER_LEVEL_MUTE); 295 + snd_s1810c_send_ctl_packet(dev, 296 + a, b, c, 1, MIXER_LEVEL_0DB); 328 297 } else { 329 298 /* Leave the rest disconnected */ 330 - snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0); 331 - snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0); 299 + snd_s1810c_send_ctl_packet(dev, 300 + a, b, c, 0, MIXER_LEVEL_MUTE); 301 + snd_s1810c_send_ctl_packet(dev, 302 + a, b, c, 1, MIXER_LEVEL_MUTE); 332 303 } 333 304 } 334 305 } 335 306 336 307 /* Set initial volume levels for S/PDIF (again) ? */ 337 - a = 0x64; 338 - e = 0xbc; 308 + a = SC1810C_SEL_MIXER; 309 + e = MIXER_LEVEL_N99DB; 339 310 c = 3; 340 311 for (n = 0; n < 2; n++) { 341 312 off = n * 18; ··· 349 308 snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e); 350 309 snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e); 351 310 } 352 - e = 0xb53bf0; 311 + e = MIXER_LEVEL_N3DB; 353 312 } 354 313 355 314 /* Connect S/PDIF outputs (again) ? */ 356 - a = 0x65; 357 - e = 0x01000000; 358 - snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e); 359 - snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e); 315 + a = SC1810C_SEL_OUTPUT; 316 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, MIXER_LEVEL_0DB); 317 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, MIXER_LEVEL_0DB); 360 318 361 319 /* Again ? */ 362 - snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e); 363 - snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e); 320 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, MIXER_LEVEL_0DB); 321 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, MIXER_LEVEL_0DB); 364 322 break; 365 323 366 324 case USB_ID(0x194f, 0x010d): /* 1824c */ 367 325 /* Set all output faders to unity gain */ 368 - a = 0x65; 326 + a = SC1810C_SEL_OUTPUT; 369 327 c = 0x00; 370 - e = 0x01000000; 371 - 372 328 for (b = 0; b < 9; b++) { 373 - snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e); 374 - snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e); 329 + snd_s1810c_send_ctl_packet(dev, a, b, c, 0, MIXER_LEVEL_0DB); 330 + snd_s1810c_send_ctl_packet(dev, a, b, c, 1, MIXER_LEVEL_0DB); 375 331 } 376 332 377 333 /* Set ··· 383 345 * Daw 17 -> ADAT out 7, (left) Daw 18 -> ADAT out 8 (right) 384 346 * Everything else muted 385 347 */ 386 - a = 0x64; 348 + a = SC1810C_SEL_MIXER; 387 349 /* The first Daw channel is channel 18 */ 388 350 left = 18; 389 351 ··· 392 354 393 355 for (b = 0; b < 36; b++) { 394 356 if (b == left) { 395 - snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x01000000); 396 - snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x00); 357 + snd_s1810c_send_ctl_packet(dev, 358 + a, b, c, 0, MIXER_LEVEL_0DB); 359 + snd_s1810c_send_ctl_packet(dev, 360 + a, b, c, 1, MIXER_LEVEL_MUTE); 397 361 } else if (b == right) { 398 - snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x00); 399 - snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x01000000); 362 + snd_s1810c_send_ctl_packet(dev, 363 + a, b, c, 0, MIXER_LEVEL_MUTE); 364 + snd_s1810c_send_ctl_packet(dev, 365 + a, b, c, 1, MIXER_LEVEL_0DB); 400 366 } else { 401 - snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x00); 402 - snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x00); 367 + snd_s1810c_send_ctl_packet(dev, 368 + a, b, c, 0, MIXER_LEVEL_MUTE); 369 + snd_s1810c_send_ctl_packet(dev, 370 + a, b, c, 1, MIXER_LEVEL_MUTE); 403 371 } 404 372 } 405 373 left += 2;