xref: /kernel/linux/linux-5.10/sound/usb/line6/pcm.h (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Line 6 Linux USB driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci	PCM interface to POD series devices.
108c2ecf20Sopenharmony_ci*/
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#ifndef PCM_H
138c2ecf20Sopenharmony_ci#define PCM_H
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <sound/pcm.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include "driver.h"
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/*
208c2ecf20Sopenharmony_ci	number of USB frames per URB
218c2ecf20Sopenharmony_ci	The Line 6 Windows driver always transmits two frames per packet, but
228c2ecf20Sopenharmony_ci	the Linux driver performs significantly better (i.e., lower latency)
238c2ecf20Sopenharmony_ci	with only one frame per packet.
248c2ecf20Sopenharmony_ci*/
258c2ecf20Sopenharmony_ci#define LINE6_ISO_PACKETS	1
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci/* in a "full speed" device (such as the PODxt Pro) this means 1ms,
288c2ecf20Sopenharmony_ci *  for "high speed" it's 1/8ms
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_ci#define LINE6_ISO_INTERVAL	1
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci#define LINE6_IMPULSE_DEFAULT_PERIOD 100
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/*
358c2ecf20Sopenharmony_ci	Get substream from Line 6 PCM data structure
368c2ecf20Sopenharmony_ci*/
378c2ecf20Sopenharmony_ci#define get_substream(line6pcm, stream)	\
388c2ecf20Sopenharmony_ci		(line6pcm->pcm->streams[stream].substream)
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/*
418c2ecf20Sopenharmony_ci	PCM mode bits.
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	There are several features of the Line 6 USB driver which require PCM
448c2ecf20Sopenharmony_ci	data to be exchanged with the device:
458c2ecf20Sopenharmony_ci	*) PCM playback and capture via ALSA
468c2ecf20Sopenharmony_ci	*) software monitoring (for devices without hardware monitoring)
478c2ecf20Sopenharmony_ci	*) optional impulse response measurement
488c2ecf20Sopenharmony_ci	However, from the device's point of view, there is just a single
498c2ecf20Sopenharmony_ci	capture and playback stream, which must be shared between these
508c2ecf20Sopenharmony_ci	subsystems. It is therefore necessary to maintain the state of the
518c2ecf20Sopenharmony_ci	subsystems with respect to PCM usage.
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	We define two bit flags, "opened" and "running", for each playback
548c2ecf20Sopenharmony_ci	or capture stream.  Both can contain the bit flag corresponding to
558c2ecf20Sopenharmony_ci	LINE6_STREAM_* type,
568c2ecf20Sopenharmony_ci	  LINE6_STREAM_PCM = ALSA PCM playback or capture
578c2ecf20Sopenharmony_ci	  LINE6_STREAM_MONITOR = software monitoring
588c2ecf20Sopenharmony_ci	  IMPULSE = optional impulse response measurement
598c2ecf20Sopenharmony_ci	The opened flag indicates whether the buffer is allocated while
608c2ecf20Sopenharmony_ci	the running flag indicates whether the stream is running.
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	For monitor or impulse operations, the driver needs to call
638c2ecf20Sopenharmony_ci	line6_pcm_acquire() or line6_pcm_release() with the appropriate
648c2ecf20Sopenharmony_ci	LINE6_STREAM_* flag.
658c2ecf20Sopenharmony_ci*/
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci/* stream types */
688c2ecf20Sopenharmony_cienum {
698c2ecf20Sopenharmony_ci	LINE6_STREAM_PCM,
708c2ecf20Sopenharmony_ci	LINE6_STREAM_MONITOR,
718c2ecf20Sopenharmony_ci	LINE6_STREAM_IMPULSE,
728c2ecf20Sopenharmony_ci	LINE6_STREAM_CAPTURE_HELPER,
738c2ecf20Sopenharmony_ci};
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/* misc bit flags for PCM operation */
768c2ecf20Sopenharmony_cienum {
778c2ecf20Sopenharmony_ci	LINE6_FLAG_PAUSE_PLAYBACK,
788c2ecf20Sopenharmony_ci	LINE6_FLAG_PREPARED,
798c2ecf20Sopenharmony_ci};
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistruct line6_pcm_properties {
828c2ecf20Sopenharmony_ci	struct snd_pcm_hardware playback_hw, capture_hw;
838c2ecf20Sopenharmony_ci	struct snd_pcm_hw_constraint_ratdens rates;
848c2ecf20Sopenharmony_ci	int bytes_per_channel;
858c2ecf20Sopenharmony_ci};
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_cistruct line6_pcm_stream {
888c2ecf20Sopenharmony_ci	/* allocated URBs */
898c2ecf20Sopenharmony_ci	struct urb **urbs;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	/* Temporary buffer;
928c2ecf20Sopenharmony_ci	 * Since the packet size is not known in advance, this buffer is
938c2ecf20Sopenharmony_ci	 * large enough to store maximum size packets.
948c2ecf20Sopenharmony_ci	 */
958c2ecf20Sopenharmony_ci	unsigned char *buffer;
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	/* Free frame position in the buffer. */
988c2ecf20Sopenharmony_ci	snd_pcm_uframes_t pos;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	/* Count processed bytes;
1018c2ecf20Sopenharmony_ci	 * This is modulo period size (to determine when a period is finished).
1028c2ecf20Sopenharmony_ci	 */
1038c2ecf20Sopenharmony_ci	unsigned bytes;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	/* Counter to create desired sample rate */
1068c2ecf20Sopenharmony_ci	unsigned count;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	/* period size in bytes */
1098c2ecf20Sopenharmony_ci	unsigned period;
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	/* Processed frame position in the buffer;
1128c2ecf20Sopenharmony_ci	 * The contents of the ring buffer have been consumed by the USB
1138c2ecf20Sopenharmony_ci	 * subsystem (i.e., sent to the USB device) up to this position.
1148c2ecf20Sopenharmony_ci	 */
1158c2ecf20Sopenharmony_ci	snd_pcm_uframes_t pos_done;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	/* Bit mask of active URBs */
1188c2ecf20Sopenharmony_ci	unsigned long active_urbs;
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	/* Bit mask of URBs currently being unlinked */
1218c2ecf20Sopenharmony_ci	unsigned long unlink_urbs;
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	/* Spin lock to protect updates of the buffer positions (not contents)
1248c2ecf20Sopenharmony_ci	 */
1258c2ecf20Sopenharmony_ci	spinlock_t lock;
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	/* Bit flags for operational stream types */
1288c2ecf20Sopenharmony_ci	unsigned long opened;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	/* Bit flags for running stream types */
1318c2ecf20Sopenharmony_ci	unsigned long running;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	int last_frame;
1348c2ecf20Sopenharmony_ci};
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistruct snd_line6_pcm {
1378c2ecf20Sopenharmony_ci	/* Pointer back to the Line 6 driver data structure */
1388c2ecf20Sopenharmony_ci	struct usb_line6 *line6;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	/* Properties. */
1418c2ecf20Sopenharmony_ci	struct line6_pcm_properties *properties;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	/* ALSA pcm stream */
1448c2ecf20Sopenharmony_ci	struct snd_pcm *pcm;
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	/* protection to state changes of in/out streams */
1478c2ecf20Sopenharmony_ci	struct mutex state_mutex;
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	/* Capture and playback streams */
1508c2ecf20Sopenharmony_ci	struct line6_pcm_stream in;
1518c2ecf20Sopenharmony_ci	struct line6_pcm_stream out;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	/* Previously captured frame (for software monitoring) */
1548c2ecf20Sopenharmony_ci	unsigned char *prev_fbuf;
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	/* Size of previously captured frame (for software monitoring/sync) */
1578c2ecf20Sopenharmony_ci	int prev_fsize;
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	/* Maximum size of USB packet */
1608c2ecf20Sopenharmony_ci	int max_packet_size_in;
1618c2ecf20Sopenharmony_ci	int max_packet_size_out;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	/* PCM playback volume (left and right) */
1648c2ecf20Sopenharmony_ci	int volume_playback[2];
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	/* PCM monitor volume */
1678c2ecf20Sopenharmony_ci	int volume_monitor;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	/* Volume of impulse response test signal (if zero, test is disabled) */
1708c2ecf20Sopenharmony_ci	int impulse_volume;
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	/* Period of impulse response test signal */
1738c2ecf20Sopenharmony_ci	int impulse_period;
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	/* Counter for impulse response test signal */
1768c2ecf20Sopenharmony_ci	int impulse_count;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	/* Several status bits (see LINE6_FLAG_*) */
1798c2ecf20Sopenharmony_ci	unsigned long flags;
1808c2ecf20Sopenharmony_ci};
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ciextern int line6_init_pcm(struct usb_line6 *line6,
1838c2ecf20Sopenharmony_ci			  struct line6_pcm_properties *properties);
1848c2ecf20Sopenharmony_ciextern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
1858c2ecf20Sopenharmony_ciextern int snd_line6_prepare(struct snd_pcm_substream *substream);
1868c2ecf20Sopenharmony_ciextern int snd_line6_hw_params(struct snd_pcm_substream *substream,
1878c2ecf20Sopenharmony_ci			       struct snd_pcm_hw_params *hw_params);
1888c2ecf20Sopenharmony_ciextern int snd_line6_hw_free(struct snd_pcm_substream *substream);
1898c2ecf20Sopenharmony_ciextern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream);
1908c2ecf20Sopenharmony_ciextern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
1918c2ecf20Sopenharmony_ciextern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type,
1928c2ecf20Sopenharmony_ci			       bool start);
1938c2ecf20Sopenharmony_ciextern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type);
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci#endif
196