Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.git] / drivers / staging / line6 / pcm.h
1 /*
2  * Line6 Linux USB driver - 0.9.1beta
3  *
4  * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
5  *
6  *      This program is free software; you can redistribute it and/or
7  *      modify it under the terms of the GNU General Public License as
8  *      published by the Free Software Foundation, version 2.
9  *
10  */
11
12 /*
13         PCM interface to POD series devices.
14 */
15
16 #ifndef PCM_H
17 #define PCM_H
18
19 #include <sound/pcm.h>
20
21 #include "driver.h"
22 #include "usbdefs.h"
23
24 /* number of URBs */
25 #define LINE6_ISO_BUFFERS       2
26
27 /*
28         number of USB frames per URB
29         The Line6 Windows driver always transmits two frames per packet, but
30         the Linux driver performs significantly better (i.e., lower latency)
31         with only one frame per packet.
32 */
33 #define LINE6_ISO_PACKETS       1
34
35 /* in a "full speed" device (such as the PODxt Pro) this means 1ms */
36 #define LINE6_ISO_INTERVAL      1
37
38 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
39 #define LINE6_IMPULSE_DEFAULT_PERIOD 100
40 #endif
41
42 #define LINE6_BACKUP_MONITOR_SIGNAL 0
43 #define LINE6_REUSE_DMA_AREA_FOR_PLAYBACK 0
44
45 /*
46         Get substream from Line6 PCM data structure
47 */
48 #define get_substream(line6pcm, stream) \
49                 (line6pcm->pcm->streams[stream].substream)
50
51 /*
52         PCM mode bits and masks.
53         "ALSA": operations triggered by applications via ALSA
54         "MONITOR": software monitoring
55         "IMPULSE": optional impulse response operation
56 */
57 enum {
58         /* individual bits: */
59         BIT_PCM_ALSA_PLAYBACK,
60         BIT_PCM_ALSA_CAPTURE,
61         BIT_PCM_MONITOR_PLAYBACK,
62         BIT_PCM_MONITOR_CAPTURE,
63 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
64         BIT_PCM_IMPULSE_PLAYBACK,
65         BIT_PCM_IMPULSE_CAPTURE,
66 #endif
67         BIT_PAUSE_PLAYBACK,
68         BIT_PREPARED,
69
70         /* individual masks: */
71 /* *INDENT-OFF* */
72         MASK_PCM_ALSA_PLAYBACK    = 1 << BIT_PCM_ALSA_PLAYBACK,
73         MASK_PCM_ALSA_CAPTURE     = 1 << BIT_PCM_ALSA_CAPTURE,
74         MASK_PCM_MONITOR_PLAYBACK = 1 << BIT_PCM_MONITOR_PLAYBACK,
75         MASK_PCM_MONITOR_CAPTURE  = 1 << BIT_PCM_MONITOR_CAPTURE,
76 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
77         MASK_PCM_IMPULSE_PLAYBACK = 1 << BIT_PCM_IMPULSE_PLAYBACK,
78         MASK_PCM_IMPULSE_CAPTURE  = 1 << BIT_PCM_IMPULSE_CAPTURE,
79 #endif
80         MASK_PAUSE_PLAYBACK       = 1 << BIT_PAUSE_PLAYBACK,
81         MASK_PREPARED             = 1 << BIT_PREPARED,
82 /* *INDENT-ON* */
83
84         /* combined masks (by operation): */
85         MASK_PCM_ALSA = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_ALSA_CAPTURE,
86         MASK_PCM_MONITOR = MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_MONITOR_CAPTURE,
87 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
88         MASK_PCM_IMPULSE = MASK_PCM_IMPULSE_PLAYBACK | MASK_PCM_IMPULSE_CAPTURE,
89 #endif
90
91         /* combined masks (by direction): */
92 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
93         MASK_PLAYBACK =
94             MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK |
95             MASK_PCM_IMPULSE_PLAYBACK,
96         MASK_CAPTURE =
97             MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE |
98             MASK_PCM_IMPULSE_CAPTURE
99 #else
100         MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK,
101         MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE
102 #endif
103 };
104
105 struct line6_pcm_properties {
106         struct snd_pcm_hardware snd_line6_playback_hw, snd_line6_capture_hw;
107         struct snd_pcm_hw_constraint_ratdens snd_line6_rates;
108         int bytes_per_frame;
109 };
110
111 struct snd_line6_pcm {
112         /**
113                  Pointer back to the Line6 driver data structure.
114         */
115         struct usb_line6 *line6;
116
117         /**
118                  Properties.
119         */
120         struct line6_pcm_properties *properties;
121
122         /**
123                  ALSA pcm stream
124         */
125         struct snd_pcm *pcm;
126
127         /**
128                  URBs for audio playback.
129         */
130         struct urb *urb_audio_out[LINE6_ISO_BUFFERS];
131
132         /**
133                  URBs for audio capture.
134         */
135         struct urb *urb_audio_in[LINE6_ISO_BUFFERS];
136
137         /**
138                  Temporary buffer for playback.
139                  Since the packet size is not known in advance, this buffer is
140                  large enough to store maximum size packets.
141         */
142         unsigned char *buffer_out;
143
144         /**
145                  Temporary buffer for capture.
146                  Since the packet size is not known in advance, this buffer is
147                  large enough to store maximum size packets.
148         */
149         unsigned char *buffer_in;
150
151         /**
152                  Temporary buffer index for playback.
153         */
154         int index_out;
155
156         /**
157                  Previously captured frame (for software monitoring).
158         */
159         unsigned char *prev_fbuf;
160
161         /**
162                  Size of previously captured frame (for software monitoring).
163         */
164         int prev_fsize;
165
166         /**
167                  Free frame position in the playback buffer.
168         */
169         snd_pcm_uframes_t pos_out;
170
171         /**
172                  Count processed bytes for playback.
173                  This is modulo period size (to determine when a period is
174                  finished).
175         */
176         unsigned bytes_out;
177
178         /**
179                  Counter to create desired playback sample rate.
180         */
181         unsigned count_out;
182
183         /**
184                  Playback period size in bytes
185         */
186         unsigned period_out;
187
188         /**
189                  Processed frame position in the playback buffer.
190                  The contents of the output ring buffer have been consumed by
191                  the USB subsystem (i.e., sent to the USB device) up to this
192                  position.
193         */
194         snd_pcm_uframes_t pos_out_done;
195
196         /**
197                  Count processed bytes for capture.
198                  This is modulo period size (to determine when a period is
199                  finished).
200         */
201         unsigned bytes_in;
202
203         /**
204                  Counter to create desired capture sample rate.
205         */
206         unsigned count_in;
207
208         /**
209                  Capture period size in bytes
210         */
211         unsigned period_in;
212
213         /**
214                  Processed frame position in the capture buffer.
215                  The contents of the output ring buffer have been consumed by
216                  the USB subsystem (i.e., sent to the USB device) up to this
217                  position.
218         */
219         snd_pcm_uframes_t pos_in_done;
220
221         /**
222                  Bit mask of active playback URBs.
223         */
224         unsigned long active_urb_out;
225
226         /**
227                  Maximum size of USB packet.
228         */
229         int max_packet_size;
230
231         /**
232                  USB endpoint for listening to audio data.
233         */
234         int ep_audio_read;
235
236         /**
237                  USB endpoint for writing audio data.
238         */
239         int ep_audio_write;
240
241         /**
242                  Bit mask of active capture URBs.
243         */
244         unsigned long active_urb_in;
245
246         /**
247                  Bit mask of playback URBs currently being unlinked.
248         */
249         unsigned long unlink_urb_out;
250
251         /**
252                  Bit mask of capture URBs currently being unlinked.
253         */
254         unsigned long unlink_urb_in;
255
256         /**
257                  Spin lock to protect updates of the playback buffer positions (not
258                  contents!)
259         */
260         spinlock_t lock_audio_out;
261
262         /**
263                  Spin lock to protect updates of the capture buffer positions (not
264                  contents!)
265         */
266         spinlock_t lock_audio_in;
267
268         /**
269                  Spin lock to protect trigger.
270         */
271         spinlock_t lock_trigger;
272
273         /**
274                  PCM playback volume (left and right).
275         */
276         int volume_playback[2];
277
278         /**
279                  PCM monitor volume.
280         */
281         int volume_monitor;
282
283 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
284         /**
285                  Volume of impulse response test signal (if zero, test is disabled).
286         */
287         int impulse_volume;
288
289         /**
290                  Period of impulse response test signal.
291         */
292         int impulse_period;
293
294         /**
295                  Counter for impulse response test signal.
296         */
297         int impulse_count;
298 #endif
299
300         /**
301                  Several status bits (see BIT_*).
302         */
303         unsigned long flags;
304
305         int last_frame_in, last_frame_out;
306 };
307
308 extern int line6_init_pcm(struct usb_line6 *line6,
309                           struct line6_pcm_properties *properties);
310 extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
311 extern int snd_line6_prepare(struct snd_pcm_substream *substream);
312 extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
313 extern int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels);
314 extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels);
315
316 #define PRINT_FRAME_DIFF(op) {                                          \
317         static int diff_prev = 1000;                                    \
318         int diff = line6pcm->last_frame_out - line6pcm->last_frame_in;  \
319         if ((diff != diff_prev) && (abs(diff) < 100)) {                 \
320                 printk(KERN_INFO "%s frame diff = %d\n", op, diff);     \
321                 diff_prev = diff;                                       \
322         }                                                               \
323 }
324
325 #endif