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