xref: /linux/sound/usb/usx2y/us144mkii.h (revision 05a54fa773284d1a7923cdfdd8f0c8dabb98bd26)
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