1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 // Copyright (c) 2025 Šerif Rami <ramiserifpersia@gmail.com> 3 4 #ifndef __US144MKII_PCM_H 5 #define __US144MKII_PCM_H 6 7 #include "us144mkii.h" 8 9 /** 10 * tascam_pcm_hw - Hardware capabilities for TASCAM US-144MKII PCM. 11 * 12 * Defines the supported PCM formats, rates, channels, and buffer/period sizes 13 * for the TASCAM US-144MKII audio interface. 14 */ 15 extern const struct snd_pcm_hardware tascam_pcm_hw; 16 17 /** 18 * tascam_playback_ops - ALSA PCM operations for playback. 19 * 20 * This structure defines the callback functions for playback stream operations. 21 */ 22 extern const struct snd_pcm_ops tascam_playback_ops; 23 24 /** 25 * tascam_capture_ops - ALSA PCM operations for capture. 26 * 27 * This structure defines the callback functions for capture stream operations. 28 */ 29 extern const struct snd_pcm_ops tascam_capture_ops; 30 31 /** 32 * playback_urb_complete() - Completion handler for playback isochronous URBs. 33 * @urb: the completed URB 34 * 35 * This function runs in interrupt context. It calculates the number of bytes 36 * to send in the next set of packets based on the feedback-driven clock, 37 * copies the audio data from the ALSA ring buffer, and resubmits the URB. 38 */ 39 void playback_urb_complete(struct urb *urb); 40 41 /** 42 * feedback_urb_complete() - Completion handler for feedback isochronous URBs. 43 * @urb: the completed URB 44 * 45 * This is the master clock for the driver. It runs in interrupt context. 46 * It reads the feedback value from the device, which indicates how many 47 * samples the device has consumed. This information is used to adjust the 48 * playback rate and to advance the capture stream pointer, keeping both 49 * streams in sync. It then calls snd_pcm_period_elapsed if necessary and 50 * resubmits itself. 51 */ 52 void feedback_urb_complete(struct urb *urb); 53 54 /** 55 * capture_urb_complete() - Completion handler for capture bulk URBs. 56 * @urb: the completed URB 57 * 58 * This function runs in interrupt context. It copies the received raw data 59 * into an intermediate ring buffer and then schedules the workqueue to process 60 * it. It then resubmits the URB to receive more data. 61 */ 62 void capture_urb_complete(struct urb *urb); 63 64 /** 65 * tascam_stop_pcm_work_handler() - Work handler to stop PCM streams. 66 * @work: Pointer to the work_struct. 67 * 68 * This function is scheduled to stop PCM streams (playback and capture) 69 * from a workqueue context, avoiding blocking operations in interrupt context. 70 */ 71 void tascam_stop_pcm_work_handler(struct work_struct *work); 72 73 /** 74 * tascam_init_pcm() - Initializes the ALSA PCM device. 75 * @pcm: Pointer to the ALSA PCM device to initialize. 76 * 77 * This function sets up the PCM operations, adds ALSA controls for routing 78 * and sample rate, and preallocates pages for the PCM buffer. 79 * 80 * Return: 0 on success, or a negative error code on failure. 81 */ 82 int tascam_init_pcm(struct snd_pcm *pcm); 83 84 /** 85 * us144mkii_configure_device_for_rate() - Set sample rate via USB control msgs 86 * @tascam: the tascam_card instance 87 * @rate: the target sample rate (e.g., 44100, 96000) 88 * 89 * This function sends a sequence of vendor-specific and UAC control messages 90 * to configure the device hardware for the specified sample rate. 91 * 92 * Return: 0 on success, or a negative error code on failure. 93 */ 94 int us144mkii_configure_device_for_rate(struct tascam_card *tascam, int rate); 95 96 /** 97 * process_playback_routing_us144mkii() - Apply playback routing matrix 98 * @tascam: The driver instance. 99 * @src_buffer: Buffer containing 4 channels of S24_3LE audio from ALSA. 100 * @dst_buffer: Buffer to be filled for the USB device. 101 * @frames: Number of frames to process. 102 */ 103 void process_playback_routing_us144mkii(struct tascam_card *tascam, 104 const u8 *src_buffer, u8 *dst_buffer, 105 size_t frames); 106 107 /** 108 * process_capture_routing_us144mkii() - Apply capture routing matrix 109 * @tascam: The driver instance. 110 * @decoded_block: Buffer containing 4 channels of S32LE decoded audio. 111 * @routed_block: Buffer to be filled for ALSA. 112 */ 113 void process_capture_routing_us144mkii(struct tascam_card *tascam, 114 const s32 *decoded_block, 115 s32 *routed_block); 116 117 /** 118 * tascam_pcm_hw_params() - Configures hardware parameters for PCM streams. 119 * @substream: The ALSA PCM substream. 120 * @params: The hardware parameters to apply. 121 * 122 * This function allocates pages for the PCM buffer and, for playback streams, 123 * selects the appropriate feedback patterns based on the requested sample rate. 124 * It also configures the device hardware for the selected sample rate if it 125 * has changed. 126 * 127 * Return: 0 on success, or a negative error code on failure. 128 */ 129 int tascam_pcm_hw_params(struct snd_pcm_substream *substream, 130 struct snd_pcm_hw_params *params); 131 132 /** 133 * tascam_pcm_hw_free() - Frees hardware parameters for PCM streams. 134 * @substream: The ALSA PCM substream. 135 * 136 * This function is a stub for freeing hardware-related resources. 137 * 138 * Return: 0 on success. 139 */ 140 int tascam_pcm_hw_free(struct snd_pcm_substream *substream); 141 142 /** 143 * tascam_pcm_trigger() - Triggers the start or stop of PCM streams. 144 * @substream: The ALSA PCM substream. 145 * @cmd: The trigger command (e.g., SNDRV_PCM_TRIGGER_START). 146 * 147 * This function handles starting and stopping of playback and capture streams 148 * by submitting or killing the associated URBs. 149 * 150 * Return: 0 on success, or a negative error code on failure. 151 */ 152 int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd); 153 154 /** 155 * tascam_capture_work_handler() - Deferred work for processing capture data. 156 * @work: the work_struct instance 157 * 158 * This function runs in a kernel thread context, not an IRQ context. It reads 159 * raw data from the capture ring buffer, decodes it, applies routing, and 160 * copies the final audio data into the ALSA capture ring buffer. This offloads 161 * the CPU-intensive decoding from the time-sensitive URB completion handlers. 162 */ 163 void tascam_capture_work_handler(struct work_struct *work); 164 165 #endif /* __US144MKII_PCM_H */ 166