This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / sound / usb / usx2y / usbusx2yaudio.c
1 /*
2  *   US-428 AUDIO
3
4  *   Copyright (c) 2002-2003 by Karsten Wiese
5  
6  *   based on
7
8  *   (Tentative) USB Audio Driver for ALSA
9  *
10  *   Main and PCM part
11  *
12  *   Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
13  *
14  *   Many codes borrowed from audio.c by 
15  *          Alan Cox (alan@lxorguk.ukuu.org.uk)
16  *          Thomas Sailer (sailer@ife.ee.ethz.ch)
17  *
18  *
19  *   This program is free software; you can redistribute it and/or modify
20  *   it under the terms of the GNU General Public License as published by
21  *   the Free Software Foundation; either version 2 of the License, or
22  *   (at your option) any later version.
23  *
24  *   This program is distributed in the hope that it will be useful,
25  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
26  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  *   GNU General Public License for more details.
28  *
29  *   You should have received a copy of the GNU General Public License
30  *   along with this program; if not, write to the Free Software
31  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
32  */
33
34
35 #include <sound/driver.h>
36 #include <linux/interrupt.h>
37 #include <linux/usb.h>
38 #include <sound/core.h>
39 #include <sound/info.h>
40 #include <sound/pcm.h>
41 #include <sound/pcm_params.h>
42 #include "usx2y.h"
43 #include "usbusx2y.h"
44
45
46 struct snd_usX2Y_substream {
47         usX2Ydev_t      *usX2Y;
48         snd_pcm_substream_t *pcm_substream;
49
50         unsigned char           endpoint;               
51         unsigned int            datapipe;               /* the data i/o pipe */
52         unsigned int            maxpacksize;            /* max packet size in bytes */
53
54         char                    prepared,
55                                 running,
56                                 stalled;
57
58         int                     hwptr;                  /* free frame position in the buffer (only for playback) */
59         int                     hwptr_done;             /* processed frame position in the buffer */
60         int                     transfer_done;          /* processed frames since last period update */
61
62         struct urb              *urb[NRURBS];   /* data urb table */
63         int                     next_urb_complete;
64         struct urb              *completed_urb;
65         char                    *tmpbuf;                        /* temporary buffer for playback */
66         volatile int            submitted_urbs;
67         wait_queue_head_t       wait_queue;
68 };
69
70
71
72
73
74
75 static int usX2Y_urb_capt_retire(snd_usX2Y_substream_t *subs)
76 {
77         struct urb      *urb = subs->completed_urb;
78         snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
79         unsigned char   *cp;
80         int             i, len, lens = 0, hwptr_done = subs->hwptr_done;
81         usX2Ydev_t      *usX2Y = subs->usX2Y;
82
83         for (i = 0; i < NRPACKS; i++) {
84                 cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
85                 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
86                         snd_printdd("activ frame status %i\n", urb->iso_frame_desc[i].status);
87                         return urb->iso_frame_desc[i].status;
88                 }
89                 len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
90                 if (! len) {
91                         snd_printk("0 == len ERROR!\n");
92                         continue;
93                 }
94
95                 /* copy a data chunk */
96                 if ((hwptr_done + len) > runtime->buffer_size) {
97                         int cnt = runtime->buffer_size - hwptr_done;
98                         int blen = cnt * usX2Y->stride;
99                         memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, blen);
100                         memcpy(runtime->dma_area, cp + blen, len * usX2Y->stride - blen);
101                 } else {
102                         memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, len * usX2Y->stride);
103                 }
104                 lens += len;
105                 if ((hwptr_done += len) >= runtime->buffer_size)
106                         hwptr_done -= runtime->buffer_size;
107         }
108
109         subs->hwptr_done = hwptr_done;
110         subs->transfer_done += lens;
111         /* update the pointer, call callback if necessary */
112         if (subs->transfer_done >= runtime->period_size) {
113                 subs->transfer_done -= runtime->period_size;
114                 snd_pcm_period_elapsed(subs->pcm_substream);
115         }
116         return 0;
117 }
118 /*
119  * prepare urb for playback data pipe
120  *
121  * we copy the data directly from the pcm buffer.
122  * the current position to be copied is held in hwptr field.
123  * since a urb can handle only a single linear buffer, if the total
124  * transferred area overflows the buffer boundary, we cannot send
125  * it directly from the buffer.  thus the data is once copied to
126  * a temporary buffer and urb points to that.
127  */
128 static int usX2Y_urb_play_prepare(snd_usX2Y_substream_t *subs,
129                                   struct urb *cap_urb,
130                                   struct urb *urb)
131 {
132         int count, counts, pack;
133         usX2Ydev_t* usX2Y = subs->usX2Y;
134         snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
135
136         count = 0;
137         for (pack = 0; pack < NRPACKS; pack++) {
138                 /* calculate the size of a packet */
139                 counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
140                 count += counts;
141                 if (counts < 43 || counts > 50) {
142                         snd_printk("should not be here with counts=%i\n", counts);
143                         return -EPIPE;
144                 }
145
146                 /* set up descriptor */
147                 urb->iso_frame_desc[pack].offset = pack ? urb->iso_frame_desc[pack - 1].offset + urb->iso_frame_desc[pack - 1].length : 0;
148                 urb->iso_frame_desc[pack].length = counts * usX2Y->stride;
149         }
150         if (subs->hwptr + count > runtime->buffer_size) {
151                 /* err, the transferred area goes over buffer boundary.
152                  * copy the data to the temp buffer.
153                  */
154                 int len;
155                 len = runtime->buffer_size - subs->hwptr;
156                 urb->transfer_buffer = subs->tmpbuf;
157                 memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * usX2Y->stride, len * usX2Y->stride);
158                 memcpy(subs->tmpbuf + len * usX2Y->stride, runtime->dma_area, (count - len) * usX2Y->stride);
159                 subs->hwptr += count;
160                 subs->hwptr -= runtime->buffer_size;
161         } else {
162                 /* set the buffer pointer */
163                 urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
164                 if ((subs->hwptr += count) >= runtime->buffer_size)
165                         subs->hwptr -= runtime->buffer_size;                    
166         }
167         urb->transfer_buffer_length = count * usX2Y->stride;
168         return 0;
169 }
170
171 /*
172  * process after playback data complete
173  *
174  * update the current position and call callback if a period is processed.
175  */
176 inline static int usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb *urb)
177 {
178         snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
179         int             len = (urb->iso_frame_desc[0].actual_length
180 #if NRPACKS > 1
181                                + urb->iso_frame_desc[1].actual_length
182 #endif
183                                ) / subs->usX2Y->stride;
184
185         subs->transfer_done += len;
186         subs->hwptr_done +=  len;
187         if (subs->hwptr_done >= runtime->buffer_size)
188                 subs->hwptr_done -= runtime->buffer_size;
189         if (subs->transfer_done >= runtime->period_size) {
190                 subs->transfer_done -= runtime->period_size;
191                 snd_pcm_period_elapsed(subs->pcm_substream);
192         }
193         return 0;
194 }
195
196 inline static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int frame)
197 {
198         int err;
199         if (!urb)
200                 return -ENODEV;
201         urb->start_frame = (frame + NRURBS*NRPACKS) & (1024 - 1);
202         urb->hcpriv = NULL;
203         urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */
204         if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
205                 snd_printk("%i\n", err);
206                 return err;
207         } else {
208                 subs->submitted_urbs++;
209                 if (subs->next_urb_complete < 0) 
210                         subs->next_urb_complete = 0;
211         }
212         return 0;
213 }
214
215
216 static inline int frame_distance(int from, int to)
217 {
218         int distance = to - from;
219         if (distance < -512)
220                 distance += 1024;
221         else
222                 if (distance > 511)
223                         distance -= 1024;
224         return distance;
225 }
226
227
228 static void usX2Y_subs_set_next_urb_complete(snd_usX2Y_substream_t *subs)
229 {
230         int next_urb_complete = subs->next_urb_complete + 1;
231         int distance;
232         if (next_urb_complete >= NRURBS)
233                 next_urb_complete = 0;
234         distance = frame_distance(subs->completed_urb->start_frame,
235                                   subs->urb[next_urb_complete]->start_frame);
236         if (1 == distance) {
237                 subs->next_urb_complete = next_urb_complete;
238         } else {
239                 snd_printdd("distance %i not set_nuc %i %i %i \n", distance, subs->endpoint, next_urb_complete, subs->urb[next_urb_complete]->status);
240                 subs->next_urb_complete = -1;
241         }
242 }
243
244
245 static inline void usX2Y_usbframe_complete(snd_usX2Y_substream_t *capsubs, snd_usX2Y_substream_t *playbacksubs, int frame)
246 {
247         {
248                 struct urb *urb;
249                 if ((urb = playbacksubs->completed_urb)) {
250                         if (playbacksubs->prepared)
251                                 usX2Y_urb_play_retire(playbacksubs, urb);
252                         usX2Y_subs_set_next_urb_complete(playbacksubs);
253                 }
254                 if (playbacksubs->running) {
255                         if (NULL == urb)
256                                 urb = playbacksubs->urb[playbacksubs->next_urb_complete + 1];
257                         if (urb && 0 == usX2Y_urb_play_prepare(playbacksubs,
258                                                                capsubs->completed_urb,
259                                                                urb)) {
260                                 if (usX2Y_urb_submit(playbacksubs, urb, frame) < 0)
261                                         return;
262                         } else
263                                 snd_pcm_stop(playbacksubs->pcm_substream, SNDRV_PCM_STATE_XRUN);
264                 }
265                 playbacksubs->completed_urb = NULL;
266         }
267         if (capsubs->running)
268                 usX2Y_urb_capt_retire(capsubs);
269         usX2Y_subs_set_next_urb_complete(capsubs);
270         if (capsubs->prepared)
271                 usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame);
272         capsubs->completed_urb = NULL;
273 }
274
275
276 static void usX2Y_clients_stop(snd_usX2Y_substream_t *subs)
277 {
278         usX2Ydev_t *usX2Y = subs->usX2Y;
279         int i;
280         for (i = 0; i < 4; i++) {
281                 snd_usX2Y_substream_t *substream = usX2Y->substream[i];
282                 if (substream && substream->running)
283                         snd_pcm_stop(substream->pcm_substream, SNDRV_PCM_STATE_XRUN);
284         }
285 }
286
287
288 static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs)
289 {
290         snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
291
292         subs->submitted_urbs--;
293         if (urb->status) {
294                 snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
295                 subs->stalled = 1;
296                 usX2Y_clients_stop(subs);
297                 urb->status = 0;
298                 return;
299         }
300         if (urb == subs->urb[subs->next_urb_complete]) {
301                 subs->completed_urb = urb;
302         } else {
303                 snd_printk("Sequence Error!(ep=%i;nuc=%i,frame=%i)\n",
304                            subs->endpoint, subs->next_urb_complete, urb->start_frame);
305                 subs->stalled = 1;
306                 usX2Y_clients_stop(subs);
307                 return;
308         }
309         if (waitqueue_active(&subs->wait_queue))
310                 wake_up(&subs->wait_queue);
311         {
312                 snd_usX2Y_substream_t *capsubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE],
313                         *playbacksubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
314                 if (capsubs->completed_urb &&
315                     (playbacksubs->completed_urb ||
316                      !playbacksubs->prepared ||
317                      (playbacksubs->prepared && (playbacksubs->next_urb_complete < 0 || // not started yet
318                                                  frame_distance(capsubs->completed_urb->start_frame,
319                                                                 playbacksubs->urb[playbacksubs->next_urb_complete]->start_frame)
320                                                  > 0 ||                                 // other expected later
321                                                  playbacksubs->stalled))))
322                         usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame);
323         }
324 }
325
326
327 static int usX2Y_urbs_capt_start(snd_usX2Y_substream_t *subs)
328 {
329         int i, err;
330
331         for (i = 0; i < NRURBS; i++) {
332                 unsigned long pack;
333                 struct urb *urb = subs->urb[i];
334                 urb->dev = subs->usX2Y->chip.dev;
335                 urb->transfer_flags = URB_ISO_ASAP;
336                 for (pack = 0; pack < NRPACKS; pack++) {
337                         urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
338                         urb->iso_frame_desc[pack].length = subs->maxpacksize;
339                 }
340                 urb->transfer_buffer_length = subs->maxpacksize * NRPACKS; 
341                 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
342                         snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
343                         return -EPIPE;
344                 } else {
345                         subs->submitted_urbs++;
346                 }
347                 urb->transfer_flags = 0;
348         }
349         subs->stalled = 0;
350         subs->next_urb_complete = 0;
351         subs->prepared = 1;
352         return 0;
353 }
354
355 /* 
356  *  wait until all urbs are processed.
357  */
358 static int usX2Y_urbs_wait_clear(snd_usX2Y_substream_t *subs)
359 {
360         int timeout = HZ;
361
362         do {
363                 if (0 == subs->submitted_urbs)
364                         break;
365                 set_current_state(TASK_UNINTERRUPTIBLE);
366                 snd_printdd("snd_usX2Y_urbs_wait_clear waiting\n");
367                 schedule_timeout(1);
368         } while (--timeout > 0);
369         if (subs->submitted_urbs)
370                 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", subs->submitted_urbs);
371         return 0;
372 }
373 /*
374  * return the current pcm pointer.  just return the hwptr_done value.
375  */
376 static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(snd_pcm_substream_t *substream)
377 {
378         snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
379         return subs->hwptr_done;
380 }
381 /*
382  * start/stop substream
383  */
384 static int snd_usX2Y_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
385 {
386         snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
387
388         switch (cmd) {
389         case SNDRV_PCM_TRIGGER_START:
390                 snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
391                 if (subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE]->stalled)
392                         return -EPIPE;
393                 else
394                         subs->running = 1;
395                 break;
396         case SNDRV_PCM_TRIGGER_STOP:
397                 snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
398                 subs->running = 0;
399                 break;
400         default:
401                 return -EINVAL;
402         }
403         return 0;
404 }
405
406
407
408 static void usX2Y_urb_release(struct urb** urb, int free_tb)
409 {
410         if (*urb) {
411                 if (free_tb)
412                         kfree((*urb)->transfer_buffer);
413                 usb_free_urb(*urb);
414                 *urb = NULL;
415         }
416 }
417 /*
418  * release a substream
419  */
420 static void usX2Y_urbs_release(snd_usX2Y_substream_t *subs)
421 {
422         int i;
423         snd_printdd("snd_usX2Y_urbs_release() %i\n", subs->endpoint);
424         usX2Y_urbs_wait_clear(subs);
425         for (i = 0; i < NRURBS; i++)
426                 usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK]);
427
428         if (subs->tmpbuf) {
429                 kfree(subs->tmpbuf);
430                 subs->tmpbuf = NULL;
431         }
432 }
433
434 static void usX2Y_substream_prepare(snd_usX2Y_substream_t *subs)
435 {
436         snd_printdd("usX2Y_substream_prepare() ep=%i urb0=%p urb1=%p\n", subs->endpoint, subs->urb[0], subs->urb[1]);
437         /* reset the pointer */
438         subs->hwptr = 0;
439         subs->hwptr_done = 0;
440         subs->transfer_done = 0;
441 }
442
443
444 /*
445  * initialize a substream's urbs
446  */
447 static int usX2Y_urbs_allocate(snd_usX2Y_substream_t *subs)
448 {
449         int i;
450         int is_playback = subs == subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
451         struct usb_device *dev = subs->usX2Y->chip.dev;
452
453         snd_assert(!subs->prepared, return 0);
454
455         if (is_playback) {      /* allocate a temporary buffer for playback */
456                 subs->datapipe = usb_sndisocpipe(dev, subs->endpoint);
457                 subs->maxpacksize = dev->epmaxpacketout[subs->endpoint];
458                 if (NULL == subs->tmpbuf) {
459                         subs->tmpbuf = kcalloc(NRPACKS, subs->maxpacksize, GFP_KERNEL);
460                         if (NULL == subs->tmpbuf) {
461                                 snd_printk(KERN_ERR "cannot malloc tmpbuf\n");
462                                 return -ENOMEM;
463                         }
464                 }
465         } else {
466                 subs->datapipe = usb_rcvisocpipe(dev, subs->endpoint);
467                 subs->maxpacksize = dev->epmaxpacketin[subs->endpoint];
468         }
469
470         /* allocate and initialize data urbs */
471         for (i = 0; i < NRURBS; i++) {
472                 struct urb** purb = subs->urb + i;
473                 if (*purb)
474                         continue;
475                 *purb = usb_alloc_urb(NRPACKS, GFP_KERNEL);
476                 if (NULL == *purb) {
477                         usX2Y_urbs_release(subs);
478                         return -ENOMEM;
479                 }
480                 if (!is_playback && !(*purb)->transfer_buffer) {
481                         /* allocate a capture buffer per urb */
482                         (*purb)->transfer_buffer = kmalloc(subs->maxpacksize*NRPACKS, GFP_KERNEL);
483                         if (NULL == (*purb)->transfer_buffer) {
484                                 usX2Y_urbs_release(subs);
485                                 return -ENOMEM;
486                         }
487                 }
488                 (*purb)->dev = dev;
489                 (*purb)->pipe = subs->datapipe;
490                 (*purb)->number_of_packets = NRPACKS;
491                 (*purb)->context = subs;
492                 (*purb)->interval = 1;
493                 (*purb)->complete = snd_usb_complete_callback(i_usX2Y_urb_complete);
494         }
495         return 0;
496 }
497
498 static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs)
499 {
500         usX2Ydev_t*     usX2Y = urb->context;
501         
502         if (urb->status) {
503                 snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status);
504                 return;
505         }
506         if (0 == --usX2Y->US04->len)
507                 wake_up(&usX2Y->In04WaitQueue);
508 }
509 /*
510  * allocate a buffer, setup samplerate
511  *
512  * so far we use a physically linear buffer although packetize transfer
513  * doesn't need a continuous area.
514  * if sg buffer is supported on the later version of alsa, we'll follow
515  * that.
516  */
517 static struct s_c2
518 {
519         char c1, c2;
520 }
521         SetRate44100[] =
522 {
523         { 0x14, 0x08},  // this line sets 44100, well actually a little less
524         { 0x18, 0x40},  // only tascam / frontier design knows the further lines .......
525         { 0x18, 0x42},
526         { 0x18, 0x45},
527         { 0x18, 0x46},
528         { 0x18, 0x48},
529         { 0x18, 0x4A},
530         { 0x18, 0x4C},
531         { 0x18, 0x4E},
532         { 0x18, 0x50},
533         { 0x18, 0x52},
534         { 0x18, 0x54},
535         { 0x18, 0x56},
536         { 0x18, 0x58},
537         { 0x18, 0x5A},
538         { 0x18, 0x5C},
539         { 0x18, 0x5E},
540         { 0x18, 0x60},
541         { 0x18, 0x62},
542         { 0x18, 0x64},
543         { 0x18, 0x66},
544         { 0x18, 0x68},
545         { 0x18, 0x6A},
546         { 0x18, 0x6C},
547         { 0x18, 0x6E},
548         { 0x18, 0x70},
549         { 0x18, 0x72},
550         { 0x18, 0x74},
551         { 0x18, 0x76},
552         { 0x18, 0x78},
553         { 0x18, 0x7A},
554         { 0x18, 0x7C},
555         { 0x18, 0x7E}
556 };
557 static struct s_c2 SetRate48000[] =
558 {
559         { 0x14, 0x09},  // this line sets 48000, well actually a little less
560         { 0x18, 0x40},  // only tascam / frontier design knows the further lines .......
561         { 0x18, 0x42},
562         { 0x18, 0x45},
563         { 0x18, 0x46},
564         { 0x18, 0x48},
565         { 0x18, 0x4A},
566         { 0x18, 0x4C},
567         { 0x18, 0x4E},
568         { 0x18, 0x50},
569         { 0x18, 0x52},
570         { 0x18, 0x54},
571         { 0x18, 0x56},
572         { 0x18, 0x58},
573         { 0x18, 0x5A},
574         { 0x18, 0x5C},
575         { 0x18, 0x5E},
576         { 0x18, 0x60},
577         { 0x18, 0x62},
578         { 0x18, 0x64},
579         { 0x18, 0x66},
580         { 0x18, 0x68},
581         { 0x18, 0x6A},
582         { 0x18, 0x6C},
583         { 0x18, 0x6E},
584         { 0x18, 0x70},
585         { 0x18, 0x73},
586         { 0x18, 0x74},
587         { 0x18, 0x76},
588         { 0x18, 0x78},
589         { 0x18, 0x7A},
590         { 0x18, 0x7C},
591         { 0x18, 0x7E}
592 };
593 #define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
594
595 static int usX2Y_rate_set(usX2Ydev_t *usX2Y, int rate)
596 {
597         int                     err = 0, i;
598         snd_usX2Y_urbSeq_t      *us = NULL;
599         int                     *usbdata = NULL;
600         DECLARE_WAITQUEUE(wait, current);
601         struct s_c2             *ra = rate == 48000 ? SetRate48000 : SetRate44100;
602
603         if (usX2Y->rate != rate) {
604                 do {
605                         us = kmalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
606                         if (NULL == us) {
607                                 err = -ENOMEM;
608                                 break;
609                         }
610                         memset(us, 0, sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS); 
611                         usbdata = kmalloc(sizeof(int)*NOOF_SETRATE_URBS, GFP_KERNEL);
612                         if (NULL == usbdata) {
613                                 err = -ENOMEM;
614                                 break;
615                         }
616                         for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
617                                 if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
618                                         err = -ENOMEM;
619                                         break;
620                                 }
621                                 ((char*)(usbdata + i))[0] = ra[i].c1;
622                                 ((char*)(usbdata + i))[1] = ra[i].c2;
623                                 usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4),
624                                                   usbdata + i, 2, i_usX2Y_04Int, usX2Y);
625 #ifdef OLD_USB
626                                 us->urb[i]->transfer_flags = USB_QUEUE_BULK;
627 #endif
628                         }
629                         if (err)
630                                 break;
631
632                         add_wait_queue(&usX2Y->In04WaitQueue, &wait);
633                         set_current_state(TASK_INTERRUPTIBLE);
634                         us->submitted = 0;
635                         us->len =       NOOF_SETRATE_URBS;
636                         usX2Y->US04 =   us;
637                 
638                         do {
639                                 signed long     timeout = schedule_timeout(HZ/2);
640                         
641                                 if (signal_pending(current)) {
642                                         err = -ERESTARTSYS;
643                                         break;
644                                 }
645                                 if (0 == timeout) {
646                                         err = -ENODEV;
647                                         break;
648                                 }
649                                 usX2Y->rate = rate;
650                                 usX2Y->refframes = rate == 48000 ? 47 : 44;
651                         } while (0);
652                 
653                         remove_wait_queue(&usX2Y->In04WaitQueue, &wait);
654                 } while (0);
655
656                 if (us) {
657                         us->submitted = 2*NOOF_SETRATE_URBS;
658                         for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
659                                 usb_unlink_urb(us->urb[i]);
660                                 usb_free_urb(us->urb[i]);
661                         }
662                         usX2Y->US04 = NULL;
663                         kfree(usbdata);
664                         kfree(us);
665                 }
666         }
667
668         return err;
669 }
670
671
672 static int usX2Y_format_set(usX2Ydev_t *usX2Y, snd_pcm_format_t format)
673 {
674         int alternate, unlink_err, err;
675         struct list_head* p;
676         if (format == SNDRV_PCM_FORMAT_S24_3LE) {
677                 alternate = 2;
678                 usX2Y->stride = 6;
679         } else {
680                 alternate = 1;
681                 usX2Y->stride = 4;
682         }
683         list_for_each(p, &usX2Y->chip.midi_list) {
684                 snd_usbmidi_input_stop(p);
685         }
686         unlink_err = usb_unlink_urb(usX2Y->In04urb);
687         if ((err = usb_set_interface(usX2Y->chip.dev, 0, alternate))) {
688                 snd_printk("usb_set_interface error \n");
689                 return err;
690         }
691         if (0 == unlink_err) {
692                 usX2Y->In04urb->dev = usX2Y->chip.dev;
693                 err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
694         }
695         list_for_each(p, &usX2Y->chip.midi_list) {
696                 snd_usbmidi_input_start(p);
697         }
698         usX2Y->format = format;
699         usX2Y->rate = 0;
700         return err;
701 }
702
703
704 static int snd_usX2Y_pcm_hw_params(snd_pcm_substream_t *substream,
705                                    snd_pcm_hw_params_t *hw_params)
706 {
707         int                     err = 0;
708         unsigned int            rate = params_rate(hw_params);
709         snd_pcm_format_t        format = params_format(hw_params);
710         snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
711
712         {       // all pcm substreams off one usX2Y have to operate at the same rate & format
713                 snd_card_t *card = substream->pstr->pcm->card;
714                 struct list_head *list;
715                 list_for_each(list, &card->devices) {
716                         snd_device_t *dev;
717                         snd_pcm_t *pcm;
718                         int s;
719                         dev = snd_device(list);
720                         if (dev->type != SNDRV_DEV_PCM)
721                                 continue;
722                         pcm = dev->device_data;
723                         for (s = 0; s < 2; ++s) {
724                                 snd_pcm_substream_t *test_substream;
725                                 test_substream = pcm->streams[s].substream;
726                                 if (test_substream && test_substream != substream  &&
727                                     test_substream->runtime &&
728                                     ((test_substream->runtime->format &&
729                                       test_substream->runtime->format != format) ||
730                                      (test_substream->runtime->rate &&
731                                       test_substream->runtime->rate != rate)))
732                                         return -EINVAL;
733                         }
734                 }
735         }
736         if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
737                 snd_printk("snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err);
738                 return err;
739         }
740         return 0;
741 }
742
743 /*
744  * free the buffer
745  */
746 static int snd_usX2Y_pcm_hw_free(snd_pcm_substream_t *substream)
747 {
748         snd_pcm_runtime_t *runtime = substream->runtime;
749         snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
750         snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
751
752         if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
753                 snd_usX2Y_substream_t *cap_subs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE];
754                 subs->prepared = 0;
755                 usX2Y_urbs_release(subs);
756                 if (!cap_subs->pcm_substream ||
757                     !cap_subs->pcm_substream->runtime ||
758                     !cap_subs->pcm_substream->runtime->status ||
759                     cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
760                         cap_subs->prepared = 0;
761                         usX2Y_urbs_release(cap_subs);
762                 }
763         } else {
764                 snd_usX2Y_substream_t *playback_subs = subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
765                 if (!playback_subs->prepared) {
766                         subs->prepared = 0;
767                         usX2Y_urbs_release(subs);
768                 }
769         }
770
771         return snd_pcm_lib_free_pages(substream);
772 }
773 /*
774  * prepare callback
775  *
776  * set format and initialize urbs
777  */
778 static int snd_usX2Y_pcm_prepare(snd_pcm_substream_t *substream)
779 {
780         snd_pcm_runtime_t *runtime = substream->runtime;
781         snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
782         snd_usX2Y_substream_t *capsubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE];
783         int err = 0;
784         snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
785
786 // Start hardware streams
787 // SyncStream first....
788         if (! capsubs->prepared) {
789                 if (subs->usX2Y->format != runtime->format)
790                         if ((err = usX2Y_format_set(subs->usX2Y, runtime->format)) < 0)
791                                 return err;
792                 if (subs->usX2Y->rate != runtime->rate)
793                         if ((err = usX2Y_rate_set(subs->usX2Y, runtime->rate)) < 0)
794                                 return err;
795                 snd_printdd("starting capture pipe for playpipe\n");
796                 usX2Y_urbs_allocate(capsubs);
797                 capsubs->completed_urb = NULL;
798                 {
799                         DECLARE_WAITQUEUE(wait, current);
800                         add_wait_queue(&capsubs->wait_queue, &wait);
801                         if (0 <= (err = usX2Y_urbs_capt_start(capsubs))) {
802                                 signed long timeout;
803                                 set_current_state(TASK_INTERRUPTIBLE);
804                                 timeout = schedule_timeout(HZ/4);
805                                 if (signal_pending(current))
806                                         err = -ERESTARTSYS;
807                                 else {
808                                         snd_printdd("%li\n", HZ/4 - timeout);
809                                         if (0 == timeout)
810                                                 err = -EPIPE;
811                                 }
812                         }
813                         remove_wait_queue(&capsubs->wait_queue, &wait);
814                         if (0 > err)
815                                 return err;
816                 }
817         }
818
819         if (subs != capsubs) {
820                 int u;
821                 if (!subs->prepared) {
822                         if ((err = usX2Y_urbs_allocate(subs)) < 0)
823                                 return err;
824                         subs->prepared = 1;
825                 }
826                 while (subs->submitted_urbs)
827                 for (u = 0; u < NRURBS; u++) {
828                         snd_printdd("%i\n", subs->urb[u]->status);
829                         while(subs->urb[u]->status  ||  NULL != subs->urb[u]->hcpriv) {
830                                 signed long timeout;
831                                 snd_printdd("ep=%i waiting for urb=%p status=%i hcpriv=%p\n",
832                                            subs->endpoint, subs->urb[u],
833                                            subs->urb[u]->status, subs->urb[u]->hcpriv);
834                                 set_current_state(TASK_INTERRUPTIBLE);
835                                 timeout = schedule_timeout(HZ/10);
836                                 if (signal_pending(current)) {
837                                         return -ERESTARTSYS;
838                                 }
839                         }
840                 }
841                 subs->completed_urb = NULL;
842                 subs->next_urb_complete = -1;
843                 subs->stalled = 0;
844         }
845
846         usX2Y_substream_prepare(subs);
847         return err;
848 }
849
850 static snd_pcm_hardware_t snd_usX2Y_2c =
851 {
852         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
853                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
854                                  SNDRV_PCM_INFO_MMAP_VALID),
855         .formats =                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
856         .rates =                   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
857         .rate_min =                44100,
858         .rate_max =                48000,
859         .channels_min =            2,
860         .channels_max =            2,
861         .buffer_bytes_max =     (2*128*1024),
862         .period_bytes_min =     64,
863         .period_bytes_max =     (128*1024),
864         .periods_min =          2,
865         .periods_max =          1024,
866         .fifo_size =              0
867 };
868
869
870
871 static int snd_usX2Y_pcm_open(snd_pcm_substream_t *substream)
872 {
873         snd_usX2Y_substream_t   *subs = ((snd_usX2Y_substream_t **)
874                                          snd_pcm_substream_chip(substream))[substream->stream];
875         snd_pcm_runtime_t       *runtime = substream->runtime;
876
877         runtime->hw = snd_usX2Y_2c;
878         runtime->private_data = subs;
879         subs->pcm_substream = substream;
880         snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
881         return 0;
882 }
883
884
885
886 static int snd_usX2Y_pcm_close(snd_pcm_substream_t *substream)
887 {
888         snd_pcm_runtime_t *runtime = substream->runtime;
889         snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
890         int err = 0;
891
892         subs->pcm_substream = NULL;
893
894         return err;
895 }
896
897
898 static snd_pcm_ops_t snd_usX2Y_pcm_ops = 
899 {
900         .open =         snd_usX2Y_pcm_open,
901         .close =        snd_usX2Y_pcm_close,
902         .ioctl =        snd_pcm_lib_ioctl,
903         .hw_params =    snd_usX2Y_pcm_hw_params,
904         .hw_free =      snd_usX2Y_pcm_hw_free,
905         .prepare =      snd_usX2Y_pcm_prepare,
906         .trigger =      snd_usX2Y_pcm_trigger,
907         .pointer =      snd_usX2Y_pcm_pointer,
908 };
909
910
911 /*
912  * free a usb stream instance
913  */
914 static void usX2Y_audio_stream_free(snd_usX2Y_substream_t **usX2Y_substream)
915 {
916         if (NULL != usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]) {
917                 kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]);
918                 usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL;
919         }
920         kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]);
921         usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL;
922 }
923
924 static void snd_usX2Y_pcm_private_free(snd_pcm_t *pcm)
925 {
926         snd_usX2Y_substream_t **usX2Y_stream = pcm->private_data;
927         if (usX2Y_stream) {
928                 snd_pcm_lib_preallocate_free_for_all(pcm);
929                 usX2Y_audio_stream_free(usX2Y_stream);
930         }
931 }
932
933 static int usX2Y_audio_stream_new(snd_card_t *card, int playback_endpoint, int capture_endpoint)
934 {
935         snd_pcm_t *pcm;
936         int err, i;
937         snd_usX2Y_substream_t **usX2Y_substream =
938                 usX2Y(card)->substream + 2 * usX2Y(card)->chip.pcm_devs;
939
940         for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
941              i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
942                 usX2Y_substream[i] = kcalloc(1, sizeof(snd_usX2Y_substream_t), GFP_KERNEL);
943                 if (NULL == usX2Y_substream[i]) {
944                         snd_printk(KERN_ERR "cannot malloc\n");
945                         return -ENOMEM;
946                 }
947                 init_waitqueue_head(&usX2Y_substream[i]->wait_queue);
948                 usX2Y_substream[i]->usX2Y = usX2Y(card);
949         }
950
951         if (playback_endpoint)
952                 usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
953         usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;
954
955         err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->chip.pcm_devs,
956                           playback_endpoint ? 1 : 0, 1,
957                           &pcm);
958         if (err < 0) {
959                 usX2Y_audio_stream_free(usX2Y_substream);
960                 return err;
961         }
962
963         if (playback_endpoint)
964                 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_pcm_ops);
965         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_pcm_ops);
966
967         pcm->private_data = usX2Y_substream;
968         pcm->private_free = snd_usX2Y_pcm_private_free;
969         pcm->info_flags = 0;
970
971         sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->chip.pcm_devs);
972
973         if ((playback_endpoint &&
974              0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
975                                                      SNDRV_DMA_TYPE_CONTINUOUS,
976                                                      snd_dma_continuous_data(GFP_KERNEL),
977                                                      64*1024, 128*1024))) ||
978             0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
979                                                      SNDRV_DMA_TYPE_CONTINUOUS,
980                                                      snd_dma_continuous_data(GFP_KERNEL),
981                                                      64*1024, 128*1024))) {
982                 snd_usX2Y_pcm_private_free(pcm);
983                 return err;
984         }
985         usX2Y(card)->chip.pcm_devs++;
986
987         return 0;
988 }
989
990 /*
991  * free the chip instance
992  *
993  * here we have to do not much, since pcm and controls are already freed
994  *
995  */
996 static int snd_usX2Y_device_dev_free(snd_device_t *device)
997 {
998         return 0;
999 }
1000
1001
1002 /*
1003  * create a chip instance and set its names.
1004  */
1005 int usX2Y_audio_create(snd_card_t* card)
1006 {
1007         int err = 0;
1008         static snd_device_ops_t ops = {
1009                 .dev_free = snd_usX2Y_device_dev_free,
1010         };
1011         
1012         INIT_LIST_HEAD(&usX2Y(card)->chip.pcm_list);
1013
1014         if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, usX2Y(card), &ops)) < 0) {
1015 //              snd_usX2Y_audio_free(usX2Y(card));
1016                 return err;
1017         }
1018
1019         if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
1020                 return err;
1021         if (usX2Y(card)->chip.dev->descriptor.idProduct == USB_ID_US428)
1022              if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
1023                      return err;
1024         if (usX2Y(card)->chip.dev->descriptor.idProduct != USB_ID_US122)
1025                 err = usX2Y_rate_set(usX2Y(card), 44100);       // Lets us428 recognize output-volume settings, disturbs us122.
1026         return err;
1027 }