Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/usb/mixer_s1810c.c
51947 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Presonus Studio 1810c driver for ALSA
4
* Copyright (C) 2019 Nick Kossifidis <[email protected]>
5
*
6
* Based on reverse engineering of the communication protocol
7
* between the windows driver / Univeral Control (UC) program
8
* and the device, through usbmon.
9
*
10
* For now this bypasses the mixer, with all channels split,
11
* so that the software can mix with greater flexibility.
12
* It also adds controls for the 4 buttons on the front of
13
* the device.
14
*/
15
16
#include <linux/usb.h>
17
#include <linux/usb/audio-v2.h>
18
#include <linux/slab.h>
19
#include <sound/core.h>
20
#include <sound/control.h>
21
22
#include "usbaudio.h"
23
#include "mixer.h"
24
#include "mixer_quirks.h"
25
#include "helper.h"
26
#include "mixer_s1810c.h"
27
28
/*
29
* DISCLAIMER: These are just guesses based on the
30
* dumps I got.
31
*
32
* It seems like a selects between
33
* device (0), mixer (0x64) and output (0x65)
34
*
35
* For mixer (0x64):
36
* * b selects an input channel (see below).
37
* * c selects an output channel pair (see below).
38
* * d selects left (0) or right (1) of that pair.
39
* * e level : see MIXER_LEVEL_* defines below.
40
* Also used for setting volume levels
41
* in which case b is also set so I guess
42
* this way it is possible to set the volume
43
* level from the specified input to the
44
* specified output.
45
*
46
* IN Channels:
47
* 0 - 7 Mic/Inst/Line (Analog inputs)
48
* 8 - 9 S/PDIF
49
* 10 - 17 ADAT
50
* 18 - 35 DAW (Inputs from the host)
51
*
52
* OUT Channels (pairs):
53
* 0 -> Main out
54
* 1 -> Line1/2
55
* 2 -> Line3/4
56
* 3 -> S/PDIF
57
* 4 -> ADAT?
58
*
59
* For device (0):
60
* * b and c are not used, at least not on the
61
* dumps I got.
62
* * d sets the control id to be modified
63
* (see below).
64
* * e sets the setting for that control.
65
* (so for the switches I was interested
66
* in it's 0/1)
67
*
68
* For output (0x65):
69
* * b is the output channel (see above).
70
* * c is zero.
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
83
*
84
* See longer description above. This could be combined
85
* (as a union?) with the longer struct s1810c_state_packet
86
*/
87
struct s1810c_ctl_packet {
88
__le32 selector;
89
__le32 b;
90
__le32 tag;
91
__le32 len;
92
__le32 c;
93
__le32 d;
94
__le32 e;
95
};
96
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 */
105
#define SC1810C_CTL_LINE_SW 0
106
#define SC1810C_CTL_MUTE_SW 1
107
#define SC1824C_CTL_MONO_SW 2
108
#define SC1810C_CTL_AB_SW 3
109
#define SC1810C_CTL_48V_SW 4
110
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
119
#define SC1810C_SET_STATE_REQ 161
120
#define SC1810C_SET_STATE_REQTYPE SC1810C_CMD_REQTYPE
121
#define SC1810C_SET_STATE_TAG 0x64656D73
122
#define SC1810C_SET_STATE_LEN 0xF4
123
124
#define SC1810C_GET_STATE_REQ 162
125
#define SC1810C_GET_STATE_REQTYPE \
126
(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN)
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
147
148
/**
149
* This packet includes mixer volumes and
150
* various other fields, it's an extended
151
* version of ctl_packet, with a and b
152
* being zero and different tag/length.
153
*/
154
struct s1810c_state_packet {
155
__le32 fields[63];
156
};
157
158
/** indices into s1810c_state_packet.fields[]
159
*/
160
#define SC1810C_STATE_TAG_IDX 2
161
#define SC1810C_STATE_LEN_IDX 3
162
163
#define SC1810C_STATE_48V_SW 58
164
#define SC1810C_STATE_LINE_SW 59
165
#define SC1810C_STATE_MUTE_SW 60
166
#define SC1824C_STATE_MONO_SW 61
167
#define SC1810C_STATE_AB_SW 62
168
169
struct s1810_mixer_state {
170
uint16_t seqnum;
171
struct mutex usb_mutex;
172
struct mutex data_mutex;
173
};
174
175
static int
176
snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 sel,
177
u32 b, u32 c, u32 d, u32 e)
178
{
179
struct s1810c_ctl_packet pkt = { 0 };
180
int ret = 0;
181
182
pkt.tag = __cpu_to_le32(SC1810C_CMD_TAG);
183
pkt.len = __cpu_to_le32(SC1810C_CMD_LEN);
184
185
pkt.selector = __cpu_to_le32(sel);
186
pkt.b = __cpu_to_le32(b);
187
pkt.c = __cpu_to_le32(c);
188
pkt.d = __cpu_to_le32(d);
189
pkt.e = __cpu_to_le32(e);
190
191
ret = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
192
SC1810C_CMD_REQ,
193
SC1810C_CMD_REQTYPE, 0, 0, &pkt, sizeof(pkt));
194
if (ret < 0) {
195
dev_warn(&dev->dev, "could not send ctl packet\n");
196
return ret;
197
}
198
return 0;
199
}
200
201
/*
202
* When opening Universal Control the program periodically
203
* sends and receives state packets for syncinc state between
204
* the device and the host.
205
*
206
* Note that if we send only the request to get data back we'll
207
* get an error, we need to first send an empty state packet and
208
* then ask to receive a filled. Their seqnumbers must also match.
209
*/
210
static int
211
snd_sc1810c_get_status_field(struct usb_device *dev,
212
u32 *field, int field_idx, uint16_t *seqnum)
213
{
214
struct s1810c_state_packet pkt_out = { { 0 } };
215
struct s1810c_state_packet pkt_in = { { 0 } };
216
int ret = 0;
217
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);
220
ret = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
221
SC1810C_SET_STATE_REQ,
222
SC1810C_SET_STATE_REQTYPE,
223
(*seqnum), 0, &pkt_out, sizeof(pkt_out));
224
if (ret < 0) {
225
dev_warn(&dev->dev, "could not send state packet (%d)\n", ret);
226
return ret;
227
}
228
229
ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
230
SC1810C_GET_STATE_REQ,
231
SC1810C_GET_STATE_REQTYPE,
232
(*seqnum), 0, &pkt_in, sizeof(pkt_in));
233
if (ret < 0) {
234
dev_warn(&dev->dev, "could not get state field %u (%d)\n",
235
field_idx, ret);
236
return ret;
237
}
238
239
(*field) = __le32_to_cpu(pkt_in.fields[field_idx]);
240
(*seqnum)++;
241
return 0;
242
}
243
244
/*
245
* This is what I got when bypassing the mixer with
246
* all channels split. I'm not 100% sure of what's going
247
* on, I could probably clean this up based on my observations
248
* but I prefer to keep the same behavior as the windows driver.
249
*/
250
static int snd_s1810c_init_mixer_maps(struct snd_usb_audio *chip)
251
{
252
u32 a, b, c, e, n, off, left, right;
253
struct usb_device *dev = chip->dev;
254
255
switch (chip->usb_id) {
256
case USB_ID(0x194f, 0x010c): /* 1810c */
257
/* Set initial volume levels ? */
258
a = SC1810C_SEL_MIXER;
259
e = MIXER_LEVEL_N99DB;
260
for (n = 0; n < 2; n++) {
261
off = n * 18;
262
for (b = off; b < 18 + off; b++) {
263
/* This channel to all outputs ? */
264
for (c = 0; c <= 8; c++) {
265
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
266
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
267
}
268
/* This channel to main output (again) */
269
snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
270
snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
271
}
272
/*
273
* I noticed on UC that DAW channels have different
274
* initial volumes, so this makes sense.
275
*/
276
e = MIXER_LEVEL_N3DB;
277
}
278
279
/* Connect analog outputs ? */
280
a = SC1810C_SEL_OUTPUT;
281
for (b = 1; b < 3; b++) {
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);
284
}
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);
287
288
/* Set initial volume levels for S/PDIF mappings ? */
289
a = SC1810C_SEL_MIXER;
290
e = MIXER_LEVEL_N99DB;
291
c = 3;
292
for (n = 0; n < 2; n++) {
293
off = n * 18;
294
for (b = off; b < 18 + off; b++) {
295
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
296
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
297
}
298
e = MIXER_LEVEL_N3DB;
299
}
300
301
/* Connect S/PDIF output ? */
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);
305
306
/* Connect all outputs (again) ? */
307
a = SC1810C_SEL_OUTPUT;
308
for (b = 0; b < 4; b++) {
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);
311
}
312
313
/* Basic routing to get sound out of the device */
314
a = SC1810C_SEL_MIXER;
315
for (c = 0; c < 4; c++) {
316
for (b = 0; b < 36; b++) {
317
if ((c == 0 && b == 18) || /* DAW1/2 -> Main */
318
(c == 1 && b == 20) || /* DAW3/4 -> Line3/4 */
319
(c == 2 && b == 22) || /* DAW4/5 -> Line5/6 */
320
(c == 3 && b == 24)) { /* DAW5/6 -> S/PDIF */
321
/* Left */
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);
326
b++;
327
/* Right */
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);
332
} else {
333
/* Leave the rest disconnected */
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);
338
}
339
}
340
}
341
342
/* Set initial volume levels for S/PDIF (again) ? */
343
a = SC1810C_SEL_MIXER;
344
e = MIXER_LEVEL_N99DB;
345
c = 3;
346
for (n = 0; n < 2; n++) {
347
off = n * 18;
348
for (b = off; b < 18 + off; b++) {
349
snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
350
snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
351
}
352
e = MIXER_LEVEL_N3DB;
353
}
354
355
/* Connect S/PDIF outputs (again) ? */
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);
359
360
/* Again ? */
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);
363
break;
364
365
case USB_ID(0x194f, 0x010d): /* 1824c */
366
/* Set all output faders to unity gain */
367
a = SC1810C_SEL_OUTPUT;
368
c = 0x00;
369
for (b = 0; b < 9; b++) {
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);
372
}
373
374
/* Set
375
* Daw 1 -> Line out 1 (left), Daw 2 -> Line out 2 (right)
376
* Daw 3 -> Line out 3, (left) Daw 4 -> Line out 4 (right)
377
* Daw 5 -> Line out 5, (left) Daw 6 -> Line out 6 (right)
378
* Daw 7 -> Line out 7, (left) Daw 8 -> Line out 8 (right)
379
* Daw 9 -> SPDIF out 1, (left) Daw 10 -> SPDIF out 2 (right)
380
* Daw 11 -> ADAT out 1, (left) Daw 12 -> ADAT out 2 (right)
381
* Daw 13 -> ADAT out 3, (left) Daw 14 -> ADAT out 4 (right)
382
* Daw 15 -> ADAT out 5, (left) Daw 16 -> ADAT out 6 (right)
383
* Daw 17 -> ADAT out 7, (left) Daw 18 -> ADAT out 8 (right)
384
* Everything else muted
385
*/
386
a = SC1810C_SEL_MIXER;
387
/* The first Daw channel is channel 18 */
388
left = 18;
389
390
for (c = 0; c < 9; c++) {
391
right = left + 1;
392
393
for (b = 0; b < 36; b++) {
394
if (b == left) {
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);
399
} else if (b == right) {
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);
404
} else {
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);
409
}
410
}
411
left += 2;
412
}
413
break;
414
}
415
return 0;
416
}
417
418
/*
419
* Sync state with the device and retrieve the requested field,
420
* whose index is specified in (kctl->private_value & 0xFF),
421
* from the received fields array.
422
*/
423
static int
424
snd_s1810c_get_switch_state(struct usb_mixer_interface *mixer,
425
struct snd_kcontrol *kctl, u32 *state)
426
{
427
struct snd_usb_audio *chip = mixer->chip;
428
struct s1810_mixer_state *private = mixer->private_data;
429
u32 field = 0;
430
u32 ctl_idx = (u32) (kctl->private_value & 0xFF);
431
int ret;
432
433
guard(mutex)(&private->usb_mutex);
434
ret = snd_sc1810c_get_status_field(chip->dev, &field,
435
ctl_idx, &private->seqnum);
436
if (ret < 0)
437
return ret;
438
439
*state = field;
440
return ret;
441
}
442
443
/*
444
* Send a control packet to the device for the control id
445
* specified in (kctl->private_value >> 8) with value
446
* specified in (kctl->private_value >> 16).
447
*/
448
static int
449
snd_s1810c_set_switch_state(struct usb_mixer_interface *mixer,
450
struct snd_kcontrol *kctl)
451
{
452
struct snd_usb_audio *chip = mixer->chip;
453
struct s1810_mixer_state *private = mixer->private_data;
454
u32 pval = (u32) kctl->private_value;
455
u32 ctl_id = (pval >> 8) & 0xFF;
456
u32 ctl_val = (pval >> 16) & 0x1;
457
458
guard(mutex)(&private->usb_mutex);
459
return snd_s1810c_send_ctl_packet(chip->dev, 0, 0, 0, ctl_id, ctl_val);
460
}
461
462
/* Generic get/set/init functions for switch controls */
463
464
static int
465
snd_s1810c_switch_get(struct snd_kcontrol *kctl,
466
struct snd_ctl_elem_value *ctl_elem)
467
{
468
struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
469
struct usb_mixer_interface *mixer = list->mixer;
470
struct s1810_mixer_state *private = mixer->private_data;
471
u32 pval = (u32) kctl->private_value;
472
u32 ctl_idx = pval & 0xFF;
473
u32 state = 0;
474
int ret;
475
476
guard(mutex)(&private->data_mutex);
477
ret = snd_s1810c_get_switch_state(mixer, kctl, &state);
478
if (ret < 0)
479
return ret;
480
481
switch (ctl_idx) {
482
case SC1810C_STATE_LINE_SW:
483
case SC1810C_STATE_AB_SW:
484
ctl_elem->value.enumerated.item[0] = (int)state;
485
break;
486
default:
487
ctl_elem->value.integer.value[0] = (long)state;
488
}
489
490
return 0;
491
}
492
493
static int
494
snd_s1810c_switch_set(struct snd_kcontrol *kctl,
495
struct snd_ctl_elem_value *ctl_elem)
496
{
497
struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
498
struct usb_mixer_interface *mixer = list->mixer;
499
struct s1810_mixer_state *private = mixer->private_data;
500
u32 pval = (u32) kctl->private_value;
501
u32 ctl_idx = pval & 0xFF;
502
u32 curval = 0;
503
u32 newval = 0;
504
int ret = 0;
505
506
guard(mutex)(&private->data_mutex);
507
ret = snd_s1810c_get_switch_state(mixer, kctl, &curval);
508
if (ret < 0)
509
return ret;
510
511
switch (ctl_idx) {
512
case SC1810C_STATE_LINE_SW:
513
case SC1810C_STATE_AB_SW:
514
newval = (u32) ctl_elem->value.enumerated.item[0];
515
break;
516
default:
517
newval = (u32) ctl_elem->value.integer.value[0];
518
}
519
520
if (curval == newval)
521
return 0;
522
523
kctl->private_value &= ~(0x1 << 16);
524
kctl->private_value |= (unsigned int)(newval & 0x1) << 16;
525
ret = snd_s1810c_set_switch_state(mixer, kctl);
526
527
return (ret < 0) ? 0 : 1;
528
}
529
530
static int
531
snd_s1810c_switch_init(struct usb_mixer_interface *mixer,
532
const struct snd_kcontrol_new *new_kctl)
533
{
534
struct snd_kcontrol *kctl;
535
struct usb_mixer_elem_info *elem;
536
537
elem = kzalloc(sizeof(struct usb_mixer_elem_info), GFP_KERNEL);
538
if (!elem)
539
return -ENOMEM;
540
541
elem->head.mixer = mixer;
542
elem->control = 0;
543
elem->head.id = 0;
544
elem->channels = 1;
545
546
kctl = snd_ctl_new1(new_kctl, elem);
547
if (!kctl) {
548
kfree(elem);
549
return -ENOMEM;
550
}
551
kctl->private_free = snd_usb_mixer_elem_free;
552
553
return snd_usb_mixer_add_control(&elem->head, kctl);
554
}
555
556
static int
557
snd_s1810c_line_sw_info(struct snd_kcontrol *kctl,
558
struct snd_ctl_elem_info *uinfo)
559
{
560
static const char *const texts[2] = {
561
"Preamp On (Mic/Inst)",
562
"Preamp Off (Line in)"
563
};
564
565
return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
566
}
567
568
static const struct snd_kcontrol_new snd_s1810c_line_sw = {
569
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
570
.name = "Line 1/2 Source Type",
571
.info = snd_s1810c_line_sw_info,
572
.get = snd_s1810c_switch_get,
573
.put = snd_s1810c_switch_set,
574
.private_value = (SC1810C_STATE_LINE_SW | SC1810C_CTL_LINE_SW << 8)
575
};
576
577
static const struct snd_kcontrol_new snd_s1810c_mute_sw = {
578
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
579
.name = "Mute Main Out Switch",
580
.info = snd_ctl_boolean_mono_info,
581
.get = snd_s1810c_switch_get,
582
.put = snd_s1810c_switch_set,
583
.private_value = (SC1810C_STATE_MUTE_SW | SC1810C_CTL_MUTE_SW << 8)
584
};
585
586
static const struct snd_kcontrol_new snd_s1824c_mono_sw = {
587
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
588
.name = "Mono Main Out Switch",
589
.info = snd_ctl_boolean_mono_info,
590
.get = snd_s1810c_switch_get,
591
.put = snd_s1810c_switch_set,
592
.private_value = (SC1824C_STATE_MONO_SW | SC1824C_CTL_MONO_SW << 8)
593
};
594
595
static const struct snd_kcontrol_new snd_s1810c_48v_sw = {
596
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
597
.name = "48V Phantom Power On Mic Inputs Switch",
598
.info = snd_ctl_boolean_mono_info,
599
.get = snd_s1810c_switch_get,
600
.put = snd_s1810c_switch_set,
601
.private_value = (SC1810C_STATE_48V_SW | SC1810C_CTL_48V_SW << 8)
602
};
603
604
static int
605
snd_s1810c_ab_sw_info(struct snd_kcontrol *kctl,
606
struct snd_ctl_elem_info *uinfo)
607
{
608
static const char *const texts[2] = {
609
"1/2",
610
"3/4"
611
};
612
613
return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
614
}
615
616
static const struct snd_kcontrol_new snd_s1810c_ab_sw = {
617
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
618
.name = "Headphone 1 Source Route",
619
.info = snd_s1810c_ab_sw_info,
620
.get = snd_s1810c_switch_get,
621
.put = snd_s1810c_switch_set,
622
.private_value = (SC1810C_STATE_AB_SW | SC1810C_CTL_AB_SW << 8)
623
};
624
625
static void snd_sc1810_mixer_state_free(struct usb_mixer_interface *mixer)
626
{
627
struct s1810_mixer_state *private = mixer->private_data;
628
kfree(private);
629
mixer->private_data = NULL;
630
}
631
632
/* Entry point, called from mixer_quirks.c */
633
int snd_sc1810_init_mixer(struct usb_mixer_interface *mixer)
634
{
635
struct s1810_mixer_state *private = NULL;
636
struct snd_usb_audio *chip = mixer->chip;
637
struct usb_device *dev = chip->dev;
638
int ret = 0;
639
640
/* Run this only once */
641
if (!list_empty(&chip->mixer_list))
642
return 0;
643
644
ret = snd_s1810c_init_mixer_maps(chip);
645
if (ret < 0)
646
return ret;
647
648
private = kzalloc(sizeof(struct s1810_mixer_state), GFP_KERNEL);
649
if (!private)
650
return -ENOMEM;
651
652
mutex_init(&private->usb_mutex);
653
mutex_init(&private->data_mutex);
654
655
mixer->private_data = private;
656
mixer->private_free = snd_sc1810_mixer_state_free;
657
658
private->seqnum = 1;
659
660
ret = snd_s1810c_switch_init(mixer, &snd_s1810c_line_sw);
661
if (ret < 0)
662
return ret;
663
664
ret = snd_s1810c_switch_init(mixer, &snd_s1810c_mute_sw);
665
if (ret < 0)
666
return ret;
667
668
ret = snd_s1810c_switch_init(mixer, &snd_s1810c_48v_sw);
669
if (ret < 0)
670
return ret;
671
672
switch (chip->usb_id) {
673
case USB_ID(0x194f, 0x010c): /* Presonus Studio 1810c */
674
dev_info(&dev->dev,
675
"Presonus Studio 1810c, device_setup: %u\n", chip->setup);
676
if (chip->setup == 1)
677
dev_info(&dev->dev, "(8out/18in @ 48kHz)\n");
678
else if (chip->setup == 2)
679
dev_info(&dev->dev, "(6out/8in @ 192kHz)\n");
680
else
681
dev_info(&dev->dev, "(8out/14in @ 96kHz)\n");
682
683
ret = snd_s1810c_switch_init(mixer, &snd_s1810c_ab_sw);
684
if (ret < 0)
685
return ret;
686
687
break;
688
case USB_ID(0x194f, 0x010d): /* Presonus Studio 1824c */
689
ret = snd_s1810c_switch_init(mixer, &snd_s1824c_mono_sw);
690
if (ret < 0)
691
return ret;
692
693
break;
694
}
695
696
return ret;
697
}
698
699