1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 // Copyright (c) 2025 Šerif Rami <ramiserifpersia@gmail.com> 3 4 #ifndef __US144MKII_H 5 #define __US144MKII_H 6 7 #include <linux/kfifo.h> 8 #include <linux/timer.h> 9 #include <linux/usb.h> 10 #include <linux/workqueue.h> 11 #include <sound/control.h> 12 #include <sound/core.h> 13 #include <sound/initval.h> 14 #include <sound/pcm.h> 15 #include <sound/rawmidi.h> 16 17 #define DRIVER_NAME "us144mkii" 18 19 /* --- USB Device Identification --- */ 20 #define USB_VID_TASCAM 0x0644 21 #define USB_PID_TASCAM_US144 0x800f 22 #define USB_PID_TASCAM_US144MKII 0x8020 23 24 /* --- USB Endpoints (Alternate Setting 1) --- */ 25 #define EP_PLAYBACK_FEEDBACK 0x81 26 #define EP_AUDIO_OUT 0x02 27 #define EP_MIDI_IN 0x83 28 #define EP_MIDI_OUT 0x04 29 #define EP_AUDIO_IN 0x86 30 31 /* --- USB Control Message Protocol --- */ 32 #define RT_H2D_CLASS_EP (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT) 33 #define RT_D2H_CLASS_EP (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT) 34 #define RT_H2D_VENDOR_DEV (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) 35 #define RT_D2H_VENDOR_DEV (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) 36 37 enum uac_request { 38 UAC_SET_CUR = 0x01, 39 UAC_GET_CUR = 0x81, 40 }; 41 42 enum uac_control_selector { 43 UAC_SAMPLING_FREQ_CONTROL = 0x0100, 44 }; 45 46 enum tascam_vendor_request { 47 VENDOR_REQ_REGISTER_WRITE = 0x41, 48 VENDOR_REQ_DEEP_SLEEP = 0x44, 49 VENDOR_REQ_MODE_CONTROL = 0x49, 50 }; 51 52 enum tascam_mode_value { 53 MODE_VAL_HANDSHAKE_READ = 0x0000, 54 MODE_VAL_CONFIG = 0x0010, 55 MODE_VAL_STREAM_START = 0x0030, 56 }; 57 58 #define HANDSHAKE_SUCCESS_VAL 0x12 59 60 enum tascam_register { 61 REG_ADDR_UNKNOWN_0D = 0x0d04, 62 REG_ADDR_UNKNOWN_0E = 0x0e00, 63 REG_ADDR_UNKNOWN_0F = 0x0f00, 64 REG_ADDR_RATE_44100 = 0x1000, 65 REG_ADDR_RATE_48000 = 0x1002, 66 REG_ADDR_RATE_88200 = 0x1008, 67 REG_ADDR_RATE_96000 = 0x100a, 68 REG_ADDR_UNKNOWN_11 = 0x110b, 69 }; 70 71 #define REG_VAL_ENABLE 0x0101 72 73 /* --- URB Configuration --- */ 74 #define NUM_PLAYBACK_URBS 4 75 #define PLAYBACK_URB_PACKETS 8 76 #define NUM_FEEDBACK_URBS 4 77 #define FEEDBACK_URB_PACKETS 1 78 #define FEEDBACK_PACKET_SIZE 3 79 #define NUM_CAPTURE_URBS 8 80 #define CAPTURE_URB_SIZE 512 81 #define CAPTURE_RING_BUFFER_SIZE (CAPTURE_URB_SIZE * NUM_CAPTURE_URBS * 4) 82 #define NUM_MIDI_IN_URBS 4 83 #define MIDI_IN_BUF_SIZE 64 84 #define MIDI_IN_FIFO_SIZE (MIDI_IN_BUF_SIZE * NUM_MIDI_IN_URBS) 85 #define MIDI_OUT_BUF_SIZE 64 86 #define NUM_MIDI_OUT_URBS 4 87 #define USB_CTRL_TIMEOUT_MS 1000 88 #define FEEDBACK_SYNC_LOSS_THRESHOLD 41 89 90 /* --- Audio Format Configuration --- */ 91 #define BYTES_PER_SAMPLE 3 92 #define NUM_CHANNELS 4 93 #define BYTES_PER_FRAME (NUM_CHANNELS * BYTES_PER_SAMPLE) 94 #define FEEDBACK_ACCUMULATOR_SIZE 128 95 96 /* --- Capture Decoding Defines --- */ 97 #define DECODED_CHANNELS_PER_FRAME 4 98 #define DECODED_SAMPLE_SIZE 4 99 #define FRAMES_PER_DECODE_BLOCK 8 100 #define RAW_BYTES_PER_DECODE_BLOCK 512 101 102 /** 103 * struct us144mkii_frame_pattern_observer - State for dynamic feedback 104 * patterns. 105 * @sample_rate_khz: The current sample rate in kHz. 106 * @base_feedback_value: The nominal feedback value for the current rate. 107 * @feedback_offset: An offset to align the feedback value range. 108 * @full_frame_patterns: A 2D array of pre-calculated packet size patterns. 109 * @current_index: The current index into the pattern array. 110 * @previous_index: The previous index, used for state tracking. 111 * @sync_locked: A flag indicating if the pattern has locked to the stream. 112 */ 113 struct us144mkii_frame_pattern_observer { 114 unsigned int sample_rate_khz; 115 unsigned int base_feedback_value; 116 int feedback_offset; 117 unsigned int full_frame_patterns[5][8]; 118 unsigned int current_index; 119 unsigned int previous_index; 120 bool sync_locked; 121 }; 122 123 /** 124 * struct tascam_card - Main driver data structure for the TASCAM US-144MKII. 125 * @dev: Pointer to the USB device. 126 * @iface0: Pointer to USB interface 0 (audio). 127 * @iface1: Pointer to USB interface 1 (MIDI). 128 * @card: Pointer to the ALSA sound card instance. 129 * @pcm: Pointer to the ALSA PCM device. 130 * @rmidi: Pointer to the ALSA rawmidi device. 131 * 132 * @playback_substream: Pointer to the active playback PCM substream. 133 * @playback_urbs: Array of URBs for playback. 134 * @playback_urb_alloc_size: Size of allocated buffer for each playback URB. 135 * @feedback_urbs: Array of URBs for feedback. 136 * @feedback_urb_alloc_size: Size of allocated buffer for each feedback URB. 137 * @playback_active: Atomic flag indicating if playback is active. 138 * @playback_frames_consumed: Total frames consumed by playback. 139 * @driver_playback_pos: Current position in the ALSA playback buffer (frames). 140 * @last_period_pos: Last reported period position for playback. 141 * 142 * @capture_substream: Pointer to the active capture PCM substream. 143 * @capture_urbs: Array of URBs for capture. 144 * @capture_urb_alloc_size: Size of allocated buffer for each capture URB. 145 * @capture_active: Atomic flag indicating if capture is active. 146 * @driver_capture_pos: Current position in the ALSA capture buffer (frames). 147 * @capture_frames_processed: Total frames processed for capture. 148 * @last_capture_period_pos: Last reported period position for capture. 149 * @capture_ring_buffer: Ring buffer for raw capture data from USB. 150 * @capture_ring_buffer_read_ptr: Read pointer for the capture ring buffer. 151 * @capture_ring_buffer_write_ptr: Write pointer for the capture ring buffer. 152 * @capture_decode_raw_block: Buffer for a raw 512-byte capture block. 153 * @capture_decode_dst_block: Buffer for decoded 32-bit capture samples. 154 * @capture_routing_buffer: Intermediate buffer for capture routing. 155 * @capture_work: Work struct for deferred capture processing. 156 * @stop_work: Work struct for deferred stream stopping. 157 * @stop_pcm_work: Work struct for stopping PCM due to a fatal error (e.g. 158 * xrun). 159 * 160 * @midi_in_substream: Pointer to the active MIDI input substream. 161 * @midi_out_substream: Pointer to the active MIDI output substream. 162 * @midi_in_urbs: Array of URBs for MIDI input. 163 * @midi_out_urbs: Array of URBs for MIDI output. 164 * @midi_in_active: Atomic flag indicating if MIDI input is active. 165 * @midi_out_active: Atomic flag indicating if MIDI output is active. 166 * @midi_in_fifo: FIFO for raw MIDI input data. 167 * @midi_in_work: Work struct for deferred MIDI input processing. 168 * @midi_out_work: Work struct for deferred MIDI output processing. 169 * @midi_in_lock: Spinlock for MIDI input FIFO. 170 * @midi_out_lock: Spinlock for MIDI output. 171 * @midi_out_urbs_in_flight: Bitmap of MIDI output URBs currently in flight. 172 * @midi_running_status: Stores the last MIDI status byte for running status. 173 * @error_timer: Timer for MIDI error retry logic. 174 * 175 * @lock: Main spinlock for protecting shared driver state. 176 * @active_urbs: Atomic counter for active URBs. 177 * @current_rate: Currently configured sample rate of the device. 178 * @line_out_source: Source for Line Outputs (0: Playback 1-2, 1: Playback 3-4). 179 * @digital_out_source: Source for Digital Outputs (0: Playback 1-2, 1: Playback 180 * 3-4). 181 * @capture_12_source: Source for Capture channels 1-2 (0: Analog In, 1: Digital 182 * In). 183 * @capture_34_source: Source for Capture channels 3-4 (0: Analog In, 1: Digital 184 * In). 185 * 186 * @feedback_accumulator_pattern: Stores the calculated frames per packet for 187 * feedback. 188 * @feedback_pattern_out_idx: Read index for feedback_accumulator_pattern. 189 * @feedback_pattern_in_idx: Write index for feedback_accumulator_pattern. 190 * @feedback_synced: Flag indicating if feedback is synced. 191 * @feedback_consecutive_errors: Counter for consecutive feedback errors. 192 * @feedback_urb_skip_count: Number of feedback URBs to skip initially for 193 * stabilization. 194 * @fpo: Holds the state for the dynamic feedback pattern generation. 195 * 196 * @playback_anchor: USB anchor for playback URBs. 197 * @capture_anchor: USB anchor for capture URBs. 198 * @feedback_anchor: USB anchor for feedback URBs. 199 * @midi_in_anchor: USB anchor for MIDI input URBs. 200 * @midi_out_anchor: USB anchor for MIDI output URBs. 201 */ 202 struct tascam_card { 203 /* --- Core device pointers --- */ 204 struct usb_device *dev; 205 struct usb_interface *iface0; 206 struct usb_interface *iface1; 207 struct snd_card *card; 208 struct snd_pcm *pcm; 209 struct snd_rawmidi *rmidi; 210 211 /* --- PCM Substreams --- */ 212 struct snd_pcm_substream *playback_substream; 213 struct snd_pcm_substream *capture_substream; 214 215 /* --- URBs and Anchors --- */ 216 struct urb *playback_urbs[NUM_PLAYBACK_URBS]; 217 size_t playback_urb_alloc_size; 218 struct urb *feedback_urbs[NUM_FEEDBACK_URBS]; 219 size_t feedback_urb_alloc_size; 220 struct urb *capture_urbs[NUM_CAPTURE_URBS]; 221 size_t capture_urb_alloc_size; 222 struct urb *midi_in_urbs[NUM_MIDI_IN_URBS]; 223 struct urb *midi_out_urbs[NUM_MIDI_OUT_URBS]; 224 struct usb_anchor playback_anchor; 225 struct usb_anchor capture_anchor; 226 struct usb_anchor feedback_anchor; 227 struct usb_anchor midi_in_anchor; 228 struct usb_anchor midi_out_anchor; 229 230 /* --- Stream State --- */ 231 spinlock_t lock; 232 atomic_t playback_active; 233 atomic_t capture_active; 234 atomic_t active_urbs; 235 int current_rate; 236 237 /* --- Playback State --- */ 238 u64 playback_frames_consumed; 239 snd_pcm_uframes_t driver_playback_pos; 240 u64 last_period_pos; 241 242 /* --- Capture State --- */ 243 u64 capture_frames_processed; 244 snd_pcm_uframes_t driver_capture_pos; 245 u64 last_capture_period_pos; 246 u8 *capture_ring_buffer; 247 size_t capture_ring_buffer_read_ptr; 248 size_t capture_ring_buffer_write_ptr; 249 u8 *capture_decode_raw_block; 250 s32 *capture_decode_dst_block; 251 s32 *capture_routing_buffer; 252 253 /* --- MIDI State --- */ 254 struct snd_rawmidi_substream *midi_in_substream; 255 struct snd_rawmidi_substream *midi_out_substream; 256 atomic_t midi_in_active; 257 atomic_t midi_out_active; 258 struct kfifo midi_in_fifo; 259 spinlock_t midi_in_lock; 260 spinlock_t midi_out_lock; 261 unsigned long midi_out_urbs_in_flight; 262 u8 midi_running_status; 263 struct timer_list error_timer; 264 struct completion midi_out_drain_completion; 265 266 /* --- Feedback Sync State --- */ 267 unsigned int feedback_accumulator_pattern[FEEDBACK_ACCUMULATOR_SIZE]; 268 unsigned int feedback_pattern_out_idx; 269 unsigned int feedback_pattern_in_idx; 270 bool feedback_synced; 271 unsigned int feedback_consecutive_errors; 272 unsigned int feedback_urb_skip_count; 273 struct us144mkii_frame_pattern_observer fpo; 274 275 /* --- Workqueues --- */ 276 struct work_struct stop_work; 277 struct work_struct stop_pcm_work; 278 struct work_struct capture_work; 279 struct work_struct midi_in_work; 280 struct work_struct midi_out_work; 281 282 /* --- Mixer/Routing State --- */ 283 unsigned int line_out_source; 284 unsigned int digital_out_source; 285 unsigned int capture_12_source; 286 unsigned int capture_34_source; 287 }; 288 289 /* main.c */ 290 /** 291 * tascam_free_urbs() - Free all allocated URBs and associated buffers. 292 * @tascam: the tascam_card instance 293 * 294 * This function kills, unlinks, and frees all playback, feedback, capture, 295 * and MIDI URBs, along with their transfer buffers and the capture 296 * ring/decode buffers. 297 */ 298 void tascam_free_urbs(struct tascam_card *tascam); 299 300 /** 301 * tascam_alloc_urbs() - Allocate all URBs and associated buffers. 302 * @tascam: the tascam_card instance 303 * 304 * This function allocates and initializes all URBs for playback, feedback, 305 * capture, and MIDI, as well as the necessary buffers for data processing. 306 * 307 * Return: 0 on success, or a negative error code on failure. 308 */ 309 int tascam_alloc_urbs(struct tascam_card *tascam); 310 311 /** 312 * tascam_stop_work_handler() - Work handler to stop all active streams. 313 * @work: Pointer to the work_struct. 314 * 315 * This function is scheduled to stop all active URBs (playback, feedback, 316 * capture) and reset the active_urbs counter. 317 */ 318 void tascam_stop_work_handler(struct work_struct *work); 319 320 /* us144mkii_pcm.h */ 321 #include "us144mkii_pcm.h" 322 323 /* us144mkii_midi.c */ 324 /** 325 * tascam_midi_in_urb_complete() - Completion handler for MIDI IN URBs 326 * @urb: The completed URB. 327 * 328 * This function runs in interrupt context. It places the raw data from the 329 * USB endpoint into a kfifo and schedules a work item to process it later, 330 * ensuring the interrupt handler remains fast. 331 */ 332 void tascam_midi_in_urb_complete(struct urb *urb); 333 334 /** 335 * tascam_midi_out_urb_complete() - Completion handler for MIDI OUT bulk URB. 336 * @urb: The completed URB. 337 * 338 * This function runs in interrupt context. It marks the output URB as no 339 * longer in-flight. It then re-schedules the work handler to check for and 340 * send any more data waiting in the ALSA buffer. This is a safe, non-blocking 341 * way to continue the data transmission chain. 342 */ 343 void tascam_midi_out_urb_complete(struct urb *urb); 344 345 /** 346 * tascam_create_midi() - Create and initialize the ALSA rawmidi device. 347 * @tascam: The driver instance. 348 * 349 * Return: 0 on success, or a negative error code on failure. 350 */ 351 int tascam_create_midi(struct tascam_card *tascam); 352 353 /* us144mkii_controls.c */ 354 /** 355 * tascam_create_controls() - Creates and adds ALSA mixer controls for the 356 * device. 357 * @tascam: The driver instance. 358 * 359 * This function registers custom ALSA controls for managing audio routing 360 * (line out source, digital out source, capture 1-2 source, capture 3-4 source) 361 * and displaying the current sample rate. 362 * 363 * Return: 0 on success, or a negative error code on failure. 364 */ 365 int tascam_create_controls(struct tascam_card *tascam); 366 367 #endif /* __US144MKII_H */ 368