linux/sound/usb/mixer_scarlett2.c

// SPDX-License-Identifier: GPL-2.0
/*
 *   Focusrite Scarlett 2 Protocol Driver for ALSA
 *   (including Scarlett 2nd Gen, 3rd Gen, 4th Gen, Clarett USB, and
 *   Clarett+ series products)
 *
 *   Supported models:
 *   - 6i6/18i8/18i20 Gen 2
 *   - Solo/2i2/4i4/8i6/18i8/18i20 Gen 3
 *   - Solo/2i2/4i4 Gen 4
 *   - Clarett 2Pre/4Pre/8Pre USB
 *   - Clarett+ 2Pre/4Pre/8Pre
 *
 *   Copyright (c) 2018-2023 by Geoffrey D. Bennett <g at b4.vu>
 *   Copyright (c) 2020-2021 by Vladimir Sadovnikov <[email protected]>
 *   Copyright (c) 2022 by Christian Colglazier <[email protected]>
 *
 *   Based on the Scarlett (Gen 1) Driver for ALSA:
 *
 *   Copyright (c) 2013 by Tobias Hoffmann
 *   Copyright (c) 2013 by Robin Gareus <robin at gareus.org>
 *   Copyright (c) 2002 by Takashi Iwai <tiwai at suse.de>
 *   Copyright (c) 2014 by Chris J Arges <chris.j.arges at canonical.com>
 *
 *   Many codes borrowed from audio.c by
 *     Alan Cox (alan at lxorguk.ukuu.org.uk)
 *     Thomas Sailer (sailer at ife.ee.ethz.ch)
 *
 *   Code cleanup:
 *   David Henningsson <david.henningsson at canonical.com>
 */

/* The protocol was reverse engineered by looking at the communication
 * between Focusrite Control 2.3.4 and the Focusrite(R) Scarlett 18i20
 * (firmware 1083) using usbmon in July-August 2018.
 *
 * Scarlett 18i8 support added in April 2019.
 *
 * Scarlett 6i6 support added in June 2019 (thanks to Martin Wittmann
 * for providing usbmon output and testing).
 *
 * Scarlett 4i4/8i6 Gen 3 support added in May 2020 (thanks to Laurent
 * Debricon for donating a 4i4 and to Fredrik Unger for providing 8i6
 * usbmon output and testing).
 *
 * Scarlett 18i8/18i20 Gen 3 support added in June 2020 (thanks to
 * Darren Jaeckel, Alex Sedlack, and Clovis Lunel for providing usbmon
 * output, protocol traces and testing).
 *
 * Support for loading mixer volume and mux configuration from the
 * interface during driver initialisation added in May 2021 (thanks to
 * Vladimir Sadovnikov for figuring out how).
 *
 * Support for Solo/2i2 Gen 3 added in May 2021 (thanks to Alexander
 * Vorona for 2i2 protocol traces).
 *
 * Support for phantom power, direct monitoring, speaker switching,
 * and talkback added in May-June 2021.
 *
 * Support for Clarett+ 8Pre added in Aug 2022 by Christian
 * Colglazier.
 *
 * Support for Clarett 8Pre USB added in Sep 2023 (thanks to Philippe
 * Perrot for confirmation).
 *
 * Support for Clarett+ 4Pre and 2Pre added in Sep 2023 (thanks to
 * Gregory Rozzo for donating a 4Pre, and David Sherwood and Patrice
 * Peterson for usbmon output).
 *
 * Support for Clarett 2Pre and 4Pre USB added in Oct 2023.
 *
 * Support for firmware updates added in Dec 2023.
 *
 * Support for Scarlett Solo/2i2/4i4 Gen 4 added in Dec 2023 (thanks
 * to many LinuxMusicians people and to Focusrite for hardware
 * donations).
 *
 * This ALSA mixer gives access to (model-dependent):
 *  - input, output, mixer-matrix muxes
 *  - mixer-matrix gain stages
 *  - gain/volume/mute controls
 *  - level meters
 *  - line/inst level, pad, and air controls
 *  - phantom power, direct monitor, speaker switching, and talkback
 *    controls
 *  - disable/enable MSD mode
 *  - disable/enable standalone mode
 *  - input mute, gain, autogain, safe mode
 *  - direct monitor mixes
 *  - compressor and EQ
 *  - Bluetooth volume
 *
 * <ditaa>
 *    /--------------\    18chn            20chn     /--------------\
 *    | Hardware  in +--+------\    /-------------+--+ ALSA PCM out |
 *    \--------------/  |      |    |             |  \--------------/
 *                      |      |    |    /-----\  |
 *                      |      |    |    |     |  |
 *                      |      v    v    v     |  |
 *                      |   +---------------+  |  |
 *                      |    \ Matrix  Mux /   |  |
 *                      |     +-----+-----+    |  |
 *                      |           |          |  |
 *                      |           |18chn     |  |
 *                      |           |          |  |
 *                      |           |     10chn|  |
 *                      |           v          |  |
 *                      |     +------------+   |  |
 *                      |     | Mixer      |   |  |
 *                      |     |     Matrix |   |  |
 *                      |     |            |   |  |
 *                      |     | 18x10 Gain |   |  |
 *                      |     |   stages   |   |  |
 *                      |     +-----+------+   |  |
 *                      |           |          |  |
 *                      |18chn      |10chn     |  |20chn
 *                      |           |          |  |
 *                      |           +----------/  |
 *                      |           |             |
 *                      v           v             v
 *                      ===========================
 *               +---------------+       +--—------------+
 *                \ Output  Mux /         \ Capture Mux /
 *                 +---+---+---+           +-----+-----+
 *                     |   |                     |
 *                10chn|   |                     |18chn
 *                     |   |                     |
 *  /--------------\   |   |                     |   /--------------\
 *  | S/PDIF, ADAT |<--/   |10chn                \-->| ALSA PCM in  |
 *  | Hardware out |       |                         \--------------/
 *  \--------------/       |
 *                         v
 *                  +-------------+    Software gain per channel.
 *                  | Master Gain |<-- 18i20 only: Switch per channel
 *                  +------+------+    to select HW or SW gain control.
 *                         |
 *                         |10chn
 *  /--------------\       |
 *  | Analogue     |<------/
 *  | Hardware out |
 *  \--------------/
 * </ditaa>
 *
 * Gen 3/4 devices have a Mass Storage Device (MSD) mode where a small
 * disk with registration and driver download information is presented
 * to the host. To access the full functionality of the device without
 * proprietary software, MSD mode can be disabled by:
 * - holding down the 48V button for five seconds while powering on
 *   the device, or
 * - using this driver and alsamixer to change the "MSD Mode" setting
 *   to Off and power-cycling the device
 */

#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/moduleparam.h>

#include <sound/control.h>
#include <sound/tlv.h>
#include <sound/hwdep.h>

#include <uapi/sound/scarlett2.h>

#include "usbaudio.h"
#include "mixer.h"
#include "helper.h"

#include "mixer_scarlett2.h"

/* device_setup value to allow turning MSD mode back on */
#define SCARLETT2_MSD_ENABLE

/* device_setup value to disable this mixer driver */
#define SCARLETT2_DISABLE

/* some gui mixers can't handle negative ctl values */
#define SCARLETT2_VOLUME_BIAS

/* maximum preamp input gain value
 * (the corresponding value in dB is per-device)
 */
#define SCARLETT2_MAX_GAIN_VALUE

/* maximum Bluetooth volume value */
#define SCARLETT2_MAX_BLUETOOTH_VOLUME

/* mixer range from -80dB to +12dB in 0.5dB steps */
#define SCARLETT2_MIXER_MIN_DB
#define SCARLETT2_MIXER_BIAS
#define SCARLETT2_MIXER_MAX_DB
#define SCARLETT2_MIXER_MAX_VALUE
#define SCARLETT2_MIXER_VALUE_COUNT

/* map from (dB + 80) * 2 to mixer value
 * for dB in 0 .. 184: int(8192 * pow(10, ((dB - 160) / 2 / 20)))
 */
static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] =;

/* Maximum number of analogue outputs */
#define SCARLETT2_ANALOGUE_MAX

/* Maximum number of various input controls */
#define SCARLETT2_LEVEL_SWITCH_MAX
#define SCARLETT2_PAD_SWITCH_MAX
#define SCARLETT2_AIR_SWITCH_MAX
#define SCARLETT2_DSP_SWITCH_MAX
#define SCARLETT2_INPUT_MUTE_SWITCH_MAX
#define SCARLETT2_PHANTOM_SWITCH_MAX
#define SCARLETT2_INPUT_GAIN_MAX

/* Maximum number of inputs to the mixer */
#define SCARLETT2_INPUT_MIX_MAX

/* Maximum number of outputs from the mixer */
#define SCARLETT2_OUTPUT_MIX_MAX

/* Maximum number of mixer gain controls */
#define SCARLETT2_MIX_MAX

/* Maximum number of direct monitor mixer gain controls
 * 1 (Solo) or 2 (2i2) direct monitor selections (Mono & Stereo)
 * 2 Mix outputs (A/Left & B/Right)
 * 4 Mix inputs
 */
#define SCARLETT2_MONITOR_MIX_MAX

/* Maximum size of the data in the USB mux assignment message:
 * 20 inputs, 20 outputs, 25 matrix inputs, 12 spare
 */
#define SCARLETT2_MUX_MAX

/* Maximum number of sources (sum of input port counts) */
#define SCARLETT2_MAX_SRCS

/* Maximum number of meters (sum of output port counts) */
#define SCARLETT2_MAX_METERS

/* Compressor parameter data
 *
 * The compressor parameters are 32-bit fixed point values with 24
 * bits of fraction. Integer values are sufficient for the parameters
 * except for ratio which we can set in 0.5:1 steps.
 */
struct compressor_param {};

/* The available compressor parameters on the Vocaster:
 * - Enable: Off, On
 * - Threshold: -40dB to 0dB
 * - Ratio: 1:1 to 50:1 in 0.5:1 steps
 * - Knee Width: 0dB to 10dB
 * - Attack: 30ms to 127ms
 * - Release: 30ms to 127ms
 * - Makeup Gain: 0dB to 24dB
 */
static const struct compressor_param compressor_params[] =;

#define SCARLETT2_COMPRESSOR_PARAM_COUNT
#define SCARLETT2_COMPRESSOR_CTLS_MAX

/* Maximum number of filter controls */
#define SCARLETT2_PRECOMP_FLT_CTLS_MAX
#define SCARLETT2_PEQ_FLT_CTLS_MAX

/* Number of biquad filter coefficients */
#define SCARLETT2_BIQUAD_COEFFS

/* Maximum number of filter coefficient values */
#define SCARLETT2_PRECOMP_FLT_VALUES_MAX
#define SCARLETT2_PEQ_FLT_VALUES_MAX

/* Maximum number of PEQ filter slots */
#define SCARLETT2_PEQ_FLT_SLOTS_MAX

/* Hardware port types:
 * - None (no input to mux)
 * - Analogue I/O
 * - S/PDIF I/O
 * - ADAT I/O
 * - Mixer I/O
 * - PCM I/O
 */
enum {};

/* I/O count of each port type kept in struct scarlett2_ports */
enum {};

/* Dim/Mute buttons on the 18i20 */
enum {};

/* Autogain target values */

#define SCARLETT2_AG_TARGET_MIN

enum {};

/* Flash Write State */
enum {};

static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] =;

/* The autogain_status is set based on the autogain_switch and
 * raw_autogain_status values.
 *
 * If autogain_switch is set, autogain_status is set to 0 (Running).
 * The other status values are from the raw_autogain_status value + 1.
 */
static const char *const scarlett2_autogain_status_gen4[] =;

static const char *const scarlett2_autogain_status_vocaster[] =;

/* Power Status Values */
enum {};

/* Notification callback functions */
struct scarlett2_notification {};

static void scarlett2_notify_ack(struct usb_mixer_interface *mixer);
static void scarlett2_notify_sync(struct usb_mixer_interface *mixer);
static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer);
static void scarlett2_notify_monitor(struct usb_mixer_interface *mixer);
static void scarlett2_notify_volume(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_level(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_pad(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_air(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_dsp(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_mute(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_phantom(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_other(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_select(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_gain(struct usb_mixer_interface *mixer);
static void scarlett2_notify_autogain(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_safe(struct usb_mixer_interface *mixer);
static void scarlett2_notify_monitor_other(struct usb_mixer_interface *mixer);
static void scarlett2_notify_direct_monitor(struct usb_mixer_interface *mixer);
static void scarlett2_notify_power_status(struct usb_mixer_interface *mixer);
static void scarlett2_notify_pcm_input_switch(
					struct usb_mixer_interface *mixer);
static void scarlett2_notify_bluetooth(struct usb_mixer_interface *mixer);

/* Arrays of notification callback functions */

static const struct scarlett2_notification scarlett2_notifications[] =;

static const struct scarlett2_notification scarlett3a_notifications[] =;

static const struct scarlett2_notification vocaster_notifications[] =;

static const struct scarlett2_notification scarlett4_solo_notifications[] =;

static const struct scarlett2_notification scarlett4_2i2_notifications[] =;

static const struct scarlett2_notification scarlett4_4i4_notifications[] =;

/* Configuration parameters that can be read and written */
enum {};

/* Autogain target configuration parameters and names */

static const int scarlett2_ag_target_configs[] =;

static const char *const scarlett2_ag_target_names[] =;

/* Location, size, and activation command number for the configuration
 * parameters. Size is in bits and may be 1, 8, 16, or 32.
 *
 * Vocaster and 4th Gen devices have a parameter buffer to set certain
 * configuration parameters. When pbuf is set, rather than writing to
 * the given offset, the channel and value are written to the
 * parameter buffer and the activate command is sent to the device.
 *
 * Some Gen 4 configuration parameters are written with 0x02 for a
 * desired value of 0x01, and 0x03 for 0x00. These are indicated with
 * mute set to 1. 0x02 and 0x03 are temporary values while the device
 * makes the change and the channel and/or corresponding DSP channel
 * output is muted.
 */
struct scarlett2_config {};

struct scarlett2_config_set {};

/* Input gain TLV dB ranges */

static const DECLARE_TLV_DB_MINMAX(
	db_scale_vocaster_gain, 0, 70 * 100
);

static const DECLARE_TLV_DB_MINMAX(
	db_scale_gen4_gain, 0, 69 * 100
);

/* Gen 2 devices without SW/HW volume switch: 6i6, 18i8 */

static const struct scarlett2_config_set scarlett2_config_set_gen2a =;

/* Gen 2 devices with SW/HW volume switch: 18i20 */

static const struct scarlett2_config_set scarlett2_config_set_gen2b =;

/* Gen 3 devices without a mixer (Solo and 2i2) */
static const struct scarlett2_config_set scarlett2_config_set_gen3a =;

/* Gen 3 devices without SW/HW volume switch: 4i4, 8i6 */
static const struct scarlett2_config_set scarlett2_config_set_gen3b =;

/* Gen 3 devices with SW/HW volume switch: 18i8, 18i20 */
static const struct scarlett2_config_set scarlett2_config_set_gen3c =;

/* Vocaster */
static const struct scarlett2_config_set scarlett2_config_set_vocaster =;

/* Solo Gen 4 */
static const struct scarlett2_config_set scarlett2_config_set_gen4_solo =;

/* 2i2 Gen 4 */
static const struct scarlett2_config_set scarlett2_config_set_gen4_2i2 =;

/* 4i4 Gen 4 */
static const struct scarlett2_config_set scarlett2_config_set_gen4_4i4 =;

/* Clarett USB and Clarett+ devices: 2Pre, 4Pre, 8Pre */
static const struct scarlett2_config_set scarlett2_config_set_clarett =;

/* Description of each hardware port type:
 * - id: hardware ID of this port type
 * - src_descr: printf format string for mux input selections
 * - src_num_offset: added to channel number for the fprintf
 * - dst_descr: printf format string for mixer controls
 */
struct scarlett2_port {};

static const struct scarlett2_port scarlett2_ports[SCARLETT2_PORT_TYPE_COUNT] =;

/* Number of mux tables: one for each band of sample rates
 * (44.1/48kHz, 88.2/96kHz, and 176.4/176kHz)
 */
#define SCARLETT2_MUX_TABLES

/* Maximum number of entries in a mux table */
#define SCARLETT2_MAX_MUX_ENTRIES

/* One entry within mux_assignment defines the port type and range of
 * ports to add to the set_mux message. The end of the list is marked
 * with count == 0.
 */
struct scarlett2_mux_entry {};

/* Maximum number of entries in a mux table */
#define SCARLETT2_MAX_METER_ENTRIES

/* One entry within meter_assignment defines the range of mux outputs
 * that consecutive meter entries are mapped to. The end of the list
 * is marked with count == 0.
 */
struct scarlett2_meter_entry {};

struct scarlett2_device_info {};

struct scarlett2_data {};

/*** Model-specific data ***/

static const struct scarlett2_device_info s6i6_gen2_info =;

static const struct scarlett2_device_info s18i8_gen2_info =;

static const struct scarlett2_device_info s18i20_gen2_info =;

static const struct scarlett2_device_info solo_gen3_info =;

static const struct scarlett2_device_info s2i2_gen3_info =;

static const struct scarlett2_device_info s4i4_gen3_info =;

static const struct scarlett2_device_info s8i6_gen3_info =;

static const u8 scarlett2_spdif_s18i8_gen3_values[] =;

static const char * const scarlett2_spdif_s18i8_gen3_texts[] =;

static const struct scarlett2_device_info s18i8_gen3_info =;

static const u8 scarlett2_spdif_s18i20_gen3_values[] =;

static const char * const scarlett2_spdif_s18i20_gen3_texts[] =;

static const struct scarlett2_device_info s18i20_gen3_info =;

static const struct scarlett2_device_info vocaster_one_info =;

static const struct scarlett2_device_info vocaster_two_info =;

static const struct scarlett2_device_info solo_gen4_info =;

static const struct scarlett2_device_info s2i2_gen4_info =;

static const struct scarlett2_device_info s4i4_gen4_info =;

static const struct scarlett2_device_info clarett_2pre_info =;

static const u8 scarlett2_spdif_clarett_values[] =;

static const char * const scarlett2_spdif_clarett_texts[] =;

static const struct scarlett2_device_info clarett_4pre_info =;

static const struct scarlett2_device_info clarett_8pre_info =;

struct scarlett2_device_entry {};

static const struct scarlett2_device_entry scarlett2_devices[] =;

/* get the starting port index number for a given port type/direction */
static int scarlett2_get_port_start_num(
	const int port_count[][SCARLETT2_PORT_DIRNS],
	int direction, int port_type)
{}

/*** USB Interactions ***/

/* Commands for sending/receiving requests/responses */
#define SCARLETT2_USB_CMD_INIT
#define SCARLETT2_USB_CMD_REQ
#define SCARLETT2_USB_CMD_RESP

#define SCARLETT2_USB_INIT_1
#define SCARLETT2_USB_INIT_2
#define SCARLETT2_USB_REBOOT
#define SCARLETT2_USB_GET_METER
#define SCARLETT2_USB_GET_MIX
#define SCARLETT2_USB_SET_MIX
#define SCARLETT2_USB_GET_MUX
#define SCARLETT2_USB_SET_MUX
#define SCARLETT2_USB_INFO_FLASH
#define SCARLETT2_USB_INFO_SEGMENT
#define SCARLETT2_USB_ERASE_SEGMENT
#define SCARLETT2_USB_GET_ERASE
#define SCARLETT2_USB_WRITE_SEGMENT
#define SCARLETT2_USB_READ_SEGMENT
#define SCARLETT2_USB_GET_SYNC
#define SCARLETT2_USB_GET_DATA
#define SCARLETT2_USB_SET_DATA
#define SCARLETT2_USB_DATA_CMD

#define SCARLETT2_USB_CONFIG_SAVE

#define SCARLETT2_USB_METER_LEVELS_GET_MAGIC

#define SCARLETT2_FLASH_BLOCK_SIZE
#define SCARLETT2_FLASH_RW_MAX
#define SCARLETT2_SEGMENT_NUM_MIN
#define SCARLETT2_SEGMENT_NUM_MAX

#define SCARLETT2_SEGMENT_SETTINGS_NAME
#define SCARLETT2_SEGMENT_FIRMWARE_NAME

/* proprietary request/response format */
struct scarlett2_usb_packet {};

static void scarlett2_fill_request_header(struct scarlett2_data *private,
					  struct scarlett2_usb_packet *req,
					  u32 cmd, u16 req_size)
{}

static int scarlett2_usb_tx(struct usb_device *dev, int interface,
			    void *buf, u16 size)
{}

static int scarlett2_usb_rx(struct usb_device *dev, int interface,
			    u32 usb_req, void *buf, u16 size)
{}

/* Send a proprietary format request to the Scarlett interface */
static int scarlett2_usb(
	struct usb_mixer_interface *mixer, u32 cmd,
	void *req_data, u16 req_size, void *resp_data, u16 resp_size)
{}

/* Send a USB message to get data; result placed in *buf */
static int scarlett2_usb_get(
	struct usb_mixer_interface *mixer,
	int offset, void *buf, int size)
{}

/* Return true if the given configuration item is present in the
 * configuration set used by this device.
 */
static int scarlett2_has_config_item(
	struct scarlett2_data *private, int config_item_num)
{}

/* Send a USB message to get configuration parameters; result placed in *buf */
static int scarlett2_usb_get_config(
	struct usb_mixer_interface *mixer,
	int config_item_num, int count, void *buf)
{}

/* Send a SCARLETT2_USB_SET_DATA command.
 * offset: location in the device's data space
 * size: size in bytes of the value (1, 2, 4)
 */
static int scarlett2_usb_set_data(
	struct usb_mixer_interface *mixer,
	int offset, int size, int value)
{}

/* Send a SCARLETT2_USB_SET_DATA command with multiple values.
 * offset: location in the device's data space
 * size: size in bytes of each value (1, 2, 4)
 * count: number of values
 */
static int scarlett2_usb_set_data_buf(
	struct usb_mixer_interface *mixer,
	int offset, int size, int count, void *buf)
{}

/* Send a SCARLETT2_USB_DATA_CMD command.
 * Configuration changes require activation with this after they have
 * been uploaded by a previous SCARLETT2_USB_SET_DATA.
 * The value for activate needed is determined by the configuration
 * item.
 */
static int scarlett2_usb_activate_config(
	struct usb_mixer_interface *mixer, int activate)
{}

/* Send USB messages to set a SCARLETT2_CONFIG_* parameter */
static int scarlett2_usb_set_config(
	struct usb_mixer_interface *mixer,
	int config_item_num, int index, int value)
{}

/* Send USB messages to set a SCARLETT2_CONFIG_* parameter with
 * multiple values
 */
static int scarlett2_usb_set_config_buf(
	struct usb_mixer_interface *mixer,
	int config_item_num, int index, int count, void *buf)
{}

/* Send SCARLETT2_USB_DATA_CMD SCARLETT2_USB_CONFIG_SAVE */
static void scarlett2_config_save(struct usb_mixer_interface *mixer)
{}

/* Delayed work to save config */
static void scarlett2_config_save_work(struct work_struct *work)
{}

/* Send a USB message to get sync status; result placed in *sync */
static int scarlett2_usb_get_sync_status(
	struct usb_mixer_interface *mixer,
	u8 *sync)
{}

/* Return true if the device has a mixer that we can control */
static int scarlett2_has_mixer(struct scarlett2_data *private)
{}

/* Map from mixer value to (db + 80) * 2
 * (reverse of scarlett2_mixer_values[])
 */
static int scarlett2_mixer_value_to_db(int value)
{}

/* Send a USB message to get the volumes for all inputs of one mix
 * and put the values into private->mix[]
 */
static int scarlett2_usb_get_mix(struct usb_mixer_interface *mixer,
				 int mix_num)
{}

/* Send a USB message to set the volumes for all inputs of one mix
 * (values obtained from private->mix[])
 */
static int scarlett2_usb_set_mix(struct usb_mixer_interface *mixer,
				 int mix_num)
{}

/* Convert a port number index (per info->port_count) to a hardware ID */
static u32 scarlett2_mux_src_num_to_id(
	const int port_count[][SCARLETT2_PORT_DIRNS], int num)
{}

/* Convert a hardware ID to a port number index */
static u32 scarlett2_mux_id_to_num(
	const int port_count[][SCARLETT2_PORT_DIRNS], int direction, u32 id)
{}

/* Convert one mux entry from the interface and load into private->mux[] */
static void scarlett2_usb_populate_mux(struct scarlett2_data *private,
				       u32 mux_entry)
{}

/* Update the meter level map
 *
 * The meter level data from the interface (SCARLETT2_USB_GET_METER
 * request) is returned in mux_assignment order, but to avoid exposing
 * that to userspace, scarlett2_meter_ctl_get() rearranges the data
 * into scarlett2_ports order using the meter_level_map[] array which
 * is set up by this function.
 *
 * In addition, the meter level data values returned from the
 * interface are invalid for destinations where:
 *
 * - the source is "Off"; therefore we set those values to zero (map
 *   value of 255)
 *
 * - the source is assigned to a previous (with respect to the
 *   mux_assignment order) destination; therefore we set those values
 *   to the value previously reported for that source
 */
static void scarlett2_update_meter_level_map(struct scarlett2_data *private)
{}

/* Send USB message to get mux inputs and then populate private->mux[] */
static int scarlett2_usb_get_mux(struct usb_mixer_interface *mixer)
{}

/* Send USB messages to set mux inputs */
static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer)
{}

/* Send USB message to get meter levels */
static int scarlett2_usb_get_meter_levels(struct usb_mixer_interface *mixer,
					  u16 num_meters, u16 *levels)
{}

/* For config items with mute=1, xor bits 0 & 1 together to get the
 * current/next state. This won't have any effect on values which are
 * only ever 0/1.
 */
static uint8_t scarlett2_decode_muteable(uint8_t v)
{}

/*** Control Functions ***/

/* helper function to create a new control */
static int scarlett2_add_new_ctl(struct usb_mixer_interface *mixer,
				 const struct snd_kcontrol_new *ncontrol,
				 int index, int channels, const char *name,
				 struct snd_kcontrol **kctl_return)
{}

/*** Firmware Version Control ***/

static int scarlett2_firmware_version_ctl_get(
	struct snd_kcontrol *kctl,
	struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_firmware_version_ctl_info(
	struct snd_kcontrol *kctl,
	struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_firmware_version_ctl =;

static int scarlett2_add_firmware_version_ctl(
	struct usb_mixer_interface *mixer)
{}

/*** Minimum Firmware Version Control ***/

static int scarlett2_min_firmware_version_ctl_get(
	struct snd_kcontrol *kctl,
	struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_min_firmware_version_ctl_info(
	struct snd_kcontrol *kctl,
	struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_min_firmware_version_ctl =;

static int scarlett2_add_min_firmware_version_ctl(
	struct usb_mixer_interface *mixer)
{}

/*** Sync Control ***/

/* Update sync control after receiving notification that the status
 * has changed
 */
static int scarlett2_update_sync(struct usb_mixer_interface *mixer)
{}

static int scarlett2_sync_ctl_info(struct snd_kcontrol *kctl,
				   struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_sync_ctl_get(struct snd_kcontrol *kctl,
				  struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_sync_ctl =;

static int scarlett2_add_sync_ctl(struct usb_mixer_interface *mixer)
{}

/*** Autogain Switch and Status Controls ***/

/* Forward declarations as phantom power and autogain can disable each other */
static int scarlett2_check_input_phantom_updated(struct usb_mixer_interface *);
static int scarlett2_phantom_is_switching(struct scarlett2_data *, int);

/* Set the access mode of a control to read-only (val = 0) or
 * read-write (val = 1).
 */
static void scarlett2_set_ctl_access(struct snd_kcontrol *kctl, int val)
{}

/* Check if autogain is running on any input */
static int scarlett2_autogain_is_running(struct scarlett2_data *private)
{}

static int scarlett2_update_autogain(struct usb_mixer_interface *mixer)
{}

/* Update access mode for controls affected by autogain */
static void scarlett2_autogain_update_access(struct usb_mixer_interface *mixer)
{}

/* Notify of access mode change for all controls read-only while
 * autogain runs.
 */
static void scarlett2_autogain_notify_access(struct usb_mixer_interface *mixer)
{}

/* Call scarlett2_update_autogain() and
 * scarlett2_autogain_update_access() if autogain_updated is set.
 */
static int scarlett2_check_autogain_updated(
	struct usb_mixer_interface *mixer)
{}

/* If autogain_updated is set when a *_ctl_put() function for a
 * control that is meant to be read-only while autogain is running,
 * update the autogain status and access mode of affected controls.
 * Return -EPERM if autogain is running.
 */
static int scarlett2_check_put_during_autogain(
	struct usb_mixer_interface *mixer)
{}

static int scarlett2_autogain_switch_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_autogain_switch_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_autogain_status_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_autogain_switch_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_autogain_status_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_autogain_switch_ctl =;

static const struct snd_kcontrol_new scarlett2_autogain_status_ctl =;

/*** Autogain Target Controls ***/

static int scarlett2_ag_target_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_ag_target_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_ag_target_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static const DECLARE_TLV_DB_MINMAX(
	db_scale_ag_target, SCARLETT2_AG_TARGET_MIN * 100, 0
);

static const struct snd_kcontrol_new scarlett2_ag_target_ctl =;

/*** Input Select Control ***/

static int scarlett2_update_input_select(struct usb_mixer_interface *mixer)
{}

static int scarlett2_input_select_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_input_select_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_input_select_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_input_select_ctl =;

/*** Input Link Switch Controls ***/

/* snd_ctl_boolean_mono_info() with autogain-updated check
 * (for controls that are read-only while autogain is running)
 */
static int scarlett2_autogain_disables_ctl_info(struct snd_kcontrol *kctl,
						struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_input_link_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_input_link_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_input_link_ctl =;

/*** Input Gain Controls ***/

static int scarlett2_update_input_gain(struct usb_mixer_interface *mixer)
{}

static int scarlett2_input_gain_ctl_info(struct snd_kcontrol *kctl,
					 struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_input_gain_ctl_get(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_input_gain_ctl_put(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_input_gain_ctl =;

/*** Safe Controls ***/

static int scarlett2_update_input_safe(struct usb_mixer_interface *mixer)
{}

static int scarlett2_safe_ctl_get(struct snd_kcontrol *kctl,
				  struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_safe_ctl_put(struct snd_kcontrol *kctl,
				  struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_safe_ctl =;

/*** PCM Input Control ***/

static int scarlett2_update_pcm_input_switch(struct usb_mixer_interface *mixer)
{}

static int scarlett2_pcm_input_switch_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_pcm_input_switch_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_pcm_input_switch_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_pcm_input_switch_ctl =;

/*** Analogue Line Out Volume Controls ***/

/* Update hardware volume controls after receiving notification that
 * they have changed
 */
static int scarlett2_update_volumes(struct usb_mixer_interface *mixer)
{}

static int scarlett2_volume_ctl_info(struct snd_kcontrol *kctl,
				     struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_master_volume_ctl_get(struct snd_kcontrol *kctl,
					   struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_headphone_volume_ctl_get(
	struct snd_kcontrol *kctl,
	struct snd_ctl_elem_value *ucontrol)
{}

static int line_out_remap(struct scarlett2_data *private, int index)
{}

static int scarlett2_volume_ctl_get(struct snd_kcontrol *kctl,
				    struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_volume_ctl_put(struct snd_kcontrol *kctl,
				    struct snd_ctl_elem_value *ucontrol)
{}

static const DECLARE_TLV_DB_MINMAX(
	db_scale_scarlett2_volume, -SCARLETT2_VOLUME_BIAS * 100, 0
);

static const struct snd_kcontrol_new scarlett2_master_volume_ctl =;

static const struct snd_kcontrol_new scarlett2_headphone_volume_ctl =;

static const struct snd_kcontrol_new scarlett2_line_out_volume_ctl =;

/*** Mute Switch Controls ***/

static int scarlett2_update_dim_mute(struct usb_mixer_interface *mixer)
{}

static int scarlett2_mute_ctl_get(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_mute_ctl_put(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_mute_ctl =;

/*** HW/SW Volume Switch Controls ***/

static void scarlett2_sw_hw_ctl_ro(struct scarlett2_data *private, int index)
{}

static void scarlett2_sw_hw_ctl_rw(struct scarlett2_data *private, int index)
{}

static int scarlett2_sw_hw_enum_ctl_info(struct snd_kcontrol *kctl,
					 struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_sw_hw_enum_ctl_get(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static void scarlett2_vol_ctl_set_writable(struct usb_mixer_interface *mixer,
					   int index, int value)
{}

static int scarlett2_sw_hw_change(struct usb_mixer_interface *mixer,
				  int ctl_index, int val)
{}

static int scarlett2_sw_hw_enum_ctl_put(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_sw_hw_enum_ctl =;

/*** Line Level/Instrument Level Switch Controls ***/

static int scarlett2_update_input_level(struct usb_mixer_interface *mixer)
{}

static int scarlett2_level_enum_ctl_info(struct snd_kcontrol *kctl,
					 struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_level_enum_ctl =;

/*** Pad Switch Controls ***/

static int scarlett2_update_input_pad(struct usb_mixer_interface *mixer)
{}

static int scarlett2_pad_ctl_get(struct snd_kcontrol *kctl,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_pad_ctl_put(struct snd_kcontrol *kctl,
				 struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_pad_ctl =;

/*** Air Switch Controls ***/

static int scarlett2_update_input_air(struct usb_mixer_interface *mixer)
{}

static int scarlett2_air_ctl_get(struct snd_kcontrol *kctl,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_air_ctl_put(struct snd_kcontrol *kctl,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_air_with_drive_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_air_ctl[2] =;

/*** DSP Switch Control ***/

static int scarlett2_update_input_dsp(struct usb_mixer_interface *mixer)
{}

static int scarlett2_dsp_ctl_get(struct snd_kcontrol *kctl,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_dsp_ctl_put(struct snd_kcontrol *kctl,
				 struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_dsp_ctl =;

/*** DSP Compressor Parameter Controls ***/

static int scarlett2_update_compressor_values(struct usb_mixer_interface *mixer)
{}

static int scarlett2_compressor_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_compressor_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_compressor_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_compressor_ctl =;

/*** DSP Pre-Compressor and PEQ Filter Controls ***/

static int scarlett2_precomp_flt_switch_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_peq_flt_switch_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_precomp_flt_switch_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_peq_flt_switch_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_precomp_flt_switch_ctl =;

static const struct snd_kcontrol_new scarlett2_peq_flt_switch_ctl =;

static int scarlett2_update_filter_values(struct usb_mixer_interface *mixer)
{}

static int scarlett2_precomp_flt_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_peq_flt_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_precomp_flt_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_peq_flt_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_flt_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_precomp_flt_ctl =;

static const struct snd_kcontrol_new scarlett2_peq_flt_ctl =;

/*** Input Mute Switch Controls ***/

static int scarlett2_update_input_mute(struct usb_mixer_interface *mixer)
{}

static int scarlett2_input_mute_ctl_get(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_input_mute_ctl_put(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_input_mute_ctl =;

/*** Phantom Switch Controls ***/

static int scarlett2_update_input_phantom(struct usb_mixer_interface *mixer)
{}

/* Check if phantom power on the given input is currently changing state */
static int scarlett2_phantom_is_switching(
	struct scarlett2_data *private, int line_num)
{}

/* Update autogain controls' access mode when phantom power changes state */
static void scarlett2_phantom_update_access(struct usb_mixer_interface *mixer)
{}

/* Notify of access mode change for autogain which can't be enabled
 * while phantom power is changing.
 */
static void scarlett2_phantom_notify_access(struct usb_mixer_interface *mixer)
{}

/* Call scarlett2_update_input_phantom() and
 * scarlett2_phantom_update_access() if input_phantom_updated is set.
 */
static int scarlett2_check_input_phantom_updated(
	struct usb_mixer_interface *mixer)
{}

static int scarlett2_phantom_ctl_get(struct snd_kcontrol *kctl,
				     struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl,
				     struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_phantom_ctl =;

/*** Phantom Persistence Control ***/

static int scarlett2_phantom_persistence_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_phantom_persistence_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_phantom_persistence_ctl =;

/*** Speaker Switching Control ***/

static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer)
{}

static int scarlett2_speaker_switch_enum_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_speaker_switch_enum_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

/* when speaker switching gets enabled, switch the main/alt speakers
 * to HW volume and disable those controls
 */
static int scarlett2_speaker_switch_enable(struct usb_mixer_interface *mixer)
{}

/* when speaker switching gets disabled, reenable the hw/sw controls
 * and invalidate the routing
 */
static void scarlett2_speaker_switch_disable(struct usb_mixer_interface *mixer)
{}

static int scarlett2_speaker_switch_enum_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_speaker_switch_enum_ctl =;

static int scarlett2_add_speaker_switch_ctl(struct usb_mixer_interface *mixer)
{}

/*** Talkback and Talkback Map Controls ***/

static int scarlett2_talkback_enum_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_talkback_enum_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_talkback_enum_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_talkback_enum_ctl =;

static int scarlett2_talkback_map_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_talkback_map_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_talkback_map_ctl =;

static int scarlett2_add_talkback_ctls(struct usb_mixer_interface *mixer)
{}

/*** Dim/Mute Controls ***/

static int scarlett2_dim_mute_ctl_get(struct snd_kcontrol *kctl,
				      struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl,
				      struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_dim_mute_ctl =;

/*** Create the analogue output controls ***/

static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
{}

/*** Create the analogue input controls ***/

static int scarlett2_add_dsp_ctls(struct usb_mixer_interface *mixer, int i)
{}

static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer)
{}

/*** Mixer Volume Controls ***/

static int scarlett2_update_mix(struct usb_mixer_interface *mixer)
{}

static int scarlett2_mixer_ctl_info(struct snd_kcontrol *kctl,
				    struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_mixer_ctl_get(struct snd_kcontrol *kctl,
				   struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl,
				   struct snd_ctl_elem_value *ucontrol)
{}

static const DECLARE_TLV_DB_MINMAX(
	db_scale_scarlett2_mixer,
	SCARLETT2_MIXER_MIN_DB * 100,
	SCARLETT2_MIXER_MAX_DB * 100
);

static const struct snd_kcontrol_new scarlett2_mixer_ctl =;

static int scarlett2_add_mixer_ctls(struct usb_mixer_interface *mixer)
{}

/*** Direct Monitor Control ***/

static int scarlett2_update_direct_monitor(struct usb_mixer_interface *mixer)
{}

static int scarlett2_update_monitor_mix(struct usb_mixer_interface *mixer)
{}

static int scarlett2_direct_monitor_ctl_get(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_direct_monitor_ctl_put(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_direct_monitor_stereo_enum_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

/* Direct Monitor for Solo is mono-only and only needs a boolean control
 * Direct Monitor for 2i2 is selectable between Off/Mono/Stereo
 */
static const struct snd_kcontrol_new scarlett2_direct_monitor_ctl[2] =;

static int scarlett2_monitor_mix_ctl_get(struct snd_kcontrol *kctl,
					 struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_monitor_mix_ctl_put(struct snd_kcontrol *kctl,
					 struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_monitor_mix_ctl =;

static int scarlett2_add_direct_monitor_ctls(struct usb_mixer_interface *mixer)
{}

/*** Mux Source Selection Controls ***/

static int scarlett2_mux_src_enum_ctl_info(struct snd_kcontrol *kctl,
					   struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_mux_src_enum_ctl_get(struct snd_kcontrol *kctl,
					  struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl,
					  struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_mux_src_enum_ctl =;

static int scarlett2_add_mux_enums(struct usb_mixer_interface *mixer)
{}

/*** Meter Controls ***/

static int scarlett2_meter_ctl_info(struct snd_kcontrol *kctl,
				    struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl,
				   struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_meter_ctl =;

static int scarlett2_add_meter_ctl(struct usb_mixer_interface *mixer)
{}

/*** MSD Controls ***/

static int scarlett2_msd_ctl_get(struct snd_kcontrol *kctl,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_msd_ctl_put(struct snd_kcontrol *kctl,
				 struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_msd_ctl =;

static int scarlett2_add_msd_ctl(struct usb_mixer_interface *mixer)
{}

/*** Standalone Control ***/

static int scarlett2_standalone_ctl_get(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_standalone_ctl_put(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_standalone_ctl =;

static int scarlett2_add_standalone_ctl(struct usb_mixer_interface *mixer)
{}

/*** Power Status ***/

static int scarlett2_update_power_status(struct usb_mixer_interface *mixer)
{}

static int scarlett2_power_status_ctl_get(struct snd_kcontrol *kctl,
					  struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_power_status_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_power_status_ctl =;

static int scarlett2_add_power_status_ctl(struct usb_mixer_interface *mixer)
{}

/*** Bluetooth Volume ***/

static int scarlett2_update_bluetooth_volume(struct usb_mixer_interface *mixer)
{}

static int scarlett2_bluetooth_volume_ctl_get(struct snd_kcontrol *kctl,
					     struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_bluetooth_volume_ctl_put(struct snd_kcontrol *kctl,
					     struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_bluetooth_volume_ctl_info(
	struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new scarlett2_bluetooth_volume_ctl =;

static int scarlett2_add_bluetooth_volume_ctl(
	struct usb_mixer_interface *mixer)
{}

/*** S/PDIF Mode Controls ***/

static int scarlett2_update_spdif_mode(struct usb_mixer_interface *mixer)
{}

static int scarlett2_spdif_mode_ctl_info(struct snd_kcontrol *kctl,
					   struct snd_ctl_elem_info *uinfo)
{}

static int scarlett2_spdif_mode_ctl_get(struct snd_kcontrol *kctl,
					  struct snd_ctl_elem_value *ucontrol)
{}

static int scarlett2_spdif_mode_ctl_put(struct snd_kcontrol *kctl,
					  struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new scarlett2_spdif_mode_ctl =;

static int scarlett2_add_spdif_mode_ctl(struct usb_mixer_interface *mixer)
{}

/*** Notification Handlers ***/

/* Notify on sync change */
static void scarlett2_notify_sync(struct usb_mixer_interface *mixer)
{}

/* Notify on monitor change (Gen 2/3) */
static void scarlett2_notify_monitor(struct usb_mixer_interface *mixer)
{}

/* Notify on volume change (Gen 4) */
static void scarlett2_notify_volume(struct usb_mixer_interface *mixer)
{}

/* Notify on dim/mute change */
static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer)
{}

/* Notify on input level switch change */
static void scarlett2_notify_input_level(struct usb_mixer_interface *mixer)
{}

/* Notify on input pad switch change */
static void scarlett2_notify_input_pad(struct usb_mixer_interface *mixer)
{}

/* Notify on input air switch change */
static void scarlett2_notify_input_air(struct usb_mixer_interface *mixer)
{}

/* Notify on input DSP switch change */
static void scarlett2_notify_input_dsp(struct usb_mixer_interface *mixer)
{}

/* Notify on input mute switch change */
static void scarlett2_notify_input_mute(struct usb_mixer_interface *mixer)
{}

/* Notify on input phantom switch change */
static void scarlett2_notify_input_phantom(struct usb_mixer_interface *mixer)
{}

/* Notify on "input other" change (level/pad/air/phantom) */
static void scarlett2_notify_input_other(struct usb_mixer_interface *mixer)
{}

/* Notify on input select change */
static void scarlett2_notify_input_select(struct usb_mixer_interface *mixer)
{}

/* Notify on input gain change */
static void scarlett2_notify_input_gain(struct usb_mixer_interface *mixer)
{}

/* Notify on autogain change */
static void scarlett2_notify_autogain(struct usb_mixer_interface *mixer)
{}

/* Notify on input safe switch change */
static void scarlett2_notify_input_safe(struct usb_mixer_interface *mixer)
{}

/* Notify on "monitor other" change (speaker switching, talkback) */
static void scarlett2_notify_monitor_other(struct usb_mixer_interface *mixer)
{}

/* Notify on direct monitor switch change */
static void scarlett2_notify_direct_monitor(struct usb_mixer_interface *mixer)
{}

/* Notify on power change */
static void scarlett2_notify_power_status(struct usb_mixer_interface *mixer)
{}

/* Notify on mux change */
static void scarlett2_notify_mux(struct usb_mixer_interface *mixer)
{}

/* Notify on PCM input switch change */
static void scarlett2_notify_pcm_input_switch(struct usb_mixer_interface *mixer)
{}

/* Notify on Bluetooth change */
static void scarlett2_notify_bluetooth(struct usb_mixer_interface *mixer)
{}

/* Handle acknowledgement that a command was received; let
 * scarlett2_usb() know that it can proceed
 */
static void scarlett2_notify_ack(struct usb_mixer_interface *mixer)
{}

/* Interrupt callback */
static void scarlett2_notify(struct urb *urb)
{}

/*** Cleanup/Suspend Callbacks ***/

static void scarlett2_private_free(struct usb_mixer_interface *mixer)
{}

static void scarlett2_private_suspend(struct usb_mixer_interface *mixer)
{}

/*** Initialisation ***/

static void scarlett2_count_io(struct scarlett2_data *private)
{}

/* Look through the interface descriptors for the Focusrite Control
 * interface (bInterfaceClass = 255 Vendor Specific Class) and set
 * bInterfaceNumber, bEndpointAddress, wMaxPacketSize, and bInterval
 * in private
 */
static int scarlett2_find_fc_interface(struct usb_device *dev,
				       struct scarlett2_data *private)
{}

/* Initialise private data */
static int scarlett2_init_private(struct usb_mixer_interface *mixer,
				  const struct scarlett2_device_entry *entry)
{}

/* Submit a URB to receive notifications from the device */
static int scarlett2_init_notify(struct usb_mixer_interface *mixer)
{}

/* Cargo cult proprietary initialisation sequence */
static int scarlett2_usb_init(struct usb_mixer_interface *mixer)
{}

/* Get the flash segment numbers for the App_Settings and App_Upgrade
 * segments and put them in the private data
 */
static int scarlett2_get_flash_segment_nums(struct usb_mixer_interface *mixer)
{}

/* Read configuration from the interface on start */
static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
{}

static const struct scarlett2_device_entry *get_scarlett2_device_entry(
	struct usb_mixer_interface *mixer)
{}

static int snd_scarlett2_controls_create(
	struct usb_mixer_interface *mixer,
	const struct scarlett2_device_entry *entry)
{}

/*** hwdep interface ***/

/* Set private->hwdep_in_use; prevents access to the ALSA controls
 * while doing a config erase/firmware upgrade.
 */
static void scarlett2_lock(struct scarlett2_data *private)
{}

/* Call SCARLETT2_USB_GET_ERASE to get the erase progress */
static int scarlett2_get_erase_progress(struct usb_mixer_interface *mixer)
{}

/* Repeatedly call scarlett2_get_erase_progress() until it returns
 * 0xff (erase complete) or we've waited 10 seconds (it usually takes
 * <3 seconds).
 */
static int scarlett2_wait_for_erase(struct usb_mixer_interface *mixer)
{}

/* Reboot the device; wait for the erase to complete if one is in
 * progress.
 */
static int scarlett2_reboot(struct usb_mixer_interface *mixer)
{}

/* Select a flash segment for reading/erasing/writing */
static int scarlett2_ioctl_select_flash_segment(
	struct usb_mixer_interface *mixer,
	unsigned long arg)
{}

/* Erase the previously-selected flash segment */
static int scarlett2_ioctl_erase_flash_segment(
	struct usb_mixer_interface *mixer)
{}

/* Get the erase progress from the device */
static int scarlett2_ioctl_get_erase_progress(
	struct usb_mixer_interface *mixer,
	unsigned long arg)
{}

static int scarlett2_hwdep_open(struct snd_hwdep *hw, struct file *file)
{}

static int scarlett2_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
				 unsigned int cmd, unsigned long arg)
{}

static long scarlett2_hwdep_read(struct snd_hwdep *hw,
				 char __user *buf,
				 long count, loff_t *offset)
{}

static long scarlett2_hwdep_write(struct snd_hwdep *hw,
				  const char __user *buf,
				  long count, loff_t *offset)
{}

static int scarlett2_hwdep_release(struct snd_hwdep *hw, struct file *file)
{}

static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer)
{}

int snd_scarlett2_init(struct usb_mixer_interface *mixer)
{}