1 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 /* 3 * Focusrite Control Protocol Driver for ALSA 4 * 5 * Copyright (c) 2024-2025 by Geoffrey D. Bennett <g at b4.vu> 6 */ 7 /* 8 * DOC: FCP (Focusrite Control Protocol) User-Space API 9 * 10 * This header defines the interface between the FCP kernel driver and 11 * user-space programs to enable the use of the proprietary features 12 * available in Focusrite USB audio interfaces. This includes Scarlett 13 * 2nd Gen, 3rd Gen, 4th Gen, Clarett USB, Clarett+, and Vocaster 14 * series devices. 15 * 16 * The interface is provided via ALSA's hwdep interface. Opening the 17 * hwdep device requires CAP_SYS_RAWIO privileges as this interface 18 * provides near-direct access. 19 * 20 * For details on the FCP protocol, refer to the kernel scarlett2 21 * driver in sound/usb/mixer_scarlett2.c and the fcp-support project 22 * at https://github.com/geoffreybennett/fcp-support 23 * 24 * For examples of using these IOCTLs, see the fcp-server source in 25 * the fcp-support project. 26 * 27 * IOCTL Interface 28 * -------------- 29 * FCP_IOCTL_PVERSION: 30 * Returns the protocol version supported by the driver. 31 * 32 * FCP_IOCTL_INIT: 33 * Initialises the protocol and synchronises sequence numbers 34 * between the driver and device. Must be called at least once 35 * before sending commands. Can be safely called again at any time. 36 * 37 * FCP_IOCTL_CMD: 38 * Sends an FCP command to the device and returns the response. 39 * Requires prior initialisation via FCP_IOCTL_INIT. 40 * 41 * FCP_IOCTL_SET_METER_MAP: 42 * Configures the Level Meter control's mapping between device 43 * meters and control channels. Requires FCP_IOCTL_INIT to have been 44 * called first. The map size and number of slots cannot be changed 45 * after initial configuration, although the map itself can be 46 * updated. Once configured, the Level Meter remains functional even 47 * after the hwdep device is closed. 48 * 49 * FCP_IOCTL_SET_METER_LABELS: 50 * Set the labels for the Level Meter control. Requires 51 * FCP_IOCTL_SET_METER_MAP to have been called first. labels[] 52 * should contain a sequence of null-terminated labels corresponding 53 * to the control's channels. 54 */ 55 #ifndef __UAPI_SOUND_FCP_H 56 #define __UAPI_SOUND_FCP_H 57 58 #include <linux/types.h> 59 #include <linux/ioctl.h> 60 61 #define FCP_HWDEP_MAJOR 2 62 #define FCP_HWDEP_MINOR 0 63 #define FCP_HWDEP_SUBMINOR 0 64 65 #define FCP_HWDEP_VERSION \ 66 ((FCP_HWDEP_MAJOR << 16) | \ 67 (FCP_HWDEP_MINOR << 8) | \ 68 FCP_HWDEP_SUBMINOR) 69 70 #define FCP_HWDEP_VERSION_MAJOR(v) (((v) >> 16) & 0xFF) 71 #define FCP_HWDEP_VERSION_MINOR(v) (((v) >> 8) & 0xFF) 72 #define FCP_HWDEP_VERSION_SUBMINOR(v) ((v) & 0xFF) 73 74 /* Get protocol version */ 75 #define FCP_IOCTL_PVERSION _IOR('S', 0x60, int) 76 77 /* Start the protocol */ 78 79 /* Step 0 and step 2 responses are variable length and placed in 80 * resp[] one after the other. 81 */ 82 struct fcp_init { 83 __u16 step0_resp_size; 84 __u16 step2_resp_size; 85 __u32 init1_opcode; 86 __u32 init2_opcode; 87 __u8 resp[]; 88 } __attribute__((packed)); 89 90 #define FCP_IOCTL_INIT _IOWR('S', 0x64, struct fcp_init) 91 92 /* Perform a command */ 93 94 /* The request data is placed in data[] and the response data will 95 * overwrite it. 96 */ 97 struct fcp_cmd { 98 __u32 opcode; 99 __u16 req_size; 100 __u16 resp_size; 101 __u8 data[]; 102 } __attribute__((packed)); 103 #define FCP_IOCTL_CMD _IOWR('S', 0x65, struct fcp_cmd) 104 105 /* Set the meter map */ 106 struct fcp_meter_map { 107 __u16 map_size; 108 __u16 meter_slots; 109 __s16 map[]; 110 } __attribute__((packed)); 111 #define FCP_IOCTL_SET_METER_MAP _IOW('S', 0x66, struct fcp_meter_map) 112 113 /* Set the meter labels */ 114 struct fcp_meter_labels { 115 __u16 labels_size; 116 char labels[]; 117 } __attribute__((packed)); 118 #define FCP_IOCTL_SET_METER_LABELS _IOW('S', 0x67, struct fcp_meter_labels) 119 120 #endif /* __UAPI_SOUND_FCP_H */ 121