xref: /linux/sound/usb/usx2y/us144mkii_pcm.h (revision 05a54fa773284d1a7923cdfdd8f0c8dabb98bd26)
15c8c1079SŠerif Rami /* SPDX-License-Identifier: GPL-2.0-only */
25c8c1079SŠerif Rami // Copyright (c) 2025 Šerif Rami <ramiserifpersia@gmail.com>
35c8c1079SŠerif Rami 
45c8c1079SŠerif Rami #ifndef __US144MKII_PCM_H
55c8c1079SŠerif Rami #define __US144MKII_PCM_H
65c8c1079SŠerif Rami 
75c8c1079SŠerif Rami #include "us144mkii.h"
85c8c1079SŠerif Rami 
95c8c1079SŠerif Rami /**
105c8c1079SŠerif Rami  * tascam_pcm_hw - Hardware capabilities for TASCAM US-144MKII PCM.
115c8c1079SŠerif Rami  *
125c8c1079SŠerif Rami  * Defines the supported PCM formats, rates, channels, and buffer/period sizes
135c8c1079SŠerif Rami  * for the TASCAM US-144MKII audio interface.
145c8c1079SŠerif Rami  */
155c8c1079SŠerif Rami extern const struct snd_pcm_hardware tascam_pcm_hw;
165c8c1079SŠerif Rami 
175c8c1079SŠerif Rami /**
185c8c1079SŠerif Rami  * tascam_playback_ops - ALSA PCM operations for playback.
195c8c1079SŠerif Rami  *
205c8c1079SŠerif Rami  * This structure defines the callback functions for playback stream operations.
215c8c1079SŠerif Rami  */
225c8c1079SŠerif Rami extern const struct snd_pcm_ops tascam_playback_ops;
235c8c1079SŠerif Rami 
245c8c1079SŠerif Rami /**
255c8c1079SŠerif Rami  * tascam_capture_ops - ALSA PCM operations for capture.
265c8c1079SŠerif Rami  *
275c8c1079SŠerif Rami  * This structure defines the callback functions for capture stream operations.
285c8c1079SŠerif Rami  */
295c8c1079SŠerif Rami extern const struct snd_pcm_ops tascam_capture_ops;
305c8c1079SŠerif Rami 
315c8c1079SŠerif Rami /**
32a2a2210fSŠerif Rami  * playback_urb_complete() - Completion handler for playback isochronous URBs.
33a2a2210fSŠerif Rami  * @urb: the completed URB
34a2a2210fSŠerif Rami  *
35a2a2210fSŠerif Rami  * This function runs in interrupt context. It calculates the number of bytes
36a2a2210fSŠerif Rami  * to send in the next set of packets based on the feedback-driven clock,
37a2a2210fSŠerif Rami  * copies the audio data from the ALSA ring buffer, and resubmits the URB.
38a2a2210fSŠerif Rami  */
39a2a2210fSŠerif Rami void playback_urb_complete(struct urb *urb);
40a2a2210fSŠerif Rami 
41a2a2210fSŠerif Rami /**
42a2a2210fSŠerif Rami  * feedback_urb_complete() - Completion handler for feedback isochronous URBs.
43a2a2210fSŠerif Rami  * @urb: the completed URB
44a2a2210fSŠerif Rami  *
45a2a2210fSŠerif Rami  * This is the master clock for the driver. It runs in interrupt context.
46a2a2210fSŠerif Rami  * It reads the feedback value from the device, which indicates how many
47a2a2210fSŠerif Rami  * samples the device has consumed. This information is used to adjust the
48a2a2210fSŠerif Rami  * playback rate and to advance the capture stream pointer, keeping both
49a2a2210fSŠerif Rami  * streams in sync. It then calls snd_pcm_period_elapsed if necessary and
50a2a2210fSŠerif Rami  * resubmits itself.
51a2a2210fSŠerif Rami  */
52a2a2210fSŠerif Rami void feedback_urb_complete(struct urb *urb);
53a2a2210fSŠerif Rami 
54a2a2210fSŠerif Rami /**
55*c1bb0c13SŠerif Rami  * capture_urb_complete() - Completion handler for capture bulk URBs.
56*c1bb0c13SŠerif Rami  * @urb: the completed URB
57*c1bb0c13SŠerif Rami  *
58*c1bb0c13SŠerif Rami  * This function runs in interrupt context. It copies the received raw data
59*c1bb0c13SŠerif Rami  * into an intermediate ring buffer and then schedules the workqueue to process
60*c1bb0c13SŠerif Rami  * it. It then resubmits the URB to receive more data.
61*c1bb0c13SŠerif Rami  */
62*c1bb0c13SŠerif Rami void capture_urb_complete(struct urb *urb);
63*c1bb0c13SŠerif Rami 
64*c1bb0c13SŠerif Rami /**
65a2a2210fSŠerif Rami  * tascam_stop_pcm_work_handler() - Work handler to stop PCM streams.
66a2a2210fSŠerif Rami  * @work: Pointer to the work_struct.
67a2a2210fSŠerif Rami  *
68a2a2210fSŠerif Rami  * This function is scheduled to stop PCM streams (playback and capture)
69a2a2210fSŠerif Rami  * from a workqueue context, avoiding blocking operations in interrupt context.
70a2a2210fSŠerif Rami  */
71a2a2210fSŠerif Rami void tascam_stop_pcm_work_handler(struct work_struct *work);
72a2a2210fSŠerif Rami 
73a2a2210fSŠerif Rami /**
745c8c1079SŠerif Rami  * tascam_init_pcm() - Initializes the ALSA PCM device.
755c8c1079SŠerif Rami  * @pcm: Pointer to the ALSA PCM device to initialize.
765c8c1079SŠerif Rami  *
77*c1bb0c13SŠerif Rami  * This function sets up the PCM operations, adds ALSA controls for routing
78*c1bb0c13SŠerif Rami  * and sample rate, and preallocates pages for the PCM buffer.
795c8c1079SŠerif Rami  *
805c8c1079SŠerif Rami  * Return: 0 on success, or a negative error code on failure.
815c8c1079SŠerif Rami  */
825c8c1079SŠerif Rami int tascam_init_pcm(struct snd_pcm *pcm);
835c8c1079SŠerif Rami 
845c8c1079SŠerif Rami /**
85a2a2210fSŠerif Rami  * us144mkii_configure_device_for_rate() - Set sample rate via USB control msgs
86a2a2210fSŠerif Rami  * @tascam: the tascam_card instance
87a2a2210fSŠerif Rami  * @rate: the target sample rate (e.g., 44100, 96000)
88a2a2210fSŠerif Rami  *
89a2a2210fSŠerif Rami  * This function sends a sequence of vendor-specific and UAC control messages
90a2a2210fSŠerif Rami  * to configure the device hardware for the specified sample rate.
91a2a2210fSŠerif Rami  *
92a2a2210fSŠerif Rami  * Return: 0 on success, or a negative error code on failure.
93a2a2210fSŠerif Rami  */
94a2a2210fSŠerif Rami int us144mkii_configure_device_for_rate(struct tascam_card *tascam, int rate);
95a2a2210fSŠerif Rami 
96a2a2210fSŠerif Rami /**
97a2a2210fSŠerif Rami  * process_playback_routing_us144mkii() - Apply playback routing matrix
98a2a2210fSŠerif Rami  * @tascam: The driver instance.
99a2a2210fSŠerif Rami  * @src_buffer: Buffer containing 4 channels of S24_3LE audio from ALSA.
100a2a2210fSŠerif Rami  * @dst_buffer: Buffer to be filled for the USB device.
101a2a2210fSŠerif Rami  * @frames: Number of frames to process.
102a2a2210fSŠerif Rami  */
103a2a2210fSŠerif Rami void process_playback_routing_us144mkii(struct tascam_card *tascam,
104a2a2210fSŠerif Rami 					const u8 *src_buffer, u8 *dst_buffer,
105a2a2210fSŠerif Rami 					size_t frames);
106a2a2210fSŠerif Rami 
107a2a2210fSŠerif Rami /**
108*c1bb0c13SŠerif Rami  * process_capture_routing_us144mkii() - Apply capture routing matrix
109*c1bb0c13SŠerif Rami  * @tascam: The driver instance.
110*c1bb0c13SŠerif Rami  * @decoded_block: Buffer containing 4 channels of S32LE decoded audio.
111*c1bb0c13SŠerif Rami  * @routed_block: Buffer to be filled for ALSA.
112*c1bb0c13SŠerif Rami  */
113*c1bb0c13SŠerif Rami void process_capture_routing_us144mkii(struct tascam_card *tascam,
114*c1bb0c13SŠerif Rami 				       const s32 *decoded_block,
115*c1bb0c13SŠerif Rami 				       s32 *routed_block);
116*c1bb0c13SŠerif Rami 
117*c1bb0c13SŠerif Rami /**
1185c8c1079SŠerif Rami  * tascam_pcm_hw_params() - Configures hardware parameters for PCM streams.
1195c8c1079SŠerif Rami  * @substream: The ALSA PCM substream.
1205c8c1079SŠerif Rami  * @params: The hardware parameters to apply.
1215c8c1079SŠerif Rami  *
122a2a2210fSŠerif Rami  * This function allocates pages for the PCM buffer and, for playback streams,
123a2a2210fSŠerif Rami  * selects the appropriate feedback patterns based on the requested sample rate.
124a2a2210fSŠerif Rami  * It also configures the device hardware for the selected sample rate if it
125a2a2210fSŠerif Rami  * has changed.
1265c8c1079SŠerif Rami  *
127a2a2210fSŠerif Rami  * Return: 0 on success, or a negative error code on failure.
1285c8c1079SŠerif Rami  */
1295c8c1079SŠerif Rami int tascam_pcm_hw_params(struct snd_pcm_substream *substream,
1305c8c1079SŠerif Rami 			 struct snd_pcm_hw_params *params);
1315c8c1079SŠerif Rami 
1325c8c1079SŠerif Rami /**
1335c8c1079SŠerif Rami  * tascam_pcm_hw_free() - Frees hardware parameters for PCM streams.
1345c8c1079SŠerif Rami  * @substream: The ALSA PCM substream.
1355c8c1079SŠerif Rami  *
1365c8c1079SŠerif Rami  * This function is a stub for freeing hardware-related resources.
1375c8c1079SŠerif Rami  *
1385c8c1079SŠerif Rami  * Return: 0 on success.
1395c8c1079SŠerif Rami  */
1405c8c1079SŠerif Rami int tascam_pcm_hw_free(struct snd_pcm_substream *substream);
1415c8c1079SŠerif Rami 
1425c8c1079SŠerif Rami /**
1435c8c1079SŠerif Rami  * tascam_pcm_trigger() - Triggers the start or stop of PCM streams.
1445c8c1079SŠerif Rami  * @substream: The ALSA PCM substream.
1455c8c1079SŠerif Rami  * @cmd: The trigger command (e.g., SNDRV_PCM_TRIGGER_START).
1465c8c1079SŠerif Rami  *
1475c8c1079SŠerif Rami  * This function handles starting and stopping of playback and capture streams
148a2a2210fSŠerif Rami  * by submitting or killing the associated URBs.
1495c8c1079SŠerif Rami  *
1505c8c1079SŠerif Rami  * Return: 0 on success, or a negative error code on failure.
1515c8c1079SŠerif Rami  */
1525c8c1079SŠerif Rami int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
1535c8c1079SŠerif Rami 
154*c1bb0c13SŠerif Rami /**
155*c1bb0c13SŠerif Rami  * tascam_capture_work_handler() - Deferred work for processing capture data.
156*c1bb0c13SŠerif Rami  * @work: the work_struct instance
157*c1bb0c13SŠerif Rami  *
158*c1bb0c13SŠerif Rami  * This function runs in a kernel thread context, not an IRQ context. It reads
159*c1bb0c13SŠerif Rami  * raw data from the capture ring buffer, decodes it, applies routing, and
160*c1bb0c13SŠerif Rami  * copies the final audio data into the ALSA capture ring buffer. This offloads
161*c1bb0c13SŠerif Rami  * the CPU-intensive decoding from the time-sensitive URB completion handlers.
162*c1bb0c13SŠerif Rami  */
163*c1bb0c13SŠerif Rami void tascam_capture_work_handler(struct work_struct *work);
164*c1bb0c13SŠerif Rami 
1655c8c1079SŠerif Rami #endif /* __US144MKII_PCM_H */
166