Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *   US-X2Y AUDIO
0004  *   Copyright (c) 2002-2004 by Karsten Wiese
0005  *
0006  *   based on
0007  *
0008  *   (Tentative) USB Audio Driver for ALSA
0009  *
0010  *   Main and PCM part
0011  *
0012  *   Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
0013  *
0014  *   Many codes borrowed from audio.c by
0015  *      Alan Cox (alan@lxorguk.ukuu.org.uk)
0016  *      Thomas Sailer (sailer@ife.ee.ethz.ch)
0017  */
0018 
0019 
0020 #include <linux/interrupt.h>
0021 #include <linux/slab.h>
0022 #include <linux/usb.h>
0023 #include <linux/moduleparam.h>
0024 #include <sound/core.h>
0025 #include <sound/info.h>
0026 #include <sound/pcm.h>
0027 #include <sound/pcm_params.h>
0028 #include "usx2y.h"
0029 #include "usbusx2y.h"
0030 
0031 /* Default value used for nr of packs per urb.
0032  * 1 to 4 have been tested ok on uhci.
0033  * To use 3 on ohci, you'd need a patch:
0034  * look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
0035  * "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
0036  *
0037  * 1, 2 and 4 work out of the box on ohci, if I recall correctly.
0038  * Bigger is safer operation, smaller gives lower latencies.
0039  */
0040 #define USX2Y_NRPACKS 4
0041 
0042 /* If your system works ok with this module's parameter
0043  * nrpacks set to 1, you might as well comment
0044  * this define out, and thereby produce smaller, faster code.
0045  * You'd also set USX2Y_NRPACKS to 1 then.
0046  */
0047 #define USX2Y_NRPACKS_VARIABLE 1
0048 
0049 #ifdef USX2Y_NRPACKS_VARIABLE
0050 static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
0051 #define  nr_of_packs() nrpacks
0052 module_param(nrpacks, int, 0444);
0053 MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
0054 #else
0055 #define nr_of_packs() USX2Y_NRPACKS
0056 #endif
0057 
0058 static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs)
0059 {
0060     struct urb  *urb = subs->completed_urb;
0061     struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
0062     unsigned char   *cp;
0063     int     i, len, lens = 0, hwptr_done = subs->hwptr_done;
0064     int     cnt, blen;
0065     struct usx2ydev *usx2y = subs->usx2y;
0066 
0067     for (i = 0; i < nr_of_packs(); i++) {
0068         cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
0069         if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
0070             snd_printk(KERN_ERR
0071                    "active frame status %i. Most probably some hardware problem.\n",
0072                    urb->iso_frame_desc[i].status);
0073             return urb->iso_frame_desc[i].status;
0074         }
0075         len = urb->iso_frame_desc[i].actual_length / usx2y->stride;
0076         if (!len) {
0077             snd_printd("0 == len ERROR!\n");
0078             continue;
0079         }
0080 
0081         /* copy a data chunk */
0082         if ((hwptr_done + len) > runtime->buffer_size) {
0083             cnt = runtime->buffer_size - hwptr_done;
0084             blen = cnt * usx2y->stride;
0085             memcpy(runtime->dma_area + hwptr_done * usx2y->stride, cp, blen);
0086             memcpy(runtime->dma_area, cp + blen, len * usx2y->stride - blen);
0087         } else {
0088             memcpy(runtime->dma_area + hwptr_done * usx2y->stride, cp,
0089                    len * usx2y->stride);
0090         }
0091         lens += len;
0092         hwptr_done += len;
0093         if (hwptr_done >= runtime->buffer_size)
0094             hwptr_done -= runtime->buffer_size;
0095     }
0096 
0097     subs->hwptr_done = hwptr_done;
0098     subs->transfer_done += lens;
0099     /* update the pointer, call callback if necessary */
0100     if (subs->transfer_done >= runtime->period_size) {
0101         subs->transfer_done -= runtime->period_size;
0102         snd_pcm_period_elapsed(subs->pcm_substream);
0103     }
0104     return 0;
0105 }
0106 
0107 /*
0108  * prepare urb for playback data pipe
0109  *
0110  * we copy the data directly from the pcm buffer.
0111  * the current position to be copied is held in hwptr field.
0112  * since a urb can handle only a single linear buffer, if the total
0113  * transferred area overflows the buffer boundary, we cannot send
0114  * it directly from the buffer.  thus the data is once copied to
0115  * a temporary buffer and urb points to that.
0116  */
0117 static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs,
0118                   struct urb *cap_urb,
0119                   struct urb *urb)
0120 {
0121     struct usx2ydev *usx2y = subs->usx2y;
0122     struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
0123     int count, counts, pack, len;
0124 
0125     count = 0;
0126     for (pack = 0; pack <  nr_of_packs(); pack++) {
0127         /* calculate the size of a packet */
0128         counts = cap_urb->iso_frame_desc[pack].actual_length / usx2y->stride;
0129         count += counts;
0130         if (counts < 43 || counts > 50) {
0131             snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
0132             return -EPIPE;
0133         }
0134         /* set up descriptor */
0135         urb->iso_frame_desc[pack].offset = pack ?
0136             urb->iso_frame_desc[pack - 1].offset +
0137             urb->iso_frame_desc[pack - 1].length :
0138             0;
0139         urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
0140     }
0141     if (atomic_read(&subs->state) >= STATE_PRERUNNING) {
0142         if (subs->hwptr + count > runtime->buffer_size) {
0143             /* err, the transferred area goes over buffer boundary.
0144              * copy the data to the temp buffer.
0145              */
0146             len = runtime->buffer_size - subs->hwptr;
0147             urb->transfer_buffer = subs->tmpbuf;
0148             memcpy(subs->tmpbuf, runtime->dma_area +
0149                    subs->hwptr * usx2y->stride, len * usx2y->stride);
0150             memcpy(subs->tmpbuf + len * usx2y->stride,
0151                    runtime->dma_area, (count - len) * usx2y->stride);
0152             subs->hwptr += count;
0153             subs->hwptr -= runtime->buffer_size;
0154         } else {
0155             /* set the buffer pointer */
0156             urb->transfer_buffer = runtime->dma_area + subs->hwptr * usx2y->stride;
0157             subs->hwptr += count;
0158             if (subs->hwptr >= runtime->buffer_size)
0159                 subs->hwptr -= runtime->buffer_size;
0160         }
0161     } else {
0162         urb->transfer_buffer = subs->tmpbuf;
0163     }
0164     urb->transfer_buffer_length = count * usx2y->stride;
0165     return 0;
0166 }
0167 
0168 /*
0169  * process after playback data complete
0170  *
0171  * update the current position and call callback if a period is processed.
0172  */
0173 static void usx2y_urb_play_retire(struct snd_usx2y_substream *subs, struct urb *urb)
0174 {
0175     struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
0176     int     len = urb->actual_length / subs->usx2y->stride;
0177 
0178     subs->transfer_done += len;
0179     subs->hwptr_done +=  len;
0180     if (subs->hwptr_done >= runtime->buffer_size)
0181         subs->hwptr_done -= runtime->buffer_size;
0182     if (subs->transfer_done >= runtime->period_size) {
0183         subs->transfer_done -= runtime->period_size;
0184         snd_pcm_period_elapsed(subs->pcm_substream);
0185     }
0186 }
0187 
0188 static int usx2y_urb_submit(struct snd_usx2y_substream *subs, struct urb *urb, int frame)
0189 {
0190     int err;
0191 
0192     if (!urb)
0193         return -ENODEV;
0194     urb->start_frame = frame + NRURBS * nr_of_packs();  // let hcd do rollover sanity checks
0195     urb->hcpriv = NULL;
0196     urb->dev = subs->usx2y->dev; /* we need to set this at each time */
0197     err = usb_submit_urb(urb, GFP_ATOMIC);
0198     if (err < 0) {
0199         snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
0200         return err;
0201     }
0202     return 0;
0203 }
0204 
0205 static int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs,
0206                    struct snd_usx2y_substream *playbacksubs,
0207                    int frame)
0208 {
0209     int err, state;
0210     struct urb *urb = playbacksubs->completed_urb;
0211 
0212     state = atomic_read(&playbacksubs->state);
0213     if (urb) {
0214         if (state == STATE_RUNNING)
0215             usx2y_urb_play_retire(playbacksubs, urb);
0216         else if (state >= STATE_PRERUNNING)
0217             atomic_inc(&playbacksubs->state);
0218     } else {
0219         switch (state) {
0220         case STATE_STARTING1:
0221             urb = playbacksubs->urb[0];
0222             atomic_inc(&playbacksubs->state);
0223             break;
0224         case STATE_STARTING2:
0225             urb = playbacksubs->urb[1];
0226             atomic_inc(&playbacksubs->state);
0227             break;
0228         }
0229     }
0230     if (urb) {
0231         err = usx2y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb);
0232         if (err)
0233             return err;
0234         err = usx2y_urb_submit(playbacksubs, urb, frame);
0235         if (err)
0236             return err;
0237     }
0238 
0239     playbacksubs->completed_urb = NULL;
0240 
0241     state = atomic_read(&capsubs->state);
0242     if (state >= STATE_PREPARED) {
0243         if (state == STATE_RUNNING) {
0244             err = usx2y_urb_capt_retire(capsubs);
0245             if (err)
0246                 return err;
0247         } else if (state >= STATE_PRERUNNING) {
0248             atomic_inc(&capsubs->state);
0249         }
0250         err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame);
0251         if (err)
0252             return err;
0253     }
0254     capsubs->completed_urb = NULL;
0255     return 0;
0256 }
0257 
0258 static void usx2y_clients_stop(struct usx2ydev *usx2y)
0259 {
0260     struct snd_usx2y_substream *subs;
0261     struct urb *urb;
0262     int s, u;
0263 
0264     for (s = 0; s < 4; s++) {
0265         subs = usx2y->subs[s];
0266         if (subs) {
0267             snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
0268             atomic_set(&subs->state, STATE_STOPPED);
0269         }
0270     }
0271     for (s = 0; s < 4; s++) {
0272         subs = usx2y->subs[s];
0273         if (subs) {
0274             if (atomic_read(&subs->state) >= STATE_PRERUNNING)
0275                 snd_pcm_stop_xrun(subs->pcm_substream);
0276             for (u = 0; u < NRURBS; u++) {
0277                 urb = subs->urb[u];
0278                 if (urb)
0279                     snd_printdd("%i status=%i start_frame=%i\n",
0280                             u, urb->status, urb->start_frame);
0281             }
0282         }
0283     }
0284     usx2y->prepare_subs = NULL;
0285     wake_up(&usx2y->prepare_wait_queue);
0286 }
0287 
0288 static void usx2y_error_urb_status(struct usx2ydev *usx2y,
0289                    struct snd_usx2y_substream *subs, struct urb *urb)
0290 {
0291     snd_printk(KERN_ERR "ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
0292     urb->status = 0;
0293     usx2y_clients_stop(usx2y);
0294 }
0295 
0296 static void i_usx2y_urb_complete(struct urb *urb)
0297 {
0298     struct snd_usx2y_substream *subs = urb->context;
0299     struct usx2ydev *usx2y = subs->usx2y;
0300     struct snd_usx2y_substream *capsubs, *playbacksubs;
0301 
0302     if (unlikely(atomic_read(&subs->state) < STATE_PREPARED)) {
0303         snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
0304                 usb_get_current_frame_number(usx2y->dev),
0305                 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
0306                 urb->status, urb->start_frame);
0307         return;
0308     }
0309     if (unlikely(urb->status)) {
0310         usx2y_error_urb_status(usx2y, subs, urb);
0311         return;
0312     }
0313 
0314     subs->completed_urb = urb;
0315 
0316     capsubs = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
0317     playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
0318 
0319     if (capsubs->completed_urb &&
0320         atomic_read(&capsubs->state) >= STATE_PREPARED &&
0321         (playbacksubs->completed_urb ||
0322          atomic_read(&playbacksubs->state) < STATE_PREPARED)) {
0323         if (!usx2y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) {
0324             usx2y->wait_iso_frame += nr_of_packs();
0325         } else {
0326             snd_printdd("\n");
0327             usx2y_clients_stop(usx2y);
0328         }
0329     }
0330 }
0331 
0332 static void usx2y_urbs_set_complete(struct usx2ydev *usx2y,
0333                     void (*complete)(struct urb *))
0334 {
0335     struct snd_usx2y_substream *subs;
0336     struct urb *urb;
0337     int s, u;
0338 
0339     for (s = 0; s < 4; s++) {
0340         subs = usx2y->subs[s];
0341         if (subs) {
0342             for (u = 0; u < NRURBS; u++) {
0343                 urb = subs->urb[u];
0344                 if (urb)
0345                     urb->complete = complete;
0346             }
0347         }
0348     }
0349 }
0350 
0351 static void usx2y_subs_startup_finish(struct usx2ydev *usx2y)
0352 {
0353     usx2y_urbs_set_complete(usx2y, i_usx2y_urb_complete);
0354     usx2y->prepare_subs = NULL;
0355 }
0356 
0357 static void i_usx2y_subs_startup(struct urb *urb)
0358 {
0359     struct snd_usx2y_substream *subs = urb->context;
0360     struct usx2ydev *usx2y = subs->usx2y;
0361     struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs;
0362 
0363     if (prepare_subs) {
0364         if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
0365             usx2y_subs_startup_finish(usx2y);
0366             atomic_inc(&prepare_subs->state);
0367             wake_up(&usx2y->prepare_wait_queue);
0368         }
0369     }
0370 
0371     i_usx2y_urb_complete(urb);
0372 }
0373 
0374 static void usx2y_subs_prepare(struct snd_usx2y_substream *subs)
0375 {
0376     snd_printdd("usx2y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n",
0377             subs, subs->endpoint, subs->urb[0], subs->urb[1]);
0378     /* reset the pointer */
0379     subs->hwptr = 0;
0380     subs->hwptr_done = 0;
0381     subs->transfer_done = 0;
0382 }
0383 
0384 static void usx2y_urb_release(struct urb **urb, int free_tb)
0385 {
0386     if (*urb) {
0387         usb_kill_urb(*urb);
0388         if (free_tb)
0389             kfree((*urb)->transfer_buffer);
0390         usb_free_urb(*urb);
0391         *urb = NULL;
0392     }
0393 }
0394 
0395 /*
0396  * release a substreams urbs
0397  */
0398 static void usx2y_urbs_release(struct snd_usx2y_substream *subs)
0399 {
0400     int i;
0401 
0402     snd_printdd("%s %i\n", __func__, subs->endpoint);
0403     for (i = 0; i < NRURBS; i++)
0404         usx2y_urb_release(subs->urb + i,
0405                   subs != subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
0406 
0407     kfree(subs->tmpbuf);
0408     subs->tmpbuf = NULL;
0409 }
0410 
0411 /*
0412  * initialize a substream's urbs
0413  */
0414 static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs)
0415 {
0416     int i;
0417     unsigned int pipe;
0418     int is_playback = subs == subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
0419     struct usb_device *dev = subs->usx2y->dev;
0420     struct urb **purb;
0421 
0422     pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
0423             usb_rcvisocpipe(dev, subs->endpoint);
0424     subs->maxpacksize = usb_maxpacket(dev, pipe);
0425     if (!subs->maxpacksize)
0426         return -EINVAL;
0427 
0428     if (is_playback && !subs->tmpbuf) { /* allocate a temporary buffer for playback */
0429         subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL);
0430         if (!subs->tmpbuf)
0431             return -ENOMEM;
0432     }
0433     /* allocate and initialize data urbs */
0434     for (i = 0; i < NRURBS; i++) {
0435         purb = subs->urb + i;
0436         if (*purb) {
0437             usb_kill_urb(*purb);
0438             continue;
0439         }
0440         *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
0441         if (!*purb) {
0442             usx2y_urbs_release(subs);
0443             return -ENOMEM;
0444         }
0445         if (!is_playback && !(*purb)->transfer_buffer) {
0446             /* allocate a capture buffer per urb */
0447             (*purb)->transfer_buffer =
0448                 kmalloc_array(subs->maxpacksize,
0449                           nr_of_packs(), GFP_KERNEL);
0450             if (!(*purb)->transfer_buffer) {
0451                 usx2y_urbs_release(subs);
0452                 return -ENOMEM;
0453             }
0454         }
0455         (*purb)->dev = dev;
0456         (*purb)->pipe = pipe;
0457         (*purb)->number_of_packets = nr_of_packs();
0458         (*purb)->context = subs;
0459         (*purb)->interval = 1;
0460         (*purb)->complete = i_usx2y_subs_startup;
0461     }
0462     return 0;
0463 }
0464 
0465 static void usx2y_subs_startup(struct snd_usx2y_substream *subs)
0466 {
0467     struct usx2ydev *usx2y = subs->usx2y;
0468 
0469     usx2y->prepare_subs = subs;
0470     subs->urb[0]->start_frame = -1;
0471     wmb();
0472     usx2y_urbs_set_complete(usx2y, i_usx2y_subs_startup);
0473 }
0474 
0475 static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
0476 {
0477     int i, err;
0478     struct usx2ydev *usx2y = subs->usx2y;
0479     struct urb *urb;
0480     unsigned long pack;
0481 
0482     err = usx2y_urbs_allocate(subs);
0483     if (err < 0)
0484         return err;
0485     subs->completed_urb = NULL;
0486     for (i = 0; i < 4; i++) {
0487         struct snd_usx2y_substream *subs = usx2y->subs[i];
0488 
0489         if (subs && atomic_read(&subs->state) >= STATE_PREPARED)
0490             goto start;
0491     }
0492 
0493  start:
0494     usx2y_subs_startup(subs);
0495     for (i = 0; i < NRURBS; i++) {
0496         urb = subs->urb[i];
0497         if (usb_pipein(urb->pipe)) {
0498             if (!i)
0499                 atomic_set(&subs->state, STATE_STARTING3);
0500             urb->dev = usx2y->dev;
0501             for (pack = 0; pack < nr_of_packs(); pack++) {
0502                 urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
0503                 urb->iso_frame_desc[pack].length = subs->maxpacksize;
0504             }
0505             urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
0506             err = usb_submit_urb(urb, GFP_ATOMIC);
0507             if (err < 0) {
0508                 snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
0509                 err = -EPIPE;
0510                 goto cleanup;
0511             } else {
0512                 if (!i)
0513                     usx2y->wait_iso_frame = urb->start_frame;
0514             }
0515             urb->transfer_flags = 0;
0516         } else {
0517             atomic_set(&subs->state, STATE_STARTING1);
0518             break;
0519         }
0520     }
0521     err = 0;
0522     wait_event(usx2y->prepare_wait_queue, !usx2y->prepare_subs);
0523     if (atomic_read(&subs->state) != STATE_PREPARED)
0524         err = -EPIPE;
0525 
0526  cleanup:
0527     if (err) {
0528         usx2y_subs_startup_finish(usx2y);
0529         usx2y_clients_stop(usx2y);  // something is completely wrong > stop everything
0530     }
0531     return err;
0532 }
0533 
0534 /*
0535  * return the current pcm pointer.  just return the hwptr_done value.
0536  */
0537 static snd_pcm_uframes_t snd_usx2y_pcm_pointer(struct snd_pcm_substream *substream)
0538 {
0539     struct snd_usx2y_substream *subs = substream->runtime->private_data;
0540 
0541     return subs->hwptr_done;
0542 }
0543 
0544 /*
0545  * start/stop substream
0546  */
0547 static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
0548 {
0549     struct snd_usx2y_substream *subs = substream->runtime->private_data;
0550 
0551     switch (cmd) {
0552     case SNDRV_PCM_TRIGGER_START:
0553         snd_printdd("%s(START)\n", __func__);
0554         if (atomic_read(&subs->state) == STATE_PREPARED &&
0555             atomic_read(&subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= STATE_PREPARED) {
0556             atomic_set(&subs->state, STATE_PRERUNNING);
0557         } else {
0558             snd_printdd("\n");
0559             return -EPIPE;
0560         }
0561         break;
0562     case SNDRV_PCM_TRIGGER_STOP:
0563         snd_printdd("%s(STOP)\n", __func__);
0564         if (atomic_read(&subs->state) >= STATE_PRERUNNING)
0565             atomic_set(&subs->state, STATE_PREPARED);
0566         break;
0567     default:
0568         return -EINVAL;
0569     }
0570     return 0;
0571 }
0572 
0573 /*
0574  * allocate a buffer, setup samplerate
0575  *
0576  * so far we use a physically linear buffer although packetize transfer
0577  * doesn't need a continuous area.
0578  * if sg buffer is supported on the later version of alsa, we'll follow
0579  * that.
0580  */
0581 struct s_c2 {
0582     char c1, c2;
0583 };
0584 
0585 static const struct s_c2 setrate_44100[] = {
0586     { 0x14, 0x08},  // this line sets 44100, well actually a little less
0587     { 0x18, 0x40},  // only tascam / frontier design knows the further lines .......
0588     { 0x18, 0x42},
0589     { 0x18, 0x45},
0590     { 0x18, 0x46},
0591     { 0x18, 0x48},
0592     { 0x18, 0x4A},
0593     { 0x18, 0x4C},
0594     { 0x18, 0x4E},
0595     { 0x18, 0x50},
0596     { 0x18, 0x52},
0597     { 0x18, 0x54},
0598     { 0x18, 0x56},
0599     { 0x18, 0x58},
0600     { 0x18, 0x5A},
0601     { 0x18, 0x5C},
0602     { 0x18, 0x5E},
0603     { 0x18, 0x60},
0604     { 0x18, 0x62},
0605     { 0x18, 0x64},
0606     { 0x18, 0x66},
0607     { 0x18, 0x68},
0608     { 0x18, 0x6A},
0609     { 0x18, 0x6C},
0610     { 0x18, 0x6E},
0611     { 0x18, 0x70},
0612     { 0x18, 0x72},
0613     { 0x18, 0x74},
0614     { 0x18, 0x76},
0615     { 0x18, 0x78},
0616     { 0x18, 0x7A},
0617     { 0x18, 0x7C},
0618     { 0x18, 0x7E}
0619 };
0620 
0621 static const struct s_c2 setrate_48000[] = {
0622     { 0x14, 0x09},  // this line sets 48000, well actually a little less
0623     { 0x18, 0x40},  // only tascam / frontier design knows the further lines .......
0624     { 0x18, 0x42},
0625     { 0x18, 0x45},
0626     { 0x18, 0x46},
0627     { 0x18, 0x48},
0628     { 0x18, 0x4A},
0629     { 0x18, 0x4C},
0630     { 0x18, 0x4E},
0631     { 0x18, 0x50},
0632     { 0x18, 0x52},
0633     { 0x18, 0x54},
0634     { 0x18, 0x56},
0635     { 0x18, 0x58},
0636     { 0x18, 0x5A},
0637     { 0x18, 0x5C},
0638     { 0x18, 0x5E},
0639     { 0x18, 0x60},
0640     { 0x18, 0x62},
0641     { 0x18, 0x64},
0642     { 0x18, 0x66},
0643     { 0x18, 0x68},
0644     { 0x18, 0x6A},
0645     { 0x18, 0x6C},
0646     { 0x18, 0x6E},
0647     { 0x18, 0x70},
0648     { 0x18, 0x73},
0649     { 0x18, 0x74},
0650     { 0x18, 0x76},
0651     { 0x18, 0x78},
0652     { 0x18, 0x7A},
0653     { 0x18, 0x7C},
0654     { 0x18, 0x7E}
0655 };
0656 
0657 #define NOOF_SETRATE_URBS ARRAY_SIZE(setrate_48000)
0658 
0659 static void i_usx2y_04int(struct urb *urb)
0660 {
0661     struct usx2ydev *usx2y = urb->context;
0662 
0663     if (urb->status)
0664         snd_printk(KERN_ERR "snd_usx2y_04int() urb->status=%i\n", urb->status);
0665     if (!--usx2y->us04->len)
0666         wake_up(&usx2y->in04_wait_queue);
0667 }
0668 
0669 static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
0670 {
0671     int err = 0, i;
0672     struct snd_usx2y_urb_seq *us = NULL;
0673     int *usbdata = NULL;
0674     const struct s_c2 *ra = rate == 48000 ? setrate_48000 : setrate_44100;
0675     struct urb *urb;
0676 
0677     if (usx2y->rate != rate) {
0678         us = kzalloc(struct_size(us, urb, NOOF_SETRATE_URBS),
0679                  GFP_KERNEL);
0680         if (!us) {
0681             err = -ENOMEM;
0682             goto cleanup;
0683         }
0684         usbdata = kmalloc_array(NOOF_SETRATE_URBS, sizeof(int),
0685                     GFP_KERNEL);
0686         if (!usbdata) {
0687             err = -ENOMEM;
0688             goto cleanup;
0689         }
0690         for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
0691             us->urb[i] = usb_alloc_urb(0, GFP_KERNEL);
0692             if (!us->urb[i]) {
0693                 err = -ENOMEM;
0694                 goto cleanup;
0695             }
0696             ((char *)(usbdata + i))[0] = ra[i].c1;
0697             ((char *)(usbdata + i))[1] = ra[i].c2;
0698             usb_fill_bulk_urb(us->urb[i], usx2y->dev, usb_sndbulkpipe(usx2y->dev, 4),
0699                       usbdata + i, 2, i_usx2y_04int, usx2y);
0700         }
0701         err = usb_urb_ep_type_check(us->urb[0]);
0702         if (err < 0)
0703             goto cleanup;
0704         us->submitted = 0;
0705         us->len =   NOOF_SETRATE_URBS;
0706         usx2y->us04 =   us;
0707         wait_event_timeout(usx2y->in04_wait_queue, !us->len, HZ);
0708         usx2y->us04 =   NULL;
0709         if (us->len)
0710             err = -ENODEV;
0711     cleanup:
0712         if (us) {
0713             us->submitted = 2*NOOF_SETRATE_URBS;
0714             for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
0715                 urb = us->urb[i];
0716                 if (!urb)
0717                     continue;
0718                 if (urb->status) {
0719                     if (!err)
0720                         err = -ENODEV;
0721                     usb_kill_urb(urb);
0722                 }
0723                 usb_free_urb(urb);
0724             }
0725             usx2y->us04 = NULL;
0726             kfree(usbdata);
0727             kfree(us);
0728             if (!err)
0729                 usx2y->rate = rate;
0730         }
0731     }
0732 
0733     return err;
0734 }
0735 
0736 static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format)
0737 {
0738     int alternate, err;
0739     struct list_head *p;
0740 
0741     if (format == SNDRV_PCM_FORMAT_S24_3LE) {
0742         alternate = 2;
0743         usx2y->stride = 6;
0744     } else {
0745         alternate = 1;
0746         usx2y->stride = 4;
0747     }
0748     list_for_each(p, &usx2y->midi_list) {
0749         snd_usbmidi_input_stop(p);
0750     }
0751     usb_kill_urb(usx2y->in04_urb);
0752     err = usb_set_interface(usx2y->dev, 0, alternate);
0753     if (err) {
0754         snd_printk(KERN_ERR "usb_set_interface error\n");
0755         return err;
0756     }
0757     usx2y->in04_urb->dev = usx2y->dev;
0758     err = usb_submit_urb(usx2y->in04_urb, GFP_KERNEL);
0759     list_for_each(p, &usx2y->midi_list) {
0760         snd_usbmidi_input_start(p);
0761     }
0762     usx2y->format = format;
0763     usx2y->rate = 0;
0764     return err;
0765 }
0766 
0767 
0768 static int snd_usx2y_pcm_hw_params(struct snd_pcm_substream *substream,
0769                    struct snd_pcm_hw_params *hw_params)
0770 {
0771     int         err = 0;
0772     unsigned int        rate = params_rate(hw_params);
0773     snd_pcm_format_t    format = params_format(hw_params);
0774     struct snd_card *card = substream->pstr->pcm->card;
0775     struct usx2ydev *dev = usx2y(card);
0776     struct snd_usx2y_substream *subs;
0777     struct snd_pcm_substream *test_substream;
0778     int i;
0779 
0780     mutex_lock(&usx2y(card)->pcm_mutex);
0781     snd_printdd("snd_usx2y_hw_params(%p, %p)\n", substream, hw_params);
0782     /* all pcm substreams off one usx2y have to operate at the same
0783      * rate & format
0784      */
0785     for (i = 0; i < dev->pcm_devs * 2; i++) {
0786         subs = dev->subs[i];
0787         if (!subs)
0788             continue;
0789         test_substream = subs->pcm_substream;
0790         if (!test_substream || test_substream == substream ||
0791             !test_substream->runtime)
0792             continue;
0793         if ((test_substream->runtime->format &&
0794              test_substream->runtime->format != format) ||
0795             (test_substream->runtime->rate &&
0796              test_substream->runtime->rate != rate)) {
0797             err = -EINVAL;
0798             goto error;
0799         }
0800     }
0801 
0802  error:
0803     mutex_unlock(&usx2y(card)->pcm_mutex);
0804     return err;
0805 }
0806 
0807 /*
0808  * free the buffer
0809  */
0810 static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream)
0811 {
0812     struct snd_pcm_runtime *runtime = substream->runtime;
0813     struct snd_usx2y_substream *subs = runtime->private_data;
0814     struct snd_usx2y_substream *cap_subs, *playback_subs;
0815 
0816     mutex_lock(&subs->usx2y->pcm_mutex);
0817     snd_printdd("snd_usx2y_hw_free(%p)\n", substream);
0818 
0819     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0820         cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
0821         atomic_set(&subs->state, STATE_STOPPED);
0822         usx2y_urbs_release(subs);
0823         if (!cap_subs->pcm_substream ||
0824             !cap_subs->pcm_substream->runtime ||
0825             !cap_subs->pcm_substream->runtime->status ||
0826             cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
0827             atomic_set(&cap_subs->state, STATE_STOPPED);
0828             usx2y_urbs_release(cap_subs);
0829         }
0830     } else {
0831         playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
0832         if (atomic_read(&playback_subs->state) < STATE_PREPARED) {
0833             atomic_set(&subs->state, STATE_STOPPED);
0834             usx2y_urbs_release(subs);
0835         }
0836     }
0837     mutex_unlock(&subs->usx2y->pcm_mutex);
0838     return 0;
0839 }
0840 
0841 /*
0842  * prepare callback
0843  *
0844  * set format and initialize urbs
0845  */
0846 static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream)
0847 {
0848     struct snd_pcm_runtime *runtime = substream->runtime;
0849     struct snd_usx2y_substream *subs = runtime->private_data;
0850     struct usx2ydev *usx2y = subs->usx2y;
0851     struct snd_usx2y_substream *capsubs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
0852     int err = 0;
0853 
0854     snd_printdd("%s(%p)\n", __func__, substream);
0855 
0856     mutex_lock(&usx2y->pcm_mutex);
0857     usx2y_subs_prepare(subs);
0858     // Start hardware streams
0859     // SyncStream first....
0860     if (atomic_read(&capsubs->state) < STATE_PREPARED) {
0861         if (usx2y->format != runtime->format) {
0862             err = usx2y_format_set(usx2y, runtime->format);
0863             if (err < 0)
0864                 goto up_prepare_mutex;
0865         }
0866         if (usx2y->rate != runtime->rate) {
0867             err = usx2y_rate_set(usx2y, runtime->rate);
0868             if (err < 0)
0869                 goto up_prepare_mutex;
0870         }
0871         snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
0872         err = usx2y_urbs_start(capsubs);
0873         if (err < 0)
0874             goto up_prepare_mutex;
0875     }
0876 
0877     if (subs != capsubs && atomic_read(&subs->state) < STATE_PREPARED)
0878         err = usx2y_urbs_start(subs);
0879 
0880  up_prepare_mutex:
0881     mutex_unlock(&usx2y->pcm_mutex);
0882     return err;
0883 }
0884 
0885 static const struct snd_pcm_hardware snd_usx2y_2c = {
0886     .info =         (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
0887                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
0888                  SNDRV_PCM_INFO_MMAP_VALID |
0889                  SNDRV_PCM_INFO_BATCH),
0890     .formats =                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
0891     .rates =                   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
0892     .rate_min =                44100,
0893     .rate_max =                48000,
0894     .channels_min =            2,
0895     .channels_max =            2,
0896     .buffer_bytes_max = (2*128*1024),
0897     .period_bytes_min = 64,
0898     .period_bytes_max = (128*1024),
0899     .periods_min =      2,
0900     .periods_max =      1024,
0901     .fifo_size =              0
0902 };
0903 
0904 static int snd_usx2y_pcm_open(struct snd_pcm_substream *substream)
0905 {
0906     struct snd_usx2y_substream  *subs =
0907         ((struct snd_usx2y_substream **)
0908          snd_pcm_substream_chip(substream))[substream->stream];
0909     struct snd_pcm_runtime  *runtime = substream->runtime;
0910 
0911     if (subs->usx2y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
0912         return -EBUSY;
0913 
0914     runtime->hw = snd_usx2y_2c;
0915     runtime->private_data = subs;
0916     subs->pcm_substream = substream;
0917     snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
0918     return 0;
0919 }
0920 
0921 static int snd_usx2y_pcm_close(struct snd_pcm_substream *substream)
0922 {
0923     struct snd_pcm_runtime *runtime = substream->runtime;
0924     struct snd_usx2y_substream *subs = runtime->private_data;
0925 
0926     subs->pcm_substream = NULL;
0927 
0928     return 0;
0929 }
0930 
0931 static const struct snd_pcm_ops snd_usx2y_pcm_ops = {
0932     .open =     snd_usx2y_pcm_open,
0933     .close =    snd_usx2y_pcm_close,
0934     .hw_params =    snd_usx2y_pcm_hw_params,
0935     .hw_free =  snd_usx2y_pcm_hw_free,
0936     .prepare =  snd_usx2y_pcm_prepare,
0937     .trigger =  snd_usx2y_pcm_trigger,
0938     .pointer =  snd_usx2y_pcm_pointer,
0939 };
0940 
0941 /*
0942  * free a usb stream instance
0943  */
0944 static void usx2y_audio_stream_free(struct snd_usx2y_substream **usx2y_substream)
0945 {
0946     int stream;
0947 
0948     for_each_pcm_streams(stream) {
0949         kfree(usx2y_substream[stream]);
0950         usx2y_substream[stream] = NULL;
0951     }
0952 }
0953 
0954 static void snd_usx2y_pcm_private_free(struct snd_pcm *pcm)
0955 {
0956     struct snd_usx2y_substream **usx2y_stream = pcm->private_data;
0957 
0958     if (usx2y_stream)
0959         usx2y_audio_stream_free(usx2y_stream);
0960 }
0961 
0962 static int usx2y_audio_stream_new(struct snd_card *card, int playback_endpoint, int capture_endpoint)
0963 {
0964     struct snd_pcm *pcm;
0965     int err, i;
0966     struct snd_usx2y_substream **usx2y_substream =
0967         usx2y(card)->subs + 2 * usx2y(card)->pcm_devs;
0968 
0969     for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
0970          i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
0971         usx2y_substream[i] = kzalloc(sizeof(struct snd_usx2y_substream), GFP_KERNEL);
0972         if (!usx2y_substream[i])
0973             return -ENOMEM;
0974 
0975         usx2y_substream[i]->usx2y = usx2y(card);
0976     }
0977 
0978     if (playback_endpoint)
0979         usx2y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
0980     usx2y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;
0981 
0982     err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usx2y(card)->pcm_devs,
0983               playback_endpoint ? 1 : 0, 1,
0984               &pcm);
0985     if (err < 0) {
0986         usx2y_audio_stream_free(usx2y_substream);
0987         return err;
0988     }
0989 
0990     if (playback_endpoint)
0991         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usx2y_pcm_ops);
0992     snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usx2y_pcm_ops);
0993 
0994     pcm->private_data = usx2y_substream;
0995     pcm->private_free = snd_usx2y_pcm_private_free;
0996     pcm->info_flags = 0;
0997 
0998     sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usx2y(card)->pcm_devs);
0999 
1000     if (playback_endpoint) {
1001         snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
1002                        SNDRV_DMA_TYPE_CONTINUOUS,
1003                        NULL,
1004                        64*1024, 128*1024);
1005     }
1006 
1007     snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
1008                    SNDRV_DMA_TYPE_CONTINUOUS,
1009                    NULL,
1010                    64*1024, 128*1024);
1011     usx2y(card)->pcm_devs++;
1012 
1013     return 0;
1014 }
1015 
1016 /*
1017  * create a chip instance and set its names.
1018  */
1019 int usx2y_audio_create(struct snd_card *card)
1020 {
1021     int err;
1022 
1023     err = usx2y_audio_stream_new(card, 0xA, 0x8);
1024     if (err < 0)
1025         return err;
1026     if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) == USB_ID_US428) {
1027         err = usx2y_audio_stream_new(card, 0, 0xA);
1028         if (err < 0)
1029             return err;
1030     }
1031     if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) != USB_ID_US122)
1032         err = usx2y_rate_set(usx2y(card), 44100);   // Lets us428 recognize output-volume settings, disturbs us122.
1033     return err;
1034 }