~ubuntu-branches/ubuntu/precise/alsa-driver/precise

« back to all changes in this revision

Viewing changes to alsa-kernel/usb/6fire/pcm.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2011-02-21 18:06:40 UTC
  • mfrom: (1.1.15 upstream)
  • Revision ID: james.westby@ubuntu.com-20110221180640-a8p2yxtvgf7xbxub
Tags: 1.0.24+dfsg-0ubuntu1
* New upstream release
* Refreshed patches:
  - distinguish_kernel_makefile_and_source_dirs.patch
  - debian_dfsg_configure.patch
* debian/control: Update Vcs-bzr field to point to new branch location

Show diffs side-by-side

added added

removed removed

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