Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Line 6 Linux USB driver
0004  *
0005  * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
0006  */
0007 
0008 /*
0009     PCM interface to POD series devices.
0010 */
0011 
0012 #ifndef PCM_H
0013 #define PCM_H
0014 
0015 #include <sound/pcm.h>
0016 
0017 #include "driver.h"
0018 
0019 /*
0020     number of USB frames per URB
0021     The Line 6 Windows driver always transmits two frames per packet, but
0022     the Linux driver performs significantly better (i.e., lower latency)
0023     with only one frame per packet.
0024 */
0025 #define LINE6_ISO_PACKETS   1
0026 
0027 /* in a "full speed" device (such as the PODxt Pro) this means 1ms,
0028  *  for "high speed" it's 1/8ms
0029  */
0030 #define LINE6_ISO_INTERVAL  1
0031 
0032 #define LINE6_IMPULSE_DEFAULT_PERIOD 100
0033 
0034 /*
0035     Get substream from Line 6 PCM data structure
0036 */
0037 #define get_substream(line6pcm, stream) \
0038         (line6pcm->pcm->streams[stream].substream)
0039 
0040 /*
0041     PCM mode bits.
0042 
0043     There are several features of the Line 6 USB driver which require PCM
0044     data to be exchanged with the device:
0045     *) PCM playback and capture via ALSA
0046     *) software monitoring (for devices without hardware monitoring)
0047     *) optional impulse response measurement
0048     However, from the device's point of view, there is just a single
0049     capture and playback stream, which must be shared between these
0050     subsystems. It is therefore necessary to maintain the state of the
0051     subsystems with respect to PCM usage.
0052 
0053     We define two bit flags, "opened" and "running", for each playback
0054     or capture stream.  Both can contain the bit flag corresponding to
0055     LINE6_STREAM_* type,
0056       LINE6_STREAM_PCM = ALSA PCM playback or capture
0057       LINE6_STREAM_MONITOR = software monitoring
0058       IMPULSE = optional impulse response measurement
0059     The opened flag indicates whether the buffer is allocated while
0060     the running flag indicates whether the stream is running.
0061 
0062     For monitor or impulse operations, the driver needs to call
0063     line6_pcm_acquire() or line6_pcm_release() with the appropriate
0064     LINE6_STREAM_* flag.
0065 */
0066 
0067 /* stream types */
0068 enum {
0069     LINE6_STREAM_PCM,
0070     LINE6_STREAM_MONITOR,
0071     LINE6_STREAM_IMPULSE,
0072     LINE6_STREAM_CAPTURE_HELPER,
0073 };
0074 
0075 /* misc bit flags for PCM operation */
0076 enum {
0077     LINE6_FLAG_PAUSE_PLAYBACK,
0078     LINE6_FLAG_PREPARED,
0079 };
0080 
0081 struct line6_pcm_properties {
0082     struct snd_pcm_hardware playback_hw, capture_hw;
0083     struct snd_pcm_hw_constraint_ratdens rates;
0084     int bytes_per_channel;
0085 };
0086 
0087 struct line6_pcm_stream {
0088     /* allocated URBs */
0089     struct urb **urbs;
0090 
0091     /* Temporary buffer;
0092      * Since the packet size is not known in advance, this buffer is
0093      * large enough to store maximum size packets.
0094      */
0095     unsigned char *buffer;
0096 
0097     /* Free frame position in the buffer. */
0098     snd_pcm_uframes_t pos;
0099 
0100     /* Count processed bytes;
0101      * This is modulo period size (to determine when a period is finished).
0102      */
0103     unsigned bytes;
0104 
0105     /* Counter to create desired sample rate */
0106     unsigned count;
0107 
0108     /* period size in bytes */
0109     unsigned period;
0110 
0111     /* Processed frame position in the buffer;
0112      * The contents of the ring buffer have been consumed by the USB
0113      * subsystem (i.e., sent to the USB device) up to this position.
0114      */
0115     snd_pcm_uframes_t pos_done;
0116 
0117     /* Bit mask of active URBs */
0118     unsigned long active_urbs;
0119 
0120     /* Bit mask of URBs currently being unlinked */
0121     unsigned long unlink_urbs;
0122 
0123     /* Spin lock to protect updates of the buffer positions (not contents)
0124      */
0125     spinlock_t lock;
0126 
0127     /* Bit flags for operational stream types */
0128     unsigned long opened;
0129 
0130     /* Bit flags for running stream types */
0131     unsigned long running;
0132 
0133     int last_frame;
0134 };
0135 
0136 struct snd_line6_pcm {
0137     /* Pointer back to the Line 6 driver data structure */
0138     struct usb_line6 *line6;
0139 
0140     /* Properties. */
0141     struct line6_pcm_properties *properties;
0142 
0143     /* ALSA pcm stream */
0144     struct snd_pcm *pcm;
0145 
0146     /* protection to state changes of in/out streams */
0147     struct mutex state_mutex;
0148 
0149     /* Capture and playback streams */
0150     struct line6_pcm_stream in;
0151     struct line6_pcm_stream out;
0152 
0153     /* Previously captured frame (for software monitoring) */
0154     unsigned char *prev_fbuf;
0155 
0156     /* Size of previously captured frame (for software monitoring/sync) */
0157     int prev_fsize;
0158 
0159     /* Maximum size of USB packet */
0160     int max_packet_size_in;
0161     int max_packet_size_out;
0162 
0163     /* PCM playback volume (left and right) */
0164     int volume_playback[2];
0165 
0166     /* PCM monitor volume */
0167     int volume_monitor;
0168 
0169     /* Volume of impulse response test signal (if zero, test is disabled) */
0170     int impulse_volume;
0171 
0172     /* Period of impulse response test signal */
0173     int impulse_period;
0174 
0175     /* Counter for impulse response test signal */
0176     int impulse_count;
0177 
0178     /* Several status bits (see LINE6_FLAG_*) */
0179     unsigned long flags;
0180 };
0181 
0182 extern int line6_init_pcm(struct usb_line6 *line6,
0183               struct line6_pcm_properties *properties);
0184 extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
0185 extern int snd_line6_prepare(struct snd_pcm_substream *substream);
0186 extern int snd_line6_hw_params(struct snd_pcm_substream *substream,
0187                    struct snd_pcm_hw_params *hw_params);
0188 extern int snd_line6_hw_free(struct snd_pcm_substream *substream);
0189 extern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream);
0190 extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
0191 extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type,
0192                    bool start);
0193 extern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type);
0194 
0195 #endif