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_s1810c.c (15629B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Presonus Studio 1810c driver for ALSA
      4 * Copyright (C) 2019 Nick Kossifidis <mickflemm@gmail.com>
      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#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/*
     35 * DISCLAIMER: These are just guesses based on the
     36 * dumps I got.
     37 *
     38 * It seems like a selects between
     39 * device (0), mixer (0x64) and output (0x65)
     40 *
     41 * For mixer (0x64):
     42 *  * b selects an input channel (see below).
     43 *  * c selects an output channel pair (see below).
     44 *  * 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
     48 *	in which case b is also set so I guess
     49 *	this way it is possible to set the volume
     50 *	level from the specified input to the
     51 *	specified output.
     52 *
     53 * IN Channels:
     54 * 0  - 7  Mic/Inst/Line (Analog inputs)
     55 * 8  - 9  S/PDIF
     56 * 10 - 17 ADAT
     57 * 18 - 35 DAW (Inputs from the host)
     58 *
     59 * OUT Channels (pairs):
     60 * 0 -> Main out
     61 * 1 -> Line1/2
     62 * 2 -> Line3/4
     63 * 3 -> S/PDIF
     64 * 4 -> ADAT?
     65 *
     66 * For device (0):
     67 *  * b and c are not used, at least not on the
     68 *    dumps I got.
     69 *  * d sets the control id to be modified
     70 *    (see below).
     71 *  * e sets the setting for that control.
     72 *    (so for the switches I was interested
     73 *    in it's 0/1)
     74 *
     75 * For output (0x65):
     76 *   * b is the output channel (see above).
     77 *   * c is zero.
     78 *   * e I guess the same as with mixer except 0x0109
     79 *	 which I didn't see in my dumps.
     80 *
     81 * The two fixed fields have the same values for
     82 * mixer and output but a different set for device.
     83 */
     84struct s1810c_ctl_packet {
     85	u32 a;
     86	u32 b;
     87	u32 fixed1;
     88	u32 fixed2;
     89	u32 c;
     90	u32 d;
     91	u32 e;
     92};
     93
     94#define SC1810C_CTL_LINE_SW	0
     95#define SC1810C_CTL_MUTE_SW	1
     96#define SC1810C_CTL_AB_SW	3
     97#define SC1810C_CTL_48V_SW	4
     98
     99#define SC1810C_SET_STATE_REQ	161
    100#define SC1810C_SET_STATE_REQTYPE SC1810C_CMD_REQTYPE
    101#define SC1810C_SET_STATE_F1	0x64656D73
    102#define SC1810C_SET_STATE_F2	0xF4
    103
    104#define SC1810C_GET_STATE_REQ	162
    105#define SC1810C_GET_STATE_REQTYPE \
    106	(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN)
    107#define SC1810C_GET_STATE_F1	SC1810C_SET_STATE_F1
    108#define SC1810C_GET_STATE_F2	SC1810C_SET_STATE_F2
    109
    110#define SC1810C_STATE_F1_IDX	2
    111#define SC1810C_STATE_F2_IDX	3
    112
    113/*
    114 * This packet includes mixer volumes and
    115 * various other fields, it's an extended
    116 * version of ctl_packet, with a and b
    117 * being zero and different f1/f2.
    118 */
    119struct s1810c_state_packet {
    120	u32 fields[63];
    121};
    122
    123#define SC1810C_STATE_48V_SW	58
    124#define SC1810C_STATE_LINE_SW	59
    125#define SC1810C_STATE_MUTE_SW	60
    126#define SC1810C_STATE_AB_SW	62
    127
    128struct s1810_mixer_state {
    129	uint16_t seqnum;
    130	struct mutex usb_mutex;
    131	struct mutex data_mutex;
    132};
    133
    134static int
    135snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 a,
    136			   u32 b, u32 c, u32 d, u32 e)
    137{
    138	struct s1810c_ctl_packet pkt = { 0 };
    139	int ret = 0;
    140
    141	pkt.fixed1 = SC1810C_CMD_F1;
    142	pkt.fixed2 = SC1810C_CMD_F2;
    143
    144	pkt.a = a;
    145	pkt.b = b;
    146	pkt.c = c;
    147	pkt.d = d;
    148	/*
    149	 * Value for settings 0/1 for this
    150	 * output channel is always 0 (probably because
    151	 * there is no ADAT output on 1810c)
    152	 */
    153	pkt.e = (c == 4) ? 0 : e;
    154
    155	ret = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
    156			      SC1810C_CMD_REQ,
    157			      SC1810C_CMD_REQTYPE, 0, 0, &pkt, sizeof(pkt));
    158	if (ret < 0) {
    159		dev_warn(&dev->dev, "could not send ctl packet\n");
    160		return ret;
    161	}
    162	return 0;
    163}
    164
    165/*
    166 * When opening Universal Control the program periodically
    167 * sends and receives state packets for syncinc state between
    168 * the device and the host.
    169 *
    170 * Note that if we send only the request to get data back we'll
    171 * get an error, we need to first send an empty state packet and
    172 * then ask to receive a filled. Their seqnumbers must also match.
    173 */
    174static int
    175snd_sc1810c_get_status_field(struct usb_device *dev,
    176			     u32 *field, int field_idx, uint16_t *seqnum)
    177{
    178	struct s1810c_state_packet pkt_out = { { 0 } };
    179	struct s1810c_state_packet pkt_in = { { 0 } };
    180	int ret = 0;
    181
    182	pkt_out.fields[SC1810C_STATE_F1_IDX] = SC1810C_SET_STATE_F1;
    183	pkt_out.fields[SC1810C_STATE_F2_IDX] = SC1810C_SET_STATE_F2;
    184	ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
    185			      SC1810C_SET_STATE_REQ,
    186			      SC1810C_SET_STATE_REQTYPE,
    187			      (*seqnum), 0, &pkt_out, sizeof(pkt_out));
    188	if (ret < 0) {
    189		dev_warn(&dev->dev, "could not send state packet (%d)\n", ret);
    190		return ret;
    191	}
    192
    193	ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
    194			      SC1810C_GET_STATE_REQ,
    195			      SC1810C_GET_STATE_REQTYPE,
    196			      (*seqnum), 0, &pkt_in, sizeof(pkt_in));
    197	if (ret < 0) {
    198		dev_warn(&dev->dev, "could not get state field %u (%d)\n",
    199			 field_idx, ret);
    200		return ret;
    201	}
    202
    203	(*field) = pkt_in.fields[field_idx];
    204	(*seqnum)++;
    205	return 0;
    206}
    207
    208/*
    209 * This is what I got when bypassing the mixer with
    210 * all channels split. I'm not 100% sure of what's going
    211 * on, I could probably clean this up based on my observations
    212 * but I prefer to keep the same behavior as the windows driver.
    213 */
    214static int snd_s1810c_init_mixer_maps(struct snd_usb_audio *chip)
    215{
    216	u32 a, b, c, e, n, off;
    217	struct usb_device *dev = chip->dev;
    218
    219	/* Set initial volume levels ? */
    220	a = 0x64;
    221	e = 0xbc;
    222	for (n = 0; n < 2; n++) {
    223		off = n * 18;
    224		for (b = off; b < 18 + off; b++) {
    225			/* This channel to all outputs ? */
    226			for (c = 0; c <= 8; c++) {
    227				snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
    228				snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
    229			}
    230			/* This channel to main output (again) */
    231			snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
    232			snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
    233		}
    234		/*
    235		 * I noticed on UC that DAW channels have different
    236		 * initial volumes, so this makes sense.
    237		 */
    238		e = 0xb53bf0;
    239	}
    240
    241	/* Connect analog outputs ? */
    242	a = 0x65;
    243	e = 0x01000000;
    244	for (b = 1; b < 3; b++) {
    245		snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
    246		snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
    247	}
    248	snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, e);
    249	snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, e);
    250
    251	/* Set initial volume levels for S/PDIF mappings ? */
    252	a = 0x64;
    253	e = 0xbc;
    254	c = 3;
    255	for (n = 0; n < 2; n++) {
    256		off = n * 18;
    257		for (b = off; b < 18 + off; b++) {
    258			snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
    259			snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
    260		}
    261		e = 0xb53bf0;
    262	}
    263
    264	/* Connect S/PDIF output ? */
    265	a = 0x65;
    266	e = 0x01000000;
    267	snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
    268	snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
    269
    270	/* Connect all outputs (again) ? */
    271	a = 0x65;
    272	e = 0x01000000;
    273	for (b = 0; b < 4; b++) {
    274		snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
    275		snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
    276	}
    277
    278	/* Basic routing to get sound out of the device */
    279	a = 0x64;
    280	e = 0x01000000;
    281	for (c = 0; c < 4; c++) {
    282		for (b = 0; b < 36; b++) {
    283			if ((c == 0 && b == 18) ||	/* DAW1/2 -> Main */
    284			    (c == 1 && b == 20) ||	/* DAW3/4 -> Line3/4 */
    285			    (c == 2 && b == 22) ||	/* DAW4/5 -> Line5/6 */
    286			    (c == 3 && b == 24)) {	/* DAW5/6 -> S/PDIF */
    287				/* Left */
    288				snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
    289				snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
    290				b++;
    291				/* Right */
    292				snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
    293				snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
    294			} else {
    295				/* Leave the rest disconnected */
    296				snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
    297				snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
    298			}
    299		}
    300	}
    301
    302	/* Set initial volume levels for S/PDIF (again) ? */
    303	a = 0x64;
    304	e = 0xbc;
    305	c = 3;
    306	for (n = 0; n < 2; n++) {
    307		off = n * 18;
    308		for (b = off; b < 18 + off; b++) {
    309			snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
    310			snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
    311		}
    312		e = 0xb53bf0;
    313	}
    314
    315	/* Connect S/PDIF outputs (again) ? */
    316	a = 0x65;
    317	e = 0x01000000;
    318	snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
    319	snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
    320
    321	/* Again ? */
    322	snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
    323	snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
    324
    325	return 0;
    326}
    327
    328/*
    329 * Sync state with the device and retrieve the requested field,
    330 * whose index is specified in (kctl->private_value & 0xFF),
    331 * from the received fields array.
    332 */
    333static int
    334snd_s1810c_get_switch_state(struct usb_mixer_interface *mixer,
    335			    struct snd_kcontrol *kctl, u32 *state)
    336{
    337	struct snd_usb_audio *chip = mixer->chip;
    338	struct s1810_mixer_state *private = mixer->private_data;
    339	u32 field = 0;
    340	u32 ctl_idx = (u32) (kctl->private_value & 0xFF);
    341	int ret = 0;
    342
    343	mutex_lock(&private->usb_mutex);
    344	ret = snd_sc1810c_get_status_field(chip->dev, &field,
    345					   ctl_idx, &private->seqnum);
    346	if (ret < 0)
    347		goto unlock;
    348
    349	*state = field;
    350 unlock:
    351	mutex_unlock(&private->usb_mutex);
    352	return ret ? ret : 0;
    353}
    354
    355/*
    356 * Send a control packet to the device for the control id
    357 * specified in (kctl->private_value >> 8) with value
    358 * specified in (kctl->private_value >> 16).
    359 */
    360static int
    361snd_s1810c_set_switch_state(struct usb_mixer_interface *mixer,
    362			    struct snd_kcontrol *kctl)
    363{
    364	struct snd_usb_audio *chip = mixer->chip;
    365	struct s1810_mixer_state *private = mixer->private_data;
    366	u32 pval = (u32) kctl->private_value;
    367	u32 ctl_id = (pval >> 8) & 0xFF;
    368	u32 ctl_val = (pval >> 16) & 0x1;
    369	int ret = 0;
    370
    371	mutex_lock(&private->usb_mutex);
    372	ret = snd_s1810c_send_ctl_packet(chip->dev, 0, 0, 0, ctl_id, ctl_val);
    373	mutex_unlock(&private->usb_mutex);
    374	return ret;
    375}
    376
    377/* Generic get/set/init functions for switch controls */
    378
    379static int
    380snd_s1810c_switch_get(struct snd_kcontrol *kctl,
    381		      struct snd_ctl_elem_value *ctl_elem)
    382{
    383	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
    384	struct usb_mixer_interface *mixer = list->mixer;
    385	struct s1810_mixer_state *private = mixer->private_data;
    386	u32 pval = (u32) kctl->private_value;
    387	u32 ctl_idx = pval & 0xFF;
    388	u32 state = 0;
    389	int ret = 0;
    390
    391	mutex_lock(&private->data_mutex);
    392	ret = snd_s1810c_get_switch_state(mixer, kctl, &state);
    393	if (ret < 0)
    394		goto unlock;
    395
    396	switch (ctl_idx) {
    397	case SC1810C_STATE_LINE_SW:
    398	case SC1810C_STATE_AB_SW:
    399		ctl_elem->value.enumerated.item[0] = (int)state;
    400		break;
    401	default:
    402		ctl_elem->value.integer.value[0] = (long)state;
    403	}
    404
    405 unlock:
    406	mutex_unlock(&private->data_mutex);
    407	return (ret < 0) ? ret : 0;
    408}
    409
    410static int
    411snd_s1810c_switch_set(struct snd_kcontrol *kctl,
    412		      struct snd_ctl_elem_value *ctl_elem)
    413{
    414	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
    415	struct usb_mixer_interface *mixer = list->mixer;
    416	struct s1810_mixer_state *private = mixer->private_data;
    417	u32 pval = (u32) kctl->private_value;
    418	u32 ctl_idx = pval & 0xFF;
    419	u32 curval = 0;
    420	u32 newval = 0;
    421	int ret = 0;
    422
    423	mutex_lock(&private->data_mutex);
    424	ret = snd_s1810c_get_switch_state(mixer, kctl, &curval);
    425	if (ret < 0)
    426		goto unlock;
    427
    428	switch (ctl_idx) {
    429	case SC1810C_STATE_LINE_SW:
    430	case SC1810C_STATE_AB_SW:
    431		newval = (u32) ctl_elem->value.enumerated.item[0];
    432		break;
    433	default:
    434		newval = (u32) ctl_elem->value.integer.value[0];
    435	}
    436
    437	if (curval == newval)
    438		goto unlock;
    439
    440	kctl->private_value &= ~(0x1 << 16);
    441	kctl->private_value |= (unsigned int)(newval & 0x1) << 16;
    442	ret = snd_s1810c_set_switch_state(mixer, kctl);
    443
    444 unlock:
    445	mutex_unlock(&private->data_mutex);
    446	return (ret < 0) ? 0 : 1;
    447}
    448
    449static int
    450snd_s1810c_switch_init(struct usb_mixer_interface *mixer,
    451		       const struct snd_kcontrol_new *new_kctl)
    452{
    453	struct snd_kcontrol *kctl;
    454	struct usb_mixer_elem_info *elem;
    455
    456	elem = kzalloc(sizeof(struct usb_mixer_elem_info), GFP_KERNEL);
    457	if (!elem)
    458		return -ENOMEM;
    459
    460	elem->head.mixer = mixer;
    461	elem->control = 0;
    462	elem->head.id = 0;
    463	elem->channels = 1;
    464
    465	kctl = snd_ctl_new1(new_kctl, elem);
    466	if (!kctl) {
    467		kfree(elem);
    468		return -ENOMEM;
    469	}
    470	kctl->private_free = snd_usb_mixer_elem_free;
    471
    472	return snd_usb_mixer_add_control(&elem->head, kctl);
    473}
    474
    475static int
    476snd_s1810c_line_sw_info(struct snd_kcontrol *kctl,
    477			struct snd_ctl_elem_info *uinfo)
    478{
    479	static const char *const texts[2] = {
    480		"Preamp On (Mic/Inst)",
    481		"Preamp Off (Line in)"
    482	};
    483
    484	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
    485}
    486
    487static const struct snd_kcontrol_new snd_s1810c_line_sw = {
    488	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    489	.name = "Line 1/2 Source Type",
    490	.info = snd_s1810c_line_sw_info,
    491	.get = snd_s1810c_switch_get,
    492	.put = snd_s1810c_switch_set,
    493	.private_value = (SC1810C_STATE_LINE_SW | SC1810C_CTL_LINE_SW << 8)
    494};
    495
    496static const struct snd_kcontrol_new snd_s1810c_mute_sw = {
    497	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    498	.name = "Mute Main Out Switch",
    499	.info = snd_ctl_boolean_mono_info,
    500	.get = snd_s1810c_switch_get,
    501	.put = snd_s1810c_switch_set,
    502	.private_value = (SC1810C_STATE_MUTE_SW | SC1810C_CTL_MUTE_SW << 8)
    503};
    504
    505static const struct snd_kcontrol_new snd_s1810c_48v_sw = {
    506	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    507	.name = "48V Phantom Power On Mic Inputs Switch",
    508	.info = snd_ctl_boolean_mono_info,
    509	.get = snd_s1810c_switch_get,
    510	.put = snd_s1810c_switch_set,
    511	.private_value = (SC1810C_STATE_48V_SW | SC1810C_CTL_48V_SW << 8)
    512};
    513
    514static int
    515snd_s1810c_ab_sw_info(struct snd_kcontrol *kctl,
    516		      struct snd_ctl_elem_info *uinfo)
    517{
    518	static const char *const texts[2] = {
    519		"1/2",
    520		"3/4"
    521	};
    522
    523	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
    524}
    525
    526static const struct snd_kcontrol_new snd_s1810c_ab_sw = {
    527	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    528	.name = "Headphone 1 Source Route",
    529	.info = snd_s1810c_ab_sw_info,
    530	.get = snd_s1810c_switch_get,
    531	.put = snd_s1810c_switch_set,
    532	.private_value = (SC1810C_STATE_AB_SW | SC1810C_CTL_AB_SW << 8)
    533};
    534
    535static void snd_sc1810_mixer_state_free(struct usb_mixer_interface *mixer)
    536{
    537	struct s1810_mixer_state *private = mixer->private_data;
    538	kfree(private);
    539	mixer->private_data = NULL;
    540}
    541
    542/* Entry point, called from mixer_quirks.c */
    543int snd_sc1810_init_mixer(struct usb_mixer_interface *mixer)
    544{
    545	struct s1810_mixer_state *private = NULL;
    546	struct snd_usb_audio *chip = mixer->chip;
    547	struct usb_device *dev = chip->dev;
    548	int ret = 0;
    549
    550	/* Run this only once */
    551	if (!list_empty(&chip->mixer_list))
    552		return 0;
    553
    554	dev_info(&dev->dev,
    555		 "Presonus Studio 1810c, device_setup: %u\n", chip->setup);
    556	if (chip->setup == 1)
    557		dev_info(&dev->dev, "(8out/18in @ 48kHz)\n");
    558	else if (chip->setup == 2)
    559		dev_info(&dev->dev, "(6out/8in @ 192kHz)\n");
    560	else
    561		dev_info(&dev->dev, "(8out/14in @ 96kHz)\n");
    562
    563	ret = snd_s1810c_init_mixer_maps(chip);
    564	if (ret < 0)
    565		return ret;
    566
    567	private = kzalloc(sizeof(struct s1810_mixer_state), GFP_KERNEL);
    568	if (!private)
    569		return -ENOMEM;
    570
    571	mutex_init(&private->usb_mutex);
    572	mutex_init(&private->data_mutex);
    573
    574	mixer->private_data = private;
    575	mixer->private_free = snd_sc1810_mixer_state_free;
    576
    577	private->seqnum = 1;
    578
    579	ret = snd_s1810c_switch_init(mixer, &snd_s1810c_line_sw);
    580	if (ret < 0)
    581		return ret;
    582
    583	ret = snd_s1810c_switch_init(mixer, &snd_s1810c_mute_sw);
    584	if (ret < 0)
    585		return ret;
    586
    587	ret = snd_s1810c_switch_init(mixer, &snd_s1810c_48v_sw);
    588	if (ret < 0)
    589		return ret;
    590
    591	ret = snd_s1810c_switch_init(mixer, &snd_s1810c_ab_sw);
    592	if (ret < 0)
    593		return ret;
    594	return ret;
    595}