root/sound/usb/usx2y/usbusx2yaudio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usX2Y_urb_capt_retire
  2. usX2Y_urb_play_prepare
  3. usX2Y_urb_play_retire
  4. usX2Y_urb_submit
  5. usX2Y_usbframe_complete
  6. usX2Y_clients_stop
  7. usX2Y_error_urb_status
  8. i_usX2Y_urb_complete
  9. usX2Y_urbs_set_complete
  10. usX2Y_subs_startup_finish
  11. i_usX2Y_subs_startup
  12. usX2Y_subs_prepare
  13. usX2Y_urb_release
  14. usX2Y_urbs_release
  15. usX2Y_urbs_allocate
  16. usX2Y_subs_startup
  17. usX2Y_urbs_start
  18. snd_usX2Y_pcm_pointer
  19. snd_usX2Y_pcm_trigger
  20. i_usX2Y_04Int
  21. usX2Y_rate_set
  22. usX2Y_format_set
  23. snd_usX2Y_pcm_hw_params
  24. snd_usX2Y_pcm_hw_free
  25. snd_usX2Y_pcm_prepare
  26. snd_usX2Y_pcm_open
  27. snd_usX2Y_pcm_close
  28. usX2Y_audio_stream_free
  29. snd_usX2Y_pcm_private_free
  30. usX2Y_audio_stream_new
  31. usX2Y_audio_create

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *   US-X2Y AUDIO
   4  *   Copyright (c) 2002-2004 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 
  20 #include <linux/interrupt.h>
  21 #include <linux/slab.h>
  22 #include <linux/usb.h>
  23 #include <linux/moduleparam.h>
  24 #include <sound/core.h>
  25 #include <sound/info.h>
  26 #include <sound/pcm.h>
  27 #include <sound/pcm_params.h>
  28 #include "usx2y.h"
  29 #include "usbusx2y.h"
  30 
  31 #define USX2Y_NRPACKS 4                 /* Default value used for nr of packs per urb.
  32                                           1 to 4 have been tested ok on uhci.
  33                                           To use 3 on ohci, you'd need a patch:
  34                                           look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
  35                                           "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
  36                                           .
  37                                           1, 2 and 4 work out of the box on ohci, if I recall correctly.
  38                                           Bigger is safer operation,
  39                                           smaller gives lower latencies.
  40                                         */
  41 #define USX2Y_NRPACKS_VARIABLE y        /* If your system works ok with this module's parameter
  42                                            nrpacks set to 1, you might as well comment 
  43                                            this #define out, and thereby produce smaller, faster code.
  44                                            You'd also set USX2Y_NRPACKS to 1 then.
  45                                         */
  46 
  47 #ifdef USX2Y_NRPACKS_VARIABLE
  48  static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
  49  #define  nr_of_packs() nrpacks
  50  module_param(nrpacks, int, 0444);
  51  MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
  52 #else
  53  #define nr_of_packs() USX2Y_NRPACKS
  54 #endif
  55 
  56 
  57 static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
  58 {
  59         struct urb      *urb = subs->completed_urb;
  60         struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
  61         unsigned char   *cp;
  62         int             i, len, lens = 0, hwptr_done = subs->hwptr_done;
  63         struct usX2Ydev *usX2Y = subs->usX2Y;
  64 
  65         for (i = 0; i < nr_of_packs(); i++) {
  66                 cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
  67                 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
  68                         snd_printk(KERN_ERR "active frame status %i. "
  69                                    "Most probably some hardware problem.\n",
  70                                    urb->iso_frame_desc[i].status);
  71                         return urb->iso_frame_desc[i].status;
  72                 }
  73                 len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
  74                 if (! len) {
  75                         snd_printd("0 == len ERROR!\n");
  76                         continue;
  77                 }
  78 
  79                 /* copy a data chunk */
  80                 if ((hwptr_done + len) > runtime->buffer_size) {
  81                         int cnt = runtime->buffer_size - hwptr_done;
  82                         int blen = cnt * usX2Y->stride;
  83                         memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, blen);
  84                         memcpy(runtime->dma_area, cp + blen, len * usX2Y->stride - blen);
  85                 } else {
  86                         memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp,
  87                                len * usX2Y->stride);
  88                 }
  89                 lens += len;
  90                 if ((hwptr_done += len) >= runtime->buffer_size)
  91                         hwptr_done -= runtime->buffer_size;
  92         }
  93 
  94         subs->hwptr_done = hwptr_done;
  95         subs->transfer_done += lens;
  96         /* update the pointer, call callback if necessary */
  97         if (subs->transfer_done >= runtime->period_size) {
  98                 subs->transfer_done -= runtime->period_size;
  99                 snd_pcm_period_elapsed(subs->pcm_substream);
 100         }
 101         return 0;
 102 }
 103 /*
 104  * prepare urb for playback data pipe
 105  *
 106  * we copy the data directly from the pcm buffer.
 107  * the current position to be copied is held in hwptr field.
 108  * since a urb can handle only a single linear buffer, if the total
 109  * transferred area overflows the buffer boundary, we cannot send
 110  * it directly from the buffer.  thus the data is once copied to
 111  * a temporary buffer and urb points to that.
 112  */
 113 static int usX2Y_urb_play_prepare(struct snd_usX2Y_substream *subs,
 114                                   struct urb *cap_urb,
 115                                   struct urb *urb)
 116 {
 117         int count, counts, pack;
 118         struct usX2Ydev *usX2Y = subs->usX2Y;
 119         struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
 120 
 121         count = 0;
 122         for (pack = 0; pack <  nr_of_packs(); pack++) {
 123                 /* calculate the size of a packet */
 124                 counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
 125                 count += counts;
 126                 if (counts < 43 || counts > 50) {
 127                         snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
 128                         return -EPIPE;
 129                 }
 130                 /* set up descriptor */
 131                 urb->iso_frame_desc[pack].offset = pack ?
 132                         urb->iso_frame_desc[pack - 1].offset +
 133                         urb->iso_frame_desc[pack - 1].length :
 134                         0;
 135                 urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
 136         }
 137         if (atomic_read(&subs->state) >= state_PRERUNNING)
 138                 if (subs->hwptr + count > runtime->buffer_size) {
 139                         /* err, the transferred area goes over buffer boundary.
 140                          * copy the data to the temp buffer.
 141                          */
 142                         int len;
 143                         len = runtime->buffer_size - subs->hwptr;
 144                         urb->transfer_buffer = subs->tmpbuf;
 145                         memcpy(subs->tmpbuf, runtime->dma_area +
 146                                subs->hwptr * usX2Y->stride, len * usX2Y->stride);
 147                         memcpy(subs->tmpbuf + len * usX2Y->stride,
 148                                runtime->dma_area, (count - len) * usX2Y->stride);
 149                         subs->hwptr += count;
 150                         subs->hwptr -= runtime->buffer_size;
 151                 } else {
 152                         /* set the buffer pointer */
 153                         urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
 154                         if ((subs->hwptr += count) >= runtime->buffer_size)
 155                                 subs->hwptr -= runtime->buffer_size;
 156                 }
 157         else
 158                 urb->transfer_buffer = subs->tmpbuf;
 159         urb->transfer_buffer_length = count * usX2Y->stride;
 160         return 0;
 161 }
 162 
 163 /*
 164  * process after playback data complete
 165  *
 166  * update the current position and call callback if a period is processed.
 167  */
 168 static void usX2Y_urb_play_retire(struct snd_usX2Y_substream *subs, struct urb *urb)
 169 {
 170         struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
 171         int             len = urb->actual_length / subs->usX2Y->stride;
 172 
 173         subs->transfer_done += len;
 174         subs->hwptr_done +=  len;
 175         if (subs->hwptr_done >= runtime->buffer_size)
 176                 subs->hwptr_done -= runtime->buffer_size;
 177         if (subs->transfer_done >= runtime->period_size) {
 178                 subs->transfer_done -= runtime->period_size;
 179                 snd_pcm_period_elapsed(subs->pcm_substream);
 180         }
 181 }
 182 
 183 static int usX2Y_urb_submit(struct snd_usX2Y_substream *subs, struct urb *urb, int frame)
 184 {
 185         int err;
 186         if (!urb)
 187                 return -ENODEV;
 188         urb->start_frame = (frame + NRURBS * nr_of_packs());  // let hcd do rollover sanity checks
 189         urb->hcpriv = NULL;
 190         urb->dev = subs->usX2Y->dev; /* we need to set this at each time */
 191         if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
 192                 snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
 193                 return err;
 194         }
 195         return 0;
 196 }
 197 
 198 static inline int usX2Y_usbframe_complete(struct snd_usX2Y_substream *capsubs,
 199                                           struct snd_usX2Y_substream *playbacksubs,
 200                                           int frame)
 201 {
 202         int err, state;
 203         struct urb *urb = playbacksubs->completed_urb;
 204 
 205         state = atomic_read(&playbacksubs->state);
 206         if (NULL != urb) {
 207                 if (state == state_RUNNING)
 208                         usX2Y_urb_play_retire(playbacksubs, urb);
 209                 else if (state >= state_PRERUNNING)
 210                         atomic_inc(&playbacksubs->state);
 211         } else {
 212                 switch (state) {
 213                 case state_STARTING1:
 214                         urb = playbacksubs->urb[0];
 215                         atomic_inc(&playbacksubs->state);
 216                         break;
 217                 case state_STARTING2:
 218                         urb = playbacksubs->urb[1];
 219                         atomic_inc(&playbacksubs->state);
 220                         break;
 221                 }
 222         }
 223         if (urb) {
 224                 if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
 225                     (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
 226                         return err;
 227                 }
 228         }
 229 
 230         playbacksubs->completed_urb = NULL;
 231 
 232         state = atomic_read(&capsubs->state);
 233         if (state >= state_PREPARED) {
 234                 if (state == state_RUNNING) {
 235                         if ((err = usX2Y_urb_capt_retire(capsubs)))
 236                                 return err;
 237                 } else if (state >= state_PRERUNNING)
 238                         atomic_inc(&capsubs->state);
 239                 if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
 240                         return err;
 241         }
 242         capsubs->completed_urb = NULL;
 243         return 0;
 244 }
 245 
 246 
 247 static void usX2Y_clients_stop(struct usX2Ydev *usX2Y)
 248 {
 249         int s, u;
 250 
 251         for (s = 0; s < 4; s++) {
 252                 struct snd_usX2Y_substream *subs = usX2Y->subs[s];
 253                 if (subs) {
 254                         snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
 255                         atomic_set(&subs->state, state_STOPPED);
 256                 }
 257         }
 258         for (s = 0; s < 4; s++) {
 259                 struct snd_usX2Y_substream *subs = usX2Y->subs[s];
 260                 if (subs) {
 261                         if (atomic_read(&subs->state) >= state_PRERUNNING)
 262                                 snd_pcm_stop_xrun(subs->pcm_substream);
 263                         for (u = 0; u < NRURBS; u++) {
 264                                 struct urb *urb = subs->urb[u];
 265                                 if (NULL != urb)
 266                                         snd_printdd("%i status=%i start_frame=%i\n",
 267                                                     u, urb->status, urb->start_frame);
 268                         }
 269                 }
 270         }
 271         usX2Y->prepare_subs = NULL;
 272         wake_up(&usX2Y->prepare_wait_queue);
 273 }
 274 
 275 static void usX2Y_error_urb_status(struct usX2Ydev *usX2Y,
 276                                    struct snd_usX2Y_substream *subs, struct urb *urb)
 277 {
 278         snd_printk(KERN_ERR "ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
 279         urb->status = 0;
 280         usX2Y_clients_stop(usX2Y);
 281 }
 282 
 283 static void i_usX2Y_urb_complete(struct urb *urb)
 284 {
 285         struct snd_usX2Y_substream *subs = urb->context;
 286         struct usX2Ydev *usX2Y = subs->usX2Y;
 287 
 288         if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
 289                 snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
 290                             usb_get_current_frame_number(usX2Y->dev),
 291                             subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
 292                             urb->status, urb->start_frame);
 293                 return;
 294         }
 295         if (unlikely(urb->status)) {
 296                 usX2Y_error_urb_status(usX2Y, subs, urb);
 297                 return;
 298         }
 299 
 300         subs->completed_urb = urb;
 301 
 302         {
 303                 struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
 304                         *playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
 305                 if (capsubs->completed_urb &&
 306                     atomic_read(&capsubs->state) >= state_PREPARED &&
 307                     (playbacksubs->completed_urb ||
 308                      atomic_read(&playbacksubs->state) < state_PREPARED)) {
 309                         if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame))
 310                                 usX2Y->wait_iso_frame += nr_of_packs();
 311                         else {
 312                                 snd_printdd("\n");
 313                                 usX2Y_clients_stop(usX2Y);
 314                         }
 315                 }
 316         }
 317 }
 318 
 319 static void usX2Y_urbs_set_complete(struct usX2Ydev * usX2Y,
 320                                     void (*complete)(struct urb *))
 321 {
 322         int s, u;
 323         for (s = 0; s < 4; s++) {
 324                 struct snd_usX2Y_substream *subs = usX2Y->subs[s];
 325                 if (NULL != subs)
 326                         for (u = 0; u < NRURBS; u++) {
 327                                 struct urb * urb = subs->urb[u];
 328                                 if (NULL != urb)
 329                                         urb->complete = complete;
 330                         }
 331         }
 332 }
 333 
 334 static void usX2Y_subs_startup_finish(struct usX2Ydev * usX2Y)
 335 {
 336         usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete);
 337         usX2Y->prepare_subs = NULL;
 338 }
 339 
 340 static void i_usX2Y_subs_startup(struct urb *urb)
 341 {
 342         struct snd_usX2Y_substream *subs = urb->context;
 343         struct usX2Ydev *usX2Y = subs->usX2Y;
 344         struct snd_usX2Y_substream *prepare_subs = usX2Y->prepare_subs;
 345         if (NULL != prepare_subs)
 346                 if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
 347                         usX2Y_subs_startup_finish(usX2Y);
 348                         atomic_inc(&prepare_subs->state);
 349                         wake_up(&usX2Y->prepare_wait_queue);
 350                 }
 351 
 352         i_usX2Y_urb_complete(urb);
 353 }
 354 
 355 static void usX2Y_subs_prepare(struct snd_usX2Y_substream *subs)
 356 {
 357         snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n",
 358                     subs, subs->endpoint, subs->urb[0], subs->urb[1]);
 359         /* reset the pointer */
 360         subs->hwptr = 0;
 361         subs->hwptr_done = 0;
 362         subs->transfer_done = 0;
 363 }
 364 
 365 
 366 static void usX2Y_urb_release(struct urb **urb, int free_tb)
 367 {
 368         if (*urb) {
 369                 usb_kill_urb(*urb);
 370                 if (free_tb)
 371                         kfree((*urb)->transfer_buffer);
 372                 usb_free_urb(*urb);
 373                 *urb = NULL;
 374         }
 375 }
 376 /*
 377  * release a substreams urbs
 378  */
 379 static void usX2Y_urbs_release(struct snd_usX2Y_substream *subs)
 380 {
 381         int i;
 382         snd_printdd("usX2Y_urbs_release() %i\n", subs->endpoint);
 383         for (i = 0; i < NRURBS; i++)
 384                 usX2Y_urb_release(subs->urb + i,
 385                                   subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
 386 
 387         kfree(subs->tmpbuf);
 388         subs->tmpbuf = NULL;
 389 }
 390 /*
 391  * initialize a substream's urbs
 392  */
 393 static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
 394 {
 395         int i;
 396         unsigned int pipe;
 397         int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
 398         struct usb_device *dev = subs->usX2Y->dev;
 399 
 400         pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
 401                         usb_rcvisocpipe(dev, subs->endpoint);
 402         subs->maxpacksize = usb_maxpacket(dev, pipe, is_playback);
 403         if (!subs->maxpacksize)
 404                 return -EINVAL;
 405 
 406         if (is_playback && NULL == subs->tmpbuf) {      /* allocate a temporary buffer for playback */
 407                 subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL);
 408                 if (!subs->tmpbuf)
 409                         return -ENOMEM;
 410         }
 411         /* allocate and initialize data urbs */
 412         for (i = 0; i < NRURBS; i++) {
 413                 struct urb **purb = subs->urb + i;
 414                 if (*purb) {
 415                         usb_kill_urb(*purb);
 416                         continue;
 417                 }
 418                 *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
 419                 if (NULL == *purb) {
 420                         usX2Y_urbs_release(subs);
 421                         return -ENOMEM;
 422                 }
 423                 if (!is_playback && !(*purb)->transfer_buffer) {
 424                         /* allocate a capture buffer per urb */
 425                         (*purb)->transfer_buffer =
 426                                 kmalloc_array(subs->maxpacksize,
 427                                               nr_of_packs(), GFP_KERNEL);
 428                         if (NULL == (*purb)->transfer_buffer) {
 429                                 usX2Y_urbs_release(subs);
 430                                 return -ENOMEM;
 431                         }
 432                 }
 433                 (*purb)->dev = dev;
 434                 (*purb)->pipe = pipe;
 435                 (*purb)->number_of_packets = nr_of_packs();
 436                 (*purb)->context = subs;
 437                 (*purb)->interval = 1;
 438                 (*purb)->complete = i_usX2Y_subs_startup;
 439         }
 440         return 0;
 441 }
 442 
 443 static void usX2Y_subs_startup(struct snd_usX2Y_substream *subs)
 444 {
 445         struct usX2Ydev *usX2Y = subs->usX2Y;
 446         usX2Y->prepare_subs = subs;
 447         subs->urb[0]->start_frame = -1;
 448         wmb();
 449         usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup);
 450 }
 451 
 452 static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
 453 {
 454         int i, err;
 455         struct usX2Ydev *usX2Y = subs->usX2Y;
 456 
 457         if ((err = usX2Y_urbs_allocate(subs)) < 0)
 458                 return err;
 459         subs->completed_urb = NULL;
 460         for (i = 0; i < 4; i++) {
 461                 struct snd_usX2Y_substream *subs = usX2Y->subs[i];
 462                 if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
 463                         goto start;
 464         }
 465 
 466  start:
 467         usX2Y_subs_startup(subs);
 468         for (i = 0; i < NRURBS; i++) {
 469                 struct urb *urb = subs->urb[i];
 470                 if (usb_pipein(urb->pipe)) {
 471                         unsigned long pack;
 472                         if (0 == i)
 473                                 atomic_set(&subs->state, state_STARTING3);
 474                         urb->dev = usX2Y->dev;
 475                         for (pack = 0; pack < nr_of_packs(); pack++) {
 476                                 urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
 477                                 urb->iso_frame_desc[pack].length = subs->maxpacksize;
 478                         }
 479                         urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); 
 480                         if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
 481                                 snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
 482                                 err = -EPIPE;
 483                                 goto cleanup;
 484                         } else
 485                                 if (i == 0)
 486                                         usX2Y->wait_iso_frame = urb->start_frame;
 487                         urb->transfer_flags = 0;
 488                 } else {
 489                         atomic_set(&subs->state, state_STARTING1);
 490                         break;
 491                 }
 492         }
 493         err = 0;
 494         wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
 495         if (atomic_read(&subs->state) != state_PREPARED)
 496                 err = -EPIPE;
 497 
 498  cleanup:
 499         if (err) {
 500                 usX2Y_subs_startup_finish(usX2Y);
 501                 usX2Y_clients_stop(usX2Y);              // something is completely wroong > stop evrything
 502         }
 503         return err;
 504 }
 505 
 506 /*
 507  * return the current pcm pointer.  just return the hwptr_done value.
 508  */
 509 static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(struct snd_pcm_substream *substream)
 510 {
 511         struct snd_usX2Y_substream *subs = substream->runtime->private_data;
 512         return subs->hwptr_done;
 513 }
 514 /*
 515  * start/stop substream
 516  */
 517 static int snd_usX2Y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 518 {
 519         struct snd_usX2Y_substream *subs = substream->runtime->private_data;
 520 
 521         switch (cmd) {
 522         case SNDRV_PCM_TRIGGER_START:
 523                 snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
 524                 if (atomic_read(&subs->state) == state_PREPARED &&
 525                     atomic_read(&subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= state_PREPARED) {
 526                         atomic_set(&subs->state, state_PRERUNNING);
 527                 } else {
 528                         snd_printdd("\n");
 529                         return -EPIPE;
 530                 }
 531                 break;
 532         case SNDRV_PCM_TRIGGER_STOP:
 533                 snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
 534                 if (atomic_read(&subs->state) >= state_PRERUNNING)
 535                         atomic_set(&subs->state, state_PREPARED);
 536                 break;
 537         default:
 538                 return -EINVAL;
 539         }
 540         return 0;
 541 }
 542 
 543 
 544 /*
 545  * allocate a buffer, setup samplerate
 546  *
 547  * so far we use a physically linear buffer although packetize transfer
 548  * doesn't need a continuous area.
 549  * if sg buffer is supported on the later version of alsa, we'll follow
 550  * that.
 551  */
 552 static struct s_c2
 553 {
 554         char c1, c2;
 555 }
 556         SetRate44100[] =
 557 {
 558         { 0x14, 0x08},  // this line sets 44100, well actually a little less
 559         { 0x18, 0x40},  // only tascam / frontier design knows the further lines .......
 560         { 0x18, 0x42},
 561         { 0x18, 0x45},
 562         { 0x18, 0x46},
 563         { 0x18, 0x48},
 564         { 0x18, 0x4A},
 565         { 0x18, 0x4C},
 566         { 0x18, 0x4E},
 567         { 0x18, 0x50},
 568         { 0x18, 0x52},
 569         { 0x18, 0x54},
 570         { 0x18, 0x56},
 571         { 0x18, 0x58},
 572         { 0x18, 0x5A},
 573         { 0x18, 0x5C},
 574         { 0x18, 0x5E},
 575         { 0x18, 0x60},
 576         { 0x18, 0x62},
 577         { 0x18, 0x64},
 578         { 0x18, 0x66},
 579         { 0x18, 0x68},
 580         { 0x18, 0x6A},
 581         { 0x18, 0x6C},
 582         { 0x18, 0x6E},
 583         { 0x18, 0x70},
 584         { 0x18, 0x72},
 585         { 0x18, 0x74},
 586         { 0x18, 0x76},
 587         { 0x18, 0x78},
 588         { 0x18, 0x7A},
 589         { 0x18, 0x7C},
 590         { 0x18, 0x7E}
 591 };
 592 static struct s_c2 SetRate48000[] =
 593 {
 594         { 0x14, 0x09},  // this line sets 48000, well actually a little less
 595         { 0x18, 0x40},  // only tascam / frontier design knows the further lines .......
 596         { 0x18, 0x42},
 597         { 0x18, 0x45},
 598         { 0x18, 0x46},
 599         { 0x18, 0x48},
 600         { 0x18, 0x4A},
 601         { 0x18, 0x4C},
 602         { 0x18, 0x4E},
 603         { 0x18, 0x50},
 604         { 0x18, 0x52},
 605         { 0x18, 0x54},
 606         { 0x18, 0x56},
 607         { 0x18, 0x58},
 608         { 0x18, 0x5A},
 609         { 0x18, 0x5C},
 610         { 0x18, 0x5E},
 611         { 0x18, 0x60},
 612         { 0x18, 0x62},
 613         { 0x18, 0x64},
 614         { 0x18, 0x66},
 615         { 0x18, 0x68},
 616         { 0x18, 0x6A},
 617         { 0x18, 0x6C},
 618         { 0x18, 0x6E},
 619         { 0x18, 0x70},
 620         { 0x18, 0x73},
 621         { 0x18, 0x74},
 622         { 0x18, 0x76},
 623         { 0x18, 0x78},
 624         { 0x18, 0x7A},
 625         { 0x18, 0x7C},
 626         { 0x18, 0x7E}
 627 };
 628 #define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
 629 
 630 static void i_usX2Y_04Int(struct urb *urb)
 631 {
 632         struct usX2Ydev *usX2Y = urb->context;
 633         
 634         if (urb->status)
 635                 snd_printk(KERN_ERR "snd_usX2Y_04Int() urb->status=%i\n", urb->status);
 636         if (0 == --usX2Y->US04->len)
 637                 wake_up(&usX2Y->In04WaitQueue);
 638 }
 639 
 640 static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
 641 {
 642         int                     err = 0, i;
 643         struct snd_usX2Y_urbSeq *us = NULL;
 644         int                     *usbdata = NULL;
 645         struct s_c2             *ra = rate == 48000 ? SetRate48000 : SetRate44100;
 646 
 647         if (usX2Y->rate != rate) {
 648                 us = kzalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
 649                 if (NULL == us) {
 650                         err = -ENOMEM;
 651                         goto cleanup;
 652                 }
 653                 usbdata = kmalloc_array(NOOF_SETRATE_URBS, sizeof(int),
 654                                         GFP_KERNEL);
 655                 if (NULL == usbdata) {
 656                         err = -ENOMEM;
 657                         goto cleanup;
 658                 }
 659                 for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
 660                         if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
 661                                 err = -ENOMEM;
 662                                 goto cleanup;
 663                         }
 664                         ((char*)(usbdata + i))[0] = ra[i].c1;
 665                         ((char*)(usbdata + i))[1] = ra[i].c2;
 666                         usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4),
 667                                           usbdata + i, 2, i_usX2Y_04Int, usX2Y);
 668                 }
 669                 err = usb_urb_ep_type_check(us->urb[0]);
 670                 if (err < 0)
 671                         goto cleanup;
 672                 us->submitted = 0;
 673                 us->len =       NOOF_SETRATE_URBS;
 674                 usX2Y->US04 =   us;
 675                 wait_event_timeout(usX2Y->In04WaitQueue, 0 == us->len, HZ);
 676                 usX2Y->US04 =   NULL;
 677                 if (us->len)
 678                         err = -ENODEV;
 679         cleanup:
 680                 if (us) {
 681                         us->submitted = 2*NOOF_SETRATE_URBS;
 682                         for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
 683                                 struct urb *urb = us->urb[i];
 684                                 if (!urb)
 685                                         continue;
 686                                 if (urb->status) {
 687                                         if (!err)
 688                                                 err = -ENODEV;
 689                                         usb_kill_urb(urb);
 690                                 }
 691                                 usb_free_urb(urb);
 692                         }
 693                         usX2Y->US04 = NULL;
 694                         kfree(usbdata);
 695                         kfree(us);
 696                         if (!err)
 697                                 usX2Y->rate = rate;
 698                 }
 699         }
 700 
 701         return err;
 702 }
 703 
 704 
 705 static int usX2Y_format_set(struct usX2Ydev *usX2Y, snd_pcm_format_t format)
 706 {
 707         int alternate, err;
 708         struct list_head* p;
 709         if (format == SNDRV_PCM_FORMAT_S24_3LE) {
 710                 alternate = 2;
 711                 usX2Y->stride = 6;
 712         } else {
 713                 alternate = 1;
 714                 usX2Y->stride = 4;
 715         }
 716         list_for_each(p, &usX2Y->midi_list) {
 717                 snd_usbmidi_input_stop(p);
 718         }
 719         usb_kill_urb(usX2Y->In04urb);
 720         if ((err = usb_set_interface(usX2Y->dev, 0, alternate))) {
 721                 snd_printk(KERN_ERR "usb_set_interface error \n");
 722                 return err;
 723         }
 724         usX2Y->In04urb->dev = usX2Y->dev;
 725         err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
 726         list_for_each(p, &usX2Y->midi_list) {
 727                 snd_usbmidi_input_start(p);
 728         }
 729         usX2Y->format = format;
 730         usX2Y->rate = 0;
 731         return err;
 732 }
 733 
 734 
 735 static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,
 736                                    struct snd_pcm_hw_params *hw_params)
 737 {
 738         int                     err = 0;
 739         unsigned int            rate = params_rate(hw_params);
 740         snd_pcm_format_t        format = params_format(hw_params);
 741         struct snd_card *card = substream->pstr->pcm->card;
 742         struct usX2Ydev *dev = usX2Y(card);
 743         int i;
 744 
 745         mutex_lock(&usX2Y(card)->pcm_mutex);
 746         snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
 747         /* all pcm substreams off one usX2Y have to operate at the same
 748          * rate & format
 749          */
 750         for (i = 0; i < dev->pcm_devs * 2; i++) {
 751                 struct snd_usX2Y_substream *subs = dev->subs[i];
 752                 struct snd_pcm_substream *test_substream;
 753 
 754                 if (!subs)
 755                         continue;
 756                 test_substream = subs->pcm_substream;
 757                 if (!test_substream || test_substream == substream ||
 758                     !test_substream->runtime)
 759                         continue;
 760                 if ((test_substream->runtime->format &&
 761                      test_substream->runtime->format != format) ||
 762                     (test_substream->runtime->rate &&
 763                      test_substream->runtime->rate != rate)) {
 764                         err = -EINVAL;
 765                         goto error;
 766                 }
 767         }
 768 
 769         err = snd_pcm_lib_malloc_pages(substream,
 770                                        params_buffer_bytes(hw_params));
 771         if (err < 0) {
 772                 snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n",
 773                            substream, params_buffer_bytes(hw_params), err);
 774                 goto error;
 775         }
 776 
 777  error:
 778         mutex_unlock(&usX2Y(card)->pcm_mutex);
 779         return err;
 780 }
 781 
 782 /*
 783  * free the buffer
 784  */
 785 static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
 786 {
 787         struct snd_pcm_runtime *runtime = substream->runtime;
 788         struct snd_usX2Y_substream *subs = runtime->private_data;
 789         mutex_lock(&subs->usX2Y->pcm_mutex);
 790         snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
 791 
 792         if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
 793                 struct snd_usX2Y_substream *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
 794                 atomic_set(&subs->state, state_STOPPED);
 795                 usX2Y_urbs_release(subs);
 796                 if (!cap_subs->pcm_substream ||
 797                     !cap_subs->pcm_substream->runtime ||
 798                     !cap_subs->pcm_substream->runtime->status ||
 799                     cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
 800                         atomic_set(&cap_subs->state, state_STOPPED);
 801                         usX2Y_urbs_release(cap_subs);
 802                 }
 803         } else {
 804                 struct snd_usX2Y_substream *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
 805                 if (atomic_read(&playback_subs->state) < state_PREPARED) {
 806                         atomic_set(&subs->state, state_STOPPED);
 807                         usX2Y_urbs_release(subs);
 808                 }
 809         }
 810         mutex_unlock(&subs->usX2Y->pcm_mutex);
 811         return snd_pcm_lib_free_pages(substream);
 812 }
 813 /*
 814  * prepare callback
 815  *
 816  * set format and initialize urbs
 817  */
 818 static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
 819 {
 820         struct snd_pcm_runtime *runtime = substream->runtime;
 821         struct snd_usX2Y_substream *subs = runtime->private_data;
 822         struct usX2Ydev *usX2Y = subs->usX2Y;
 823         struct snd_usX2Y_substream *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
 824         int err = 0;
 825         snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
 826 
 827         mutex_lock(&usX2Y->pcm_mutex);
 828         usX2Y_subs_prepare(subs);
 829 // Start hardware streams
 830 // SyncStream first....
 831         if (atomic_read(&capsubs->state) < state_PREPARED) {
 832                 if (usX2Y->format != runtime->format)
 833                         if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
 834                                 goto up_prepare_mutex;
 835                 if (usX2Y->rate != runtime->rate)
 836                         if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
 837                                 goto up_prepare_mutex;
 838                 snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
 839                 if (0 > (err = usX2Y_urbs_start(capsubs)))
 840                         goto up_prepare_mutex;
 841         }
 842 
 843         if (subs != capsubs && atomic_read(&subs->state) < state_PREPARED)
 844                 err = usX2Y_urbs_start(subs);
 845 
 846  up_prepare_mutex:
 847         mutex_unlock(&usX2Y->pcm_mutex);
 848         return err;
 849 }
 850 
 851 static struct snd_pcm_hardware snd_usX2Y_2c =
 852 {
 853         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 854                                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
 855                                  SNDRV_PCM_INFO_MMAP_VALID |
 856                                  SNDRV_PCM_INFO_BATCH),
 857         .formats =                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
 858         .rates =                   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
 859         .rate_min =                44100,
 860         .rate_max =                48000,
 861         .channels_min =            2,
 862         .channels_max =            2,
 863         .buffer_bytes_max =     (2*128*1024),
 864         .period_bytes_min =     64,
 865         .period_bytes_max =     (128*1024),
 866         .periods_min =          2,
 867         .periods_max =          1024,
 868         .fifo_size =              0
 869 };
 870 
 871 
 872 
 873 static int snd_usX2Y_pcm_open(struct snd_pcm_substream *substream)
 874 {
 875         struct snd_usX2Y_substream      *subs = ((struct snd_usX2Y_substream **)
 876                                          snd_pcm_substream_chip(substream))[substream->stream];
 877         struct snd_pcm_runtime  *runtime = substream->runtime;
 878 
 879         if (subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
 880                 return -EBUSY;
 881 
 882         runtime->hw = snd_usX2Y_2c;
 883         runtime->private_data = subs;
 884         subs->pcm_substream = substream;
 885         snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
 886         return 0;
 887 }
 888 
 889 
 890 
 891 static int snd_usX2Y_pcm_close(struct snd_pcm_substream *substream)
 892 {
 893         struct snd_pcm_runtime *runtime = substream->runtime;
 894         struct snd_usX2Y_substream *subs = runtime->private_data;
 895 
 896         subs->pcm_substream = NULL;
 897 
 898         return 0;
 899 }
 900 
 901 
 902 static const struct snd_pcm_ops snd_usX2Y_pcm_ops =
 903 {
 904         .open =         snd_usX2Y_pcm_open,
 905         .close =        snd_usX2Y_pcm_close,
 906         .ioctl =        snd_pcm_lib_ioctl,
 907         .hw_params =    snd_usX2Y_pcm_hw_params,
 908         .hw_free =      snd_usX2Y_pcm_hw_free,
 909         .prepare =      snd_usX2Y_pcm_prepare,
 910         .trigger =      snd_usX2Y_pcm_trigger,
 911         .pointer =      snd_usX2Y_pcm_pointer,
 912 };
 913 
 914 
 915 /*
 916  * free a usb stream instance
 917  */
 918 static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream)
 919 {
 920         kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]);
 921         usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL;
 922 
 923         kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]);
 924         usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL;
 925 }
 926 
 927 static void snd_usX2Y_pcm_private_free(struct snd_pcm *pcm)
 928 {
 929         struct snd_usX2Y_substream **usX2Y_stream = pcm->private_data;
 930         if (usX2Y_stream)
 931                 usX2Y_audio_stream_free(usX2Y_stream);
 932 }
 933 
 934 static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint, int capture_endpoint)
 935 {
 936         struct snd_pcm *pcm;
 937         int err, i;
 938         struct snd_usX2Y_substream **usX2Y_substream =
 939                 usX2Y(card)->subs + 2 * usX2Y(card)->pcm_devs;
 940 
 941         for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
 942              i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
 943                 usX2Y_substream[i] = kzalloc(sizeof(struct snd_usX2Y_substream), GFP_KERNEL);
 944                 if (!usX2Y_substream[i])
 945                         return -ENOMEM;
 946 
 947                 usX2Y_substream[i]->usX2Y = usX2Y(card);
 948         }
 949 
 950         if (playback_endpoint)
 951                 usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
 952         usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;
 953 
 954         err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->pcm_devs,
 955                           playback_endpoint ? 1 : 0, 1,
 956                           &pcm);
 957         if (err < 0) {
 958                 usX2Y_audio_stream_free(usX2Y_substream);
 959                 return err;
 960         }
 961 
 962         if (playback_endpoint)
 963                 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_pcm_ops);
 964         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_pcm_ops);
 965 
 966         pcm->private_data = usX2Y_substream;
 967         pcm->private_free = snd_usX2Y_pcm_private_free;
 968         pcm->info_flags = 0;
 969 
 970         sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->pcm_devs);
 971 
 972         if (playback_endpoint) {
 973                 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
 974                                               SNDRV_DMA_TYPE_CONTINUOUS,
 975                                               snd_dma_continuous_data(GFP_KERNEL),
 976                                               64*1024, 128*1024);
 977         }
 978 
 979         snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
 980                                       SNDRV_DMA_TYPE_CONTINUOUS,
 981                                       snd_dma_continuous_data(GFP_KERNEL),
 982                                       64*1024, 128*1024);
 983         usX2Y(card)->pcm_devs++;
 984 
 985         return 0;
 986 }
 987 
 988 /*
 989  * create a chip instance and set its names.
 990  */
 991 int usX2Y_audio_create(struct snd_card *card)
 992 {
 993         int err = 0;
 994         
 995         INIT_LIST_HEAD(&usX2Y(card)->pcm_list);
 996 
 997         if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
 998                 return err;
 999         if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) == USB_ID_US428)
1000              if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
1001                      return err;
1002         if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) != USB_ID_US122)
1003                 err = usX2Y_rate_set(usX2Y(card), 44100);       // Lets us428 recognize output-volume settings, disturbs us122.
1004         return err;
1005 }

/* [<][>][^][v][top][bottom][index][help] */