1dee1bcf2SŠerif Rami /* SPDX-License-Identifier: GPL-2.0-only */ 2dee1bcf2SŠerif Rami // Copyright (c) 2025 Šerif Rami <ramiserifpersia@gmail.com> 3dee1bcf2SŠerif Rami 4dee1bcf2SŠerif Rami #ifndef __US144MKII_H 5dee1bcf2SŠerif Rami #define __US144MKII_H 6dee1bcf2SŠerif Rami 767afec15SŠerif Rami #include <linux/kfifo.h> 867afec15SŠerif Rami #include <linux/timer.h> 9dee1bcf2SŠerif Rami #include <linux/usb.h> 10a2a2210fSŠerif Rami #include <linux/workqueue.h> 1167afec15SŠerif Rami #include <sound/control.h> 12dee1bcf2SŠerif Rami #include <sound/core.h> 13dee1bcf2SŠerif Rami #include <sound/initval.h> 1467afec15SŠerif Rami #include <sound/pcm.h> 1567afec15SŠerif Rami #include <sound/rawmidi.h> 16dee1bcf2SŠerif Rami 17dee1bcf2SŠerif Rami #define DRIVER_NAME "us144mkii" 18dee1bcf2SŠerif Rami 19dee1bcf2SŠerif Rami /* --- USB Device Identification --- */ 20dee1bcf2SŠerif Rami #define USB_VID_TASCAM 0x0644 21dee1bcf2SŠerif Rami #define USB_PID_TASCAM_US144 0x800f 22dee1bcf2SŠerif Rami #define USB_PID_TASCAM_US144MKII 0x8020 23dee1bcf2SŠerif Rami 24a2a2210fSŠerif Rami /* --- USB Endpoints (Alternate Setting 1) --- */ 25a2a2210fSŠerif Rami #define EP_PLAYBACK_FEEDBACK 0x81 26a2a2210fSŠerif Rami #define EP_AUDIO_OUT 0x02 2767afec15SŠerif Rami #define EP_MIDI_IN 0x83 2867afec15SŠerif Rami #define EP_MIDI_OUT 0x04 29c1bb0c13SŠerif Rami #define EP_AUDIO_IN 0x86 30a2a2210fSŠerif Rami 31dee1bcf2SŠerif Rami /* --- USB Control Message Protocol --- */ 32a2a2210fSŠerif Rami #define RT_H2D_CLASS_EP (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT) 33c1bb0c13SŠerif Rami #define RT_D2H_CLASS_EP (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT) 34a2a2210fSŠerif Rami #define RT_H2D_VENDOR_DEV (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) 3567afec15SŠerif Rami #define RT_D2H_VENDOR_DEV (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) 36a2a2210fSŠerif Rami 37a2a2210fSŠerif Rami enum uac_request { 38a2a2210fSŠerif Rami UAC_SET_CUR = 0x01, 39c1bb0c13SŠerif Rami UAC_GET_CUR = 0x81, 40a2a2210fSŠerif Rami }; 41a2a2210fSŠerif Rami 42a2a2210fSŠerif Rami enum uac_control_selector { 43a2a2210fSŠerif Rami UAC_SAMPLING_FREQ_CONTROL = 0x0100, 44a2a2210fSŠerif Rami }; 45a2a2210fSŠerif Rami 46a2a2210fSŠerif Rami enum tascam_vendor_request { 47a2a2210fSŠerif Rami VENDOR_REQ_REGISTER_WRITE = 0x41, 48*fdd1a1aeSŠerif Rami VENDOR_REQ_DEEP_SLEEP = 0x44, 49a2a2210fSŠerif Rami VENDOR_REQ_MODE_CONTROL = 0x49, 50a2a2210fSŠerif Rami }; 51a2a2210fSŠerif Rami 52a2a2210fSŠerif Rami enum tascam_mode_value { 53a2a2210fSŠerif Rami MODE_VAL_HANDSHAKE_READ = 0x0000, 54a2a2210fSŠerif Rami MODE_VAL_CONFIG = 0x0010, 55a2a2210fSŠerif Rami MODE_VAL_STREAM_START = 0x0030, 56a2a2210fSŠerif Rami }; 57a2a2210fSŠerif Rami 5867afec15SŠerif Rami #define HANDSHAKE_SUCCESS_VAL 0x12 5967afec15SŠerif Rami 60a2a2210fSŠerif Rami enum tascam_register { 61a2a2210fSŠerif Rami REG_ADDR_UNKNOWN_0D = 0x0d04, 62a2a2210fSŠerif Rami REG_ADDR_UNKNOWN_0E = 0x0e00, 63a2a2210fSŠerif Rami REG_ADDR_UNKNOWN_0F = 0x0f00, 64a2a2210fSŠerif Rami REG_ADDR_RATE_44100 = 0x1000, 65a2a2210fSŠerif Rami REG_ADDR_RATE_48000 = 0x1002, 66a2a2210fSŠerif Rami REG_ADDR_RATE_88200 = 0x1008, 67a2a2210fSŠerif Rami REG_ADDR_RATE_96000 = 0x100a, 68a2a2210fSŠerif Rami REG_ADDR_UNKNOWN_11 = 0x110b, 69a2a2210fSŠerif Rami }; 70a2a2210fSŠerif Rami 71a2a2210fSŠerif Rami #define REG_VAL_ENABLE 0x0101 72a2a2210fSŠerif Rami 73a2a2210fSŠerif Rami /* --- URB Configuration --- */ 74a2a2210fSŠerif Rami #define NUM_PLAYBACK_URBS 4 75a2a2210fSŠerif Rami #define PLAYBACK_URB_PACKETS 8 76a2a2210fSŠerif Rami #define NUM_FEEDBACK_URBS 4 77a2a2210fSŠerif Rami #define FEEDBACK_URB_PACKETS 1 78a2a2210fSŠerif Rami #define FEEDBACK_PACKET_SIZE 3 79c1bb0c13SŠerif Rami #define NUM_CAPTURE_URBS 8 80c1bb0c13SŠerif Rami #define CAPTURE_URB_SIZE 512 81c1bb0c13SŠerif Rami #define CAPTURE_RING_BUFFER_SIZE (CAPTURE_URB_SIZE * NUM_CAPTURE_URBS * 4) 8267afec15SŠerif Rami #define NUM_MIDI_IN_URBS 4 8367afec15SŠerif Rami #define MIDI_IN_BUF_SIZE 64 8467afec15SŠerif Rami #define MIDI_IN_FIFO_SIZE (MIDI_IN_BUF_SIZE * NUM_MIDI_IN_URBS) 8567afec15SŠerif Rami #define MIDI_OUT_BUF_SIZE 64 8667afec15SŠerif Rami #define NUM_MIDI_OUT_URBS 4 87dee1bcf2SŠerif Rami #define USB_CTRL_TIMEOUT_MS 1000 88a2a2210fSŠerif Rami #define FEEDBACK_SYNC_LOSS_THRESHOLD 41 89dee1bcf2SŠerif Rami 905c8c1079SŠerif Rami /* --- Audio Format Configuration --- */ 915c8c1079SŠerif Rami #define BYTES_PER_SAMPLE 3 925c8c1079SŠerif Rami #define NUM_CHANNELS 4 935c8c1079SŠerif Rami #define BYTES_PER_FRAME (NUM_CHANNELS * BYTES_PER_SAMPLE) 94a2a2210fSŠerif Rami #define FEEDBACK_ACCUMULATOR_SIZE 128 955c8c1079SŠerif Rami 96c1bb0c13SŠerif Rami /* --- Capture Decoding Defines --- */ 97c1bb0c13SŠerif Rami #define DECODED_CHANNELS_PER_FRAME 4 98c1bb0c13SŠerif Rami #define DECODED_SAMPLE_SIZE 4 99c1bb0c13SŠerif Rami #define FRAMES_PER_DECODE_BLOCK 8 100c1bb0c13SŠerif Rami #define RAW_BYTES_PER_DECODE_BLOCK 512 101c1bb0c13SŠerif Rami 102dee1bcf2SŠerif Rami /** 103a2a2210fSŠerif Rami * struct us144mkii_frame_pattern_observer - State for dynamic feedback 104a2a2210fSŠerif Rami * patterns. 105a2a2210fSŠerif Rami * @sample_rate_khz: The current sample rate in kHz. 106a2a2210fSŠerif Rami * @base_feedback_value: The nominal feedback value for the current rate. 107a2a2210fSŠerif Rami * @feedback_offset: An offset to align the feedback value range. 108a2a2210fSŠerif Rami * @full_frame_patterns: A 2D array of pre-calculated packet size patterns. 109a2a2210fSŠerif Rami * @current_index: The current index into the pattern array. 110a2a2210fSŠerif Rami * @previous_index: The previous index, used for state tracking. 111a2a2210fSŠerif Rami * @sync_locked: A flag indicating if the pattern has locked to the stream. 112a2a2210fSŠerif Rami */ 113a2a2210fSŠerif Rami struct us144mkii_frame_pattern_observer { 114a2a2210fSŠerif Rami unsigned int sample_rate_khz; 115a2a2210fSŠerif Rami unsigned int base_feedback_value; 116a2a2210fSŠerif Rami int feedback_offset; 117a2a2210fSŠerif Rami unsigned int full_frame_patterns[5][8]; 118a2a2210fSŠerif Rami unsigned int current_index; 119a2a2210fSŠerif Rami unsigned int previous_index; 120a2a2210fSŠerif Rami bool sync_locked; 121a2a2210fSŠerif Rami }; 122a2a2210fSŠerif Rami 123a2a2210fSŠerif Rami /** 1245c8c1079SŠerif Rami * struct tascam_card - Main driver data structure for the TASCAM US-144MKII. 125dee1bcf2SŠerif Rami * @dev: Pointer to the USB device. 126dee1bcf2SŠerif Rami * @iface0: Pointer to USB interface 0 (audio). 127dee1bcf2SŠerif Rami * @iface1: Pointer to USB interface 1 (MIDI). 128dee1bcf2SŠerif Rami * @card: Pointer to the ALSA sound card instance. 1295c8c1079SŠerif Rami * @pcm: Pointer to the ALSA PCM device. 13067afec15SŠerif Rami * @rmidi: Pointer to the ALSA rawmidi device. 131a2a2210fSŠerif Rami * 1325c8c1079SŠerif Rami * @playback_substream: Pointer to the active playback PCM substream. 133a2a2210fSŠerif Rami * @playback_urbs: Array of URBs for playback. 134a2a2210fSŠerif Rami * @playback_urb_alloc_size: Size of allocated buffer for each playback URB. 135a2a2210fSŠerif Rami * @feedback_urbs: Array of URBs for feedback. 136a2a2210fSŠerif Rami * @feedback_urb_alloc_size: Size of allocated buffer for each feedback URB. 1375c8c1079SŠerif Rami * @playback_active: Atomic flag indicating if playback is active. 1385c8c1079SŠerif Rami * @playback_frames_consumed: Total frames consumed by playback. 139a2a2210fSŠerif Rami * @driver_playback_pos: Current position in the ALSA playback buffer (frames). 140a2a2210fSŠerif Rami * @last_period_pos: Last reported period position for playback. 141a2a2210fSŠerif Rami * 142a2a2210fSŠerif Rami * @capture_substream: Pointer to the active capture PCM substream. 143c1bb0c13SŠerif Rami * @capture_urbs: Array of URBs for capture. 144c1bb0c13SŠerif Rami * @capture_urb_alloc_size: Size of allocated buffer for each capture URB. 145a2a2210fSŠerif Rami * @capture_active: Atomic flag indicating if capture is active. 146a2a2210fSŠerif Rami * @driver_capture_pos: Current position in the ALSA capture buffer (frames). 1475c8c1079SŠerif Rami * @capture_frames_processed: Total frames processed for capture. 148a2a2210fSŠerif Rami * @last_capture_period_pos: Last reported period position for capture. 149c1bb0c13SŠerif Rami * @capture_ring_buffer: Ring buffer for raw capture data from USB. 150c1bb0c13SŠerif Rami * @capture_ring_buffer_read_ptr: Read pointer for the capture ring buffer. 151c1bb0c13SŠerif Rami * @capture_ring_buffer_write_ptr: Write pointer for the capture ring buffer. 152c1bb0c13SŠerif Rami * @capture_decode_raw_block: Buffer for a raw 512-byte capture block. 153c1bb0c13SŠerif Rami * @capture_decode_dst_block: Buffer for decoded 32-bit capture samples. 154c1bb0c13SŠerif Rami * @capture_routing_buffer: Intermediate buffer for capture routing. 155c1bb0c13SŠerif Rami * @capture_work: Work struct for deferred capture processing. 156a2a2210fSŠerif Rami * @stop_work: Work struct for deferred stream stopping. 157a2a2210fSŠerif Rami * @stop_pcm_work: Work struct for stopping PCM due to a fatal error (e.g. 158a2a2210fSŠerif Rami * xrun). 159a2a2210fSŠerif Rami * 16067afec15SŠerif Rami * @midi_in_substream: Pointer to the active MIDI input substream. 16167afec15SŠerif Rami * @midi_out_substream: Pointer to the active MIDI output substream. 16267afec15SŠerif Rami * @midi_in_urbs: Array of URBs for MIDI input. 16367afec15SŠerif Rami * @midi_out_urbs: Array of URBs for MIDI output. 16467afec15SŠerif Rami * @midi_in_active: Atomic flag indicating if MIDI input is active. 16567afec15SŠerif Rami * @midi_out_active: Atomic flag indicating if MIDI output is active. 16667afec15SŠerif Rami * @midi_in_fifo: FIFO for raw MIDI input data. 16767afec15SŠerif Rami * @midi_in_work: Work struct for deferred MIDI input processing. 16867afec15SŠerif Rami * @midi_out_work: Work struct for deferred MIDI output processing. 16967afec15SŠerif Rami * @midi_in_lock: Spinlock for MIDI input FIFO. 17067afec15SŠerif Rami * @midi_out_lock: Spinlock for MIDI output. 17167afec15SŠerif Rami * @midi_out_urbs_in_flight: Bitmap of MIDI output URBs currently in flight. 17267afec15SŠerif Rami * @midi_running_status: Stores the last MIDI status byte for running status. 17367afec15SŠerif Rami * @error_timer: Timer for MIDI error retry logic. 17467afec15SŠerif Rami * 1755c8c1079SŠerif Rami * @lock: Main spinlock for protecting shared driver state. 176a2a2210fSŠerif Rami * @active_urbs: Atomic counter for active URBs. 177a2a2210fSŠerif Rami * @current_rate: Currently configured sample rate of the device. 17867afec15SŠerif Rami * @line_out_source: Source for Line Outputs (0: Playback 1-2, 1: Playback 3-4). 17967afec15SŠerif Rami * @digital_out_source: Source for Digital Outputs (0: Playback 1-2, 1: Playback 18067afec15SŠerif Rami * 3-4). 18167afec15SŠerif Rami * @capture_12_source: Source for Capture channels 1-2 (0: Analog In, 1: Digital 18267afec15SŠerif Rami * In). 18367afec15SŠerif Rami * @capture_34_source: Source for Capture channels 3-4 (0: Analog In, 1: Digital 18467afec15SŠerif Rami * In). 185a2a2210fSŠerif Rami * 186a2a2210fSŠerif Rami * @feedback_accumulator_pattern: Stores the calculated frames per packet for 187a2a2210fSŠerif Rami * feedback. 188a2a2210fSŠerif Rami * @feedback_pattern_out_idx: Read index for feedback_accumulator_pattern. 189a2a2210fSŠerif Rami * @feedback_pattern_in_idx: Write index for feedback_accumulator_pattern. 190a2a2210fSŠerif Rami * @feedback_synced: Flag indicating if feedback is synced. 191a2a2210fSŠerif Rami * @feedback_consecutive_errors: Counter for consecutive feedback errors. 192a2a2210fSŠerif Rami * @feedback_urb_skip_count: Number of feedback URBs to skip initially for 193a2a2210fSŠerif Rami * stabilization. 194a2a2210fSŠerif Rami * @fpo: Holds the state for the dynamic feedback pattern generation. 195a2a2210fSŠerif Rami * 196a2a2210fSŠerif Rami * @playback_anchor: USB anchor for playback URBs. 197c1bb0c13SŠerif Rami * @capture_anchor: USB anchor for capture URBs. 198a2a2210fSŠerif Rami * @feedback_anchor: USB anchor for feedback URBs. 19967afec15SŠerif Rami * @midi_in_anchor: USB anchor for MIDI input URBs. 20067afec15SŠerif Rami * @midi_out_anchor: USB anchor for MIDI output URBs. 201dee1bcf2SŠerif Rami */ 202dee1bcf2SŠerif Rami struct tascam_card { 203a2a2210fSŠerif Rami /* --- Core device pointers --- */ 204dee1bcf2SŠerif Rami struct usb_device *dev; 205dee1bcf2SŠerif Rami struct usb_interface *iface0; 206dee1bcf2SŠerif Rami struct usb_interface *iface1; 207dee1bcf2SŠerif Rami struct snd_card *card; 2085c8c1079SŠerif Rami struct snd_pcm *pcm; 20967afec15SŠerif Rami struct snd_rawmidi *rmidi; 2105c8c1079SŠerif Rami 211a2a2210fSŠerif Rami /* --- PCM Substreams --- */ 2125c8c1079SŠerif Rami struct snd_pcm_substream *playback_substream; 2135c8c1079SŠerif Rami struct snd_pcm_substream *capture_substream; 2145c8c1079SŠerif Rami 215a2a2210fSŠerif Rami /* --- URBs and Anchors --- */ 216a2a2210fSŠerif Rami struct urb *playback_urbs[NUM_PLAYBACK_URBS]; 217a2a2210fSŠerif Rami size_t playback_urb_alloc_size; 218a2a2210fSŠerif Rami struct urb *feedback_urbs[NUM_FEEDBACK_URBS]; 219a2a2210fSŠerif Rami size_t feedback_urb_alloc_size; 220c1bb0c13SŠerif Rami struct urb *capture_urbs[NUM_CAPTURE_URBS]; 221c1bb0c13SŠerif Rami size_t capture_urb_alloc_size; 22267afec15SŠerif Rami struct urb *midi_in_urbs[NUM_MIDI_IN_URBS]; 22367afec15SŠerif Rami struct urb *midi_out_urbs[NUM_MIDI_OUT_URBS]; 224a2a2210fSŠerif Rami struct usb_anchor playback_anchor; 225c1bb0c13SŠerif Rami struct usb_anchor capture_anchor; 226a2a2210fSŠerif Rami struct usb_anchor feedback_anchor; 22767afec15SŠerif Rami struct usb_anchor midi_in_anchor; 22867afec15SŠerif Rami struct usb_anchor midi_out_anchor; 229a2a2210fSŠerif Rami 230a2a2210fSŠerif Rami /* --- Stream State --- */ 231a2a2210fSŠerif Rami spinlock_t lock; 2325c8c1079SŠerif Rami atomic_t playback_active; 2335c8c1079SŠerif Rami atomic_t capture_active; 234a2a2210fSŠerif Rami atomic_t active_urbs; 2355c8c1079SŠerif Rami int current_rate; 236a2a2210fSŠerif Rami 237a2a2210fSŠerif Rami /* --- Playback State --- */ 238a2a2210fSŠerif Rami u64 playback_frames_consumed; 239a2a2210fSŠerif Rami snd_pcm_uframes_t driver_playback_pos; 240a2a2210fSŠerif Rami u64 last_period_pos; 241a2a2210fSŠerif Rami 242a2a2210fSŠerif Rami /* --- Capture State --- */ 243a2a2210fSŠerif Rami u64 capture_frames_processed; 244a2a2210fSŠerif Rami snd_pcm_uframes_t driver_capture_pos; 245a2a2210fSŠerif Rami u64 last_capture_period_pos; 246c1bb0c13SŠerif Rami u8 *capture_ring_buffer; 247c1bb0c13SŠerif Rami size_t capture_ring_buffer_read_ptr; 248c1bb0c13SŠerif Rami size_t capture_ring_buffer_write_ptr; 249c1bb0c13SŠerif Rami u8 *capture_decode_raw_block; 250c1bb0c13SŠerif Rami s32 *capture_decode_dst_block; 251c1bb0c13SŠerif Rami s32 *capture_routing_buffer; 252a2a2210fSŠerif Rami 25367afec15SŠerif Rami /* --- MIDI State --- */ 25467afec15SŠerif Rami struct snd_rawmidi_substream *midi_in_substream; 25567afec15SŠerif Rami struct snd_rawmidi_substream *midi_out_substream; 25667afec15SŠerif Rami atomic_t midi_in_active; 25767afec15SŠerif Rami atomic_t midi_out_active; 25867afec15SŠerif Rami struct kfifo midi_in_fifo; 25967afec15SŠerif Rami spinlock_t midi_in_lock; 26067afec15SŠerif Rami spinlock_t midi_out_lock; 26167afec15SŠerif Rami unsigned long midi_out_urbs_in_flight; 26267afec15SŠerif Rami u8 midi_running_status; 26367afec15SŠerif Rami struct timer_list error_timer; 26467afec15SŠerif Rami struct completion midi_out_drain_completion; 26567afec15SŠerif Rami 266a2a2210fSŠerif Rami /* --- Feedback Sync State --- */ 267a2a2210fSŠerif Rami unsigned int feedback_accumulator_pattern[FEEDBACK_ACCUMULATOR_SIZE]; 268a2a2210fSŠerif Rami unsigned int feedback_pattern_out_idx; 269a2a2210fSŠerif Rami unsigned int feedback_pattern_in_idx; 270a2a2210fSŠerif Rami bool feedback_synced; 271a2a2210fSŠerif Rami unsigned int feedback_consecutive_errors; 272a2a2210fSŠerif Rami unsigned int feedback_urb_skip_count; 273a2a2210fSŠerif Rami struct us144mkii_frame_pattern_observer fpo; 274a2a2210fSŠerif Rami 275a2a2210fSŠerif Rami /* --- Workqueues --- */ 276a2a2210fSŠerif Rami struct work_struct stop_work; 277a2a2210fSŠerif Rami struct work_struct stop_pcm_work; 278c1bb0c13SŠerif Rami struct work_struct capture_work; 27967afec15SŠerif Rami struct work_struct midi_in_work; 28067afec15SŠerif Rami struct work_struct midi_out_work; 28167afec15SŠerif Rami 28267afec15SŠerif Rami /* --- Mixer/Routing State --- */ 28367afec15SŠerif Rami unsigned int line_out_source; 28467afec15SŠerif Rami unsigned int digital_out_source; 28567afec15SŠerif Rami unsigned int capture_12_source; 28667afec15SŠerif Rami unsigned int capture_34_source; 287dee1bcf2SŠerif Rami }; 288dee1bcf2SŠerif Rami 28967afec15SŠerif Rami /* main.c */ 290a2a2210fSŠerif Rami /** 291a2a2210fSŠerif Rami * tascam_free_urbs() - Free all allocated URBs and associated buffers. 292a2a2210fSŠerif Rami * @tascam: the tascam_card instance 293a2a2210fSŠerif Rami * 29467afec15SŠerif Rami * This function kills, unlinks, and frees all playback, feedback, capture, 29567afec15SŠerif Rami * and MIDI URBs, along with their transfer buffers and the capture 296c1bb0c13SŠerif Rami * ring/decode buffers. 297a2a2210fSŠerif Rami */ 298a2a2210fSŠerif Rami void tascam_free_urbs(struct tascam_card *tascam); 299a2a2210fSŠerif Rami 300a2a2210fSŠerif Rami /** 301a2a2210fSŠerif Rami * tascam_alloc_urbs() - Allocate all URBs and associated buffers. 302a2a2210fSŠerif Rami * @tascam: the tascam_card instance 303a2a2210fSŠerif Rami * 304c1bb0c13SŠerif Rami * This function allocates and initializes all URBs for playback, feedback, 30567afec15SŠerif Rami * capture, and MIDI, as well as the necessary buffers for data processing. 306a2a2210fSŠerif Rami * 307a2a2210fSŠerif Rami * Return: 0 on success, or a negative error code on failure. 308a2a2210fSŠerif Rami */ 309a2a2210fSŠerif Rami int tascam_alloc_urbs(struct tascam_card *tascam); 310a2a2210fSŠerif Rami 311a2a2210fSŠerif Rami /** 312a2a2210fSŠerif Rami * tascam_stop_work_handler() - Work handler to stop all active streams. 313a2a2210fSŠerif Rami * @work: Pointer to the work_struct. 314a2a2210fSŠerif Rami * 315c1bb0c13SŠerif Rami * This function is scheduled to stop all active URBs (playback, feedback, 316c1bb0c13SŠerif Rami * capture) and reset the active_urbs counter. 317a2a2210fSŠerif Rami */ 318a2a2210fSŠerif Rami void tascam_stop_work_handler(struct work_struct *work); 319a2a2210fSŠerif Rami 32067afec15SŠerif Rami /* us144mkii_pcm.h */ 32167afec15SŠerif Rami #include "us144mkii_pcm.h" 32267afec15SŠerif Rami 32367afec15SŠerif Rami /* us144mkii_midi.c */ 32467afec15SŠerif Rami /** 32567afec15SŠerif Rami * tascam_midi_in_urb_complete() - Completion handler for MIDI IN URBs 32667afec15SŠerif Rami * @urb: The completed URB. 32767afec15SŠerif Rami * 32867afec15SŠerif Rami * This function runs in interrupt context. It places the raw data from the 32967afec15SŠerif Rami * USB endpoint into a kfifo and schedules a work item to process it later, 33067afec15SŠerif Rami * ensuring the interrupt handler remains fast. 33167afec15SŠerif Rami */ 33267afec15SŠerif Rami void tascam_midi_in_urb_complete(struct urb *urb); 33367afec15SŠerif Rami 33467afec15SŠerif Rami /** 33567afec15SŠerif Rami * tascam_midi_out_urb_complete() - Completion handler for MIDI OUT bulk URB. 33667afec15SŠerif Rami * @urb: The completed URB. 33767afec15SŠerif Rami * 33867afec15SŠerif Rami * This function runs in interrupt context. It marks the output URB as no 33967afec15SŠerif Rami * longer in-flight. It then re-schedules the work handler to check for and 34067afec15SŠerif Rami * send any more data waiting in the ALSA buffer. This is a safe, non-blocking 34167afec15SŠerif Rami * way to continue the data transmission chain. 34267afec15SŠerif Rami */ 34367afec15SŠerif Rami void tascam_midi_out_urb_complete(struct urb *urb); 34467afec15SŠerif Rami 34567afec15SŠerif Rami /** 34667afec15SŠerif Rami * tascam_create_midi() - Create and initialize the ALSA rawmidi device. 34767afec15SŠerif Rami * @tascam: The driver instance. 34867afec15SŠerif Rami * 34967afec15SŠerif Rami * Return: 0 on success, or a negative error code on failure. 35067afec15SŠerif Rami */ 35167afec15SŠerif Rami int tascam_create_midi(struct tascam_card *tascam); 35267afec15SŠerif Rami 35367afec15SŠerif Rami /* us144mkii_controls.c */ 35467afec15SŠerif Rami /** 35567afec15SŠerif Rami * tascam_create_controls() - Creates and adds ALSA mixer controls for the 35667afec15SŠerif Rami * device. 35767afec15SŠerif Rami * @tascam: The driver instance. 35867afec15SŠerif Rami * 35967afec15SŠerif Rami * This function registers custom ALSA controls for managing audio routing 36067afec15SŠerif Rami * (line out source, digital out source, capture 1-2 source, capture 3-4 source) 36167afec15SŠerif Rami * and displaying the current sample rate. 36267afec15SŠerif Rami * 36367afec15SŠerif Rami * Return: 0 on success, or a negative error code on failure. 36467afec15SŠerif Rami */ 36567afec15SŠerif Rami int tascam_create_controls(struct tascam_card *tascam); 36667afec15SŠerif Rami 367dee1bcf2SŠerif Rami #endif /* __US144MKII_H */ 368