cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mixer_scarlett.c (28770B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *   Scarlett Driver for ALSA
      4 *
      5 *   Copyright (c) 2013 by Tobias Hoffmann
      6 *   Copyright (c) 2013 by Robin Gareus <robin at gareus.org>
      7 *   Copyright (c) 2002 by Takashi Iwai <tiwai at suse.de>
      8 *   Copyright (c) 2014 by Chris J Arges <chris.j.arges at canonical.com>
      9 *
     10 *   Many codes borrowed from audio.c by
     11 *	    Alan Cox (alan at lxorguk.ukuu.org.uk)
     12 *	    Thomas Sailer (sailer at ife.ee.ethz.ch)
     13 *
     14 *   Code cleanup:
     15 *   David Henningsson <david.henningsson at canonical.com>
     16 */
     17
     18/*
     19 * Rewritten and extended to support more models, e.g. Scarlett 18i8.
     20 *
     21 * Auto-detection via UAC2 is not feasible to properly discover the vast
     22 * majority of features. It's related to both Linux/ALSA's UAC2 as well as
     23 * Focusrite's implementation of it. Eventually quirks may be sufficient but
     24 * right now it's a major headache to work around these things.
     25 *
     26 * NB. Neither the OSX nor the win driver provided by Focusrite performs
     27 * discovery, they seem to operate the same as this driver.
     28 */
     29
     30/* Mixer Interface for the Focusrite Scarlett 18i6 audio interface.
     31 *
     32 * The protocol was reverse engineered by looking at communication between
     33 * Scarlett MixControl (v 1.2.128.0) and the Focusrite(R) Scarlett 18i6
     34 * (firmware v305) using wireshark and usbmon in January 2013.
     35 * Extended in July 2013.
     36 *
     37 * this mixer gives complete access to all features of the device:
     38 *  - change Impedance of inputs (Line-in, Mic / Instrument, Hi-Z)
     39 *  - select clock source
     40 *  - dynamic input to mixer-matrix assignment
     41 *  - 18 x 6 mixer-matrix gain stages
     42 *  - bus routing & volume control
     43 *  - automatic re-initialization on connect if device was power-cycled
     44 *
     45 * USB URB commands overview (bRequest = 0x01 = UAC2_CS_CUR)
     46 * wIndex
     47 * 0x01 Analog Input line/instrument impedance switch, wValue=0x0901 +
     48 *      channel, data=Line/Inst (2bytes)
     49 *      pad (-10dB) switch, wValue=0x0b01 + channel, data=Off/On (2bytes)
     50 *      ?? wValue=0x0803/04, ?? (2bytes)
     51 * 0x0a Master Volume, wValue=0x0200+bus[0:all + only 1..4?] data(2bytes)
     52 *      Bus Mute/Unmute wValue=0x0100+bus[0:all + only 1..4?], data(2bytes)
     53 * 0x28 Clock source, wValue=0x0100, data={1:int,2:spdif,3:adat} (1byte)
     54 * 0x29 Set Sample-rate, wValue=0x0100, data=sample-rate(4bytes)
     55 * 0x32 Mixer mux, wValue=0x0600 + mixer-channel, data=input-to-connect(2bytes)
     56 * 0x33 Output mux, wValue=bus, data=input-to-connect(2bytes)
     57 * 0x34 Capture mux, wValue=0...18, data=input-to-connect(2bytes)
     58 * 0x3c Matrix Mixer gains, wValue=mixer-node  data=gain(2bytes)
     59 *      ?? [sometimes](4bytes, e.g 0x000003be 0x000003bf ...03ff)
     60 *
     61 * USB reads: (i.e. actually issued by original software)
     62 * 0x01 wValue=0x0901+channel (1byte!!), wValue=0x0b01+channed (1byte!!)
     63 * 0x29 wValue=0x0100 sample-rate(4bytes)
     64 *      wValue=0x0200 ?? 1byte (only once)
     65 * 0x2a wValue=0x0100 ?? 4bytes, sample-rate2 ??
     66 *
     67 * USB reads with bRequest = 0x03 = UAC2_CS_MEM
     68 * 0x3c wValue=0x0002 1byte: sync status (locked=1)
     69 *      wValue=0x0000 18*2byte: peak meter (inputs)
     70 *      wValue=0x0001 8(?)*2byte: peak meter (mix)
     71 *      wValue=0x0003 6*2byte: peak meter (pcm/daw)
     72 *
     73 * USB write with bRequest = 0x03
     74 * 0x3c Save settings to hardware: wValue=0x005a, data=0xa5
     75 *
     76 *
     77 * <ditaa>
     78 *  /--------------\    18chn            6chn    /--------------\
     79 *  | Hardware  in +--+-------\        /------+--+ ALSA PCM out |
     80 *  \--------------/  |       |        |      |  \--------------/
     81 *                    |       |        |      |
     82 *                    |       v        v      |
     83 *                    |   +---------------+   |
     84 *                    |    \ Matrix  Mux /    |
     85 *                    |     +-----+-----+     |
     86 *                    |           |           |
     87 *                    |           | 18chn     |
     88 *                    |           v           |
     89 *                    |     +-----------+     |
     90 *                    |     | Mixer     |     |
     91 *                    |     |    Matrix |     |
     92 *                    |     |           |     |
     93 *                    |     | 18x6 Gain |     |
     94 *                    |     |   stages  |     |
     95 *                    |     +-----+-----+     |
     96 *                    |           |           |
     97 *                    |           |           |
     98 *                    | 18chn     | 6chn      | 6chn
     99 *                    v           v           v
    100 *                    =========================
    101 *             +---------------+     +--—------------+
    102 *              \ Output  Mux /       \ Capture Mux /
    103 *               +-----+-----+         +-----+-----+
    104 *                     |                     |
    105 *                     | 6chn                |
    106 *                     v                     |
    107 *              +-------------+              |
    108 *              | Master Gain |              |
    109 *              +------+------+              |
    110 *                     |                     |
    111 *                     | 6chn                | 18chn
    112 *                     | (3 stereo pairs)    |
    113 *  /--------------\   |                     |   /--------------\
    114 *  | Hardware out |<--/                     \-->| ALSA PCM  in |
    115 *  \--------------/                             \--------------/
    116 * </ditaa>
    117 *
    118 */
    119
    120#include <linux/slab.h>
    121#include <linux/usb.h>
    122#include <linux/usb/audio-v2.h>
    123
    124#include <sound/core.h>
    125#include <sound/control.h>
    126#include <sound/tlv.h>
    127
    128#include "usbaudio.h"
    129#include "mixer.h"
    130#include "helper.h"
    131#include "power.h"
    132
    133#include "mixer_scarlett.h"
    134
    135/* some gui mixers can't handle negative ctl values */
    136#define SND_SCARLETT_LEVEL_BIAS 128
    137#define SND_SCARLETT_MATRIX_IN_MAX 18
    138#define SND_SCARLETT_CONTROLS_MAX 10
    139#define SND_SCARLETT_OFFSETS_MAX 5
    140
    141enum {
    142	SCARLETT_OUTPUTS,
    143	SCARLETT_SWITCH_IMPEDANCE,
    144	SCARLETT_SWITCH_PAD,
    145	SCARLETT_SWITCH_GAIN,
    146};
    147
    148enum {
    149	SCARLETT_OFFSET_PCM = 0,
    150	SCARLETT_OFFSET_ANALOG = 1,
    151	SCARLETT_OFFSET_SPDIF = 2,
    152	SCARLETT_OFFSET_ADAT = 3,
    153	SCARLETT_OFFSET_MIX = 4,
    154};
    155
    156struct scarlett_mixer_elem_enum_info {
    157	int start;
    158	int len;
    159	int offsets[SND_SCARLETT_OFFSETS_MAX];
    160	char const * const *names;
    161};
    162
    163struct scarlett_mixer_control {
    164	unsigned char num;
    165	unsigned char type;
    166	const char *name;
    167};
    168
    169struct scarlett_device_info {
    170	int matrix_in;
    171	int matrix_out;
    172	int input_len;
    173	int output_len;
    174
    175	struct scarlett_mixer_elem_enum_info opt_master;
    176	struct scarlett_mixer_elem_enum_info opt_matrix;
    177
    178	/* initial values for matrix mux */
    179	int matrix_mux_init[SND_SCARLETT_MATRIX_IN_MAX];
    180
    181	int num_controls;	/* number of items in controls */
    182	const struct scarlett_mixer_control controls[SND_SCARLETT_CONTROLS_MAX];
    183};
    184
    185/********************** Enum Strings *************************/
    186
    187static const struct scarlett_mixer_elem_enum_info opt_pad = {
    188	.start = 0,
    189	.len = 2,
    190	.offsets = {},
    191	.names = (char const * const []){
    192		"0dB", "-10dB"
    193	}
    194};
    195
    196static const struct scarlett_mixer_elem_enum_info opt_gain = {
    197	.start = 0,
    198	.len = 2,
    199	.offsets = {},
    200	.names = (char const * const []){
    201		"Lo", "Hi"
    202	}
    203};
    204
    205static const struct scarlett_mixer_elem_enum_info opt_impedance = {
    206	.start = 0,
    207	.len = 2,
    208	.offsets = {},
    209	.names = (char const * const []){
    210		"Line", "Hi-Z"
    211	}
    212};
    213
    214static const struct scarlett_mixer_elem_enum_info opt_clock = {
    215	.start = 1,
    216	.len = 3,
    217	.offsets = {},
    218	.names = (char const * const []){
    219		"Internal", "SPDIF", "ADAT"
    220	}
    221};
    222
    223static const struct scarlett_mixer_elem_enum_info opt_sync = {
    224	.start = 0,
    225	.len = 2,
    226	.offsets = {},
    227	.names = (char const * const []){
    228		"No Lock", "Locked"
    229	}
    230};
    231
    232static int scarlett_ctl_switch_info(struct snd_kcontrol *kctl,
    233		struct snd_ctl_elem_info *uinfo)
    234{
    235	struct usb_mixer_elem_info *elem = kctl->private_data;
    236
    237	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
    238	uinfo->count = elem->channels;
    239	uinfo->value.integer.min = 0;
    240	uinfo->value.integer.max = 1;
    241	return 0;
    242}
    243
    244static int scarlett_ctl_switch_get(struct snd_kcontrol *kctl,
    245		struct snd_ctl_elem_value *ucontrol)
    246{
    247	struct usb_mixer_elem_info *elem = kctl->private_data;
    248	int i, err, val;
    249
    250	for (i = 0; i < elem->channels; i++) {
    251		err = snd_usb_get_cur_mix_value(elem, i, i, &val);
    252		if (err < 0)
    253			return err;
    254
    255		val = !val; /* invert mute logic for mixer */
    256		ucontrol->value.integer.value[i] = val;
    257	}
    258
    259	return 0;
    260}
    261
    262static int scarlett_ctl_switch_put(struct snd_kcontrol *kctl,
    263		struct snd_ctl_elem_value *ucontrol)
    264{
    265	struct usb_mixer_elem_info *elem = kctl->private_data;
    266	int i, changed = 0;
    267	int err, oval, val;
    268
    269	for (i = 0; i < elem->channels; i++) {
    270		err = snd_usb_get_cur_mix_value(elem, i, i, &oval);
    271		if (err < 0)
    272			return err;
    273
    274		val = ucontrol->value.integer.value[i];
    275		val = !val;
    276		if (oval != val) {
    277			err = snd_usb_set_cur_mix_value(elem, i, i, val);
    278			if (err < 0)
    279				return err;
    280
    281			changed = 1;
    282		}
    283	}
    284
    285	return changed;
    286}
    287
    288static int scarlett_ctl_resume(struct usb_mixer_elem_list *list)
    289{
    290	struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
    291	int i;
    292
    293	for (i = 0; i < elem->channels; i++)
    294		if (elem->cached & (1 << i))
    295			snd_usb_set_cur_mix_value(elem, i, i,
    296						  elem->cache_val[i]);
    297	return 0;
    298}
    299
    300static int scarlett_ctl_info(struct snd_kcontrol *kctl,
    301			     struct snd_ctl_elem_info *uinfo)
    302{
    303	struct usb_mixer_elem_info *elem = kctl->private_data;
    304
    305	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    306	uinfo->count = elem->channels;
    307	uinfo->value.integer.min = 0;
    308	uinfo->value.integer.max = (int)kctl->private_value +
    309		SND_SCARLETT_LEVEL_BIAS;
    310	uinfo->value.integer.step = 1;
    311	return 0;
    312}
    313
    314static int scarlett_ctl_get(struct snd_kcontrol *kctl,
    315			    struct snd_ctl_elem_value *ucontrol)
    316{
    317	struct usb_mixer_elem_info *elem = kctl->private_data;
    318	int i, err, val;
    319
    320	for (i = 0; i < elem->channels; i++) {
    321		err = snd_usb_get_cur_mix_value(elem, i, i, &val);
    322		if (err < 0)
    323			return err;
    324
    325		val = clamp(val / 256, -128, (int)kctl->private_value) +
    326				    SND_SCARLETT_LEVEL_BIAS;
    327		ucontrol->value.integer.value[i] = val;
    328	}
    329
    330	return 0;
    331}
    332
    333static int scarlett_ctl_put(struct snd_kcontrol *kctl,
    334			    struct snd_ctl_elem_value *ucontrol)
    335{
    336	struct usb_mixer_elem_info *elem = kctl->private_data;
    337	int i, changed = 0;
    338	int err, oval, val;
    339
    340	for (i = 0; i < elem->channels; i++) {
    341		err = snd_usb_get_cur_mix_value(elem, i, i, &oval);
    342		if (err < 0)
    343			return err;
    344
    345		val = ucontrol->value.integer.value[i] -
    346			SND_SCARLETT_LEVEL_BIAS;
    347		val = val * 256;
    348		if (oval != val) {
    349			err = snd_usb_set_cur_mix_value(elem, i, i, val);
    350			if (err < 0)
    351				return err;
    352
    353			changed = 1;
    354		}
    355	}
    356
    357	return changed;
    358}
    359
    360static void scarlett_generate_name(int i, char *dst, int offsets[])
    361{
    362	if (i > offsets[SCARLETT_OFFSET_MIX])
    363		sprintf(dst, "Mix %c",
    364			'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1));
    365	else if (i > offsets[SCARLETT_OFFSET_ADAT])
    366		sprintf(dst, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]);
    367	else if (i > offsets[SCARLETT_OFFSET_SPDIF])
    368		sprintf(dst, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]);
    369	else if (i > offsets[SCARLETT_OFFSET_ANALOG])
    370		sprintf(dst, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]);
    371	else if (i > offsets[SCARLETT_OFFSET_PCM])
    372		sprintf(dst, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]);
    373	else
    374		sprintf(dst, "Off");
    375}
    376
    377static int scarlett_ctl_enum_dynamic_info(struct snd_kcontrol *kctl,
    378					  struct snd_ctl_elem_info *uinfo)
    379{
    380	struct usb_mixer_elem_info *elem = kctl->private_data;
    381	struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
    382	unsigned int items = opt->len;
    383
    384	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
    385	uinfo->count = elem->channels;
    386	uinfo->value.enumerated.items = items;
    387
    388	if (uinfo->value.enumerated.item >= items)
    389		uinfo->value.enumerated.item = items - 1;
    390
    391	/* generate name dynamically based on item number and offset info */
    392	scarlett_generate_name(uinfo->value.enumerated.item,
    393			       uinfo->value.enumerated.name,
    394			       opt->offsets);
    395
    396	return 0;
    397}
    398
    399static int scarlett_ctl_enum_info(struct snd_kcontrol *kctl,
    400				  struct snd_ctl_elem_info *uinfo)
    401{
    402	struct usb_mixer_elem_info *elem = kctl->private_data;
    403	struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
    404
    405	return snd_ctl_enum_info(uinfo, elem->channels, opt->len,
    406				 (const char * const *)opt->names);
    407}
    408
    409static int scarlett_ctl_enum_get(struct snd_kcontrol *kctl,
    410				 struct snd_ctl_elem_value *ucontrol)
    411{
    412	struct usb_mixer_elem_info *elem = kctl->private_data;
    413	struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
    414	int err, val;
    415
    416	err = snd_usb_get_cur_mix_value(elem, 0, 0, &val);
    417	if (err < 0)
    418		return err;
    419
    420	val = clamp(val - opt->start, 0, opt->len-1);
    421
    422	ucontrol->value.enumerated.item[0] = val;
    423
    424	return 0;
    425}
    426
    427static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl,
    428				 struct snd_ctl_elem_value *ucontrol)
    429{
    430	struct usb_mixer_elem_info *elem = kctl->private_data;
    431	struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
    432	int err, oval, val;
    433
    434	err = snd_usb_get_cur_mix_value(elem, 0, 0, &oval);
    435	if (err < 0)
    436		return err;
    437
    438	val = ucontrol->value.integer.value[0];
    439	val = val + opt->start;
    440	if (val != oval) {
    441		snd_usb_set_cur_mix_value(elem, 0, 0, val);
    442		return 1;
    443	}
    444	return 0;
    445}
    446
    447static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list)
    448{
    449	struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
    450
    451	if (elem->cached)
    452		snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val);
    453	return 0;
    454}
    455
    456static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,
    457				  struct snd_ctl_elem_value *ucontrol)
    458{
    459	struct usb_mixer_elem_info *elem = kctl->private_data;
    460	struct snd_usb_audio *chip = elem->head.mixer->chip;
    461	unsigned char buf[2 * MAX_CHANNELS] = {0, };
    462	int wValue = (elem->control << 8) | elem->idx_off;
    463	int idx = snd_usb_ctrl_intf(chip) | (elem->head.id << 8);
    464	int err;
    465
    466	err = snd_usb_ctl_msg(chip->dev,
    467				usb_rcvctrlpipe(chip->dev, 0),
    468				UAC2_CS_MEM,
    469				USB_RECIP_INTERFACE | USB_TYPE_CLASS |
    470				USB_DIR_IN, wValue, idx, buf, elem->channels);
    471	if (err < 0)
    472		return err;
    473
    474	ucontrol->value.enumerated.item[0] = clamp((int)buf[0], 0, 1);
    475	return 0;
    476}
    477
    478static const struct snd_kcontrol_new usb_scarlett_ctl_switch = {
    479	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    480	.name = "",
    481	.info = scarlett_ctl_switch_info,
    482	.get =  scarlett_ctl_switch_get,
    483	.put =  scarlett_ctl_switch_put,
    484};
    485
    486static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0);
    487
    488static const struct snd_kcontrol_new usb_scarlett_ctl = {
    489	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    490	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
    491		  SNDRV_CTL_ELEM_ACCESS_TLV_READ,
    492	.name = "",
    493	.info = scarlett_ctl_info,
    494	.get =  scarlett_ctl_get,
    495	.put =  scarlett_ctl_put,
    496	.private_value = 6,  /* max value */
    497	.tlv = { .p = db_scale_scarlett_gain }
    498};
    499
    500static const struct snd_kcontrol_new usb_scarlett_ctl_master = {
    501	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    502	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
    503		  SNDRV_CTL_ELEM_ACCESS_TLV_READ,
    504	.name = "",
    505	.info = scarlett_ctl_info,
    506	.get =  scarlett_ctl_get,
    507	.put =  scarlett_ctl_put,
    508	.private_value = 6,  /* max value */
    509	.tlv = { .p = db_scale_scarlett_gain }
    510};
    511
    512static const struct snd_kcontrol_new usb_scarlett_ctl_enum = {
    513	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    514	.name = "",
    515	.info = scarlett_ctl_enum_info,
    516	.get =  scarlett_ctl_enum_get,
    517	.put =  scarlett_ctl_enum_put,
    518};
    519
    520static const struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
    521	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    522	.name = "",
    523	.info = scarlett_ctl_enum_dynamic_info,
    524	.get =  scarlett_ctl_enum_get,
    525	.put =  scarlett_ctl_enum_put,
    526};
    527
    528static const struct snd_kcontrol_new usb_scarlett_ctl_sync = {
    529	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    530	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    531	.name = "",
    532	.info = scarlett_ctl_enum_info,
    533	.get =  scarlett_ctl_meter_get,
    534};
    535
    536static int add_new_ctl(struct usb_mixer_interface *mixer,
    537		       const struct snd_kcontrol_new *ncontrol,
    538		       usb_mixer_elem_resume_func_t resume,
    539		       int index, int offset, int num,
    540		       int val_type, int channels, const char *name,
    541		       const struct scarlett_mixer_elem_enum_info *opt,
    542		       struct usb_mixer_elem_info **elem_ret
    543)
    544{
    545	struct snd_kcontrol *kctl;
    546	struct usb_mixer_elem_info *elem;
    547	int err;
    548
    549	elem = kzalloc(sizeof(*elem), GFP_KERNEL);
    550	if (!elem)
    551		return -ENOMEM;
    552
    553	elem->head.mixer = mixer;
    554	elem->head.resume = resume;
    555	elem->control = offset;
    556	elem->idx_off = num;
    557	elem->head.id = index;
    558	elem->val_type = val_type;
    559
    560	elem->channels = channels;
    561
    562	/* add scarlett_mixer_elem_enum_info struct */
    563	elem->private_data = (void *)opt;
    564
    565	kctl = snd_ctl_new1(ncontrol, elem);
    566	if (!kctl) {
    567		kfree(elem);
    568		return -ENOMEM;
    569	}
    570	kctl->private_free = snd_usb_mixer_elem_free;
    571
    572	strscpy(kctl->id.name, name, sizeof(kctl->id.name));
    573
    574	err = snd_usb_mixer_add_control(&elem->head, kctl);
    575	if (err < 0)
    576		return err;
    577
    578	if (elem_ret)
    579		*elem_ret = elem;
    580
    581	return 0;
    582}
    583
    584static int add_output_ctls(struct usb_mixer_interface *mixer,
    585			   int index, const char *name,
    586			   const struct scarlett_device_info *info)
    587{
    588	int err;
    589	char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
    590	struct usb_mixer_elem_info *elem;
    591
    592	/* Add mute switch */
    593	snprintf(mx, sizeof(mx), "Master %d (%s) Playback Switch",
    594		index + 1, name);
    595	err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
    596			  scarlett_ctl_resume, 0x0a, 0x01,
    597			  2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
    598	if (err < 0)
    599		return err;
    600
    601	/* Add volume control and initialize to 0 */
    602	snprintf(mx, sizeof(mx), "Master %d (%s) Playback Volume",
    603		index + 1, name);
    604	err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
    605			  scarlett_ctl_resume, 0x0a, 0x02,
    606			  2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
    607	if (err < 0)
    608		return err;
    609
    610	/* Add L channel source playback enumeration */
    611	snprintf(mx, sizeof(mx), "Master %dL (%s) Source Playback Enum",
    612		index + 1, name);
    613	err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
    614			  scarlett_ctl_enum_resume, 0x33, 0x00,
    615			  2*index, USB_MIXER_S16, 1, mx, &info->opt_master,
    616			  &elem);
    617	if (err < 0)
    618		return err;
    619
    620	/* Add R channel source playback enumeration */
    621	snprintf(mx, sizeof(mx), "Master %dR (%s) Source Playback Enum",
    622		index + 1, name);
    623	err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
    624			  scarlett_ctl_enum_resume, 0x33, 0x00,
    625			  2*index+1, USB_MIXER_S16, 1, mx, &info->opt_master,
    626			  &elem);
    627	if (err < 0)
    628		return err;
    629
    630	return 0;
    631}
    632
    633/********************** device-specific config *************************/
    634
    635/*  untested...  */
    636static const struct scarlett_device_info s6i6_info = {
    637	.matrix_in = 18,
    638	.matrix_out = 8,
    639	.input_len = 6,
    640	.output_len = 6,
    641
    642	.opt_master = {
    643		.start = -1,
    644		.len = 27,
    645		.offsets = {0, 12, 16, 18, 18},
    646		.names = NULL
    647	},
    648
    649	.opt_matrix = {
    650		.start = -1,
    651		.len = 19,
    652		.offsets = {0, 12, 16, 18, 18},
    653		.names = NULL
    654	},
    655
    656	.num_controls = 9,
    657	.controls = {
    658		{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
    659		{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
    660		{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
    661		{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    662		{ .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    663		{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    664		{ .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    665		{ .num = 3, .type = SCARLETT_SWITCH_GAIN, .name = NULL},
    666		{ .num = 4, .type = SCARLETT_SWITCH_GAIN, .name = NULL},
    667	},
    668
    669	.matrix_mux_init = {
    670		12, 13, 14, 15,                 /* Analog -> 1..4 */
    671		16, 17,                          /* SPDIF -> 5,6 */
    672		0, 1, 2, 3, 4, 5, 6, 7,     /* PCM[1..12] -> 7..18 */
    673		8, 9, 10, 11
    674	}
    675};
    676
    677/*  untested...  */
    678static const struct scarlett_device_info s8i6_info = {
    679	.matrix_in = 18,
    680	.matrix_out = 6,
    681	.input_len = 8,
    682	.output_len = 6,
    683
    684	.opt_master = {
    685		.start = -1,
    686		.len = 25,
    687		.offsets = {0, 12, 16, 18, 18},
    688		.names = NULL
    689	},
    690
    691	.opt_matrix = {
    692		.start = -1,
    693		.len = 19,
    694		.offsets = {0, 12, 16, 18, 18},
    695		.names = NULL
    696	},
    697
    698	.num_controls = 7,
    699	.controls = {
    700		{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
    701		{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
    702		{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
    703		{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    704		{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    705		{ .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    706		{ .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    707	},
    708
    709	.matrix_mux_init = {
    710		12, 13, 14, 15,                 /* Analog -> 1..4 */
    711		16, 17,                          /* SPDIF -> 5,6 */
    712		0, 1, 2, 3, 4, 5, 6, 7,     /* PCM[1..12] -> 7..18 */
    713		8, 9, 10, 11
    714	}
    715};
    716
    717static const struct scarlett_device_info s18i6_info = {
    718	.matrix_in = 18,
    719	.matrix_out = 6,
    720	.input_len = 18,
    721	.output_len = 6,
    722
    723	.opt_master = {
    724		.start = -1,
    725		.len = 31,
    726		.offsets = {0, 6, 14, 16, 24},
    727		.names = NULL,
    728	},
    729
    730	.opt_matrix = {
    731		.start = -1,
    732		.len = 25,
    733		.offsets = {0, 6, 14, 16, 24},
    734		.names = NULL,
    735	},
    736
    737	.num_controls = 5,
    738	.controls = {
    739		{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
    740		{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
    741		{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
    742		{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    743		{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    744	},
    745
    746	.matrix_mux_init = {
    747		 6,  7,  8,  9, 10, 11, 12, 13, /* Analog -> 1..8 */
    748		16, 17, 18, 19, 20, 21,     /* ADAT[1..6] -> 9..14 */
    749		14, 15,                          /* SPDIF -> 15,16 */
    750		0, 1                          /* PCM[1,2] -> 17,18 */
    751	}
    752};
    753
    754static const struct scarlett_device_info s18i8_info = {
    755	.matrix_in = 18,
    756	.matrix_out = 8,
    757	.input_len = 18,
    758	.output_len = 8,
    759
    760	.opt_master = {
    761		.start = -1,
    762		.len = 35,
    763		.offsets = {0, 8, 16, 18, 26},
    764		.names = NULL
    765	},
    766
    767	.opt_matrix = {
    768		.start = -1,
    769		.len = 27,
    770		.offsets = {0, 8, 16, 18, 26},
    771		.names = NULL
    772	},
    773
    774	.num_controls = 10,
    775	.controls = {
    776		{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
    777		{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone 1" },
    778		{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "Headphone 2" },
    779		{ .num = 3, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
    780		{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    781		{ .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    782		{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    783		{ .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    784		{ .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    785		{ .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    786	},
    787
    788	.matrix_mux_init = {
    789		 8,  9, 10, 11, 12, 13, 14, 15, /* Analog -> 1..8 */
    790		18, 19, 20, 21, 22, 23,     /* ADAT[1..6] -> 9..14 */
    791		16, 17,                          /* SPDIF -> 15,16 */
    792		0, 1                          /* PCM[1,2] -> 17,18 */
    793	}
    794};
    795
    796static const struct scarlett_device_info s18i20_info = {
    797	.matrix_in = 18,
    798	.matrix_out = 8,
    799	.input_len = 18,
    800	.output_len = 20,
    801
    802	.opt_master = {
    803		.start = -1,
    804		.len = 47,
    805		.offsets = {0, 20, 28, 30, 38},
    806		.names = NULL
    807	},
    808
    809	.opt_matrix = {
    810		.start = -1,
    811		.len = 39,
    812		.offsets = {0, 20, 28, 30, 38},
    813		.names = NULL
    814	},
    815
    816	.num_controls = 10,
    817	.controls = {
    818		{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
    819		{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Line 3/4" },
    820		{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "Line 5/6" },
    821		{ .num = 3, .type = SCARLETT_OUTPUTS, .name = "Line 7/8" },
    822		{ .num = 4, .type = SCARLETT_OUTPUTS, .name = "Line 9/10" },
    823		{ .num = 5, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
    824		{ .num = 6, .type = SCARLETT_OUTPUTS, .name = "ADAT 1/2" },
    825		{ .num = 7, .type = SCARLETT_OUTPUTS, .name = "ADAT 3/4" },
    826		{ .num = 8, .type = SCARLETT_OUTPUTS, .name = "ADAT 5/6" },
    827		{ .num = 9, .type = SCARLETT_OUTPUTS, .name = "ADAT 7/8" },
    828		/*{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    829		{ .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    830		{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
    831		{ .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    832		{ .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
    833		{ .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},*/
    834	},
    835
    836	.matrix_mux_init = {
    837		20, 21, 22, 23, 24, 25, 26, 27, /* Analog -> 1..8 */
    838		30, 31, 32, 33, 34, 35,     /* ADAT[1..6] -> 9..14 */
    839		28, 29,                          /* SPDIF -> 15,16 */
    840		0, 1                          /* PCM[1,2] -> 17,18 */
    841	}
    842};
    843
    844
    845static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer,
    846	const struct scarlett_device_info *info)
    847{
    848	int i, err;
    849	char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
    850	const struct scarlett_mixer_control *ctl;
    851	struct usb_mixer_elem_info *elem;
    852
    853	/* create master switch and playback volume */
    854	err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
    855			  scarlett_ctl_resume, 0x0a, 0x01, 0,
    856			  USB_MIXER_S16, 1, "Master Playback Switch", NULL,
    857			  &elem);
    858	if (err < 0)
    859		return err;
    860
    861	err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
    862			  scarlett_ctl_resume, 0x0a, 0x02, 0,
    863			  USB_MIXER_S16, 1, "Master Playback Volume", NULL,
    864			  &elem);
    865	if (err < 0)
    866		return err;
    867
    868	/* iterate through controls in info struct and create each one */
    869	for (i = 0; i < info->num_controls; i++) {
    870		ctl = &info->controls[i];
    871
    872		switch (ctl->type) {
    873		case SCARLETT_OUTPUTS:
    874			err = add_output_ctls(mixer, ctl->num, ctl->name, info);
    875			if (err < 0)
    876				return err;
    877			break;
    878		case SCARLETT_SWITCH_IMPEDANCE:
    879			sprintf(mx, "Input %d Impedance Switch", ctl->num);
    880			err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
    881					  scarlett_ctl_enum_resume, 0x01,
    882					  0x09, ctl->num, USB_MIXER_S16, 1, mx,
    883					  &opt_impedance, &elem);
    884			if (err < 0)
    885				return err;
    886			break;
    887		case SCARLETT_SWITCH_PAD:
    888			sprintf(mx, "Input %d Pad Switch", ctl->num);
    889			err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
    890					  scarlett_ctl_enum_resume, 0x01,
    891					  0x0b, ctl->num, USB_MIXER_S16, 1, mx,
    892					  &opt_pad, &elem);
    893			if (err < 0)
    894				return err;
    895			break;
    896		case SCARLETT_SWITCH_GAIN:
    897			sprintf(mx, "Input %d Gain Switch", ctl->num);
    898			err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
    899					  scarlett_ctl_enum_resume, 0x01,
    900					  0x08, ctl->num, USB_MIXER_S16, 1, mx,
    901					  &opt_gain, &elem);
    902			if (err < 0)
    903				return err;
    904			break;
    905		}
    906	}
    907
    908	return 0;
    909}
    910
    911/*
    912 * Create and initialize a mixer for the Focusrite(R) Scarlett
    913 */
    914int snd_scarlett_controls_create(struct usb_mixer_interface *mixer)
    915{
    916	int err, i, o;
    917	char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
    918	const struct scarlett_device_info *info;
    919	struct usb_mixer_elem_info *elem;
    920	static char sample_rate_buffer[4] = { '\x80', '\xbb', '\x00', '\x00' };
    921
    922	/* only use UAC_VERSION_2 */
    923	if (!mixer->protocol)
    924		return 0;
    925
    926	switch (mixer->chip->usb_id) {
    927	case USB_ID(0x1235, 0x8012):
    928		info = &s6i6_info;
    929		break;
    930	case USB_ID(0x1235, 0x8002):
    931		info = &s8i6_info;
    932		break;
    933	case USB_ID(0x1235, 0x8004):
    934		info = &s18i6_info;
    935		break;
    936	case USB_ID(0x1235, 0x8014):
    937		info = &s18i8_info;
    938		break;
    939	case USB_ID(0x1235, 0x800c):
    940		info = &s18i20_info;
    941		break;
    942	default: /* device not (yet) supported */
    943		return -EINVAL;
    944	}
    945
    946	/* generic function to create controls */
    947	err = scarlett_controls_create_generic(mixer, info);
    948	if (err < 0)
    949		return err;
    950
    951	/* setup matrix controls */
    952	for (i = 0; i < info->matrix_in; i++) {
    953		snprintf(mx, sizeof(mx), "Matrix %02d Input Playback Route",
    954			 i+1);
    955		err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
    956				  scarlett_ctl_enum_resume, 0x32,
    957				  0x06, i, USB_MIXER_S16, 1, mx,
    958				  &info->opt_matrix, &elem);
    959		if (err < 0)
    960			return err;
    961
    962		for (o = 0; o < info->matrix_out; o++) {
    963			sprintf(mx, "Matrix %02d Mix %c Playback Volume", i+1,
    964				o+'A');
    965			err = add_new_ctl(mixer, &usb_scarlett_ctl,
    966					  scarlett_ctl_resume, 0x3c, 0x00,
    967					  (i << 3) + (o & 0x07), USB_MIXER_S16,
    968					  1, mx, NULL, &elem);
    969			if (err < 0)
    970				return err;
    971
    972		}
    973	}
    974
    975	for (i = 0; i < info->input_len; i++) {
    976		snprintf(mx, sizeof(mx), "Input Source %02d Capture Route",
    977			 i+1);
    978		err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
    979				  scarlett_ctl_enum_resume, 0x34,
    980				  0x00, i, USB_MIXER_S16, 1, mx,
    981				  &info->opt_master, &elem);
    982		if (err < 0)
    983			return err;
    984	}
    985
    986	/* val_len == 1 needed here */
    987	err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
    988			  scarlett_ctl_enum_resume, 0x28, 0x01, 0,
    989			  USB_MIXER_U8, 1, "Sample Clock Source",
    990			  &opt_clock, &elem);
    991	if (err < 0)
    992		return err;
    993
    994	/* val_len == 1 and UAC2_CS_MEM */
    995	err = add_new_ctl(mixer, &usb_scarlett_ctl_sync, NULL, 0x3c, 0x00, 2,
    996			  USB_MIXER_U8, 1, "Sample Clock Sync Status",
    997			  &opt_sync, &elem);
    998	if (err < 0)
    999		return err;
   1000
   1001	/* initialize sampling rate to 48000 */
   1002	err = snd_usb_ctl_msg(mixer->chip->dev,
   1003		usb_sndctrlpipe(mixer->chip->dev, 0), UAC2_CS_CUR,
   1004		USB_RECIP_INTERFACE | USB_TYPE_CLASS |
   1005		USB_DIR_OUT, 0x0100, snd_usb_ctrl_intf(mixer->chip) |
   1006		(0x29 << 8), sample_rate_buffer, 4);
   1007	if (err < 0)
   1008		return err;
   1009
   1010	return err;
   1011}