root/sound/usb/6fire/pcm.c

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

DEFINITIONS

This source file includes following definitions.
  1. usb6fire_pcm_set_rate
  2. usb6fire_pcm_get_substream
  3. usb6fire_pcm_stream_stop
  4. usb6fire_pcm_stream_start
  5. usb6fire_pcm_capture
  6. usb6fire_pcm_playback
  7. usb6fire_pcm_in_urb_handler
  8. usb6fire_pcm_out_urb_handler
  9. usb6fire_pcm_open
  10. usb6fire_pcm_close
  11. usb6fire_pcm_hw_params
  12. usb6fire_pcm_hw_free
  13. usb6fire_pcm_prepare
  14. usb6fire_pcm_trigger
  15. usb6fire_pcm_pointer
  16. usb6fire_pcm_init_urb
  17. usb6fire_pcm_buffers_init
  18. usb6fire_pcm_buffers_destroy
  19. usb6fire_pcm_init
  20. usb6fire_pcm_abort
  21. usb6fire_pcm_destroy

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Linux driver for TerraTec DMX 6Fire USB
   4  *
   5  * PCM driver
   6  *
   7  * Author:      Torsten Schenk <torsten.schenk@zoho.com>
   8  * Created:     Jan 01, 2011
   9  * Copyright:   (C) Torsten Schenk
  10  */
  11 
  12 #include "pcm.h"
  13 #include "chip.h"
  14 #include "comm.h"
  15 #include "control.h"
  16 
  17 enum {
  18         OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4
  19 };
  20 
  21 /* keep next two synced with
  22  * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE
  23  * and CONTROL_RATE_XXX in control.h */
  24 static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 };
  25 static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 };
  26 static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
  27 static const int rates_alsaid[] = {
  28         SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000,
  29         SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000,
  30         SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 };
  31 
  32 enum { /* settings for pcm */
  33         OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024
  34 };
  35 
  36 enum { /* pcm streaming states */
  37         STREAM_DISABLED, /* no pcm streaming */
  38         STREAM_STARTING, /* pcm streaming requested, waiting to become ready */
  39         STREAM_RUNNING, /* pcm streaming running */
  40         STREAM_STOPPING
  41 };
  42 
  43 static const struct snd_pcm_hardware pcm_hw = {
  44         .info = SNDRV_PCM_INFO_MMAP |
  45                 SNDRV_PCM_INFO_INTERLEAVED |
  46                 SNDRV_PCM_INFO_BLOCK_TRANSFER |
  47                 SNDRV_PCM_INFO_MMAP_VALID |
  48                 SNDRV_PCM_INFO_BATCH,
  49 
  50         .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
  51 
  52         .rates = SNDRV_PCM_RATE_44100 |
  53                 SNDRV_PCM_RATE_48000 |
  54                 SNDRV_PCM_RATE_88200 |
  55                 SNDRV_PCM_RATE_96000 |
  56                 SNDRV_PCM_RATE_176400 |
  57                 SNDRV_PCM_RATE_192000,
  58 
  59         .rate_min = 44100,
  60         .rate_max = 192000,
  61         .channels_min = 1,
  62         .channels_max = 0, /* set in pcm_open, depending on capture/playback */
  63         .buffer_bytes_max = MAX_BUFSIZE,
  64         .period_bytes_min = PCM_N_PACKETS_PER_URB * (PCM_MAX_PACKET_SIZE - 4),
  65         .period_bytes_max = MAX_BUFSIZE,
  66         .periods_min = 2,
  67         .periods_max = 1024
  68 };
  69 
  70 static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)
  71 {
  72         int ret;
  73         struct control_runtime *ctrl_rt = rt->chip->control;
  74 
  75         ctrl_rt->usb_streaming = false;
  76         ret = ctrl_rt->update_streaming(ctrl_rt);
  77         if (ret < 0) {
  78                 dev_err(&rt->chip->dev->dev,
  79                         "error stopping streaming while setting samplerate %d.\n",
  80                         rates[rt->rate]);
  81                 return ret;
  82         }
  83 
  84         ret = ctrl_rt->set_rate(ctrl_rt, rt->rate);
  85         if (ret < 0) {
  86                 dev_err(&rt->chip->dev->dev,
  87                         "error setting samplerate %d.\n",
  88                         rates[rt->rate]);
  89                 return ret;
  90         }
  91 
  92         ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS,
  93                         false, false);
  94         if (ret < 0) {
  95                 dev_err(&rt->chip->dev->dev,
  96                         "error initializing channels while setting samplerate %d.\n",
  97                         rates[rt->rate]);
  98                 return ret;
  99         }
 100 
 101         ctrl_rt->usb_streaming = true;
 102         ret = ctrl_rt->update_streaming(ctrl_rt);
 103         if (ret < 0) {
 104                 dev_err(&rt->chip->dev->dev,
 105                         "error starting streaming while setting samplerate %d.\n",
 106                         rates[rt->rate]);
 107                 return ret;
 108         }
 109 
 110         rt->in_n_analog = IN_N_CHANNELS;
 111         rt->out_n_analog = OUT_N_CHANNELS;
 112         rt->in_packet_size = rates_in_packet_size[rt->rate];
 113         rt->out_packet_size = rates_out_packet_size[rt->rate];
 114         return 0;
 115 }
 116 
 117 static struct pcm_substream *usb6fire_pcm_get_substream(
 118                 struct snd_pcm_substream *alsa_sub)
 119 {
 120         struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 121 
 122         if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
 123                 return &rt->playback;
 124         else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE)
 125                 return &rt->capture;
 126         dev_err(&rt->chip->dev->dev, "error getting pcm substream slot.\n");
 127         return NULL;
 128 }
 129 
 130 /* call with stream_mutex locked */
 131 static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
 132 {
 133         int i;
 134         struct control_runtime *ctrl_rt = rt->chip->control;
 135 
 136         if (rt->stream_state != STREAM_DISABLED) {
 137 
 138                 rt->stream_state = STREAM_STOPPING;
 139 
 140                 for (i = 0; i < PCM_N_URBS; i++) {
 141                         usb_kill_urb(&rt->in_urbs[i].instance);
 142                         usb_kill_urb(&rt->out_urbs[i].instance);
 143                 }
 144                 ctrl_rt->usb_streaming = false;
 145                 ctrl_rt->update_streaming(ctrl_rt);
 146                 rt->stream_state = STREAM_DISABLED;
 147         }
 148 }
 149 
 150 /* call with stream_mutex locked */
 151 static int usb6fire_pcm_stream_start(struct pcm_runtime *rt)
 152 {
 153         int ret;
 154         int i;
 155         int k;
 156         struct usb_iso_packet_descriptor *packet;
 157 
 158         if (rt->stream_state == STREAM_DISABLED) {
 159                 /* submit our in urbs */
 160                 rt->stream_wait_cond = false;
 161                 rt->stream_state = STREAM_STARTING;
 162                 for (i = 0; i < PCM_N_URBS; i++) {
 163                         for (k = 0; k < PCM_N_PACKETS_PER_URB; k++) {
 164                                 packet = &rt->in_urbs[i].packets[k];
 165                                 packet->offset = k * rt->in_packet_size;
 166                                 packet->length = rt->in_packet_size;
 167                                 packet->actual_length = 0;
 168                                 packet->status = 0;
 169                         }
 170                         ret = usb_submit_urb(&rt->in_urbs[i].instance,
 171                                         GFP_ATOMIC);
 172                         if (ret) {
 173                                 usb6fire_pcm_stream_stop(rt);
 174                                 return ret;
 175                         }
 176                 }
 177 
 178                 /* wait for first out urb to return (sent in in urb handler) */
 179                 wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond,
 180                                 HZ);
 181                 if (rt->stream_wait_cond)
 182                         rt->stream_state = STREAM_RUNNING;
 183                 else {
 184                         usb6fire_pcm_stream_stop(rt);
 185                         return -EIO;
 186                 }
 187         }
 188         return 0;
 189 }
 190 
 191 /* call with substream locked */
 192 static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
 193 {
 194         int i;
 195         int frame;
 196         int frame_count;
 197         unsigned int total_length = 0;
 198         struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
 199         struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
 200         u32 *src = NULL;
 201         u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
 202                         * (alsa_rt->frame_bits >> 3));
 203         u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
 204                         * (alsa_rt->frame_bits >> 3));
 205         int bytes_per_frame = alsa_rt->channels << 2;
 206 
 207         for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
 208                 /* at least 4 header bytes for valid packet.
 209                  * after that: 32 bits per sample for analog channels */
 210                 if (urb->packets[i].actual_length > 4)
 211                         frame_count = (urb->packets[i].actual_length - 4)
 212                                         / (rt->in_n_analog << 2);
 213                 else
 214                         frame_count = 0;
 215 
 216                 if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
 217                         src = (u32 *) (urb->buffer + total_length);
 218                 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
 219                         src = (u32 *) (urb->buffer - 1 + total_length);
 220                 else
 221                         return;
 222                 src++; /* skip leading 4 bytes of every packet */
 223                 total_length += urb->packets[i].length;
 224                 for (frame = 0; frame < frame_count; frame++) {
 225                         memcpy(dest, src, bytes_per_frame);
 226                         dest += alsa_rt->channels;
 227                         src += rt->in_n_analog;
 228                         sub->dma_off++;
 229                         sub->period_off++;
 230                         if (dest == dest_end) {
 231                                 sub->dma_off = 0;
 232                                 dest = (u32 *) alsa_rt->dma_area;
 233                         }
 234                 }
 235         }
 236 }
 237 
 238 /* call with substream locked */
 239 static void usb6fire_pcm_playback(struct pcm_substream *sub,
 240                 struct pcm_urb *urb)
 241 {
 242         int i;
 243         int frame;
 244         int frame_count;
 245         struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
 246         struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
 247         u32 *src = (u32 *) (alsa_rt->dma_area + sub->dma_off
 248                         * (alsa_rt->frame_bits >> 3));
 249         u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
 250                         * (alsa_rt->frame_bits >> 3));
 251         u32 *dest;
 252         int bytes_per_frame = alsa_rt->channels << 2;
 253 
 254         if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
 255                 dest = (u32 *) (urb->buffer - 1);
 256         else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
 257                 dest = (u32 *) (urb->buffer);
 258         else {
 259                 dev_err(&rt->chip->dev->dev, "Unknown sample format.");
 260                 return;
 261         }
 262 
 263         for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
 264                 /* at least 4 header bytes for valid packet.
 265                  * after that: 32 bits per sample for analog channels */
 266                 if (urb->packets[i].length > 4)
 267                         frame_count = (urb->packets[i].length - 4)
 268                                         / (rt->out_n_analog << 2);
 269                 else
 270                         frame_count = 0;
 271                 dest++; /* skip leading 4 bytes of every frame */
 272                 for (frame = 0; frame < frame_count; frame++) {
 273                         memcpy(dest, src, bytes_per_frame);
 274                         src += alsa_rt->channels;
 275                         dest += rt->out_n_analog;
 276                         sub->dma_off++;
 277                         sub->period_off++;
 278                         if (src == src_end) {
 279                                 src = (u32 *) alsa_rt->dma_area;
 280                                 sub->dma_off = 0;
 281                         }
 282                 }
 283         }
 284 }
 285 
 286 static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 287 {
 288         struct pcm_urb *in_urb = usb_urb->context;
 289         struct pcm_urb *out_urb = in_urb->peer;
 290         struct pcm_runtime *rt = in_urb->chip->pcm;
 291         struct pcm_substream *sub;
 292         unsigned long flags;
 293         int total_length = 0;
 294         int frame_count;
 295         int frame;
 296         int channel;
 297         int i;
 298         u8 *dest;
 299 
 300         if (usb_urb->status || rt->panic || rt->stream_state == STREAM_STOPPING)
 301                 return;
 302         for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
 303                 if (in_urb->packets[i].status) {
 304                         rt->panic = true;
 305                         return;
 306                 }
 307 
 308         if (rt->stream_state == STREAM_DISABLED) {
 309                 dev_err(&rt->chip->dev->dev,
 310                         "internal error: stream disabled in in-urb handler.\n");
 311                 return;
 312         }
 313 
 314         /* receive our capture data */
 315         sub = &rt->capture;
 316         spin_lock_irqsave(&sub->lock, flags);
 317         if (sub->active) {
 318                 usb6fire_pcm_capture(sub, in_urb);
 319                 if (sub->period_off >= sub->instance->runtime->period_size) {
 320                         sub->period_off %= sub->instance->runtime->period_size;
 321                         spin_unlock_irqrestore(&sub->lock, flags);
 322                         snd_pcm_period_elapsed(sub->instance);
 323                 } else
 324                         spin_unlock_irqrestore(&sub->lock, flags);
 325         } else
 326                 spin_unlock_irqrestore(&sub->lock, flags);
 327 
 328         /* setup out urb structure */
 329         for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
 330                 out_urb->packets[i].offset = total_length;
 331                 out_urb->packets[i].length = (in_urb->packets[i].actual_length
 332                                 - 4) / (rt->in_n_analog << 2)
 333                                 * (rt->out_n_analog << 2) + 4;
 334                 out_urb->packets[i].status = 0;
 335                 total_length += out_urb->packets[i].length;
 336         }
 337         memset(out_urb->buffer, 0, total_length);
 338 
 339         /* now send our playback data (if a free out urb was found) */
 340         sub = &rt->playback;
 341         spin_lock_irqsave(&sub->lock, flags);
 342         if (sub->active) {
 343                 usb6fire_pcm_playback(sub, out_urb);
 344                 if (sub->period_off >= sub->instance->runtime->period_size) {
 345                         sub->period_off %= sub->instance->runtime->period_size;
 346                         spin_unlock_irqrestore(&sub->lock, flags);
 347                         snd_pcm_period_elapsed(sub->instance);
 348                 } else
 349                         spin_unlock_irqrestore(&sub->lock, flags);
 350         } else
 351                 spin_unlock_irqrestore(&sub->lock, flags);
 352 
 353         /* setup the 4th byte of each sample (0x40 for analog channels) */
 354         dest = out_urb->buffer;
 355         for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
 356                 if (out_urb->packets[i].length >= 4) {
 357                         frame_count = (out_urb->packets[i].length - 4)
 358                                         / (rt->out_n_analog << 2);
 359                         *(dest++) = 0xaa;
 360                         *(dest++) = 0xaa;
 361                         *(dest++) = frame_count;
 362                         *(dest++) = 0x00;
 363                         for (frame = 0; frame < frame_count; frame++)
 364                                 for (channel = 0;
 365                                                 channel < rt->out_n_analog;
 366                                                 channel++) {
 367                                         dest += 3; /* skip sample data */
 368                                         *(dest++) = 0x40;
 369                                 }
 370                 }
 371         usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
 372         usb_submit_urb(&in_urb->instance, GFP_ATOMIC);
 373 }
 374 
 375 static void usb6fire_pcm_out_urb_handler(struct urb *usb_urb)
 376 {
 377         struct pcm_urb *urb = usb_urb->context;
 378         struct pcm_runtime *rt = urb->chip->pcm;
 379 
 380         if (rt->stream_state == STREAM_STARTING) {
 381                 rt->stream_wait_cond = true;
 382                 wake_up(&rt->stream_wait_queue);
 383         }
 384 }
 385 
 386 static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
 387 {
 388         struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 389         struct pcm_substream *sub = NULL;
 390         struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
 391 
 392         if (rt->panic)
 393                 return -EPIPE;
 394 
 395         mutex_lock(&rt->stream_mutex);
 396         alsa_rt->hw = pcm_hw;
 397 
 398         if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 399                 if (rt->rate < ARRAY_SIZE(rates))
 400                         alsa_rt->hw.rates = rates_alsaid[rt->rate];
 401                 alsa_rt->hw.channels_max = OUT_N_CHANNELS;
 402                 sub = &rt->playback;
 403         } else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) {
 404                 if (rt->rate < ARRAY_SIZE(rates))
 405                         alsa_rt->hw.rates = rates_alsaid[rt->rate];
 406                 alsa_rt->hw.channels_max = IN_N_CHANNELS;
 407                 sub = &rt->capture;
 408         }
 409 
 410         if (!sub) {
 411                 mutex_unlock(&rt->stream_mutex);
 412                 dev_err(&rt->chip->dev->dev, "invalid stream type.\n");
 413                 return -EINVAL;
 414         }
 415 
 416         sub->instance = alsa_sub;
 417         sub->active = false;
 418         mutex_unlock(&rt->stream_mutex);
 419         return 0;
 420 }
 421 
 422 static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
 423 {
 424         struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 425         struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
 426         unsigned long flags;
 427 
 428         if (rt->panic)
 429                 return 0;
 430 
 431         mutex_lock(&rt->stream_mutex);
 432         if (sub) {
 433                 /* deactivate substream */
 434                 spin_lock_irqsave(&sub->lock, flags);
 435                 sub->instance = NULL;
 436                 sub->active = false;
 437                 spin_unlock_irqrestore(&sub->lock, flags);
 438 
 439                 /* all substreams closed? if so, stop streaming */
 440                 if (!rt->playback.instance && !rt->capture.instance) {
 441                         usb6fire_pcm_stream_stop(rt);
 442                         rt->rate = ARRAY_SIZE(rates);
 443                 }
 444         }
 445         mutex_unlock(&rt->stream_mutex);
 446         return 0;
 447 }
 448 
 449 static int usb6fire_pcm_hw_params(struct snd_pcm_substream *alsa_sub,
 450                 struct snd_pcm_hw_params *hw_params)
 451 {
 452         return snd_pcm_lib_alloc_vmalloc_buffer(alsa_sub,
 453                                                 params_buffer_bytes(hw_params));
 454 }
 455 
 456 static int usb6fire_pcm_hw_free(struct snd_pcm_substream *alsa_sub)
 457 {
 458         return snd_pcm_lib_free_vmalloc_buffer(alsa_sub);
 459 }
 460 
 461 static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
 462 {
 463         struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 464         struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
 465         struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
 466         int ret;
 467 
 468         if (rt->panic)
 469                 return -EPIPE;
 470         if (!sub)
 471                 return -ENODEV;
 472 
 473         mutex_lock(&rt->stream_mutex);
 474         sub->dma_off = 0;
 475         sub->period_off = 0;
 476 
 477         if (rt->stream_state == STREAM_DISABLED) {
 478                 for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++)
 479                         if (alsa_rt->rate == rates[rt->rate])
 480                                 break;
 481                 if (rt->rate == ARRAY_SIZE(rates)) {
 482                         mutex_unlock(&rt->stream_mutex);
 483                         dev_err(&rt->chip->dev->dev,
 484                                 "invalid rate %d in prepare.\n",
 485                                 alsa_rt->rate);
 486                         return -EINVAL;
 487                 }
 488 
 489                 ret = usb6fire_pcm_set_rate(rt);
 490                 if (ret) {
 491                         mutex_unlock(&rt->stream_mutex);
 492                         return ret;
 493                 }
 494                 ret = usb6fire_pcm_stream_start(rt);
 495                 if (ret) {
 496                         mutex_unlock(&rt->stream_mutex);
 497                         dev_err(&rt->chip->dev->dev,
 498                                 "could not start pcm stream.\n");
 499                         return ret;
 500                 }
 501         }
 502         mutex_unlock(&rt->stream_mutex);
 503         return 0;
 504 }
 505 
 506 static int usb6fire_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
 507 {
 508         struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
 509         struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 510         unsigned long flags;
 511 
 512         if (rt->panic)
 513                 return -EPIPE;
 514         if (!sub)
 515                 return -ENODEV;
 516 
 517         switch (cmd) {
 518         case SNDRV_PCM_TRIGGER_START:
 519         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 520                 spin_lock_irqsave(&sub->lock, flags);
 521                 sub->active = true;
 522                 spin_unlock_irqrestore(&sub->lock, flags);
 523                 return 0;
 524 
 525         case SNDRV_PCM_TRIGGER_STOP:
 526         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 527                 spin_lock_irqsave(&sub->lock, flags);
 528                 sub->active = false;
 529                 spin_unlock_irqrestore(&sub->lock, flags);
 530                 return 0;
 531 
 532         default:
 533                 return -EINVAL;
 534         }
 535 }
 536 
 537 static snd_pcm_uframes_t usb6fire_pcm_pointer(
 538                 struct snd_pcm_substream *alsa_sub)
 539 {
 540         struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
 541         struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 542         unsigned long flags;
 543         snd_pcm_uframes_t ret;
 544 
 545         if (rt->panic || !sub)
 546                 return SNDRV_PCM_POS_XRUN;
 547 
 548         spin_lock_irqsave(&sub->lock, flags);
 549         ret = sub->dma_off;
 550         spin_unlock_irqrestore(&sub->lock, flags);
 551         return ret;
 552 }
 553 
 554 static const struct snd_pcm_ops pcm_ops = {
 555         .open = usb6fire_pcm_open,
 556         .close = usb6fire_pcm_close,
 557         .ioctl = snd_pcm_lib_ioctl,
 558         .hw_params = usb6fire_pcm_hw_params,
 559         .hw_free = usb6fire_pcm_hw_free,
 560         .prepare = usb6fire_pcm_prepare,
 561         .trigger = usb6fire_pcm_trigger,
 562         .pointer = usb6fire_pcm_pointer,
 563         .page = snd_pcm_lib_get_vmalloc_page,
 564 };
 565 
 566 static void usb6fire_pcm_init_urb(struct pcm_urb *urb,
 567                                   struct sfire_chip *chip, bool in, int ep,
 568                                   void (*handler)(struct urb *))
 569 {
 570         urb->chip = chip;
 571         usb_init_urb(&urb->instance);
 572         urb->instance.transfer_buffer = urb->buffer;
 573         urb->instance.transfer_buffer_length =
 574                         PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE;
 575         urb->instance.dev = chip->dev;
 576         urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep)
 577                         : usb_sndisocpipe(chip->dev, ep);
 578         urb->instance.interval = 1;
 579         urb->instance.complete = handler;
 580         urb->instance.context = urb;
 581         urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
 582 }
 583 
 584 static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt)
 585 {
 586         int i;
 587 
 588         for (i = 0; i < PCM_N_URBS; i++) {
 589                 rt->out_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE,
 590                                                  PCM_N_PACKETS_PER_URB,
 591                                                  GFP_KERNEL);
 592                 if (!rt->out_urbs[i].buffer)
 593                         return -ENOMEM;
 594                 rt->in_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE,
 595                                                 PCM_N_PACKETS_PER_URB,
 596                                                 GFP_KERNEL);
 597                 if (!rt->in_urbs[i].buffer)
 598                         return -ENOMEM;
 599         }
 600         return 0;
 601 }
 602 
 603 static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt)
 604 {
 605         int i;
 606 
 607         for (i = 0; i < PCM_N_URBS; i++) {
 608                 kfree(rt->out_urbs[i].buffer);
 609                 kfree(rt->in_urbs[i].buffer);
 610         }
 611 }
 612 
 613 int usb6fire_pcm_init(struct sfire_chip *chip)
 614 {
 615         int i;
 616         int ret;
 617         struct snd_pcm *pcm;
 618         struct pcm_runtime *rt =
 619                         kzalloc(sizeof(struct pcm_runtime), GFP_KERNEL);
 620 
 621         if (!rt)
 622                 return -ENOMEM;
 623 
 624         ret = usb6fire_pcm_buffers_init(rt);
 625         if (ret) {
 626                 usb6fire_pcm_buffers_destroy(rt);
 627                 kfree(rt);
 628                 return ret;
 629         }
 630 
 631         rt->chip = chip;
 632         rt->stream_state = STREAM_DISABLED;
 633         rt->rate = ARRAY_SIZE(rates);
 634         init_waitqueue_head(&rt->stream_wait_queue);
 635         mutex_init(&rt->stream_mutex);
 636 
 637         spin_lock_init(&rt->playback.lock);
 638         spin_lock_init(&rt->capture.lock);
 639 
 640         for (i = 0; i < PCM_N_URBS; i++) {
 641                 usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP,
 642                                 usb6fire_pcm_in_urb_handler);
 643                 usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP,
 644                                 usb6fire_pcm_out_urb_handler);
 645 
 646                 rt->in_urbs[i].peer = &rt->out_urbs[i];
 647                 rt->out_urbs[i].peer = &rt->in_urbs[i];
 648         }
 649 
 650         ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
 651         if (ret < 0) {
 652                 usb6fire_pcm_buffers_destroy(rt);
 653                 kfree(rt);
 654                 dev_err(&chip->dev->dev, "cannot create pcm instance.\n");
 655                 return ret;
 656         }
 657 
 658         pcm->private_data = rt;
 659         strcpy(pcm->name, "DMX 6Fire USB");
 660         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
 661         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops);
 662 
 663         if (ret) {
 664                 usb6fire_pcm_buffers_destroy(rt);
 665                 kfree(rt);
 666                 dev_err(&chip->dev->dev,
 667                         "error preallocating pcm buffers.\n");
 668                 return ret;
 669         }
 670         rt->instance = pcm;
 671 
 672         chip->pcm = rt;
 673         return 0;
 674 }
 675 
 676 void usb6fire_pcm_abort(struct sfire_chip *chip)
 677 {
 678         struct pcm_runtime *rt = chip->pcm;
 679         int i;
 680 
 681         if (rt) {
 682                 rt->panic = true;
 683 
 684                 if (rt->playback.instance)
 685                         snd_pcm_stop_xrun(rt->playback.instance);
 686 
 687                 if (rt->capture.instance)
 688                         snd_pcm_stop_xrun(rt->capture.instance);
 689 
 690                 for (i = 0; i < PCM_N_URBS; i++) {
 691                         usb_poison_urb(&rt->in_urbs[i].instance);
 692                         usb_poison_urb(&rt->out_urbs[i].instance);
 693                 }
 694 
 695         }
 696 }
 697 
 698 void usb6fire_pcm_destroy(struct sfire_chip *chip)
 699 {
 700         struct pcm_runtime *rt = chip->pcm;
 701 
 702         usb6fire_pcm_buffers_destroy(rt);
 703         kfree(rt);
 704         chip->pcm = NULL;
 705 }

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