OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [sound/] [emu10k1/] [audio.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 **********************************************************************
3
 *     audio.c -- /dev/dsp interface for emu10k1 driver
4
 *     Copyright 1999, 2000 Creative Labs, Inc.
5
 *
6
 **********************************************************************
7
 *
8
 *     Date                 Author          Summary of changes
9
 *     ----                 ------          ------------------
10
 *     October 20, 1999     Bertrand Lee    base code release
11
 *     November 2, 1999     Alan Cox        cleaned up types/leaks
12
 *
13
 **********************************************************************
14
 *
15
 *     This program is free software; you can redistribute it and/or
16
 *     modify it under the terms of the GNU General Public License as
17
 *     published by the Free Software Foundation; either version 2 of
18
 *     the License, or (at your option) any later version.
19
 *
20
 *     This program is distributed in the hope that it will be useful,
21
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 *     GNU General Public License for more details.
24
 *
25
 *     You should have received a copy of the GNU General Public
26
 *     License along with this program; if not, write to the Free
27
 *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
28
 *     USA.
29
 *
30
 **********************************************************************
31
 */
32
 
33
#define __NO_VERSION__
34
#include <linux/module.h>
35
#include <linux/poll.h>
36
#include <linux/slab.h>
37
#include <linux/version.h>
38
#include <linux/bitops.h>
39
#include <asm/io.h>
40
#include <linux/sched.h>
41
#include <linux/smp_lock.h>
42
#include <linux/wrapper.h>
43
 
44
 
45
#include "hwaccess.h"
46
#include "cardwo.h"
47
#include "cardwi.h"
48
#include "recmgr.h"
49
#include "irqmgr.h"
50
#include "audio.h"
51
#include "8010.h"
52
 
53
static void calculate_ofrag(struct woinst *);
54
static void calculate_ifrag(struct wiinst *);
55
 
56
/* Audio file operations */
57
static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
58
{
59
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
60
        struct wiinst *wiinst = wave_dev->wiinst;
61
        ssize_t ret = 0;
62
        unsigned long flags;
63
 
64
        DPD(3, "emu10k1_audio_read(), buffer=%p, count=%d\n", buffer, (u32) count);
65
 
66
        if (ppos != &file->f_pos)
67
                return -ESPIPE;
68
 
69
        if (!access_ok(VERIFY_WRITE, buffer, count))
70
                return -EFAULT;
71
 
72
        spin_lock_irqsave(&wiinst->lock, flags);
73
 
74
        if (wiinst->mmapped) {
75
                spin_unlock_irqrestore(&wiinst->lock, flags);
76
                return -ENXIO;
77
        }
78
 
79
        if (wiinst->state == WAVE_STATE_CLOSED) {
80
                calculate_ifrag(wiinst);
81
 
82
                while (emu10k1_wavein_open(wave_dev) < 0) {
83
                        spin_unlock_irqrestore(&wiinst->lock, flags);
84
 
85
                        if (file->f_flags & O_NONBLOCK)
86
                                return -EAGAIN;
87
 
88
                        interruptible_sleep_on(&wave_dev->card->open_wait);
89
 
90
                        if (signal_pending(current))
91
                                return -ERESTARTSYS;
92
 
93
                        spin_lock_irqsave(&wiinst->lock, flags);
94
                }
95
        }
96
 
97
        spin_unlock_irqrestore(&wiinst->lock, flags);
98
 
99
        while (count > 0) {
100
                u32 bytestocopy;
101
 
102
                spin_lock_irqsave(&wiinst->lock, flags);
103
 
104
                if (!(wiinst->state & WAVE_STATE_STARTED)
105
                    && (wave_dev->enablebits & PCM_ENABLE_INPUT))
106
                        emu10k1_wavein_start(wave_dev);
107
 
108
                emu10k1_wavein_update(wave_dev->card, wiinst);
109
                emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
110
 
111
                spin_unlock_irqrestore(&wiinst->lock, flags);
112
 
113
                DPD(3, "bytestocopy --> %d\n", bytestocopy);
114
 
115
                if ((bytestocopy >= wiinst->buffer.fragment_size)
116
                    || (bytestocopy >= count)) {
117
                        bytestocopy = min_t(u32, bytestocopy, count);
118
 
119
                        emu10k1_wavein_xferdata(wiinst, (u8 *) buffer, &bytestocopy);
120
 
121
                        count -= bytestocopy;
122
                        buffer += bytestocopy;
123
                        ret += bytestocopy;
124
                }
125
 
126
                if (count > 0) {
127
                        if ((file->f_flags & O_NONBLOCK)
128
                            || (!(wave_dev->enablebits & PCM_ENABLE_INPUT)))
129
                                return (ret ? ret : -EAGAIN);
130
 
131
                        interruptible_sleep_on(&wiinst->wait_queue);
132
 
133
                        if (signal_pending(current))
134
                                return (ret ? ret : -ERESTARTSYS);
135
 
136
                }
137
        }
138
 
139
        DPD(3, "bytes copied -> %d\n", (u32) ret);
140
 
141
        return ret;
142
}
143
 
144
static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
145
{
146
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
147
        struct woinst *woinst = wave_dev->woinst;
148
        ssize_t ret;
149
        unsigned long flags;
150
 
151
        DPD(3, "emu10k1_audio_write(), buffer=%p, count=%d\n", buffer, (u32) count);
152
 
153
        if (ppos != &file->f_pos)
154
                return -ESPIPE;
155
 
156
        if (!access_ok(VERIFY_READ, buffer, count))
157
                return -EFAULT;
158
 
159
        spin_lock_irqsave(&woinst->lock, flags);
160
 
161
        if (woinst->mmapped) {
162
                spin_unlock_irqrestore(&woinst->lock, flags);
163
                return -ENXIO;
164
        }
165
 
166
        if (woinst->format.passthrough) {
167
                int r;
168
 
169
                woinst->buffer.ossfragshift = PT_BLOCKSIZE_LOG2;
170
                woinst->buffer.numfrags = PT_BLOCKCOUNT;
171
                calculate_ofrag(woinst);
172
 
173
                r = emu10k1_pt_write(file, buffer, count);
174
                spin_unlock_irqrestore(&woinst->lock, flags);
175
                return r;
176
        }
177
 
178
        if (woinst->state == WAVE_STATE_CLOSED) {
179
                calculate_ofrag(woinst);
180
 
181
                while (emu10k1_waveout_open(wave_dev) < 0) {
182
                        spin_unlock_irqrestore(&woinst->lock, flags);
183
 
184
                        if (file->f_flags & O_NONBLOCK)
185
                                return -EAGAIN;
186
 
187
                        interruptible_sleep_on(&wave_dev->card->open_wait);
188
 
189
                        if (signal_pending(current))
190
                                return -ERESTARTSYS;
191
 
192
                        spin_lock_irqsave(&woinst->lock, flags);
193
                }
194
        }
195
 
196
        spin_unlock_irqrestore(&woinst->lock, flags);
197
 
198
        ret = 0;
199
        if (count % woinst->format.bytespersample)
200
                return -EINVAL;
201
 
202
        count /= woinst->num_voices;
203
 
204
        while (count > 0) {
205
                u32 bytestocopy;
206
 
207
                spin_lock_irqsave(&woinst->lock, flags);
208
                emu10k1_waveout_update(woinst);
209
                emu10k1_waveout_getxfersize(woinst, &bytestocopy);
210
                spin_unlock_irqrestore(&woinst->lock, flags);
211
 
212
                DPD(3, "bytestocopy --> %d\n", bytestocopy);
213
 
214
                if ((bytestocopy >= woinst->buffer.fragment_size)
215
                    || (bytestocopy >= count)) {
216
 
217
                        bytestocopy = min_t(u32, bytestocopy, count);
218
 
219
                        emu10k1_waveout_xferdata(woinst, (u8 *) buffer, &bytestocopy);
220
 
221
                        count -= bytestocopy;
222
                        buffer += bytestocopy * woinst->num_voices;
223
                        ret += bytestocopy * woinst->num_voices;
224
 
225
                        spin_lock_irqsave(&woinst->lock, flags);
226
                        woinst->total_copied += bytestocopy;
227
 
228
                        if (!(woinst->state & WAVE_STATE_STARTED)
229
                            && (wave_dev->enablebits & PCM_ENABLE_OUTPUT)
230
                            && (woinst->total_copied >= woinst->buffer.fragment_size))
231
                                emu10k1_waveout_start(wave_dev);
232
 
233
                        spin_unlock_irqrestore(&woinst->lock, flags);
234
                }
235
 
236
                if (count > 0) {
237
                        if ((file->f_flags & O_NONBLOCK)
238
                            || (!(wave_dev->enablebits & PCM_ENABLE_OUTPUT)))
239
                                return (ret ? ret : -EAGAIN);
240
 
241
                        interruptible_sleep_on(&woinst->wait_queue);
242
 
243
                        if (signal_pending(current))
244
                                return (ret ? ret : -ERESTARTSYS);
245
                }
246
        }
247
 
248
        DPD(3, "bytes copied -> %d\n", (u32) ret);
249
 
250
        return ret;
251
}
252
 
253
static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
254
{
255
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
256
        struct woinst *woinst = NULL;
257
        struct wiinst *wiinst = NULL;
258
        int val = 0;
259
        u32 bytestocopy;
260
        unsigned long flags;
261
 
262
        DPF(4, "emu10k1_audio_ioctl()\n");
263
 
264
        if (file->f_mode & FMODE_WRITE)
265
                woinst = wave_dev->woinst;
266
 
267
        if (file->f_mode & FMODE_READ)
268
                wiinst = wave_dev->wiinst;
269
 
270
        switch (cmd) {
271
        case OSS_GETVERSION:
272
                DPF(2, "OSS_GETVERSION:\n");
273
                return put_user(SOUND_VERSION, (int *) arg);
274
 
275
        case SNDCTL_DSP_RESET:
276
                DPF(2, "SNDCTL_DSP_RESET:\n");
277
                wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT;
278
 
279
                if (file->f_mode & FMODE_WRITE) {
280
                        spin_lock_irqsave(&woinst->lock, flags);
281
 
282
                        if (woinst->state & WAVE_STATE_OPEN) {
283
                                emu10k1_waveout_close(wave_dev);
284
                        }
285
 
286
                        woinst->mmapped = 0;
287
                        woinst->total_copied = 0;
288
                        woinst->total_played = 0;
289
                        woinst->blocks = 0;
290
 
291
                        spin_unlock_irqrestore(&woinst->lock, flags);
292
                }
293
 
294
                if (file->f_mode & FMODE_READ) {
295
                        spin_lock_irqsave(&wiinst->lock, flags);
296
 
297
                        if (wiinst->state & WAVE_STATE_OPEN) {
298
                                emu10k1_wavein_close(wave_dev);
299
                        }
300
 
301
                        wiinst->mmapped = 0;
302
                        wiinst->total_recorded = 0;
303
                        wiinst->blocks = 0;
304
                        spin_unlock_irqrestore(&wiinst->lock, flags);
305
                }
306
 
307
                break;
308
 
309
        case SNDCTL_DSP_SYNC:
310
                DPF(2, "SNDCTL_DSP_SYNC:\n");
311
 
312
                if (file->f_mode & FMODE_WRITE) {
313
 
314
                        spin_lock_irqsave(&woinst->lock, flags);
315
 
316
                        if (woinst->state & WAVE_STATE_OPEN) {
317
 
318
                                if (woinst->state & WAVE_STATE_STARTED)
319
                                        while ((woinst->total_played < woinst->total_copied)
320
                                               && !signal_pending(current)) {
321
                                                spin_unlock_irqrestore(&woinst->lock, flags);
322
                                                interruptible_sleep_on(&woinst->wait_queue);
323
                                                spin_lock_irqsave(&woinst->lock, flags);
324
                                        }
325
                                emu10k1_waveout_close(wave_dev);
326
                        }
327
 
328
                        woinst->mmapped = 0;
329
                        woinst->total_copied = 0;
330
                        woinst->total_played = 0;
331
                        woinst->blocks = 0;
332
 
333
                        spin_unlock_irqrestore(&woinst->lock, flags);
334
                }
335
 
336
                if (file->f_mode & FMODE_READ) {
337
                        spin_lock_irqsave(&wiinst->lock, flags);
338
 
339
                        if (wiinst->state & WAVE_STATE_OPEN) {
340
                                emu10k1_wavein_close(wave_dev);
341
                        }
342
 
343
                        wiinst->mmapped = 0;
344
                        wiinst->total_recorded = 0;
345
                        wiinst->blocks = 0;
346
                        spin_unlock_irqrestore(&wiinst->lock, flags);
347
                }
348
 
349
                break;
350
 
351
        case SNDCTL_DSP_SETDUPLEX:
352
                DPF(2, "SNDCTL_DSP_SETDUPLEX:\n");
353
                break;
354
 
355
        case SNDCTL_DSP_GETCAPS:
356
                DPF(2, "SNDCTL_DSP_GETCAPS:\n");
357
                return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_COPROC, (int *) arg);
358
 
359
        case SNDCTL_DSP_SPEED:
360
                DPF(2, "SNDCTL_DSP_SPEED:\n");
361
 
362
                if (get_user(val, (int *) arg))
363
                        return -EFAULT;
364
 
365
                DPD(2, "val is %d\n", val);
366
 
367
                if (val > 0) {
368
                        if (file->f_mode & FMODE_READ) {
369
                                struct wave_format format;
370
 
371
                                spin_lock_irqsave(&wiinst->lock, flags);
372
 
373
                                format = wiinst->format;
374
                                format.samplingrate = val;
375
 
376
                                if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
377
                                        spin_unlock_irqrestore(&wiinst->lock, flags);
378
                                        return -EINVAL;
379
                                }
380
 
381
                                val = wiinst->format.samplingrate;
382
 
383
                                spin_unlock_irqrestore(&wiinst->lock, flags);
384
 
385
                                DPD(2, "set recording sampling rate -> %d\n", val);
386
                        }
387
 
388
                        if (file->f_mode & FMODE_WRITE) {
389
                                struct wave_format format;
390
 
391
                                spin_lock_irqsave(&woinst->lock, flags);
392
 
393
                                format = woinst->format;
394
                                format.samplingrate = val;
395
 
396
                                if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
397
                                        spin_unlock_irqrestore(&woinst->lock, flags);
398
                                        return -EINVAL;
399
                                }
400
 
401
                                val = woinst->format.samplingrate;
402
 
403
                                spin_unlock_irqrestore(&woinst->lock, flags);
404
 
405
                                DPD(2, "set playback sampling rate -> %d\n", val);
406
                        }
407
 
408
                        return put_user(val, (int *) arg);
409
                } else {
410
                        if (file->f_mode & FMODE_READ)
411
                                val = wiinst->format.samplingrate;
412
                        else if (file->f_mode & FMODE_WRITE)
413
                                val = woinst->format.samplingrate;
414
 
415
                        return put_user(val, (int *) arg);
416
                }
417
                break;
418
 
419
        case SNDCTL_DSP_STEREO:
420
                DPF(2, "SNDCTL_DSP_STEREO:\n");
421
 
422
                if (get_user(val, (int *) arg))
423
                        return -EFAULT;
424
 
425
                DPD(2, " val is %d\n", val);
426
 
427
                if (file->f_mode & FMODE_READ) {
428
                        struct wave_format format;
429
 
430
                        spin_lock_irqsave(&wiinst->lock, flags);
431
 
432
                        format = wiinst->format;
433
                        format.channels = val ? 2 : 1;
434
 
435
                        if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
436
                                spin_unlock_irqrestore(&wiinst->lock, flags);
437
                                return -EINVAL;
438
                        }
439
 
440
                        val = wiinst->format.channels - 1;
441
 
442
                        spin_unlock_irqrestore(&wiinst->lock, flags);
443
                        DPD(2, "set recording stereo -> %d\n", val);
444
                }
445
 
446
                if (file->f_mode & FMODE_WRITE) {
447
                        struct wave_format format;
448
 
449
                        spin_lock_irqsave(&woinst->lock, flags);
450
 
451
                        format = woinst->format;
452
                        format.channels = val ? 2 : 1;
453
 
454
                        if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
455
                                spin_unlock_irqrestore(&woinst->lock, flags);
456
                                return -EINVAL;
457
                        }
458
 
459
                        val = woinst->format.channels - 1;
460
 
461
                        spin_unlock_irqrestore(&woinst->lock, flags);
462
 
463
                        DPD(2, "set playback stereo -> %d\n", val);
464
                }
465
 
466
                return put_user(val, (int *) arg);
467
 
468
                break;
469
 
470
        case SNDCTL_DSP_CHANNELS:
471
                DPF(2, "SNDCTL_DSP_CHANNELS:\n");
472
 
473
                if (get_user(val, (int *) arg))
474
                        return -EFAULT;
475
 
476
                DPD(2, " val is %d\n", val);
477
 
478
                if (val > 0) {
479
                        if (file->f_mode & FMODE_READ) {
480
                                struct wave_format format;
481
 
482
                                spin_lock_irqsave(&wiinst->lock, flags);
483
 
484
                                format = wiinst->format;
485
                                format.channels = val;
486
 
487
                                if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
488
                                        spin_unlock_irqrestore(&wiinst->lock, flags);
489
                                        return -EINVAL;
490
                                }
491
                                val = wiinst->format.channels;
492
 
493
                                spin_unlock_irqrestore(&wiinst->lock, flags);
494
                                DPD(2, "set recording number of channels -> %d\n", val);
495
                        }
496
 
497
                        if (file->f_mode & FMODE_WRITE) {
498
                                struct wave_format format;
499
 
500
                                spin_lock_irqsave(&woinst->lock, flags);
501
 
502
                                format = woinst->format;
503
                                format.channels = val;
504
 
505
                                if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
506
                                        spin_unlock_irqrestore(&woinst->lock, flags);
507
                                        return -EINVAL;
508
                                }
509
 
510
                                val = woinst->format.channels;
511
 
512
                                spin_unlock_irqrestore(&woinst->lock, flags);
513
                                DPD(2, "set playback number of channels -> %d\n", val);
514
                        }
515
 
516
                        return put_user(val, (int *) arg);
517
                } else {
518
                        if (file->f_mode & FMODE_READ)
519
                                val = wiinst->format.channels;
520
                        else if (file->f_mode & FMODE_WRITE)
521
                                val = woinst->format.channels;
522
 
523
                        return put_user(val, (int *) arg);
524
                }
525
                break;
526
 
527
        case SNDCTL_DSP_GETFMTS:
528
                DPF(2, "SNDCTL_DSP_GETFMTS:\n");
529
 
530
                if (file->f_mode & FMODE_READ)
531
                        val = AFMT_S16_LE;
532
                else if (file->f_mode & FMODE_WRITE) {
533
                        val = AFMT_S16_LE | AFMT_U8;
534
                        if (emu10k1_find_control_gpr(&wave_dev->card->mgr,
535
                                                     wave_dev->card->pt.patch_name,
536
                                                     wave_dev->card->pt.enable_gpr_name) >= 0)
537
                                val |= AFMT_AC3;
538
                }
539
                return put_user(val, (int *) arg);
540
 
541
        case SNDCTL_DSP_SETFMT: /* Same as SNDCTL_DSP_SAMPLESIZE */
542
                DPF(2, "SNDCTL_DSP_SETFMT:\n");
543
 
544
                if (get_user(val, (int *) arg))
545
                        return -EFAULT;
546
 
547
                DPD(2, " val is %d\n", val);
548
 
549
                if (val != AFMT_QUERY) {
550
                        if (file->f_mode & FMODE_READ) {
551
                                struct wave_format format;
552
 
553
                                spin_lock_irqsave(&wiinst->lock, flags);
554
 
555
                                format = wiinst->format;
556
                                format.id = val;
557
 
558
                                if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
559
                                        spin_unlock_irqrestore(&wiinst->lock, flags);
560
                                        return -EINVAL;
561
                                }
562
 
563
                                val = wiinst->format.id;
564
 
565
                                spin_unlock_irqrestore(&wiinst->lock, flags);
566
                                DPD(2, "set recording format -> %d\n", val);
567
                        }
568
 
569
                        if (file->f_mode & FMODE_WRITE) {
570
                                struct wave_format format;
571
 
572
                                spin_lock_irqsave(&woinst->lock, flags);
573
 
574
                                format = woinst->format;
575
                                format.id = val;
576
 
577
                                if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
578
                                        spin_unlock_irqrestore(&woinst->lock, flags);
579
                                        return -EINVAL;
580
                                }
581
 
582
                                val = woinst->format.id;
583
 
584
                                spin_unlock_irqrestore(&woinst->lock, flags);
585
                                DPD(2, "set playback format -> %d\n", val);
586
                        }
587
 
588
                        return put_user(val, (int *) arg);
589
                } else {
590
                        if (file->f_mode & FMODE_READ)
591
                                val = wiinst->format.id;
592
                        else if (file->f_mode & FMODE_WRITE)
593
                                val = woinst->format.id;
594
 
595
                        return put_user(val, (int *) arg);
596
                }
597
                break;
598
 
599
        case SOUND_PCM_READ_BITS:
600
 
601
                if (file->f_mode & FMODE_READ)
602
                        val = wiinst->format.bitsperchannel;
603
                else if (file->f_mode & FMODE_WRITE)
604
                        val = woinst->format.bitsperchannel;
605
 
606
                return put_user(val, (int *) arg);
607
 
608
        case SOUND_PCM_READ_RATE:
609
 
610
                if (file->f_mode & FMODE_READ)
611
                        val = wiinst->format.samplingrate;
612
                else if (file->f_mode & FMODE_WRITE)
613
                        val = woinst->format.samplingrate;
614
 
615
                return put_user(val, (int *) arg);
616
 
617
        case SOUND_PCM_READ_CHANNELS:
618
 
619
                if (file->f_mode & FMODE_READ)
620
                        val = wiinst->format.channels;
621
                else if (file->f_mode & FMODE_WRITE)
622
                        val = woinst->format.channels;
623
 
624
                return put_user(val, (int *) arg);
625
 
626
        case SOUND_PCM_WRITE_FILTER:
627
                DPF(2, "SOUND_PCM_WRITE_FILTER: not implemented\n");
628
                break;
629
 
630
        case SOUND_PCM_READ_FILTER:
631
                DPF(2, "SOUND_PCM_READ_FILTER: not implemented\n");
632
                break;
633
 
634
        case SNDCTL_DSP_SETSYNCRO:
635
                DPF(2, "SNDCTL_DSP_SETSYNCRO: not implemented\n");
636
                break;
637
 
638
        case SNDCTL_DSP_GETTRIGGER:
639
                DPF(2, "SNDCTL_DSP_GETTRIGGER:\n");
640
 
641
                if (file->f_mode & FMODE_WRITE && (wave_dev->enablebits & PCM_ENABLE_OUTPUT))
642
                        val |= PCM_ENABLE_OUTPUT;
643
 
644
                if (file->f_mode & FMODE_READ && (wave_dev->enablebits & PCM_ENABLE_INPUT))
645
                        val |= PCM_ENABLE_INPUT;
646
 
647
                return put_user(val, (int *) arg);
648
 
649
        case SNDCTL_DSP_SETTRIGGER:
650
                DPF(2, "SNDCTL_DSP_SETTRIGGER:\n");
651
 
652
                if (get_user(val, (int *) arg))
653
                        return -EFAULT;
654
 
655
                if (file->f_mode & FMODE_WRITE) {
656
                        spin_lock_irqsave(&woinst->lock, flags);
657
 
658
                        if (val & PCM_ENABLE_OUTPUT) {
659
                                wave_dev->enablebits |= PCM_ENABLE_OUTPUT;
660
                                if (woinst->state & WAVE_STATE_OPEN)
661
                                        emu10k1_waveout_start(wave_dev);
662
                        } else {
663
                                wave_dev->enablebits &= ~PCM_ENABLE_OUTPUT;
664
                                if (woinst->state & WAVE_STATE_STARTED)
665
                                        emu10k1_waveout_stop(wave_dev);
666
                        }
667
 
668
                        spin_unlock_irqrestore(&woinst->lock, flags);
669
                }
670
 
671
                if (file->f_mode & FMODE_READ) {
672
                        spin_lock_irqsave(&wiinst->lock, flags);
673
 
674
                        if (val & PCM_ENABLE_INPUT) {
675
                                wave_dev->enablebits |= PCM_ENABLE_INPUT;
676
                                if (wiinst->state & WAVE_STATE_OPEN)
677
                                        emu10k1_wavein_start(wave_dev);
678
                        } else {
679
                                wave_dev->enablebits &= ~PCM_ENABLE_INPUT;
680
                                if (wiinst->state & WAVE_STATE_STARTED)
681
                                        emu10k1_wavein_stop(wave_dev);
682
                        }
683
 
684
                        spin_unlock_irqrestore(&wiinst->lock, flags);
685
                }
686
                break;
687
 
688
        case SNDCTL_DSP_GETOSPACE:
689
                {
690
                        audio_buf_info info;
691
 
692
                        DPF(4, "SNDCTL_DSP_GETOSPACE:\n");
693
 
694
                        if (!(file->f_mode & FMODE_WRITE))
695
                                return -EINVAL;
696
 
697
                        spin_lock_irqsave(&woinst->lock, flags);
698
 
699
                        if (woinst->state & WAVE_STATE_OPEN) {
700
                                emu10k1_waveout_update(woinst);
701
                                emu10k1_waveout_getxfersize(woinst, &bytestocopy);
702
                                info.bytes = bytestocopy;
703
                        } else {
704
                                calculate_ofrag(woinst);
705
                                info.bytes = woinst->buffer.size;
706
                        }
707
                        spin_unlock_irqrestore(&woinst->lock, flags);
708
 
709
                        info.bytes *= woinst->num_voices;
710
                        info.fragsize = woinst->buffer.fragment_size * woinst->num_voices;
711
                        info.fragstotal = woinst->buffer.numfrags * woinst->num_voices;
712
                        info.fragments = info.bytes / info.fragsize;
713
 
714
                        if (copy_to_user((int *) arg, &info, sizeof(info)))
715
                                return -EFAULT;
716
                }
717
                break;
718
 
719
        case SNDCTL_DSP_GETISPACE:
720
                {
721
                        audio_buf_info info;
722
 
723
                        DPF(4, "SNDCTL_DSP_GETISPACE:\n");
724
 
725
                        if (!(file->f_mode & FMODE_READ))
726
                                return -EINVAL;
727
 
728
                        spin_lock_irqsave(&wiinst->lock, flags);
729
                        if (wiinst->state & WAVE_STATE_OPEN) {
730
                                emu10k1_wavein_update(wave_dev->card, wiinst);
731
                                emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
732
                                info.bytes = bytestocopy;
733
                        } else {
734
                                calculate_ifrag(wiinst);
735
                                info.bytes = 0;
736
                        }
737
                        spin_unlock_irqrestore(&wiinst->lock, flags);
738
 
739
                        info.fragstotal = wiinst->buffer.numfrags;
740
                        info.fragments = info.bytes / wiinst->buffer.fragment_size;
741
                        info.fragsize = wiinst->buffer.fragment_size;
742
 
743
                        if (copy_to_user((int *) arg, &info, sizeof(info)))
744
                                return -EFAULT;
745
                }
746
                break;
747
 
748
        case SNDCTL_DSP_NONBLOCK:
749
                DPF(2, "SNDCTL_DSP_NONBLOCK:\n");
750
 
751
                file->f_flags |= O_NONBLOCK;
752
                break;
753
 
754
        case SNDCTL_DSP_GETODELAY:
755
                DPF(4, "SNDCTL_DSP_GETODELAY:\n");
756
 
757
                if (!(file->f_mode & FMODE_WRITE))
758
                        return -EINVAL;
759
 
760
                spin_lock_irqsave(&woinst->lock, flags);
761
                if (woinst->state & WAVE_STATE_OPEN) {
762
                        emu10k1_waveout_update(woinst);
763
                        emu10k1_waveout_getxfersize(woinst, &bytestocopy);
764
                        val = woinst->buffer.size - bytestocopy;
765
                } else
766
                        val = 0;
767
 
768
                val *= woinst->num_voices;
769
                spin_unlock_irqrestore(&woinst->lock, flags);
770
 
771
                return put_user(val, (int *) arg);
772
 
773
        case SNDCTL_DSP_GETIPTR:
774
                {
775
                        count_info cinfo;
776
 
777
                        DPF(4, "SNDCTL_DSP_GETIPTR: \n");
778
 
779
                        if (!(file->f_mode & FMODE_READ))
780
                                return -EINVAL;
781
 
782
                        spin_lock_irqsave(&wiinst->lock, flags);
783
 
784
                        if (wiinst->state & WAVE_STATE_OPEN) {
785
                                emu10k1_wavein_update(wave_dev->card, wiinst);
786
                                cinfo.ptr = wiinst->buffer.hw_pos;
787
                                cinfo.bytes = cinfo.ptr + wiinst->total_recorded - wiinst->total_recorded % wiinst->buffer.size;
788
                                cinfo.blocks = cinfo.bytes / wiinst->buffer.fragment_size - wiinst->blocks;
789
                                wiinst->blocks = cinfo.bytes / wiinst->buffer.fragment_size;
790
                        } else {
791
                                cinfo.ptr = 0;
792
                                cinfo.bytes = 0;
793
                                cinfo.blocks = 0;
794
                        }
795
 
796
                        if(wiinst->mmapped)
797
                                wiinst->buffer.bytestocopy %= wiinst->buffer.fragment_size;
798
 
799
                        spin_unlock_irqrestore(&wiinst->lock, flags);
800
 
801
                        if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
802
                                return -EFAULT;
803
                }
804
                break;
805
 
806
        case SNDCTL_DSP_GETOPTR:
807
                {
808
                        count_info cinfo;
809
 
810
                        DPF(4, "SNDCTL_DSP_GETOPTR:\n");
811
 
812
                        if (!(file->f_mode & FMODE_WRITE))
813
                                return -EINVAL;
814
 
815
                        spin_lock_irqsave(&woinst->lock, flags);
816
 
817
                        if (woinst->state & WAVE_STATE_OPEN ||
818
                            (woinst->format.passthrough && wave_dev->card->pt.state)) {
819
                                int num_fragments;
820
                                if (woinst->format.passthrough) {
821
                                        emu10k1_pt_waveout_update(wave_dev);
822
                                        cinfo.bytes = woinst->total_played;
823
                                } else {
824
                                        emu10k1_waveout_update(woinst);
825
                                        cinfo.bytes = woinst->total_played;
826
                                }
827
                                cinfo.ptr = woinst->buffer.hw_pos;
828
                                num_fragments = cinfo.bytes / woinst->buffer.fragment_size;
829
                                cinfo.blocks = num_fragments - woinst->blocks;
830
                                woinst->blocks = num_fragments;
831
 
832
                                cinfo.bytes *= woinst->num_voices;
833
                                cinfo.ptr *= woinst->num_voices;
834
                        } else {
835
                                cinfo.ptr = 0;
836
                                cinfo.bytes = 0;
837
                                cinfo.blocks = 0;
838
                        }
839
 
840
                        if (woinst->mmapped)
841
                                woinst->buffer.free_bytes %= woinst->buffer.fragment_size;
842
 
843
                        spin_unlock_irqrestore(&woinst->lock, flags);
844
 
845
                        if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
846
                                return -EFAULT;
847
                }
848
                break;
849
 
850
        case SNDCTL_DSP_GETBLKSIZE:
851
                DPF(2, "SNDCTL_DSP_GETBLKSIZE:\n");
852
 
853
                if (file->f_mode & FMODE_WRITE) {
854
                        spin_lock_irqsave(&woinst->lock, flags);
855
 
856
                        calculate_ofrag(woinst);
857
                        val = woinst->buffer.fragment_size * woinst->num_voices;
858
 
859
                        spin_unlock_irqrestore(&woinst->lock, flags);
860
                }
861
 
862
                if (file->f_mode & FMODE_READ) {
863
                        spin_lock_irqsave(&wiinst->lock, flags);
864
 
865
                        calculate_ifrag(wiinst);
866
                        val = wiinst->buffer.fragment_size;
867
 
868
                        spin_unlock_irqrestore(&wiinst->lock, flags);
869
                }
870
 
871
                return put_user(val, (int *) arg);
872
 
873
                break;
874
 
875
        case SNDCTL_DSP_POST:
876
                if (file->f_mode & FMODE_WRITE) {
877
                        spin_lock_irqsave(&woinst->lock, flags);
878
 
879
                        if (!(woinst->state & WAVE_STATE_STARTED)
880
                            && (wave_dev->enablebits & PCM_ENABLE_OUTPUT)
881
                            && (woinst->total_copied > 0))
882
                                emu10k1_waveout_start(wave_dev);
883
 
884
                        spin_unlock_irqrestore(&woinst->lock, flags);
885
                }
886
 
887
                break;
888
 
889
        case SNDCTL_DSP_SUBDIVIDE:
890
                DPF(2, "SNDCTL_DSP_SUBDIVIDE: not implemented\n");
891
                break;
892
 
893
        case SNDCTL_DSP_SETFRAGMENT:
894
                DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n");
895
 
896
                if (get_user(val, (int *) arg))
897
                        return -EFAULT;
898
 
899
                DPD(2, "val is %#x\n", val);
900
 
901
                if (val == 0)
902
                        return -EIO;
903
 
904
                if (file->f_mode & FMODE_WRITE) {
905
                        /* digital pass-through fragment count and size are fixed values */
906
                        if (woinst->state & WAVE_STATE_OPEN || woinst->format.passthrough)
907
                                return -EINVAL; /* too late to change */
908
 
909
                        woinst->buffer.ossfragshift = val & 0xffff;
910
                        woinst->buffer.numfrags = (val >> 16) & 0xffff;
911
                }
912
 
913
                if (file->f_mode & FMODE_READ) {
914
                        if (wiinst->state & WAVE_STATE_OPEN)
915
                                return -EINVAL; /* too late to change */
916
 
917
                        wiinst->buffer.ossfragshift = val & 0xffff;
918
                        wiinst->buffer.numfrags = (val >> 16) & 0xffff;
919
                }
920
 
921
                break;
922
 
923
        case SNDCTL_COPR_LOAD:
924
                {
925
                        copr_buffer *buf;
926
                        u32 i;
927
 
928
                        DPF(4, "SNDCTL_COPR_LOAD:\n");
929
 
930
                        buf = kmalloc(sizeof(copr_buffer), GFP_KERNEL);
931
                        if (!buf)
932
                                return -ENOMEM;
933
 
934
                        if (copy_from_user(buf, (copr_buffer *) arg, sizeof(copr_buffer))) {
935
                                kfree (buf);
936
                                return -EFAULT;
937
                        }
938
 
939
                        if ((buf->command != CMD_READ) && (buf->command != CMD_WRITE)) {
940
                                kfree (buf);
941
                                return -EINVAL;
942
                        }
943
#ifdef DBGEMU
944
                        if ( (buf->offs < 0) || (buf->offs + buf->len > 0x800) || (buf->len > 1000)) {
945
#else
946
                        if ( ((buf->offs < 0x100 ) || (buf->offs + buf->len > 0x800) || (buf->len > 1000))
947
                             && !( ( buf->offs == DBG) && (buf->len ==1) )){
948
#endif  
949
                                kfree(buf);
950
                                return -EINVAL;
951
                        }
952
 
953
                        if (buf->command == CMD_READ) {
954
                                for (i = 0; i < buf->len; i++)
955
                                        ((u32 *) buf->data)[i] = sblive_readptr(wave_dev->card, buf->offs + i, 0);
956
 
957
                                if (copy_to_user((copr_buffer *) arg, buf, sizeof(copr_buffer))) {
958
                                        kfree(buf);
959
                                        return -EFAULT;
960
                                }
961
                        } else {
962
                                for (i = 0; i < buf->len; i++)
963
                                        sblive_writeptr(wave_dev->card, buf->offs + i, 0, ((u32 *) buf->data)[i]);
964
                        }
965
 
966
                        kfree (buf);
967
                        break;
968
                }
969
 
970
        default:                /* Default is unrecognized command */
971
                DPD(2, "default: %#x\n", cmd);
972
                return -EINVAL;
973
        }
974
        return 0;
975
}
976
 
977
static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned long address, int write_access)
978
{
979
        struct emu10k1_wavedevice *wave_dev = vma->vm_private_data;
980
        struct woinst *woinst = wave_dev->woinst;
981
        struct wiinst *wiinst = wave_dev->wiinst;
982
        struct page *dmapage;
983
        unsigned long pgoff;
984
        int rd, wr;
985
 
986
        DPF(3, "emu10k1_mm_nopage()\n");
987
        DPD(3, "addr: %#lx\n", address);
988
 
989
        if (address > vma->vm_end) {
990
                DPF(1, "EXIT, returning NOPAGE_SIGBUS\n");
991
                return NOPAGE_SIGBUS; /* Disallow mremap */
992
        }
993
 
994
        pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT);
995
        if (woinst != NULL)
996
                wr = woinst->mmapped;
997
        else
998
                wr = 0;
999
 
1000
        if (wiinst != NULL)
1001
                rd = wiinst->mmapped;
1002
        else
1003
                rd = 0;
1004
 
1005
        /* if full-duplex (read+write) and we have two sets of bufs,
1006
        * then the playback buffers come first, sez soundcard.c */
1007
        if (wr) {
1008
                if (pgoff >= woinst->buffer.pages) {
1009
                        pgoff -= woinst->buffer.pages;
1010
                        dmapage = virt_to_page ((u8 *) wiinst->buffer.addr + pgoff * PAGE_SIZE);
1011
                } else
1012
                        dmapage = virt_to_page (woinst->voice[0].mem.addr[pgoff]);
1013
        } else {
1014
                dmapage = virt_to_page ((u8 *) wiinst->buffer.addr + pgoff * PAGE_SIZE);
1015
        }
1016
 
1017
        get_page (dmapage);
1018
 
1019
        DPD(3, "page: %#lx\n", (unsigned long) dmapage);
1020
        return dmapage;
1021
}
1022
 
1023
struct vm_operations_struct emu10k1_mm_ops = {
1024
        nopage:         emu10k1_mm_nopage,
1025
};
1026
 
1027
static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
1028
{
1029
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1030
        unsigned long max_pages, n_pages, pgoffset;
1031
        struct woinst *woinst = NULL;
1032
        struct wiinst *wiinst = NULL;
1033
        unsigned long flags;
1034
 
1035
        DPF(2, "emu10k1_audio_mmap()\n");
1036
 
1037
        max_pages = 0;
1038
        if (vma->vm_flags & VM_WRITE) {
1039
                woinst = wave_dev->woinst;
1040
 
1041
                spin_lock_irqsave(&woinst->lock, flags);
1042
 
1043
                /* No m'mapping possible for multichannel */
1044
                if (woinst->num_voices > 1) {
1045
                        spin_unlock_irqrestore(&woinst->lock, flags);
1046
                        return -EINVAL;
1047
                }
1048
 
1049
                if (woinst->state == WAVE_STATE_CLOSED) {
1050
                        calculate_ofrag(woinst);
1051
 
1052
                        if (emu10k1_waveout_open(wave_dev) < 0) {
1053
                                spin_unlock_irqrestore(&woinst->lock, flags);
1054
                                ERROR();
1055
                                return -EINVAL;
1056
                        }
1057
                }
1058
 
1059
                woinst->mmapped = 1;
1060
                max_pages += woinst->buffer.pages;
1061
                spin_unlock_irqrestore(&woinst->lock, flags);
1062
        }
1063
 
1064
        if (vma->vm_flags & VM_READ) {
1065
                wiinst = wave_dev->wiinst;
1066
 
1067
                spin_lock_irqsave(&wiinst->lock, flags);
1068
                if (wiinst->state == WAVE_STATE_CLOSED) {
1069
                        calculate_ifrag(wiinst);
1070
 
1071
                        if (emu10k1_wavein_open(wave_dev) < 0) {
1072
                                spin_unlock_irqrestore(&wiinst->lock, flags);
1073
                                ERROR();
1074
                                return -EINVAL;
1075
                        }
1076
                }
1077
 
1078
                wiinst->mmapped = 1;
1079
                max_pages += wiinst->buffer.pages;
1080
                spin_unlock_irqrestore(&wiinst->lock, flags);
1081
        }
1082
 
1083
        n_pages = ((vma->vm_end - vma->vm_start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
1084
        pgoffset = vma->vm_pgoff;
1085
 
1086
        DPD(2, "vma_start: %#lx, vma_end: %#lx, vma_offset: %ld\n", vma->vm_start, vma->vm_end, pgoffset);
1087
        DPD(2, "n_pages: %ld, max_pages: %ld\n", n_pages, max_pages);
1088
 
1089
        if (pgoffset + n_pages > max_pages)
1090
                return -EINVAL;
1091
 
1092
        vma->vm_flags |= VM_RESERVED;
1093
        vma->vm_ops = &emu10k1_mm_ops;
1094
        vma->vm_private_data = wave_dev;
1095
        return 0;
1096
}
1097
 
1098
static int emu10k1_audio_open(struct inode *inode, struct file *file)
1099
{
1100
        int minor = MINOR(inode->i_rdev);
1101
        struct emu10k1_card *card = NULL;
1102
        struct list_head *entry;
1103
        struct emu10k1_wavedevice *wave_dev;
1104
 
1105
        DPF(2, "emu10k1_audio_open()\n");
1106
 
1107
        /* Check for correct device to open */
1108
 
1109
        list_for_each(entry, &emu10k1_devs) {
1110
                card = list_entry(entry, struct emu10k1_card, list);
1111
 
1112
                if (!((card->audio_dev ^ minor) & ~0xf) || !((card->audio_dev1 ^ minor) & ~0xf))
1113
                        goto match;
1114
        }
1115
 
1116
        return -ENODEV;
1117
 
1118
match:
1119
 
1120
        wave_dev = (struct emu10k1_wavedevice *) kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL);
1121
 
1122
        if (wave_dev == NULL) {
1123
                ERROR();
1124
                return -ENOMEM;
1125
        }
1126
 
1127
        wave_dev->card = card;
1128
        wave_dev->wiinst = NULL;
1129
        wave_dev->woinst = NULL;
1130
        wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT;    /* Default */
1131
 
1132
        if (file->f_mode & FMODE_READ) {
1133
                /* Recording */
1134
                struct wiinst *wiinst;
1135
 
1136
                if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
1137
                        ERROR();
1138
                        kfree(wave_dev);
1139
                        return -ENOMEM;
1140
                }
1141
 
1142
                wiinst->recsrc = card->wavein.recsrc;
1143
                wiinst->fxwc = card->wavein.fxwc;
1144
 
1145
                switch (wiinst->recsrc) {
1146
                case WAVERECORD_AC97:
1147
                        wiinst->format.id = AFMT_S16_LE;
1148
                        wiinst->format.samplingrate = 8000;
1149
                        wiinst->format.bitsperchannel = 16;
1150
                        wiinst->format.channels = 1;
1151
                        break;
1152
                case WAVERECORD_MIC:
1153
                        wiinst->format.id = AFMT_S16_LE;
1154
                        wiinst->format.samplingrate = 8000;
1155
                        wiinst->format.bitsperchannel = 16;
1156
                        wiinst->format.channels = 1;
1157
                        break;
1158
                case WAVERECORD_FX:
1159
                        wiinst->format.id = AFMT_S16_LE;
1160
                        wiinst->format.samplingrate = 48000;
1161
                        wiinst->format.bitsperchannel = 16;
1162
                        wiinst->format.channels = hweight32(wiinst->fxwc);
1163
                        break;
1164
                default:
1165
                        kfree(wave_dev);
1166
                        kfree(wiinst);
1167
                        BUG();
1168
                        break;
1169
                }
1170
 
1171
                wiinst->state = WAVE_STATE_CLOSED;
1172
 
1173
                wiinst->buffer.ossfragshift = 0;
1174
                wiinst->buffer.fragment_size = 0;
1175
                wiinst->buffer.numfrags = 0;
1176
 
1177
                init_waitqueue_head(&wiinst->wait_queue);
1178
 
1179
                wiinst->mmapped = 0;
1180
                wiinst->total_recorded = 0;
1181
                wiinst->blocks = 0;
1182
                wiinst->lock = SPIN_LOCK_UNLOCKED;
1183
                tasklet_init(&wiinst->timer.tasklet, emu10k1_wavein_bh, (unsigned long) wave_dev);
1184
                wave_dev->wiinst = wiinst;
1185
                emu10k1_wavein_setformat(wave_dev, &wiinst->format);
1186
        }
1187
 
1188
        if (file->f_mode & FMODE_WRITE) {
1189
                struct woinst *woinst;
1190
                int i;
1191
 
1192
                if ((woinst = (struct woinst *) kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
1193
                        ERROR();
1194
                        return -ENODEV;
1195
                }
1196
 
1197
                if (wave_dev->wiinst != NULL) {
1198
                        woinst->format = wave_dev->wiinst->format;
1199
                } else {
1200
                        woinst->format.id = AFMT_U8;
1201
                        woinst->format.samplingrate = 8000;
1202
                        woinst->format.bitsperchannel = 8;
1203
                        woinst->format.channels = 1;
1204
                }
1205
 
1206
                woinst->state = WAVE_STATE_CLOSED;
1207
 
1208
                woinst->buffer.fragment_size = 0;
1209
                woinst->buffer.ossfragshift = 0;
1210
                woinst->buffer.numfrags = 0;
1211
                woinst->device = (card->audio_dev1 == minor);
1212
                woinst->timer.state = TIMER_STATE_UNINSTALLED;
1213
                woinst->num_voices = 1;
1214
                for (i = 0; i < WAVEOUT_MAXVOICES; i++) {
1215
                        woinst->voice[i].usage = VOICE_USAGE_FREE;
1216
                        woinst->voice[i].mem.emupageindex = -1;
1217
                }
1218
 
1219
                init_waitqueue_head(&woinst->wait_queue);
1220
 
1221
                woinst->mmapped = 0;
1222
                woinst->total_copied = 0;
1223
                woinst->total_played = 0;
1224
                woinst->blocks = 0;
1225
                woinst->lock = SPIN_LOCK_UNLOCKED;
1226
                tasklet_init(&woinst->timer.tasklet, emu10k1_waveout_bh, (unsigned long) wave_dev);
1227
                wave_dev->woinst = woinst;
1228
                emu10k1_waveout_setformat(wave_dev, &woinst->format);
1229
        }
1230
 
1231
        file->private_data = (void *) wave_dev;
1232
 
1233
        return 0;
1234
}
1235
 
1236
static int emu10k1_audio_release(struct inode *inode, struct file *file)
1237
{
1238
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1239
        struct emu10k1_card *card;
1240
        unsigned long flags;
1241
 
1242
        card = wave_dev->card;
1243
 
1244
        DPF(2, "emu10k1_audio_release()\n");
1245
 
1246
        if (file->f_mode & FMODE_WRITE) {
1247
                struct woinst *woinst = wave_dev->woinst;
1248
 
1249
                spin_lock_irqsave(&woinst->lock, flags);
1250
 
1251
                if (woinst->format.passthrough && card->pt.state != PT_STATE_INACTIVE) {
1252
                        spin_lock(&card->pt.lock);
1253
                        emu10k1_pt_stop(card);
1254
                        spin_unlock(&card->pt.lock);
1255
                }
1256
                if (woinst->state & WAVE_STATE_OPEN) {
1257
                        if (woinst->state & WAVE_STATE_STARTED) {
1258
                                if (!(file->f_flags & O_NONBLOCK)) {
1259
                                        while (!signal_pending(current)
1260
                                               && (woinst->total_played < woinst->total_copied)) {
1261
                                                DPF(4, "Buffer hasn't been totally played, sleep....\n");
1262
                                                spin_unlock_irqrestore(&woinst->lock, flags);
1263
                                                interruptible_sleep_on(&woinst->wait_queue);
1264
                                                spin_lock_irqsave(&woinst->lock, flags);
1265
                                        }
1266
                                }
1267
                        }
1268
                        emu10k1_waveout_close(wave_dev);
1269
                }
1270
 
1271
                spin_unlock_irqrestore(&woinst->lock, flags);
1272
                /* remove the tasklet */
1273
                tasklet_kill(&woinst->timer.tasklet);
1274
                kfree(wave_dev->woinst);
1275
        }
1276
 
1277
        if (file->f_mode & FMODE_READ) {
1278
                struct wiinst *wiinst = wave_dev->wiinst;
1279
 
1280
                spin_lock_irqsave(&wiinst->lock, flags);
1281
 
1282
                if (wiinst->state & WAVE_STATE_OPEN) {
1283
                        emu10k1_wavein_close(wave_dev);
1284
                }
1285
 
1286
                spin_unlock_irqrestore(&wiinst->lock, flags);
1287
                tasklet_kill(&wiinst->timer.tasklet);
1288
                kfree(wave_dev->wiinst);
1289
        }
1290
 
1291
        kfree(wave_dev);
1292
 
1293
        if (waitqueue_active(&card->open_wait))
1294
                wake_up_interruptible(&card->open_wait);
1295
 
1296
        return 0;
1297
}
1298
 
1299
/* FIXME sort out poll() + mmap() */
1300
static unsigned int emu10k1_audio_poll(struct file *file, struct poll_table_struct *wait)
1301
{
1302
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
1303
        struct woinst *woinst = wave_dev->woinst;
1304
        struct wiinst *wiinst = wave_dev->wiinst;
1305
        unsigned int mask = 0;
1306
        u32 bytestocopy;
1307
        unsigned long flags;
1308
 
1309
        DPF(4, "emu10k1_audio_poll()\n");
1310
 
1311
        if (file->f_mode & FMODE_WRITE)
1312
                poll_wait(file, &woinst->wait_queue, wait);
1313
 
1314
        if (file->f_mode & FMODE_READ)
1315
                poll_wait(file, &wiinst->wait_queue, wait);
1316
 
1317
        if (file->f_mode & FMODE_WRITE) {
1318
                spin_lock_irqsave(&woinst->lock, flags);
1319
 
1320
                if (woinst->state & WAVE_STATE_OPEN) {
1321
                        emu10k1_waveout_update(woinst);
1322
                        emu10k1_waveout_getxfersize(woinst, &bytestocopy);
1323
 
1324
                        if (bytestocopy >= woinst->buffer.fragment_size)
1325
                                mask |= POLLOUT | POLLWRNORM;
1326
                } else
1327
                        mask |= POLLOUT | POLLWRNORM;
1328
 
1329
                spin_unlock_irqrestore(&woinst->lock, flags);
1330
        }
1331
 
1332
        if (file->f_mode & FMODE_READ) {
1333
                spin_lock_irqsave(&wiinst->lock, flags);
1334
 
1335
                if (wiinst->state & WAVE_STATE_OPEN) {
1336
                        emu10k1_wavein_update(wave_dev->card, wiinst);
1337
                        emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
1338
 
1339
                        if (bytestocopy >= wiinst->buffer.fragment_size)
1340
                                mask |= POLLIN | POLLRDNORM;
1341
                }
1342
 
1343
                spin_unlock_irqrestore(&wiinst->lock, flags);
1344
        }
1345
 
1346
        return mask;
1347
}
1348
 
1349
static void calculate_ofrag(struct woinst *woinst)
1350
{
1351
        struct waveout_buffer *buffer = &woinst->buffer;
1352
        u32 fragsize;
1353
 
1354
        if (buffer->fragment_size)
1355
                return;
1356
 
1357
        if (!buffer->ossfragshift) {
1358
                fragsize = (woinst->format.bytespervoicesample * woinst->format.samplingrate * WAVEOUT_DEFAULTFRAGLEN) / 1000 - 1;
1359
 
1360
                while (fragsize) {
1361
                        fragsize >>= 1;
1362
                        buffer->ossfragshift++;
1363
                }
1364
        }
1365
 
1366
        if (buffer->ossfragshift < WAVEOUT_MINFRAGSHIFT)
1367
                buffer->ossfragshift = WAVEOUT_MINFRAGSHIFT;
1368
 
1369
        buffer->fragment_size = 1 << buffer->ossfragshift;
1370
 
1371
        while (buffer->fragment_size * WAVEOUT_MINFRAGS > WAVEOUT_MAXBUFSIZE)
1372
                buffer->fragment_size >>= 1;
1373
 
1374
        /* now we are sure that:
1375
         (2^WAVEOUT_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEOUT_MAXBUFSIZE / WAVEOUT_MINFRAGS)
1376
        */
1377
 
1378
        if (!buffer->numfrags) {
1379
                u32 numfrags;
1380
 
1381
                numfrags = (woinst->format.bytespervoicesample * woinst->format.samplingrate * WAVEOUT_DEFAULTBUFLEN) /
1382
                           (buffer->fragment_size * 1000) - 1;
1383
 
1384
                buffer->numfrags = 1;
1385
 
1386
                while (numfrags) {
1387
                        numfrags >>= 1;
1388
                        buffer->numfrags <<= 1;
1389
                }
1390
        }
1391
 
1392
        if (buffer->numfrags < WAVEOUT_MINFRAGS)
1393
                buffer->numfrags = WAVEOUT_MINFRAGS;
1394
 
1395
        if (buffer->numfrags * buffer->fragment_size > WAVEOUT_MAXBUFSIZE)
1396
                buffer->numfrags = WAVEOUT_MAXBUFSIZE / buffer->fragment_size;
1397
 
1398
        if (buffer->numfrags < WAVEOUT_MINFRAGS)
1399
                BUG();
1400
 
1401
        buffer->size = buffer->fragment_size * buffer->numfrags;
1402
        buffer->pages = buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
1403
 
1404
        DPD(2, " calculated playback fragment_size -> %d\n", buffer->fragment_size);
1405
        DPD(2, " calculated playback numfrags -> %d\n", buffer->numfrags);
1406
 
1407
        return;
1408
}
1409
 
1410
static void calculate_ifrag(struct wiinst *wiinst)
1411
{
1412
        struct wavein_buffer *buffer = &wiinst->buffer;
1413
        u32 fragsize, bufsize, size[4];
1414
        int i, j;
1415
 
1416
        if (buffer->fragment_size)
1417
                return;
1418
 
1419
        if (!buffer->ossfragshift) {
1420
                fragsize = (wiinst->format.bytespersec * WAVEIN_DEFAULTFRAGLEN) / 1000 - 1;
1421
 
1422
                while (fragsize) {
1423
                        fragsize >>= 1;
1424
                        buffer->ossfragshift++;
1425
                }
1426
        }
1427
 
1428
        if (buffer->ossfragshift < WAVEIN_MINFRAGSHIFT)
1429
                buffer->ossfragshift = WAVEIN_MINFRAGSHIFT;
1430
 
1431
        buffer->fragment_size = 1 << buffer->ossfragshift;
1432
 
1433
        while (buffer->fragment_size * WAVEIN_MINFRAGS > WAVEIN_MAXBUFSIZE)
1434
                buffer->fragment_size >>= 1;
1435
 
1436
        /* now we are sure that:
1437
           (2^WAVEIN_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEIN_MAXBUFSIZE / WAVEIN_MINFRAGS)
1438
        */
1439
 
1440
 
1441
        if (!buffer->numfrags)
1442
                buffer->numfrags = (wiinst->format.bytespersec * WAVEIN_DEFAULTBUFLEN) / (buffer->fragment_size * 1000) - 1;
1443
 
1444
        if (buffer->numfrags < WAVEIN_MINFRAGS)
1445
                buffer->numfrags = WAVEIN_MINFRAGS;
1446
 
1447
        if (buffer->numfrags * buffer->fragment_size > WAVEIN_MAXBUFSIZE)
1448
                buffer->numfrags = WAVEIN_MAXBUFSIZE / buffer->fragment_size;
1449
 
1450
        if (buffer->numfrags < WAVEIN_MINFRAGS)
1451
                BUG();
1452
 
1453
        bufsize = buffer->fragment_size * buffer->numfrags;
1454
 
1455
        /* the buffer size for recording is restricted to certain values, adjust it now */
1456
        if (bufsize >= 0x10000) {
1457
                buffer->size = 0x10000;
1458
                buffer->sizeregval = 0x1f;
1459
        } else {
1460
                buffer->size = 0;
1461
                size[0] = 384;
1462
                size[1] = 448;
1463
                size[2] = 512;
1464
                size[3] = 640;
1465
 
1466
                for (i = 0; i < 8; i++)
1467
                        for (j = 0; j < 4; j++)
1468
                                if (bufsize >= size[j]) {
1469
                                        buffer->size = size[j];
1470
                                        size[j] *= 2;
1471
                                        buffer->sizeregval = i * 4 + j + 1;
1472
                                } else
1473
                                        goto exitloop;
1474
              exitloop:
1475
                if (buffer->size == 0) {
1476
                        buffer->size = 384;
1477
                        buffer->sizeregval = 0x01;
1478
                }
1479
        }
1480
 
1481
        /* adjust the fragment size so that buffer size is an integer multiple */
1482
        while (buffer->size % buffer->fragment_size)
1483
                buffer->fragment_size >>= 1;
1484
 
1485
        buffer->numfrags = buffer->size / buffer->fragment_size;
1486
        buffer->pages =  buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
1487
 
1488
        DPD(2, " calculated recording fragment_size -> %d\n", buffer->fragment_size);
1489
        DPD(2, " calculated recording numfrags -> %d\n", buffer->numfrags);
1490
        DPD(2, " buffer size register -> %#04x\n", buffer->sizeregval);
1491
 
1492
        return;
1493
}
1494
 
1495
void emu10k1_wavein_bh(unsigned long refdata)
1496
{
1497
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
1498
        struct wiinst *wiinst = wave_dev->wiinst;
1499
        u32 bytestocopy;
1500
        unsigned long flags;
1501
 
1502
        if (!wiinst)
1503
                return;
1504
 
1505
        spin_lock_irqsave(&wiinst->lock, flags);
1506
 
1507
        if (!(wiinst->state & WAVE_STATE_STARTED)) {
1508
                spin_unlock_irqrestore(&wiinst->lock, flags);
1509
                return;
1510
        }
1511
 
1512
        emu10k1_wavein_update(wave_dev->card, wiinst);
1513
        emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
1514
 
1515
        spin_unlock_irqrestore(&wiinst->lock, flags);
1516
 
1517
        if (bytestocopy >= wiinst->buffer.fragment_size) {
1518
                if (waitqueue_active(&wiinst->wait_queue))
1519
                        wake_up_interruptible(&wiinst->wait_queue);
1520
        } else
1521
                DPD(3, "Not enough transfer size, %d\n", bytestocopy);
1522
 
1523
        return;
1524
}
1525
 
1526
void emu10k1_waveout_bh(unsigned long refdata)
1527
{
1528
        struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
1529
        struct woinst *woinst = wave_dev->woinst;
1530
        u32 bytestocopy;
1531
        unsigned long flags;
1532
 
1533
        if (!woinst)
1534
                return;
1535
 
1536
        spin_lock_irqsave(&woinst->lock, flags);
1537
 
1538
        if (!(woinst->state & WAVE_STATE_STARTED)) {
1539
                spin_unlock_irqrestore(&woinst->lock, flags);
1540
                return;
1541
        }
1542
 
1543
        emu10k1_waveout_update(woinst);
1544
        emu10k1_waveout_getxfersize(woinst, &bytestocopy);
1545
 
1546
        if (woinst->buffer.fill_silence) {
1547
                spin_unlock_irqrestore(&woinst->lock, flags);
1548
                emu10k1_waveout_fillsilence(woinst);
1549
        } else
1550
                spin_unlock_irqrestore(&woinst->lock, flags);
1551
 
1552
        if (bytestocopy >= woinst->buffer.fragment_size) {
1553
                if (waitqueue_active(&woinst->wait_queue))
1554
                        wake_up_interruptible(&woinst->wait_queue);
1555
        } else
1556
                DPD(3, "Not enough transfer size -> %d\n", bytestocopy);
1557
 
1558
        return;
1559
}
1560
 
1561
struct file_operations emu10k1_audio_fops = {
1562
        owner:          THIS_MODULE,
1563
        llseek:         no_llseek,
1564
        read:           emu10k1_audio_read,
1565
        write:          emu10k1_audio_write,
1566
        poll:           emu10k1_audio_poll,
1567
        ioctl:          emu10k1_audio_ioctl,
1568
        mmap:           emu10k1_audio_mmap,
1569
        open:           emu10k1_audio_open,
1570
        release:        emu10k1_audio_release,
1571
};

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.