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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [sound/] [sonicvibes.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*****************************************************************************/
2
 
3
/*
4
 *      sonicvibes.c  --  S3 Sonic Vibes audio driver.
5
 *
6
 *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
7
 *
8
 *      This program is free software; you can redistribute it and/or modify
9
 *      it under the terms of the GNU General Public License as published by
10
 *      the Free Software Foundation; either version 2 of the License, or
11
 *      (at your option) any later version.
12
 *
13
 *      This program is distributed in the hope that it will be useful,
14
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *      GNU General Public License for more details.
17
 *
18
 *      You should have received a copy of the GNU General Public License
19
 *      along with this program; if not, write to the Free Software
20
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 *
22
 * Special thanks to David C. Niemi
23
 *
24
 *
25
 * Module command line parameters:
26
 *   none so far
27
 *
28
 *
29
 *  Supported devices:
30
 *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
31
 *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
32
 *  /dev/midi   simple MIDI UART interface, no ioctl
33
 *
34
 *  The card has both an FM and a Wavetable synth, but I have to figure
35
 *  out first how to drive them...
36
 *
37
 *  Revision history
38
 *    06.05.1998   0.1   Initial release
39
 *    10.05.1998   0.2   Fixed many bugs, esp. ADC rate calculation
40
 *                       First stab at a simple midi interface (no bells&whistles)
41
 *    13.05.1998   0.3   Fix stupid cut&paste error: set_adc_rate was called instead of
42
 *                       set_dac_rate in the FMODE_WRITE case in sv_open
43
 *                       Fix hwptr out of bounds (now mpg123 works)
44
 *    14.05.1998   0.4   Don't allow excessive interrupt rates
45
 *    08.06.1998   0.5   First release using Alan Cox' soundcore instead of miscdevice
46
 *    03.08.1998   0.6   Do not include modversions.h
47
 *                       Now mixer behaviour can basically be selected between
48
 *                       "OSS documented" and "OSS actual" behaviour
49
 *    31.08.1998   0.7   Fix realplayer problems - dac.count issues
50
 *    10.12.1998   0.8   Fix drain_dac trying to wait on not yet initialized DMA
51
 *    16.12.1998   0.9   Fix a few f_file & FMODE_ bugs
52
 *    06.01.1999   0.10  remove the silly SA_INTERRUPT flag.
53
 *                       hopefully killed the egcs section type conflict
54
 *    12.03.1999   0.11  cinfo.blocks should be reset after GETxPTR ioctl.
55
 *                       reported by Johan Maes <joma@telindus.be>
56
 *    22.03.1999   0.12  return EAGAIN instead of EBUSY when O_NONBLOCK
57
 *                       read/write cannot be executed
58
 *    05.04.1999   0.13  added code to sv_read and sv_write which should detect
59
 *                       lockups of the sound chip and revive it. This is basically
60
 *                       an ugly hack, but at least applications using this driver
61
 *                       won't hang forever. I don't know why these lockups happen,
62
 *                       it might well be the motherboard chipset (an early 486 PCI
63
 *                       board with ALI chipset), since every busmastering 100MB
64
 *                       ethernet card I've tried (Realtek 8139 and Macronix tulip clone)
65
 *                       exhibit similar behaviour (they work for a couple of packets
66
 *                       and then lock up and can be revived by ifconfig down/up).
67
 *    07.04.1999   0.14  implemented the following ioctl's: SOUND_PCM_READ_RATE,
68
 *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS;
69
 *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
70
 *                       Note: dmaio hack might still be wrong on archs other than i386
71
 *    15.06.1999   0.15  Fix bad allocation bug.
72
 *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
73
 *    28.06.1999   0.16  Add pci_set_master
74
 *    03.08.1999   0.17  adapt to Linus' new __setup/__initcall
75
 *                       added kernel command line options "sonicvibes=reverb" and "sonicvibesdmaio=dmaioaddr"
76
 *    12.08.1999   0.18  module_init/__setup fixes
77
 *    24.08.1999   0.19  get rid of the dmaio kludge, replace with allocate_resource
78
 *    31.08.1999   0.20  add spin_lock_init
79
 *                       use new resource allocation to allocate DDMA IO space
80
 *                       replaced current->state = x with set_current_state(x)
81
 *    03.09.1999   0.21  change read semantics for MIDI to match
82
 *                       OSS more closely; remove possible wakeup race
83
 *    28.10.1999   0.22  More waitqueue races fixed
84
 *    01.12.1999   0.23  New argument to allocate_resource
85
 *    07.12.1999   0.24  More allocate_resource semantics change
86
 *    08.01.2000   0.25  Prevent some ioctl's from returning bad count values on underrun/overrun;
87
 *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
88
 *                       use Martin Mares' pci_assign_resource
89
 *    07.02.2000   0.26  Use pci_alloc_consistent and pci_register_driver
90
 *    21.11.2000   0.27  Initialize dma buffers in poll, otherwise poll may return a bogus mask
91
 *    12.12.2000   0.28  More dma buffer initializations, patch from
92
 *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
93
 *    31.01.2001   0.29  Register/Unregister gameport
94
 *                       Fix SETTRIGGER non OSS API conformity
95
 *    18.05.2001   0.30  PCI probing and error values cleaned up by Marcus
96
 *                       Meissner <mm@caldera.de>
97
 *    03.01.2003   0.31  open_mode fixes from Georg Acher <acher@in.tum.de>
98
 *
99
 */
100
 
101
/*****************************************************************************/
102
 
103
#include <linux/version.h>
104
#include <linux/module.h>
105
#include <linux/string.h>
106
#include <linux/ioport.h>
107
#include <linux/sched.h>
108
#include <linux/delay.h>
109
#include <linux/sound.h>
110
#include <linux/slab.h>
111
#include <linux/soundcard.h>
112
#include <linux/pci.h>
113
#include <asm/io.h>
114
#include <asm/dma.h>
115
#include <linux/init.h>
116
#include <linux/poll.h>
117
#include <linux/spinlock.h>
118
#include <linux/smp_lock.h>
119
#include <linux/wrapper.h>
120
#include <asm/uaccess.h>
121
#include <asm/hardirq.h>
122
#include <linux/gameport.h>
123
 
124
#include "dm.h"
125
 
126
 
127
/* --------------------------------------------------------------------- */
128
 
129
#undef OSS_DOCUMENTED_MIXER_SEMANTICS
130
 
131
/* --------------------------------------------------------------------- */
132
 
133
#ifndef PCI_VENDOR_ID_S3
134
#define PCI_VENDOR_ID_S3             0x5333
135
#endif
136
#ifndef PCI_DEVICE_ID_S3_SONICVIBES
137
#define PCI_DEVICE_ID_S3_SONICVIBES  0xca00
138
#endif
139
 
140
#define SV_MAGIC  ((PCI_VENDOR_ID_S3<<16)|PCI_DEVICE_ID_S3_SONICVIBES)
141
 
142
#define SV_EXTENT_SB      0x10
143
#define SV_EXTENT_ENH     0x10
144
#define SV_EXTENT_SYNTH   0x4
145
#define SV_EXTENT_MIDI    0x4
146
#define SV_EXTENT_GAME    0x8
147
#define SV_EXTENT_DMA     0x10
148
 
149
/*
150
 * we are not a bridge and thus use a resource for DDMA that is used for bridges but
151
 * left empty for normal devices
152
 */
153
#define RESOURCE_SB       0
154
#define RESOURCE_ENH      1
155
#define RESOURCE_SYNTH    2
156
#define RESOURCE_MIDI     3
157
#define RESOURCE_GAME     4
158
#define RESOURCE_DDMA     7
159
 
160
#define SV_MIDI_DATA      0
161
#define SV_MIDI_COMMAND   1
162
#define SV_MIDI_STATUS    1
163
 
164
#define SV_DMA_ADDR0      0
165
#define SV_DMA_ADDR1      1
166
#define SV_DMA_ADDR2      2
167
#define SV_DMA_ADDR3      3
168
#define SV_DMA_COUNT0     4
169
#define SV_DMA_COUNT1     5
170
#define SV_DMA_COUNT2     6
171
#define SV_DMA_MODE       0xb
172
#define SV_DMA_RESET      0xd
173
#define SV_DMA_MASK       0xf
174
 
175
/*
176
 * DONT reset the DMA controllers unless you understand
177
 * the reset semantics. Assuming reset semantics as in
178
 * the 8237 does not work.
179
 */
180
 
181
#define DMA_MODE_AUTOINIT 0x10
182
#define DMA_MODE_READ     0x44    /* I/O to memory, no autoinit, increment, single mode */
183
#define DMA_MODE_WRITE    0x48    /* memory to I/O, no autoinit, increment, single mode */
184
 
185
#define SV_CODEC_CONTROL  0
186
#define SV_CODEC_INTMASK  1
187
#define SV_CODEC_STATUS   2
188
#define SV_CODEC_IADDR    4
189
#define SV_CODEC_IDATA    5
190
 
191
#define SV_CCTRL_RESET      0x80
192
#define SV_CCTRL_INTADRIVE  0x20
193
#define SV_CCTRL_WAVETABLE  0x08
194
#define SV_CCTRL_REVERB     0x04
195
#define SV_CCTRL_ENHANCED   0x01
196
 
197
#define SV_CINTMASK_DMAA    0x01
198
#define SV_CINTMASK_DMAC    0x04
199
#define SV_CINTMASK_SPECIAL 0x08
200
#define SV_CINTMASK_UPDOWN  0x40
201
#define SV_CINTMASK_MIDI    0x80
202
 
203
#define SV_CSTAT_DMAA       0x01
204
#define SV_CSTAT_DMAC       0x04
205
#define SV_CSTAT_SPECIAL    0x08
206
#define SV_CSTAT_UPDOWN     0x40
207
#define SV_CSTAT_MIDI       0x80
208
 
209
#define SV_CIADDR_TRD       0x80
210
#define SV_CIADDR_MCE       0x40
211
 
212
/* codec indirect registers */
213
#define SV_CIMIX_ADCINL     0x00
214
#define SV_CIMIX_ADCINR     0x01
215
#define SV_CIMIX_AUX1INL    0x02
216
#define SV_CIMIX_AUX1INR    0x03
217
#define SV_CIMIX_CDINL      0x04
218
#define SV_CIMIX_CDINR      0x05
219
#define SV_CIMIX_LINEINL    0x06
220
#define SV_CIMIX_LINEINR    0x07
221
#define SV_CIMIX_MICIN      0x08
222
#define SV_CIMIX_SYNTHINL   0x0A
223
#define SV_CIMIX_SYNTHINR   0x0B
224
#define SV_CIMIX_AUX2INL    0x0C
225
#define SV_CIMIX_AUX2INR    0x0D
226
#define SV_CIMIX_ANALOGINL  0x0E
227
#define SV_CIMIX_ANALOGINR  0x0F
228
#define SV_CIMIX_PCMINL     0x10
229
#define SV_CIMIX_PCMINR     0x11
230
 
231
#define SV_CIGAMECONTROL    0x09
232
#define SV_CIDATAFMT        0x12
233
#define SV_CIENABLE         0x13
234
#define SV_CIUPDOWN         0x14
235
#define SV_CIREVISION       0x15
236
#define SV_CIADCOUTPUT      0x16
237
#define SV_CIDMAABASECOUNT1 0x18
238
#define SV_CIDMAABASECOUNT0 0x19
239
#define SV_CIDMACBASECOUNT1 0x1c
240
#define SV_CIDMACBASECOUNT0 0x1d
241
#define SV_CIPCMSR0         0x1e
242
#define SV_CIPCMSR1         0x1f
243
#define SV_CISYNTHSR0       0x20
244
#define SV_CISYNTHSR1       0x21
245
#define SV_CIADCCLKSOURCE   0x22
246
#define SV_CIADCALTSR       0x23
247
#define SV_CIADCPLLM        0x24
248
#define SV_CIADCPLLN        0x25
249
#define SV_CISYNTHPLLM      0x26
250
#define SV_CISYNTHPLLN      0x27
251
#define SV_CIUARTCONTROL    0x2a
252
#define SV_CIDRIVECONTROL   0x2b
253
#define SV_CISRSSPACE       0x2c
254
#define SV_CISRSCENTER      0x2d
255
#define SV_CIWAVETABLESRC   0x2e
256
#define SV_CIANALOGPWRDOWN  0x30
257
#define SV_CIDIGITALPWRDOWN 0x31
258
 
259
 
260
#define SV_CIMIX_ADCSRC_CD     0x20
261
#define SV_CIMIX_ADCSRC_DAC    0x40
262
#define SV_CIMIX_ADCSRC_AUX2   0x60
263
#define SV_CIMIX_ADCSRC_LINE   0x80
264
#define SV_CIMIX_ADCSRC_AUX1   0xa0
265
#define SV_CIMIX_ADCSRC_MIC    0xc0
266
#define SV_CIMIX_ADCSRC_MIXOUT 0xe0
267
#define SV_CIMIX_ADCSRC_MASK   0xe0
268
 
269
#define SV_CFMT_STEREO     0x01
270
#define SV_CFMT_16BIT      0x02
271
#define SV_CFMT_MASK       0x03
272
#define SV_CFMT_ASHIFT     0   
273
#define SV_CFMT_CSHIFT     4
274
 
275
static const unsigned sample_size[] = { 1, 2, 2, 4 };
276
static const unsigned sample_shift[] = { 0, 1, 1, 2 };
277
 
278
#define SV_CENABLE_PPE     0x4
279
#define SV_CENABLE_RE      0x2
280
#define SV_CENABLE_PE      0x1
281
 
282
 
283
/* MIDI buffer sizes */
284
 
285
#define MIDIINBUF  256
286
#define MIDIOUTBUF 256
287
 
288
#define FMODE_MIDI_SHIFT 2
289
#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
290
#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
291
 
292
#define FMODE_DMFM 0x10
293
 
294
/* --------------------------------------------------------------------- */
295
 
296
struct sv_state {
297
        /* magic */
298
        unsigned int magic;
299
 
300
        /* list of sonicvibes devices */
301
        struct list_head devs;
302
 
303
        /* the corresponding pci_dev structure */
304
        struct pci_dev *dev;
305
 
306
        /* soundcore stuff */
307
        int dev_audio;
308
        int dev_mixer;
309
        int dev_midi;
310
        int dev_dmfm;
311
 
312
        /* hardware resources */
313
        unsigned long iosb, ioenh, iosynth, iomidi;  /* long for SPARC */
314
        unsigned int iodmaa, iodmac, irq;
315
 
316
        /* mixer stuff */
317
        struct {
318
                unsigned int modcnt;
319
#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
320
                unsigned short vol[13];
321
#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
322
        } mix;
323
 
324
        /* wave stuff */
325
        unsigned int rateadc, ratedac;
326
        unsigned char fmt, enable;
327
 
328
        spinlock_t lock;
329
        struct semaphore open_sem;
330
        mode_t open_mode;
331
        wait_queue_head_t open_wait;
332
 
333
        struct dmabuf {
334
                void *rawbuf;
335
                dma_addr_t dmaaddr;
336
                unsigned buforder;
337
                unsigned numfrag;
338
                unsigned fragshift;
339
                unsigned hwptr, swptr;
340
                unsigned total_bytes;
341
                int count;
342
                unsigned error; /* over/underrun */
343
                wait_queue_head_t wait;
344
                /* redundant, but makes calculations easier */
345
                unsigned fragsize;
346
                unsigned dmasize;
347
                unsigned fragsamples;
348
                /* OSS stuff */
349
                unsigned mapped:1;
350
                unsigned ready:1;
351
                unsigned endcleared:1;
352
                unsigned enabled:1;
353
                unsigned ossfragshift;
354
                int ossmaxfrags;
355
                unsigned subdivision;
356
        } dma_dac, dma_adc;
357
 
358
        /* midi stuff */
359
        struct {
360
                unsigned ird, iwr, icnt;
361
                unsigned ord, owr, ocnt;
362
                wait_queue_head_t iwait;
363
                wait_queue_head_t owait;
364
                struct timer_list timer;
365
                unsigned char ibuf[MIDIINBUF];
366
                unsigned char obuf[MIDIOUTBUF];
367
        } midi;
368
 
369
        struct gameport gameport;
370
};
371
 
372
/* --------------------------------------------------------------------- */
373
 
374
static LIST_HEAD(devs);
375
static unsigned long wavetable_mem = 0;
376
 
377
/* --------------------------------------------------------------------- */
378
 
379
static inline unsigned ld2(unsigned int x)
380
{
381
        unsigned r = 0;
382
 
383
        if (x >= 0x10000) {
384
                x >>= 16;
385
                r += 16;
386
        }
387
        if (x >= 0x100) {
388
                x >>= 8;
389
                r += 8;
390
        }
391
        if (x >= 0x10) {
392
                x >>= 4;
393
                r += 4;
394
        }
395
        if (x >= 4) {
396
                x >>= 2;
397
                r += 2;
398
        }
399
        if (x >= 2)
400
                r++;
401
        return r;
402
}
403
 
404
/*
405
 * hweightN: returns the hamming weight (i.e. the number
406
 * of bits set) of a N-bit word
407
 */
408
 
409
#ifdef hweight32
410
#undef hweight32
411
#endif
412
 
413
static inline unsigned int hweight32(unsigned int w)
414
{
415
        unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
416
        res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
417
        res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
418
        res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
419
        return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
420
}
421
 
422
/* --------------------------------------------------------------------- */
423
 
424
/*
425
 * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver.
426
 */
427
 
428
#undef DMABYTEIO
429
 
430
static void set_dmaa(struct sv_state *s, unsigned int addr, unsigned int count)
431
{
432
#ifdef DMABYTEIO
433
        unsigned io = s->iodmaa, u;
434
 
435
        count--;
436
        for (u = 4; u > 0; u--, addr >>= 8, io++)
437
                outb(addr & 0xff, io);
438
        for (u = 3; u > 0; u--, count >>= 8, io++)
439
                outb(count & 0xff, io);
440
#else /* DMABYTEIO */
441
        count--;
442
        outl(addr, s->iodmaa + SV_DMA_ADDR0);
443
        outl(count, s->iodmaa + SV_DMA_COUNT0);
444
#endif /* DMABYTEIO */
445
        outb(0x18, s->iodmaa + SV_DMA_MODE);
446
}
447
 
448
static void set_dmac(struct sv_state *s, unsigned int addr, unsigned int count)
449
{
450
#ifdef DMABYTEIO
451
        unsigned io = s->iodmac, u;
452
 
453
        count >>= 1;
454
        count--;
455
        for (u = 4; u > 0; u--, addr >>= 8, io++)
456
                outb(addr & 0xff, io);
457
        for (u = 3; u > 0; u--, count >>= 8, io++)
458
                outb(count & 0xff, io);
459
#else /* DMABYTEIO */
460
        count >>= 1;
461
        count--;
462
        outl(addr, s->iodmac + SV_DMA_ADDR0);
463
        outl(count, s->iodmac + SV_DMA_COUNT0);
464
#endif /* DMABYTEIO */
465
        outb(0x14, s->iodmac + SV_DMA_MODE);
466
}
467
 
468
static inline unsigned get_dmaa(struct sv_state *s)
469
{
470
#ifdef DMABYTEIO
471
        unsigned io = s->iodmaa+6, v = 0, u;
472
 
473
        for (u = 3; u > 0; u--, io--) {
474
                v <<= 8;
475
                v |= inb(io);
476
        }
477
        return v + 1;
478
#else /* DMABYTEIO */
479
        return (inl(s->iodmaa + SV_DMA_COUNT0) & 0xffffff) + 1;
480
#endif /* DMABYTEIO */
481
}
482
 
483
static inline unsigned get_dmac(struct sv_state *s)
484
{
485
#ifdef DMABYTEIO
486
        unsigned io = s->iodmac+6, v = 0, u;
487
 
488
        for (u = 3; u > 0; u--, io--) {
489
                v <<= 8;
490
                v |= inb(io);
491
        }
492
        return (v + 1) << 1;
493
#else /* DMABYTEIO */
494
        return ((inl(s->iodmac + SV_DMA_COUNT0) & 0xffffff) + 1) << 1;
495
#endif /* DMABYTEIO */
496
}
497
 
498
static void wrindir(struct sv_state *s, unsigned char idx, unsigned char data)
499
{
500
        outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
501
        udelay(10);
502
        outb(data, s->ioenh + SV_CODEC_IDATA);
503
        udelay(10);
504
}
505
 
506
static unsigned char rdindir(struct sv_state *s, unsigned char idx)
507
{
508
        unsigned char v;
509
 
510
        outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
511
        udelay(10);
512
        v = inb(s->ioenh + SV_CODEC_IDATA);
513
        udelay(10);
514
        return v;
515
}
516
 
517
static void set_fmt(struct sv_state *s, unsigned char mask, unsigned char data)
518
{
519
        unsigned long flags;
520
 
521
        spin_lock_irqsave(&s->lock, flags);
522
        outb(SV_CIDATAFMT | SV_CIADDR_MCE, s->ioenh + SV_CODEC_IADDR);
523
        if (mask) {
524
                s->fmt = inb(s->ioenh + SV_CODEC_IDATA);
525
                udelay(10);
526
        }
527
        s->fmt = (s->fmt & mask) | data;
528
        outb(s->fmt, s->ioenh + SV_CODEC_IDATA);
529
        udelay(10);
530
        outb(0, s->ioenh + SV_CODEC_IADDR);
531
        spin_unlock_irqrestore(&s->lock, flags);
532
        udelay(10);
533
}
534
 
535
static void frobindir(struct sv_state *s, unsigned char idx, unsigned char mask, unsigned char data)
536
{
537
        outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
538
        udelay(10);
539
        outb((inb(s->ioenh + SV_CODEC_IDATA) & mask) ^ data, s->ioenh + SV_CODEC_IDATA);
540
        udelay(10);
541
}
542
 
543
#define REFFREQUENCY  24576000
544
#define ADCMULT 512
545
#define FULLRATE 48000
546
 
547
static unsigned setpll(struct sv_state *s, unsigned char reg, unsigned rate)
548
{
549
        unsigned long flags;
550
        unsigned char r, m=0, n=0;
551
        unsigned xm, xn, xr, xd, metric = ~0U;
552
        /* the warnings about m and n used uninitialized are bogus and may safely be ignored */
553
 
554
        if (rate < 625000/ADCMULT)
555
                rate = 625000/ADCMULT;
556
        if (rate > 150000000/ADCMULT)
557
                rate = 150000000/ADCMULT;
558
        /* slight violation of specs, needed for continuous sampling rates */
559
        for (r = 0; rate < 75000000/ADCMULT; r += 0x20, rate <<= 1);
560
        for (xn = 3; xn < 35; xn++)
561
                for (xm = 3; xm < 130; xm++) {
562
                        xr = REFFREQUENCY/ADCMULT * xm / xn;
563
                        xd = abs((signed)(xr - rate));
564
                        if (xd < metric) {
565
                                metric = xd;
566
                                m = xm - 2;
567
                                n = xn - 2;
568
                        }
569
                }
570
        reg &= 0x3f;
571
        spin_lock_irqsave(&s->lock, flags);
572
        outb(reg, s->ioenh + SV_CODEC_IADDR);
573
        udelay(10);
574
        outb(m, s->ioenh + SV_CODEC_IDATA);
575
        udelay(10);
576
        outb(reg+1, s->ioenh + SV_CODEC_IADDR);
577
        udelay(10);
578
        outb(r | n, s->ioenh + SV_CODEC_IDATA);
579
        spin_unlock_irqrestore(&s->lock, flags);
580
        udelay(10);
581
        return (REFFREQUENCY/ADCMULT * (m + 2) / (n + 2)) >> ((r >> 5) & 7);
582
}
583
 
584
#if 0
585
 
586
static unsigned getpll(struct sv_state *s, unsigned char reg)
587
{
588
        unsigned long flags;
589
        unsigned char m, n;
590
 
591
        reg &= 0x3f;
592
        spin_lock_irqsave(&s->lock, flags);
593
        outb(reg, s->ioenh + SV_CODEC_IADDR);
594
        udelay(10);
595
        m = inb(s->ioenh + SV_CODEC_IDATA);
596
        udelay(10);
597
        outb(reg+1, s->ioenh + SV_CODEC_IADDR);
598
        udelay(10);
599
        n = inb(s->ioenh + SV_CODEC_IDATA);
600
        spin_unlock_irqrestore(&s->lock, flags);
601
        udelay(10);
602
        return (REFFREQUENCY/ADCMULT * (m + 2) / ((n & 0x1f) + 2)) >> ((n >> 5) & 7);
603
}
604
 
605
#endif
606
 
607
static void set_dac_rate(struct sv_state *s, unsigned rate)
608
{
609
        unsigned div;
610
        unsigned long flags;
611
 
612
        if (rate > 48000)
613
                rate = 48000;
614
        if (rate < 4000)
615
                rate = 4000;
616
        div = (rate * 65536 + FULLRATE/2) / FULLRATE;
617
        if (div > 65535)
618
                div = 65535;
619
        spin_lock_irqsave(&s->lock, flags);
620
        wrindir(s, SV_CIPCMSR1, div >> 8);
621
        wrindir(s, SV_CIPCMSR0, div);
622
        spin_unlock_irqrestore(&s->lock, flags);
623
        s->ratedac = (div * FULLRATE + 32768) / 65536;
624
}
625
 
626
static void set_adc_rate(struct sv_state *s, unsigned rate)
627
{
628
        unsigned long flags;
629
        unsigned rate1, rate2, div;
630
 
631
        if (rate > 48000)
632
                rate = 48000;
633
        if (rate < 4000)
634
                rate = 4000;
635
        rate1 = setpll(s, SV_CIADCPLLM, rate);
636
        div = (48000 + rate/2) / rate;
637
        if (div > 8)
638
                div = 8;
639
        rate2 = (48000 + div/2) / div;
640
        spin_lock_irqsave(&s->lock, flags);
641
        wrindir(s, SV_CIADCALTSR, (div-1) << 4);
642
        if (abs((signed)(rate-rate2)) <= abs((signed)(rate-rate1))) {
643
                wrindir(s, SV_CIADCCLKSOURCE, 0x10);
644
                s->rateadc = rate2;
645
        } else {
646
                wrindir(s, SV_CIADCCLKSOURCE, 0x00);
647
                s->rateadc = rate1;
648
        }
649
        spin_unlock_irqrestore(&s->lock, flags);
650
}
651
 
652
/* --------------------------------------------------------------------- */
653
 
654
static inline void stop_adc(struct sv_state *s)
655
{
656
        unsigned long flags;
657
 
658
        spin_lock_irqsave(&s->lock, flags);
659
        s->enable &= ~SV_CENABLE_RE;
660
        wrindir(s, SV_CIENABLE, s->enable);
661
        spin_unlock_irqrestore(&s->lock, flags);
662
}
663
 
664
static inline void stop_dac(struct sv_state *s)
665
{
666
        unsigned long flags;
667
 
668
        spin_lock_irqsave(&s->lock, flags);
669
        s->enable &= ~(SV_CENABLE_PPE | SV_CENABLE_PE);
670
        wrindir(s, SV_CIENABLE, s->enable);
671
        spin_unlock_irqrestore(&s->lock, flags);
672
}
673
 
674
static void start_dac(struct sv_state *s)
675
{
676
        unsigned long flags;
677
 
678
        spin_lock_irqsave(&s->lock, flags);
679
        if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
680
                s->enable = (s->enable & ~SV_CENABLE_PPE) | SV_CENABLE_PE;
681
                wrindir(s, SV_CIENABLE, s->enable);
682
        }
683
        spin_unlock_irqrestore(&s->lock, flags);
684
}
685
 
686
static void start_adc(struct sv_state *s)
687
{
688
        unsigned long flags;
689
 
690
        spin_lock_irqsave(&s->lock, flags);
691
        if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
692
            && s->dma_adc.ready) {
693
                s->enable |= SV_CENABLE_RE;
694
                wrindir(s, SV_CIENABLE, s->enable);
695
        }
696
        spin_unlock_irqrestore(&s->lock, flags);
697
}
698
 
699
/* --------------------------------------------------------------------- */
700
 
701
#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
702
#define DMABUF_MINORDER 1
703
 
704
static void dealloc_dmabuf(struct sv_state *s, struct dmabuf *db)
705
{
706
        struct page *page, *pend;
707
 
708
        if (db->rawbuf) {
709
                /* undo marking the pages as reserved */
710
                pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
711
                for (page = virt_to_page(db->rawbuf); page <= pend; page++)
712
                        mem_map_unreserve(page);
713
                pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
714
        }
715
        db->rawbuf = NULL;
716
        db->mapped = db->ready = 0;
717
}
718
 
719
 
720
/* DMAA is used for playback, DMAC is used for recording */
721
 
722
static int prog_dmabuf(struct sv_state *s, unsigned rec)
723
{
724
        struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
725
        unsigned rate = rec ? s->rateadc : s->ratedac;
726
        int order;
727
        unsigned bytepersec;
728
        unsigned bufs;
729
        struct page *page, *pend;
730
        unsigned char fmt;
731
        unsigned long flags;
732
 
733
        spin_lock_irqsave(&s->lock, flags);
734
        fmt = s->fmt;
735
        if (rec) {
736
                s->enable &= ~SV_CENABLE_RE;
737
                fmt >>= SV_CFMT_CSHIFT;
738
        } else {
739
                s->enable &= ~SV_CENABLE_PE;
740
                fmt >>= SV_CFMT_ASHIFT;
741
        }
742
        wrindir(s, SV_CIENABLE, s->enable);
743
        spin_unlock_irqrestore(&s->lock, flags);
744
        fmt &= SV_CFMT_MASK;
745
        db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
746
        if (!db->rawbuf) {
747
                db->ready = db->mapped = 0;
748
                for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
749
                        if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
750
                                break;
751
                if (!db->rawbuf)
752
                        return -ENOMEM;
753
                db->buforder = order;
754
                if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
755
                        printk(KERN_DEBUG "sv: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n",
756
                               virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
757
                if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
758
                        printk(KERN_DEBUG "sv: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n",
759
                               virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
760
                /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
761
                pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
762
                for (page = virt_to_page(db->rawbuf); page <= pend; page++)
763
                        mem_map_reserve(page);
764
        }
765
        bytepersec = rate << sample_shift[fmt];
766
        bufs = PAGE_SIZE << db->buforder;
767
        if (db->ossfragshift) {
768
                if ((1000 << db->ossfragshift) < bytepersec)
769
                        db->fragshift = ld2(bytepersec/1000);
770
                else
771
                        db->fragshift = db->ossfragshift;
772
        } else {
773
                db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
774
                if (db->fragshift < 3)
775
                        db->fragshift = 3;
776
        }
777
        db->numfrag = bufs >> db->fragshift;
778
        while (db->numfrag < 4 && db->fragshift > 3) {
779
                db->fragshift--;
780
                db->numfrag = bufs >> db->fragshift;
781
        }
782
        db->fragsize = 1 << db->fragshift;
783
        if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
784
                db->numfrag = db->ossmaxfrags;
785
        db->fragsamples = db->fragsize >> sample_shift[fmt];
786
        db->dmasize = db->numfrag << db->fragshift;
787
        memset(db->rawbuf, (fmt & SV_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
788
        spin_lock_irqsave(&s->lock, flags);
789
        if (rec) {
790
                set_dmac(s, db->dmaaddr, db->numfrag << db->fragshift);
791
                /* program enhanced mode registers */
792
                wrindir(s, SV_CIDMACBASECOUNT1, (db->fragsamples-1) >> 8);
793
                wrindir(s, SV_CIDMACBASECOUNT0, db->fragsamples-1);
794
        } else {
795
                set_dmaa(s, db->dmaaddr, db->numfrag << db->fragshift);
796
                /* program enhanced mode registers */
797
                wrindir(s, SV_CIDMAABASECOUNT1, (db->fragsamples-1) >> 8);
798
                wrindir(s, SV_CIDMAABASECOUNT0, db->fragsamples-1);
799
        }
800
        spin_unlock_irqrestore(&s->lock, flags);
801
        db->enabled = 1;
802
        db->ready = 1;
803
        return 0;
804
}
805
 
806
static inline void clear_advance(struct sv_state *s)
807
{
808
        unsigned char c = (s->fmt & (SV_CFMT_16BIT << SV_CFMT_ASHIFT)) ? 0 : 0x80;
809
        unsigned char *buf = s->dma_dac.rawbuf;
810
        unsigned bsize = s->dma_dac.dmasize;
811
        unsigned bptr = s->dma_dac.swptr;
812
        unsigned len = s->dma_dac.fragsize;
813
 
814
        if (bptr + len > bsize) {
815
                unsigned x = bsize - bptr;
816
                memset(buf + bptr, c, x);
817
                bptr = 0;
818
                len -= x;
819
        }
820
        memset(buf + bptr, c, len);
821
}
822
 
823
/* call with spinlock held! */
824
static void sv_update_ptr(struct sv_state *s)
825
{
826
        unsigned hwptr;
827
        int diff;
828
 
829
        /* update ADC pointer */
830
        if (s->dma_adc.ready) {
831
                hwptr = (s->dma_adc.dmasize - get_dmac(s)) % s->dma_adc.dmasize;
832
                diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
833
                s->dma_adc.hwptr = hwptr;
834
                s->dma_adc.total_bytes += diff;
835
                s->dma_adc.count += diff;
836
                if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
837
                        wake_up(&s->dma_adc.wait);
838
                if (!s->dma_adc.mapped) {
839
                        if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
840
                                s->enable &= ~SV_CENABLE_RE;
841
                                wrindir(s, SV_CIENABLE, s->enable);
842
                                s->dma_adc.error++;
843
                        }
844
                }
845
        }
846
        /* update DAC pointer */
847
        if (s->dma_dac.ready) {
848
                hwptr = (s->dma_dac.dmasize - get_dmaa(s)) % s->dma_dac.dmasize;
849
                diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
850
                s->dma_dac.hwptr = hwptr;
851
                s->dma_dac.total_bytes += diff;
852
                if (s->dma_dac.mapped) {
853
                        s->dma_dac.count += diff;
854
                        if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
855
                                wake_up(&s->dma_dac.wait);
856
                } else {
857
                        s->dma_dac.count -= diff;
858
                        if (s->dma_dac.count <= 0) {
859
                                s->enable &= ~SV_CENABLE_PE;
860
                                wrindir(s, SV_CIENABLE, s->enable);
861
                                s->dma_dac.error++;
862
                        } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
863
                                clear_advance(s);
864
                                s->dma_dac.endcleared = 1;
865
                        }
866
                        if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
867
                                wake_up(&s->dma_dac.wait);
868
                }
869
        }
870
}
871
 
872
/* hold spinlock for the following! */
873
static void sv_handle_midi(struct sv_state *s)
874
{
875
        unsigned char ch;
876
        int wake;
877
 
878
        wake = 0;
879
        while (!(inb(s->iomidi+1) & 0x80)) {
880
                ch = inb(s->iomidi);
881
                if (s->midi.icnt < MIDIINBUF) {
882
                        s->midi.ibuf[s->midi.iwr] = ch;
883
                        s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
884
                        s->midi.icnt++;
885
                }
886
                wake = 1;
887
        }
888
        if (wake)
889
                wake_up(&s->midi.iwait);
890
        wake = 0;
891
        while (!(inb(s->iomidi+1) & 0x40) && s->midi.ocnt > 0) {
892
                outb(s->midi.obuf[s->midi.ord], s->iomidi);
893
                s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
894
                s->midi.ocnt--;
895
                if (s->midi.ocnt < MIDIOUTBUF-16)
896
                        wake = 1;
897
        }
898
        if (wake)
899
                wake_up(&s->midi.owait);
900
}
901
 
902
static void sv_interrupt(int irq, void *dev_id, struct pt_regs *regs)
903
{
904
        struct sv_state *s = (struct sv_state *)dev_id;
905
        unsigned int intsrc;
906
 
907
        /* fastpath out, to ease interrupt sharing */
908
        intsrc = inb(s->ioenh + SV_CODEC_STATUS);
909
        if (!(intsrc & (SV_CSTAT_DMAA | SV_CSTAT_DMAC | SV_CSTAT_MIDI)))
910
                return;
911
        spin_lock(&s->lock);
912
        sv_update_ptr(s);
913
        sv_handle_midi(s);
914
        spin_unlock(&s->lock);
915
}
916
 
917
static void sv_midi_timer(unsigned long data)
918
{
919
        struct sv_state *s = (struct sv_state *)data;
920
        unsigned long flags;
921
 
922
        spin_lock_irqsave(&s->lock, flags);
923
        sv_handle_midi(s);
924
        spin_unlock_irqrestore(&s->lock, flags);
925
        s->midi.timer.expires = jiffies+1;
926
        add_timer(&s->midi.timer);
927
}
928
 
929
/* --------------------------------------------------------------------- */
930
 
931
static const char invalid_magic[] = KERN_CRIT "sv: invalid magic value\n";
932
 
933
#define VALIDATE_STATE(s)                         \
934
({                                                \
935
        if (!(s) || (s)->magic != SV_MAGIC) { \
936
                printk(invalid_magic);            \
937
                return -ENXIO;                    \
938
        }                                         \
939
})
940
 
941
/* --------------------------------------------------------------------- */
942
 
943
#define MT_4          1
944
#define MT_5MUTE      2
945
#define MT_4MUTEMONO  3
946
#define MT_6MUTE      4
947
 
948
static const struct {
949
        unsigned left:5;
950
        unsigned right:5;
951
        unsigned type:3;
952
        unsigned rec:3;
953
} mixtable[SOUND_MIXER_NRDEVICES] = {
954
        [SOUND_MIXER_RECLEV] = { SV_CIMIX_ADCINL,    SV_CIMIX_ADCINR,    MT_4,         0 },
955
        [SOUND_MIXER_LINE1]  = { SV_CIMIX_AUX1INL,   SV_CIMIX_AUX1INR,   MT_5MUTE,     5 },
956
        [SOUND_MIXER_CD]     = { SV_CIMIX_CDINL,     SV_CIMIX_CDINR,     MT_5MUTE,     1 },
957
        [SOUND_MIXER_LINE]   = { SV_CIMIX_LINEINL,   SV_CIMIX_LINEINR,   MT_5MUTE,     4 },
958
        [SOUND_MIXER_MIC]    = { SV_CIMIX_MICIN,     SV_CIMIX_ADCINL,    MT_4MUTEMONO, 6 },
959
        [SOUND_MIXER_SYNTH]  = { SV_CIMIX_SYNTHINL,  SV_CIMIX_SYNTHINR,  MT_5MUTE,     2 },
960
        [SOUND_MIXER_LINE2]  = { SV_CIMIX_AUX2INL,   SV_CIMIX_AUX2INR,   MT_5MUTE,     3 },
961
        [SOUND_MIXER_VOLUME] = { SV_CIMIX_ANALOGINL, SV_CIMIX_ANALOGINR, MT_5MUTE,     7 },
962
        [SOUND_MIXER_PCM]    = { SV_CIMIX_PCMINL,    SV_CIMIX_PCMINR,    MT_6MUTE,     0 }
963
};
964
 
965
#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
966
 
967
static int return_mixval(struct sv_state *s, unsigned i, int *arg)
968
{
969
        unsigned long flags;
970
        unsigned char l, r, rl, rr;
971
 
972
        spin_lock_irqsave(&s->lock, flags);
973
        l = rdindir(s, mixtable[i].left);
974
        r = rdindir(s, mixtable[i].right);
975
        spin_unlock_irqrestore(&s->lock, flags);
976
        switch (mixtable[i].type) {
977
        case MT_4:
978
                r &= 0xf;
979
                l &= 0xf;
980
                rl = 10 + 6 * (l & 15);
981
                rr = 10 + 6 * (r & 15);
982
                break;
983
 
984
        case MT_4MUTEMONO:
985
                rl = 55 - 3 * (l & 15);
986
                if (r & 0x10)
987
                        rl += 45;
988
                rr = rl;
989
                r = l;
990
                break;
991
 
992
        case MT_5MUTE:
993
        default:
994
                rl = 100 - 3 * (l & 31);
995
                rr = 100 - 3 * (r & 31);
996
                break;
997
 
998
        case MT_6MUTE:
999
                rl = 100 - 3 * (l & 63) / 2;
1000
                rr = 100 - 3 * (r & 63) / 2;
1001
                break;
1002
        }
1003
        if (l & 0x80)
1004
                rl = 0;
1005
        if (r & 0x80)
1006
                rr = 0;
1007
        return put_user((rr << 8) | rl, arg);
1008
}
1009
 
1010
#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1011
 
1012
static const unsigned char volidx[SOUND_MIXER_NRDEVICES] =
1013
{
1014
        [SOUND_MIXER_RECLEV] = 1,
1015
        [SOUND_MIXER_LINE1]  = 2,
1016
        [SOUND_MIXER_CD]     = 3,
1017
        [SOUND_MIXER_LINE]   = 4,
1018
        [SOUND_MIXER_MIC]    = 5,
1019
        [SOUND_MIXER_SYNTH]  = 6,
1020
        [SOUND_MIXER_LINE2]  = 7,
1021
        [SOUND_MIXER_VOLUME] = 8,
1022
        [SOUND_MIXER_PCM]    = 9
1023
};
1024
 
1025
#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1026
 
1027
static unsigned mixer_recmask(struct sv_state *s)
1028
{
1029
        unsigned long flags;
1030
        int i, j;
1031
 
1032
        spin_lock_irqsave(&s->lock, flags);
1033
        j = rdindir(s, SV_CIMIX_ADCINL) >> 5;
1034
        spin_unlock_irqrestore(&s->lock, flags);
1035
        j &= 7;
1036
        for (i = 0; i < SOUND_MIXER_NRDEVICES && mixtable[i].rec != j; i++);
1037
        return 1 << i;
1038
}
1039
 
1040
static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
1041
{
1042
        unsigned long flags;
1043
        int i, val;
1044
        unsigned char l, r, rl, rr;
1045
 
1046
        VALIDATE_STATE(s);
1047
        if (cmd == SOUND_MIXER_INFO) {
1048
                mixer_info info;
1049
                strncpy(info.id, "SonicVibes", sizeof(info.id));
1050
                strncpy(info.name, "S3 SonicVibes", sizeof(info.name));
1051
                info.modify_counter = s->mix.modcnt;
1052
                if (copy_to_user((void *)arg, &info, sizeof(info)))
1053
                        return -EFAULT;
1054
                return 0;
1055
        }
1056
        if (cmd == SOUND_OLD_MIXER_INFO) {
1057
                _old_mixer_info info;
1058
                strncpy(info.id, "SonicVibes", sizeof(info.id));
1059
                strncpy(info.name, "S3 SonicVibes", sizeof(info.name));
1060
                if (copy_to_user((void *)arg, &info, sizeof(info)))
1061
                        return -EFAULT;
1062
                return 0;
1063
        }
1064
        if (cmd == OSS_GETVERSION)
1065
                return put_user(SOUND_VERSION, (int *)arg);
1066
        if (cmd == SOUND_MIXER_PRIVATE1) {  /* SRS settings */
1067
                if (get_user(val, (int *)arg))
1068
                        return -EFAULT;
1069
                spin_lock_irqsave(&s->lock, flags);
1070
                if (val & 1) {
1071
                        if (val & 2) {
1072
                                l = 4 - ((val >> 2) & 7);
1073
                                if (l & ~3)
1074
                                        l = 4;
1075
                                r = 4 - ((val >> 5) & 7);
1076
                                if (r & ~3)
1077
                                        r = 4;
1078
                                wrindir(s, SV_CISRSSPACE, l);
1079
                                wrindir(s, SV_CISRSCENTER, r);
1080
                        } else
1081
                                wrindir(s, SV_CISRSSPACE, 0x80);
1082
                }
1083
                l = rdindir(s, SV_CISRSSPACE);
1084
                r = rdindir(s, SV_CISRSCENTER);
1085
                spin_unlock_irqrestore(&s->lock, flags);
1086
                if (l & 0x80)
1087
                        return put_user(0, (int *)arg);
1088
                return put_user(((4 - (l & 7)) << 2) | ((4 - (r & 7)) << 5) | 2, (int *)arg);
1089
        }
1090
        if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
1091
                return -EINVAL;
1092
        if (_SIOC_DIR(cmd) == _SIOC_READ) {
1093
                switch (_IOC_NR(cmd)) {
1094
                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
1095
                        return put_user(mixer_recmask(s), (int *)arg);
1096
 
1097
                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
1098
                        for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1099
                                if (mixtable[i].type)
1100
                                        val |= 1 << i;
1101
                        return put_user(val, (int *)arg);
1102
 
1103
                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
1104
                        for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1105
                                if (mixtable[i].rec)
1106
                                        val |= 1 << i;
1107
                        return put_user(val, (int *)arg);
1108
 
1109
                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
1110
                        for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1111
                                if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
1112
                                        val |= 1 << i;
1113
                        return put_user(val, (int *)arg);
1114
 
1115
                case SOUND_MIXER_CAPS:
1116
                        return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
1117
 
1118
                default:
1119
                        i = _IOC_NR(cmd);
1120
                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
1121
                                return -EINVAL;
1122
#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
1123
                        return return_mixval(s, i, (int *)arg);
1124
#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1125
                        if (!volidx[i])
1126
                                return -EINVAL;
1127
                        return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
1128
#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1129
                }
1130
        }
1131
        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE))
1132
                return -EINVAL;
1133
        s->mix.modcnt++;
1134
        switch (_IOC_NR(cmd)) {
1135
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
1136
                if (get_user(val, (int *)arg))
1137
                        return -EFAULT;
1138
                i = hweight32(val);
1139
                if (i == 0)
1140
                        return 0; /*val = mixer_recmask(s);*/
1141
                else if (i > 1)
1142
                        val &= ~mixer_recmask(s);
1143
                for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
1144
                        if (!(val & (1 << i)))
1145
                                continue;
1146
                        if (mixtable[i].rec)
1147
                                break;
1148
                }
1149
                if (!mixtable[i].rec)
1150
                        return 0;
1151
                spin_lock_irqsave(&s->lock, flags);
1152
                frobindir(s, SV_CIMIX_ADCINL, 0x1f, mixtable[i].rec << 5);
1153
                frobindir(s, SV_CIMIX_ADCINR, 0x1f, mixtable[i].rec << 5);
1154
                spin_unlock_irqrestore(&s->lock, flags);
1155
                return 0;
1156
 
1157
        default:
1158
                i = _IOC_NR(cmd);
1159
                if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
1160
                        return -EINVAL;
1161
                if (get_user(val, (int *)arg))
1162
                        return -EFAULT;
1163
                l = val & 0xff;
1164
                r = (val >> 8) & 0xff;
1165
                if (mixtable[i].type == MT_4MUTEMONO)
1166
                        l = (r + l) / 2;
1167
                if (l > 100)
1168
                        l = 100;
1169
                if (r > 100)
1170
                        r = 100;
1171
                spin_lock_irqsave(&s->lock, flags);
1172
                switch (mixtable[i].type) {
1173
                case MT_4:
1174
                        if (l >= 10)
1175
                                l -= 10;
1176
                        if (r >= 10)
1177
                                r -= 10;
1178
                        frobindir(s, mixtable[i].left, 0xf0, l / 6);
1179
                        frobindir(s, mixtable[i].right, 0xf0, l / 6);
1180
                        break;
1181
 
1182
                case MT_4MUTEMONO:
1183
                        rr = 0;
1184
                        if (l < 10)
1185
                                rl = 0x80;
1186
                        else {
1187
                                if (l >= 55) {
1188
                                        rr = 0x10;
1189
                                        l -= 45;
1190
                                }
1191
                                rl = (55 - l) / 3;
1192
                        }
1193
                        wrindir(s, mixtable[i].left, rl);
1194
                        frobindir(s, mixtable[i].right, ~0x10, rr);
1195
                        break;
1196
 
1197
                case MT_5MUTE:
1198
                        if (l < 7)
1199
                                rl = 0x80;
1200
                        else
1201
                                rl = (100 - l) / 3;
1202
                        if (r < 7)
1203
                                rr = 0x80;
1204
                        else
1205
                                rr = (100 - r) / 3;
1206
                        wrindir(s, mixtable[i].left, rl);
1207
                        wrindir(s, mixtable[i].right, rr);
1208
                        break;
1209
 
1210
                case MT_6MUTE:
1211
                        if (l < 6)
1212
                                rl = 0x80;
1213
                        else
1214
                                rl = (100 - l) * 2 / 3;
1215
                        if (r < 6)
1216
                                rr = 0x80;
1217
                        else
1218
                                rr = (100 - r) * 2 / 3;
1219
                        wrindir(s, mixtable[i].left, rl);
1220
                        wrindir(s, mixtable[i].right, rr);
1221
                        break;
1222
                }
1223
                spin_unlock_irqrestore(&s->lock, flags);
1224
#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
1225
                return return_mixval(s, i, (int *)arg);
1226
#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1227
                if (!volidx[i])
1228
                        return -EINVAL;
1229
                s->mix.vol[volidx[i]-1] = val;
1230
                return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
1231
#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1232
        }
1233
}
1234
 
1235
/* --------------------------------------------------------------------- */
1236
 
1237
static int sv_open_mixdev(struct inode *inode, struct file *file)
1238
{
1239
        int minor = MINOR(inode->i_rdev);
1240
        struct list_head *list;
1241
        struct sv_state *s;
1242
 
1243
        for (list = devs.next; ; list = list->next) {
1244
                if (list == &devs)
1245
                        return -ENODEV;
1246
                s = list_entry(list, struct sv_state, devs);
1247
                if (s->dev_mixer == minor)
1248
                        break;
1249
        }
1250
        VALIDATE_STATE(s);
1251
        file->private_data = s;
1252
        return 0;
1253
}
1254
 
1255
static int sv_release_mixdev(struct inode *inode, struct file *file)
1256
{
1257
        struct sv_state *s = (struct sv_state *)file->private_data;
1258
 
1259
        VALIDATE_STATE(s);
1260
        return 0;
1261
}
1262
 
1263
static int sv_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
1264
{
1265
        return mixer_ioctl((struct sv_state *)file->private_data, cmd, arg);
1266
}
1267
 
1268
static /*const*/ struct file_operations sv_mixer_fops = {
1269
        owner:          THIS_MODULE,
1270
        llseek:         no_llseek,
1271
        ioctl:          sv_ioctl_mixdev,
1272
        open:           sv_open_mixdev,
1273
        release:        sv_release_mixdev,
1274
};
1275
 
1276
/* --------------------------------------------------------------------- */
1277
 
1278
static int drain_dac(struct sv_state *s, int nonblock)
1279
{
1280
        DECLARE_WAITQUEUE(wait, current);
1281
        unsigned long flags;
1282
        int count, tmo;
1283
 
1284
        if (s->dma_dac.mapped || !s->dma_dac.ready)
1285
                return 0;
1286
        add_wait_queue(&s->dma_dac.wait, &wait);
1287
        for (;;) {
1288
                __set_current_state(TASK_INTERRUPTIBLE);
1289
                spin_lock_irqsave(&s->lock, flags);
1290
                count = s->dma_dac.count;
1291
                spin_unlock_irqrestore(&s->lock, flags);
1292
                if (count <= 0)
1293
                        break;
1294
                if (signal_pending(current))
1295
                        break;
1296
                if (nonblock) {
1297
                        remove_wait_queue(&s->dma_dac.wait, &wait);
1298
                        set_current_state(TASK_RUNNING);
1299
                        return -EBUSY;
1300
                }
1301
                tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
1302
                tmo >>= sample_shift[(s->fmt >> SV_CFMT_ASHIFT) & SV_CFMT_MASK];
1303
                if (!schedule_timeout(tmo + 1))
1304
                        printk(KERN_DEBUG "sv: dma timed out??\n");
1305
        }
1306
        remove_wait_queue(&s->dma_dac.wait, &wait);
1307
        set_current_state(TASK_RUNNING);
1308
        if (signal_pending(current))
1309
                return -ERESTARTSYS;
1310
        return 0;
1311
}
1312
 
1313
/* --------------------------------------------------------------------- */
1314
 
1315
static ssize_t sv_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
1316
{
1317
        struct sv_state *s = (struct sv_state *)file->private_data;
1318
        DECLARE_WAITQUEUE(wait, current);
1319
        ssize_t ret;
1320
        unsigned long flags;
1321
        unsigned swptr;
1322
        int cnt;
1323
 
1324
        VALIDATE_STATE(s);
1325
        if (ppos != &file->f_pos)
1326
                return -ESPIPE;
1327
        if (s->dma_adc.mapped)
1328
                return -ENXIO;
1329
        if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
1330
                return ret;
1331
        if (!access_ok(VERIFY_WRITE, buffer, count))
1332
                return -EFAULT;
1333
        ret = 0;
1334
#if 0
1335
        spin_lock_irqsave(&s->lock, flags);
1336
        sv_update_ptr(s);
1337
        spin_unlock_irqrestore(&s->lock, flags);
1338
#endif
1339
        add_wait_queue(&s->dma_adc.wait, &wait);
1340
        while (count > 0) {
1341
                spin_lock_irqsave(&s->lock, flags);
1342
                swptr = s->dma_adc.swptr;
1343
                cnt = s->dma_adc.dmasize-swptr;
1344
                if (s->dma_adc.count < cnt)
1345
                        cnt = s->dma_adc.count;
1346
                if (cnt <= 0)
1347
                        __set_current_state(TASK_INTERRUPTIBLE);
1348
                spin_unlock_irqrestore(&s->lock, flags);
1349
                if (cnt > count)
1350
                        cnt = count;
1351
                if (cnt <= 0) {
1352
                        if (s->dma_adc.enabled)
1353
                                start_adc(s);
1354
                        if (file->f_flags & O_NONBLOCK) {
1355
                                if (!ret)
1356
                                        ret = -EAGAIN;
1357
                                break;
1358
                        }
1359
                        if (!schedule_timeout(HZ)) {
1360
                                printk(KERN_DEBUG "sv: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
1361
                                       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
1362
                                       s->dma_adc.hwptr, s->dma_adc.swptr);
1363
                                stop_adc(s);
1364
                                spin_lock_irqsave(&s->lock, flags);
1365
                                set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
1366
                                /* program enhanced mode registers */
1367
                                wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8);
1368
                                wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1);
1369
                                s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
1370
                                spin_unlock_irqrestore(&s->lock, flags);
1371
                        }
1372
                        if (signal_pending(current)) {
1373
                                if (!ret)
1374
                                        ret = -ERESTARTSYS;
1375
                                break;
1376
                        }
1377
                        continue;
1378
                }
1379
                if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
1380
                        if (!ret)
1381
                                ret = -EFAULT;
1382
                        break;
1383
                }
1384
                swptr = (swptr + cnt) % s->dma_adc.dmasize;
1385
                spin_lock_irqsave(&s->lock, flags);
1386
                s->dma_adc.swptr = swptr;
1387
                s->dma_adc.count -= cnt;
1388
                spin_unlock_irqrestore(&s->lock, flags);
1389
                count -= cnt;
1390
                buffer += cnt;
1391
                ret += cnt;
1392
                if (s->dma_adc.enabled)
1393
                        start_adc(s);
1394
        }
1395
        remove_wait_queue(&s->dma_adc.wait, &wait);
1396
        set_current_state(TASK_RUNNING);
1397
        return ret;
1398
}
1399
 
1400
static ssize_t sv_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
1401
{
1402
        struct sv_state *s = (struct sv_state *)file->private_data;
1403
        DECLARE_WAITQUEUE(wait, current);
1404
        ssize_t ret;
1405
        unsigned long flags;
1406
        unsigned swptr;
1407
        int cnt;
1408
 
1409
        VALIDATE_STATE(s);
1410
        if (ppos != &file->f_pos)
1411
                return -ESPIPE;
1412
        if (s->dma_dac.mapped)
1413
                return -ENXIO;
1414
        if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
1415
                return ret;
1416
        if (!access_ok(VERIFY_READ, buffer, count))
1417
                return -EFAULT;
1418
        ret = 0;
1419
#if 0
1420
        spin_lock_irqsave(&s->lock, flags);
1421
        sv_update_ptr(s);
1422
        spin_unlock_irqrestore(&s->lock, flags);
1423
#endif
1424
        add_wait_queue(&s->dma_dac.wait, &wait);
1425
        while (count > 0) {
1426
                spin_lock_irqsave(&s->lock, flags);
1427
                if (s->dma_dac.count < 0) {
1428
                        s->dma_dac.count = 0;
1429
                        s->dma_dac.swptr = s->dma_dac.hwptr;
1430
                }
1431
                swptr = s->dma_dac.swptr;
1432
                cnt = s->dma_dac.dmasize-swptr;
1433
                if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
1434
                        cnt = s->dma_dac.dmasize - s->dma_dac.count;
1435
                if (cnt <= 0)
1436
                        __set_current_state(TASK_INTERRUPTIBLE);
1437
                spin_unlock_irqrestore(&s->lock, flags);
1438
                if (cnt > count)
1439
                        cnt = count;
1440
                if (cnt <= 0) {
1441
                        if (s->dma_dac.enabled)
1442
                                start_dac(s);
1443
                        if (file->f_flags & O_NONBLOCK) {
1444
                                if (!ret)
1445
                                        ret = -EAGAIN;
1446
                                break;
1447
                        }
1448
                        if (!schedule_timeout(HZ)) {
1449
                                printk(KERN_DEBUG "sv: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
1450
                                       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
1451
                                       s->dma_dac.hwptr, s->dma_dac.swptr);
1452
                                stop_dac(s);
1453
                                spin_lock_irqsave(&s->lock, flags);
1454
                                set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
1455
                                /* program enhanced mode registers */
1456
                                wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8);
1457
                                wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1);
1458
                                s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
1459
                                spin_unlock_irqrestore(&s->lock, flags);
1460
                        }
1461
                        if (signal_pending(current)) {
1462
                                if (!ret)
1463
                                        ret = -ERESTARTSYS;
1464
                                break;
1465
                        }
1466
                        continue;
1467
                }
1468
                if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
1469
                        if (!ret)
1470
                                ret = -EFAULT;
1471
                        break;
1472
                }
1473
                swptr = (swptr + cnt) % s->dma_dac.dmasize;
1474
                spin_lock_irqsave(&s->lock, flags);
1475
                s->dma_dac.swptr = swptr;
1476
                s->dma_dac.count += cnt;
1477
                s->dma_dac.endcleared = 0;
1478
                spin_unlock_irqrestore(&s->lock, flags);
1479
                count -= cnt;
1480
                buffer += cnt;
1481
                ret += cnt;
1482
                if (s->dma_dac.enabled)
1483
                        start_dac(s);
1484
        }
1485
        remove_wait_queue(&s->dma_dac.wait, &wait);
1486
        set_current_state(TASK_RUNNING);
1487
        return ret;
1488
}
1489
 
1490
/* No kernel lock - we have our own spinlock */
1491
static unsigned int sv_poll(struct file *file, struct poll_table_struct *wait)
1492
{
1493
        struct sv_state *s = (struct sv_state *)file->private_data;
1494
        unsigned long flags;
1495
        unsigned int mask = 0;
1496
 
1497
        VALIDATE_STATE(s);
1498
        if (file->f_mode & FMODE_WRITE) {
1499
                if (!s->dma_dac.ready && prog_dmabuf(s, 1))
1500
                        return 0;
1501
                poll_wait(file, &s->dma_dac.wait, wait);
1502
        }
1503
        if (file->f_mode & FMODE_READ) {
1504
                if (!s->dma_adc.ready && prog_dmabuf(s, 0))
1505
                        return 0;
1506
                poll_wait(file, &s->dma_adc.wait, wait);
1507
        }
1508
        spin_lock_irqsave(&s->lock, flags);
1509
        sv_update_ptr(s);
1510
        if (file->f_mode & FMODE_READ) {
1511
                if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
1512
                        mask |= POLLIN | POLLRDNORM;
1513
        }
1514
        if (file->f_mode & FMODE_WRITE) {
1515
                if (s->dma_dac.mapped) {
1516
                        if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
1517
                                mask |= POLLOUT | POLLWRNORM;
1518
                } else {
1519
                        if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
1520
                                mask |= POLLOUT | POLLWRNORM;
1521
                }
1522
        }
1523
        spin_unlock_irqrestore(&s->lock, flags);
1524
        return mask;
1525
}
1526
 
1527
static int sv_mmap(struct file *file, struct vm_area_struct *vma)
1528
{
1529
        struct sv_state *s = (struct sv_state *)file->private_data;
1530
        struct dmabuf *db;
1531
        int ret = -EINVAL;
1532
        unsigned long size;
1533
 
1534
        VALIDATE_STATE(s);
1535
        lock_kernel();
1536
        if (vma->vm_flags & VM_WRITE) {
1537
                if ((ret = prog_dmabuf(s, 1)) != 0)
1538
                        goto out;
1539
                db = &s->dma_dac;
1540
        } else if (vma->vm_flags & VM_READ) {
1541
                if ((ret = prog_dmabuf(s, 0)) != 0)
1542
                        goto out;
1543
                db = &s->dma_adc;
1544
        } else
1545
                goto out;
1546
        ret = -EINVAL;
1547
        if (vma->vm_pgoff != 0)
1548
                goto out;
1549
        size = vma->vm_end - vma->vm_start;
1550
        if (size > (PAGE_SIZE << db->buforder))
1551
                goto out;
1552
        ret = -EAGAIN;
1553
        if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
1554
                goto out;
1555
        db->mapped = 1;
1556
        ret = 0;
1557
out:
1558
        unlock_kernel();
1559
        return ret;
1560
}
1561
 
1562
static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
1563
{
1564
        struct sv_state *s = (struct sv_state *)file->private_data;
1565
        unsigned long flags;
1566
        audio_buf_info abinfo;
1567
        count_info cinfo;
1568
        int count;
1569
        int val, mapped, ret;
1570
        unsigned char fmtm, fmtd;
1571
 
1572
        VALIDATE_STATE(s);
1573
        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
1574
                ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
1575
        switch (cmd) {
1576
        case OSS_GETVERSION:
1577
                return put_user(SOUND_VERSION, (int *)arg);
1578
 
1579
        case SNDCTL_DSP_SYNC:
1580
                if (file->f_mode & FMODE_WRITE)
1581
                        return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
1582
                return 0;
1583
 
1584
        case SNDCTL_DSP_SETDUPLEX:
1585
                return 0;
1586
 
1587
        case SNDCTL_DSP_GETCAPS:
1588
                return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
1589
 
1590
        case SNDCTL_DSP_RESET:
1591
                if (file->f_mode & FMODE_WRITE) {
1592
                        stop_dac(s);
1593
                        synchronize_irq();
1594
                        s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
1595
                }
1596
                if (file->f_mode & FMODE_READ) {
1597
                        stop_adc(s);
1598
                        synchronize_irq();
1599
                        s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
1600
                }
1601
                return 0;
1602
 
1603
        case SNDCTL_DSP_SPEED:
1604
                if (get_user(val, (int *)arg))
1605
                        return -EFAULT;
1606
                if (val >= 0) {
1607
                        if (file->f_mode & FMODE_READ) {
1608
                                stop_adc(s);
1609
                                s->dma_adc.ready = 0;
1610
                                set_adc_rate(s, val);
1611
                        }
1612
                        if (file->f_mode & FMODE_WRITE) {
1613
                                stop_dac(s);
1614
                                s->dma_dac.ready = 0;
1615
                                set_dac_rate(s, val);
1616
                        }
1617
                }
1618
                return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
1619
 
1620
        case SNDCTL_DSP_STEREO:
1621
                if (get_user(val, (int *)arg))
1622
                        return -EFAULT;
1623
                fmtd = 0;
1624
                fmtm = ~0;
1625
                if (file->f_mode & FMODE_READ) {
1626
                        stop_adc(s);
1627
                        s->dma_adc.ready = 0;
1628
                        if (val)
1629
                                fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT;
1630
                        else
1631
                                fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT);
1632
                }
1633
                if (file->f_mode & FMODE_WRITE) {
1634
                        stop_dac(s);
1635
                        s->dma_dac.ready = 0;
1636
                        if (val)
1637
                                fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT;
1638
                        else
1639
                                fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT);
1640
                }
1641
                set_fmt(s, fmtm, fmtd);
1642
                return 0;
1643
 
1644
        case SNDCTL_DSP_CHANNELS:
1645
                if (get_user(val, (int *)arg))
1646
                        return -EFAULT;
1647
                if (val != 0) {
1648
                        fmtd = 0;
1649
                        fmtm = ~0;
1650
                        if (file->f_mode & FMODE_READ) {
1651
                                stop_adc(s);
1652
                                s->dma_adc.ready = 0;
1653
                                if (val >= 2)
1654
                                        fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT;
1655
                                else
1656
                                        fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT);
1657
                        }
1658
                        if (file->f_mode & FMODE_WRITE) {
1659
                                stop_dac(s);
1660
                                s->dma_dac.ready = 0;
1661
                                if (val >= 2)
1662
                                        fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT;
1663
                                else
1664
                                        fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT);
1665
                        }
1666
                        set_fmt(s, fmtm, fmtd);
1667
                }
1668
                return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT)
1669
                                           : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, (int *)arg);
1670
 
1671
        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
1672
                return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
1673
 
1674
        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
1675
                if (get_user(val, (int *)arg))
1676
                        return -EFAULT;
1677
                if (val != AFMT_QUERY) {
1678
                        fmtd = 0;
1679
                        fmtm = ~0;
1680
                        if (file->f_mode & FMODE_READ) {
1681
                                stop_adc(s);
1682
                                s->dma_adc.ready = 0;
1683
                                if (val == AFMT_S16_LE)
1684
                                        fmtd |= SV_CFMT_16BIT << SV_CFMT_CSHIFT;
1685
                                else
1686
                                        fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_CSHIFT);
1687
                        }
1688
                        if (file->f_mode & FMODE_WRITE) {
1689
                                stop_dac(s);
1690
                                s->dma_dac.ready = 0;
1691
                                if (val == AFMT_S16_LE)
1692
                                        fmtd |= SV_CFMT_16BIT << SV_CFMT_ASHIFT;
1693
                                else
1694
                                        fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_ASHIFT);
1695
                        }
1696
                        set_fmt(s, fmtm, fmtd);
1697
                }
1698
                return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT)
1699
                                           : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? AFMT_S16_LE : AFMT_U8, (int *)arg);
1700
 
1701
        case SNDCTL_DSP_POST:
1702
                return 0;
1703
 
1704
        case SNDCTL_DSP_GETTRIGGER:
1705
                val = 0;
1706
                if (file->f_mode & FMODE_READ && s->enable & SV_CENABLE_RE)
1707
                        val |= PCM_ENABLE_INPUT;
1708
                if (file->f_mode & FMODE_WRITE && s->enable & SV_CENABLE_PE)
1709
                        val |= PCM_ENABLE_OUTPUT;
1710
                return put_user(val, (int *)arg);
1711
 
1712
        case SNDCTL_DSP_SETTRIGGER:
1713
                if (get_user(val, (int *)arg))
1714
                        return -EFAULT;
1715
                if (file->f_mode & FMODE_READ) {
1716
                        if (val & PCM_ENABLE_INPUT) {
1717
                                if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
1718
                                        return ret;
1719
                                s->dma_adc.enabled = 1;
1720
                                start_adc(s);
1721
                        } else {
1722
                                s->dma_adc.enabled = 0;
1723
                                stop_adc(s);
1724
                        }
1725
                }
1726
                if (file->f_mode & FMODE_WRITE) {
1727
                        if (val & PCM_ENABLE_OUTPUT) {
1728
                                if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
1729
                                        return ret;
1730
                                s->dma_dac.enabled = 1;
1731
                                start_dac(s);
1732
                        } else {
1733
                                s->dma_dac.enabled = 0;
1734
                                stop_dac(s);
1735
                        }
1736
                }
1737
                return 0;
1738
 
1739
        case SNDCTL_DSP_GETOSPACE:
1740
                if (!(file->f_mode & FMODE_WRITE))
1741
                        return -EINVAL;
1742
                if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
1743
                        return val;
1744
                spin_lock_irqsave(&s->lock, flags);
1745
                sv_update_ptr(s);
1746
                abinfo.fragsize = s->dma_dac.fragsize;
1747
                count = s->dma_dac.count;
1748
                if (count < 0)
1749
                        count = 0;
1750
                abinfo.bytes = s->dma_dac.dmasize - count;
1751
                abinfo.fragstotal = s->dma_dac.numfrag;
1752
                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
1753
                spin_unlock_irqrestore(&s->lock, flags);
1754
                return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
1755
 
1756
        case SNDCTL_DSP_GETISPACE:
1757
                if (!(file->f_mode & FMODE_READ))
1758
                        return -EINVAL;
1759
                if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0)
1760
                        return val;
1761
                spin_lock_irqsave(&s->lock, flags);
1762
                sv_update_ptr(s);
1763
                abinfo.fragsize = s->dma_adc.fragsize;
1764
                count = s->dma_adc.count;
1765
                if (count < 0)
1766
                        count = 0;
1767
                abinfo.bytes = count;
1768
                abinfo.fragstotal = s->dma_adc.numfrag;
1769
                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
1770
                spin_unlock_irqrestore(&s->lock, flags);
1771
                return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
1772
 
1773
        case SNDCTL_DSP_NONBLOCK:
1774
                file->f_flags |= O_NONBLOCK;
1775
                return 0;
1776
 
1777
        case SNDCTL_DSP_GETODELAY:
1778
                if (!(file->f_mode & FMODE_WRITE))
1779
                        return -EINVAL;
1780
                if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
1781
                        return val;
1782
                spin_lock_irqsave(&s->lock, flags);
1783
                sv_update_ptr(s);
1784
                count = s->dma_dac.count;
1785
                spin_unlock_irqrestore(&s->lock, flags);
1786
                if (count < 0)
1787
                        count = 0;
1788
                return put_user(count, (int *)arg);
1789
 
1790
        case SNDCTL_DSP_GETIPTR:
1791
                if (!(file->f_mode & FMODE_READ))
1792
                        return -EINVAL;
1793
                if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0)
1794
                        return val;
1795
                spin_lock_irqsave(&s->lock, flags);
1796
                sv_update_ptr(s);
1797
                cinfo.bytes = s->dma_adc.total_bytes;
1798
                count = s->dma_adc.count;
1799
                if (count < 0)
1800
                        count = 0;
1801
                cinfo.blocks = count >> s->dma_adc.fragshift;
1802
                cinfo.ptr = s->dma_adc.hwptr;
1803
                if (s->dma_adc.mapped)
1804
                        s->dma_adc.count &= s->dma_adc.fragsize-1;
1805
                spin_unlock_irqrestore(&s->lock, flags);
1806
                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
1807
 
1808
        case SNDCTL_DSP_GETOPTR:
1809
                if (!(file->f_mode & FMODE_WRITE))
1810
                        return -EINVAL;
1811
                if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
1812
                        return val;
1813
                spin_lock_irqsave(&s->lock, flags);
1814
                sv_update_ptr(s);
1815
                cinfo.bytes = s->dma_dac.total_bytes;
1816
                count = s->dma_dac.count;
1817
                if (count < 0)
1818
                        count = 0;
1819
                cinfo.blocks = count >> s->dma_dac.fragshift;
1820
                cinfo.ptr = s->dma_dac.hwptr;
1821
                if (s->dma_dac.mapped)
1822
                        s->dma_dac.count &= s->dma_dac.fragsize-1;
1823
                spin_unlock_irqrestore(&s->lock, flags);
1824
                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
1825
 
1826
        case SNDCTL_DSP_GETBLKSIZE:
1827
                if (file->f_mode & FMODE_WRITE) {
1828
                        if ((val = prog_dmabuf(s, 0)))
1829
                                return val;
1830
                        return put_user(s->dma_dac.fragsize, (int *)arg);
1831
                }
1832
                if ((val = prog_dmabuf(s, 1)))
1833
                        return val;
1834
                return put_user(s->dma_adc.fragsize, (int *)arg);
1835
 
1836
        case SNDCTL_DSP_SETFRAGMENT:
1837
                if (get_user(val, (int *)arg))
1838
                        return -EFAULT;
1839
                if (file->f_mode & FMODE_READ) {
1840
                        s->dma_adc.ossfragshift = val & 0xffff;
1841
                        s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
1842
                        if (s->dma_adc.ossfragshift < 4)
1843
                                s->dma_adc.ossfragshift = 4;
1844
                        if (s->dma_adc.ossfragshift > 15)
1845
                                s->dma_adc.ossfragshift = 15;
1846
                        if (s->dma_adc.ossmaxfrags < 4)
1847
                                s->dma_adc.ossmaxfrags = 4;
1848
                }
1849
                if (file->f_mode & FMODE_WRITE) {
1850
                        s->dma_dac.ossfragshift = val & 0xffff;
1851
                        s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
1852
                        if (s->dma_dac.ossfragshift < 4)
1853
                                s->dma_dac.ossfragshift = 4;
1854
                        if (s->dma_dac.ossfragshift > 15)
1855
                                s->dma_dac.ossfragshift = 15;
1856
                        if (s->dma_dac.ossmaxfrags < 4)
1857
                                s->dma_dac.ossmaxfrags = 4;
1858
                }
1859
                return 0;
1860
 
1861
        case SNDCTL_DSP_SUBDIVIDE:
1862
                if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
1863
                    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
1864
                        return -EINVAL;
1865
                if (get_user(val, (int *)arg))
1866
                        return -EFAULT;
1867
                if (val != 1 && val != 2 && val != 4)
1868
                        return -EINVAL;
1869
                if (file->f_mode & FMODE_READ)
1870
                        s->dma_adc.subdivision = val;
1871
                if (file->f_mode & FMODE_WRITE)
1872
                        s->dma_dac.subdivision = val;
1873
                return 0;
1874
 
1875
        case SOUND_PCM_READ_RATE:
1876
                return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
1877
 
1878
        case SOUND_PCM_READ_CHANNELS:
1879
                return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT)
1880
                                           : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, (int *)arg);
1881
 
1882
        case SOUND_PCM_READ_BITS:
1883
                return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT)
1884
                                           : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, (int *)arg);
1885
 
1886
        case SOUND_PCM_WRITE_FILTER:
1887
        case SNDCTL_DSP_SETSYNCRO:
1888
        case SOUND_PCM_READ_FILTER:
1889
                return -EINVAL;
1890
 
1891
        }
1892
        return mixer_ioctl(s, cmd, arg);
1893
}
1894
 
1895
static int sv_open(struct inode *inode, struct file *file)
1896
{
1897
        int minor = MINOR(inode->i_rdev);
1898
        DECLARE_WAITQUEUE(wait, current);
1899
        unsigned char fmtm = ~0, fmts = 0;
1900
        struct list_head *list;
1901
        struct sv_state *s;
1902
 
1903
        for (list = devs.next; ; list = list->next) {
1904
                if (list == &devs)
1905
                        return -ENODEV;
1906
                s = list_entry(list, struct sv_state, devs);
1907
                if (!((s->dev_audio ^ minor) & ~0xf))
1908
                        break;
1909
        }
1910
        VALIDATE_STATE(s);
1911
        file->private_data = s;
1912
        /* wait for device to become free */
1913
        down(&s->open_sem);
1914
        while (s->open_mode & file->f_mode) {
1915
                if (file->f_flags & O_NONBLOCK) {
1916
                        up(&s->open_sem);
1917
                        return -EBUSY;
1918
                }
1919
                add_wait_queue(&s->open_wait, &wait);
1920
                __set_current_state(TASK_INTERRUPTIBLE);
1921
                up(&s->open_sem);
1922
                schedule();
1923
                remove_wait_queue(&s->open_wait, &wait);
1924
                set_current_state(TASK_RUNNING);
1925
                if (signal_pending(current))
1926
                        return -ERESTARTSYS;
1927
                down(&s->open_sem);
1928
        }
1929
        if (file->f_mode & FMODE_READ) {
1930
                fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT);
1931
                if ((minor & 0xf) == SND_DEV_DSP16)
1932
                        fmts |= SV_CFMT_16BIT << SV_CFMT_CSHIFT;
1933
                s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
1934
                s->dma_adc.enabled = 1;
1935
                set_adc_rate(s, 8000);
1936
        }
1937
        if (file->f_mode & FMODE_WRITE) {
1938
                fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_ASHIFT);
1939
                if ((minor & 0xf) == SND_DEV_DSP16)
1940
                        fmts |= SV_CFMT_16BIT << SV_CFMT_ASHIFT;
1941
                s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
1942
                s->dma_dac.enabled = 1;
1943
                set_dac_rate(s, 8000);
1944
        }
1945
        set_fmt(s, fmtm, fmts);
1946
        s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
1947
        up(&s->open_sem);
1948
        return 0;
1949
}
1950
 
1951
static int sv_release(struct inode *inode, struct file *file)
1952
{
1953
        struct sv_state *s = (struct sv_state *)file->private_data;
1954
 
1955
        VALIDATE_STATE(s);
1956
        lock_kernel();
1957
        if (file->f_mode & FMODE_WRITE)
1958
                drain_dac(s, file->f_flags & O_NONBLOCK);
1959
        down(&s->open_sem);
1960
        if (file->f_mode & FMODE_WRITE) {
1961
                stop_dac(s);
1962
                dealloc_dmabuf(s, &s->dma_dac);
1963
        }
1964
        if (file->f_mode & FMODE_READ) {
1965
                stop_adc(s);
1966
                dealloc_dmabuf(s, &s->dma_adc);
1967
        }
1968
        s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
1969
        wake_up(&s->open_wait);
1970
        up(&s->open_sem);
1971
        unlock_kernel();
1972
        return 0;
1973
}
1974
 
1975
static /*const*/ struct file_operations sv_audio_fops = {
1976
        owner:          THIS_MODULE,
1977
        llseek:         no_llseek,
1978
        read:           sv_read,
1979
        write:          sv_write,
1980
        poll:           sv_poll,
1981
        ioctl:          sv_ioctl,
1982
        mmap:           sv_mmap,
1983
        open:           sv_open,
1984
        release:        sv_release,
1985
};
1986
 
1987
/* --------------------------------------------------------------------- */
1988
 
1989
static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
1990
{
1991
        struct sv_state *s = (struct sv_state *)file->private_data;
1992
        DECLARE_WAITQUEUE(wait, current);
1993
        ssize_t ret;
1994
        unsigned long flags;
1995
        unsigned ptr;
1996
        int cnt;
1997
 
1998
        VALIDATE_STATE(s);
1999
        if (ppos != &file->f_pos)
2000
                return -ESPIPE;
2001
        if (!access_ok(VERIFY_WRITE, buffer, count))
2002
                return -EFAULT;
2003
        if (count == 0)
2004
                return 0;
2005
        ret = 0;
2006
        add_wait_queue(&s->midi.iwait, &wait);
2007
        while (count > 0) {
2008
                spin_lock_irqsave(&s->lock, flags);
2009
                ptr = s->midi.ird;
2010
                cnt = MIDIINBUF - ptr;
2011
                if (s->midi.icnt < cnt)
2012
                        cnt = s->midi.icnt;
2013
                if (cnt <= 0)
2014
                      __set_current_state(TASK_INTERRUPTIBLE);
2015
                spin_unlock_irqrestore(&s->lock, flags);
2016
                if (cnt > count)
2017
                        cnt = count;
2018
                if (cnt <= 0) {
2019
                      if (file->f_flags & O_NONBLOCK) {
2020
                              if (!ret)
2021
                                      ret = -EAGAIN;
2022
                              break;
2023
                      }
2024
                      schedule();
2025
                      if (signal_pending(current)) {
2026
                              if (!ret)
2027
                                      ret = -ERESTARTSYS;
2028
                              break;
2029
                      }
2030
                        continue;
2031
                }
2032
                if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
2033
                        if (!ret)
2034
                                ret = -EFAULT;
2035
                        break;
2036
                }
2037
                ptr = (ptr + cnt) % MIDIINBUF;
2038
                spin_lock_irqsave(&s->lock, flags);
2039
                s->midi.ird = ptr;
2040
                s->midi.icnt -= cnt;
2041
                spin_unlock_irqrestore(&s->lock, flags);
2042
                count -= cnt;
2043
                buffer += cnt;
2044
                ret += cnt;
2045
                break;
2046
        }
2047
        __set_current_state(TASK_RUNNING);
2048
        remove_wait_queue(&s->midi.iwait, &wait);
2049
        return ret;
2050
}
2051
 
2052
static ssize_t sv_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
2053
{
2054
        struct sv_state *s = (struct sv_state *)file->private_data;
2055
        DECLARE_WAITQUEUE(wait, current);
2056
        ssize_t ret;
2057
        unsigned long flags;
2058
        unsigned ptr;
2059
        int cnt;
2060
 
2061
        VALIDATE_STATE(s);
2062
        if (ppos != &file->f_pos)
2063
                return -ESPIPE;
2064
        if (!access_ok(VERIFY_READ, buffer, count))
2065
                return -EFAULT;
2066
        if (count == 0)
2067
                return 0;
2068
        ret = 0;
2069
        add_wait_queue(&s->midi.owait, &wait);
2070
        while (count > 0) {
2071
                spin_lock_irqsave(&s->lock, flags);
2072
                ptr = s->midi.owr;
2073
                cnt = MIDIOUTBUF - ptr;
2074
                if (s->midi.ocnt + cnt > MIDIOUTBUF)
2075
                        cnt = MIDIOUTBUF - s->midi.ocnt;
2076
                if (cnt <= 0) {
2077
                        __set_current_state(TASK_INTERRUPTIBLE);
2078
                        sv_handle_midi(s);
2079
                }
2080
                spin_unlock_irqrestore(&s->lock, flags);
2081
                if (cnt > count)
2082
                        cnt = count;
2083
                if (cnt <= 0) {
2084
                        if (file->f_flags & O_NONBLOCK) {
2085
                                if (!ret)
2086
                                        ret = -EAGAIN;
2087
                                break;
2088
                        }
2089
                        schedule();
2090
                        if (signal_pending(current)) {
2091
                                if (!ret)
2092
                                        ret = -ERESTARTSYS;
2093
                                break;
2094
                        }
2095
                        continue;
2096
                }
2097
                if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
2098
                        if (!ret)
2099
                                ret = -EFAULT;
2100
                        break;
2101
                }
2102
                ptr = (ptr + cnt) % MIDIOUTBUF;
2103
                spin_lock_irqsave(&s->lock, flags);
2104
                s->midi.owr = ptr;
2105
                s->midi.ocnt += cnt;
2106
                spin_unlock_irqrestore(&s->lock, flags);
2107
                count -= cnt;
2108
                buffer += cnt;
2109
                ret += cnt;
2110
                spin_lock_irqsave(&s->lock, flags);
2111
                sv_handle_midi(s);
2112
                spin_unlock_irqrestore(&s->lock, flags);
2113
        }
2114
        __set_current_state(TASK_RUNNING);
2115
        remove_wait_queue(&s->midi.owait, &wait);
2116
        return ret;
2117
}
2118
 
2119
/* No kernel lock - we have our own spinlock */
2120
static unsigned int sv_midi_poll(struct file *file, struct poll_table_struct *wait)
2121
{
2122
        struct sv_state *s = (struct sv_state *)file->private_data;
2123
        unsigned long flags;
2124
        unsigned int mask = 0;
2125
 
2126
        VALIDATE_STATE(s);
2127
        if (file->f_mode & FMODE_WRITE)
2128
                poll_wait(file, &s->midi.owait, wait);
2129
        if (file->f_mode & FMODE_READ)
2130
                poll_wait(file, &s->midi.iwait, wait);
2131
        spin_lock_irqsave(&s->lock, flags);
2132
        if (file->f_mode & FMODE_READ) {
2133
                if (s->midi.icnt > 0)
2134
                        mask |= POLLIN | POLLRDNORM;
2135
        }
2136
        if (file->f_mode & FMODE_WRITE) {
2137
                if (s->midi.ocnt < MIDIOUTBUF)
2138
                        mask |= POLLOUT | POLLWRNORM;
2139
        }
2140
        spin_unlock_irqrestore(&s->lock, flags);
2141
        return mask;
2142
}
2143
 
2144
static int sv_midi_open(struct inode *inode, struct file *file)
2145
{
2146
        int minor = MINOR(inode->i_rdev);
2147
        DECLARE_WAITQUEUE(wait, current);
2148
        unsigned long flags;
2149
        struct list_head *list;
2150
        struct sv_state *s;
2151
 
2152
        for (list = devs.next; ; list = list->next) {
2153
                if (list == &devs)
2154
                        return -ENODEV;
2155
                s = list_entry(list, struct sv_state, devs);
2156
                if (s->dev_midi == minor)
2157
                        break;
2158
        }
2159
        VALIDATE_STATE(s);
2160
        file->private_data = s;
2161
        /* wait for device to become free */
2162
        down(&s->open_sem);
2163
        while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
2164
                if (file->f_flags & O_NONBLOCK) {
2165
                        up(&s->open_sem);
2166
                        return -EBUSY;
2167
                }
2168
                add_wait_queue(&s->open_wait, &wait);
2169
                __set_current_state(TASK_INTERRUPTIBLE);
2170
                up(&s->open_sem);
2171
                schedule();
2172
                remove_wait_queue(&s->open_wait, &wait);
2173
                set_current_state(TASK_RUNNING);
2174
                if (signal_pending(current))
2175
                        return -ERESTARTSYS;
2176
                down(&s->open_sem);
2177
        }
2178
        spin_lock_irqsave(&s->lock, flags);
2179
        if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
2180
                s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
2181
                s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
2182
                //outb(inb(s->ioenh + SV_CODEC_CONTROL) | SV_CCTRL_WAVETABLE, s->ioenh + SV_CODEC_CONTROL);
2183
                outb(inb(s->ioenh + SV_CODEC_INTMASK) | SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);
2184
                wrindir(s, SV_CIUARTCONTROL, 5); /* output MIDI data to external and internal synth */
2185
                wrindir(s, SV_CIWAVETABLESRC, 1); /* Wavetable in PC RAM */
2186
                outb(0xff, s->iomidi+1); /* reset command */
2187
                outb(0x3f, s->iomidi+1); /* uart command */
2188
                if (!(inb(s->iomidi+1) & 0x80))
2189
                        inb(s->iomidi);
2190
                s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
2191
                init_timer(&s->midi.timer);
2192
                s->midi.timer.expires = jiffies+1;
2193
                s->midi.timer.data = (unsigned long)s;
2194
                s->midi.timer.function = sv_midi_timer;
2195
                add_timer(&s->midi.timer);
2196
        }
2197
        if (file->f_mode & FMODE_READ) {
2198
                s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
2199
        }
2200
        if (file->f_mode & FMODE_WRITE) {
2201
                s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
2202
        }
2203
        spin_unlock_irqrestore(&s->lock, flags);
2204
        s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
2205
        up(&s->open_sem);
2206
        return 0;
2207
}
2208
 
2209
static int sv_midi_release(struct inode *inode, struct file *file)
2210
{
2211
        struct sv_state *s = (struct sv_state *)file->private_data;
2212
        DECLARE_WAITQUEUE(wait, current);
2213
        unsigned long flags;
2214
        unsigned count, tmo;
2215
 
2216
        VALIDATE_STATE(s);
2217
 
2218
        lock_kernel();
2219
        if (file->f_mode & FMODE_WRITE) {
2220
                add_wait_queue(&s->midi.owait, &wait);
2221
                for (;;) {
2222
                        __set_current_state(TASK_INTERRUPTIBLE);
2223
                        spin_lock_irqsave(&s->lock, flags);
2224
                        count = s->midi.ocnt;
2225
                        spin_unlock_irqrestore(&s->lock, flags);
2226
                        if (count <= 0)
2227
                                break;
2228
                        if (signal_pending(current))
2229
                                break;
2230
                        if (file->f_flags & O_NONBLOCK)
2231
                                break;
2232
                        tmo = (count * HZ) / 3100;
2233
                        if (!schedule_timeout(tmo ? : 1) && tmo)
2234
                                printk(KERN_DEBUG "sv: midi timed out??\n");
2235
                }
2236
                remove_wait_queue(&s->midi.owait, &wait);
2237
                set_current_state(TASK_RUNNING);
2238
        }
2239
        down(&s->open_sem);
2240
        s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
2241
        spin_lock_irqsave(&s->lock, flags);
2242
        if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
2243
                outb(inb(s->ioenh + SV_CODEC_INTMASK) & ~SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);
2244
                del_timer(&s->midi.timer);
2245
        }
2246
        spin_unlock_irqrestore(&s->lock, flags);
2247
        wake_up(&s->open_wait);
2248
        up(&s->open_sem);
2249
        unlock_kernel();
2250
        return 0;
2251
}
2252
 
2253
static /*const*/ struct file_operations sv_midi_fops = {
2254
        owner:          THIS_MODULE,
2255
        llseek:         no_llseek,
2256
        read:           sv_midi_read,
2257
        write:          sv_midi_write,
2258
        poll:           sv_midi_poll,
2259
        open:           sv_midi_open,
2260
        release:        sv_midi_release,
2261
};
2262
 
2263
/* --------------------------------------------------------------------- */
2264
 
2265
static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
2266
{
2267
        static const unsigned char op_offset[18] = {
2268
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
2269
                0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
2270
                0x10, 0x11, 0x12, 0x13, 0x14, 0x15
2271
        };
2272
        struct sv_state *s = (struct sv_state *)file->private_data;
2273
        struct dm_fm_voice v;
2274
        struct dm_fm_note n;
2275
        struct dm_fm_params p;
2276
        unsigned int io;
2277
        unsigned int regb;
2278
 
2279
        switch (cmd) {
2280
        case FM_IOCTL_RESET:
2281
                for (regb = 0xb0; regb < 0xb9; regb++) {
2282
                        outb(regb, s->iosynth);
2283
                        outb(0, s->iosynth+1);
2284
                        outb(regb, s->iosynth+2);
2285
                        outb(0, s->iosynth+3);
2286
                }
2287
                return 0;
2288
 
2289
        case FM_IOCTL_PLAY_NOTE:
2290
                if (copy_from_user(&n, (void *)arg, sizeof(n)))
2291
                        return -EFAULT;
2292
                if (n.voice >= 18)
2293
                        return -EINVAL;
2294
                if (n.voice >= 9) {
2295
                        regb = n.voice - 9;
2296
                        io = s->iosynth+2;
2297
                } else {
2298
                        regb = n.voice;
2299
                        io = s->iosynth;
2300
                }
2301
                outb(0xa0 + regb, io);
2302
                outb(n.fnum & 0xff, io+1);
2303
                outb(0xb0 + regb, io);
2304
                outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
2305
                return 0;
2306
 
2307
        case FM_IOCTL_SET_VOICE:
2308
                if (copy_from_user(&v, (void *)arg, sizeof(v)))
2309
                        return -EFAULT;
2310
                if (v.voice >= 18)
2311
                        return -EINVAL;
2312
                regb = op_offset[v.voice];
2313
                io = s->iosynth + ((v.op & 1) << 1);
2314
                outb(0x20 + regb, io);
2315
                outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) |
2316
                     ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
2317
                outb(0x40 + regb, io);
2318
                outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
2319
                outb(0x60 + regb, io);
2320
                outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
2321
                outb(0x80 + regb, io);
2322
                outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
2323
                outb(0xe0 + regb, io);
2324
                outb(v.waveform & 0x7, io+1);
2325
                if (n.voice >= 9) {
2326
                        regb = n.voice - 9;
2327
                        io = s->iosynth+2;
2328
                } else {
2329
                        regb = n.voice;
2330
                        io = s->iosynth;
2331
                }
2332
                outb(0xc0 + regb, io);
2333
                outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
2334
                     (v.connection & 1), io+1);
2335
                return 0;
2336
 
2337
        case FM_IOCTL_SET_PARAMS:
2338
                if (copy_from_user(&p, (void *)arg, sizeof(p)))
2339
                        return -EFAULT;
2340
                outb(0x08, s->iosynth);
2341
                outb((p.kbd_split & 1) << 6, s->iosynth+1);
2342
                outb(0xbd, s->iosynth);
2343
                outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
2344
                     ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->iosynth+1);
2345
                return 0;
2346
 
2347
        case FM_IOCTL_SET_OPL:
2348
                outb(4, s->iosynth+2);
2349
                outb(arg, s->iosynth+3);
2350
                return 0;
2351
 
2352
        case FM_IOCTL_SET_MODE:
2353
                outb(5, s->iosynth+2);
2354
                outb(arg & 1, s->iosynth+3);
2355
                return 0;
2356
 
2357
        default:
2358
                return -EINVAL;
2359
        }
2360
}
2361
 
2362
static int sv_dmfm_open(struct inode *inode, struct file *file)
2363
{
2364
        int minor = MINOR(inode->i_rdev);
2365
        DECLARE_WAITQUEUE(wait, current);
2366
        struct list_head *list;
2367
        struct sv_state *s;
2368
 
2369
        for (list = devs.next; ; list = list->next) {
2370
                if (list == &devs)
2371
                        return -ENODEV;
2372
                s = list_entry(list, struct sv_state, devs);
2373
                if (s->dev_dmfm == minor)
2374
                        break;
2375
        }
2376
        VALIDATE_STATE(s);
2377
        file->private_data = s;
2378
        /* wait for device to become free */
2379
        down(&s->open_sem);
2380
        while (s->open_mode & FMODE_DMFM) {
2381
                if (file->f_flags & O_NONBLOCK) {
2382
                        up(&s->open_sem);
2383
                        return -EBUSY;
2384
                }
2385
                add_wait_queue(&s->open_wait, &wait);
2386
                __set_current_state(TASK_INTERRUPTIBLE);
2387
                up(&s->open_sem);
2388
                schedule();
2389
                remove_wait_queue(&s->open_wait, &wait);
2390
                set_current_state(TASK_RUNNING);
2391
                if (signal_pending(current))
2392
                        return -ERESTARTSYS;
2393
                down(&s->open_sem);
2394
        }
2395
        /* init the stuff */
2396
        outb(1, s->iosynth);
2397
        outb(0x20, s->iosynth+1); /* enable waveforms */
2398
        outb(4, s->iosynth+2);
2399
        outb(0, s->iosynth+3);  /* no 4op enabled */
2400
        outb(5, s->iosynth+2);
2401
        outb(1, s->iosynth+3);  /* enable OPL3 */
2402
        s->open_mode |= FMODE_DMFM;
2403
        up(&s->open_sem);
2404
        return 0;
2405
}
2406
 
2407
static int sv_dmfm_release(struct inode *inode, struct file *file)
2408
{
2409
        struct sv_state *s = (struct sv_state *)file->private_data;
2410
        unsigned int regb;
2411
 
2412
        VALIDATE_STATE(s);
2413
        lock_kernel();
2414
        down(&s->open_sem);
2415
        s->open_mode &= ~FMODE_DMFM;
2416
        for (regb = 0xb0; regb < 0xb9; regb++) {
2417
                outb(regb, s->iosynth);
2418
                outb(0, s->iosynth+1);
2419
                outb(regb, s->iosynth+2);
2420
                outb(0, s->iosynth+3);
2421
        }
2422
        wake_up(&s->open_wait);
2423
        up(&s->open_sem);
2424
        unlock_kernel();
2425
        return 0;
2426
}
2427
 
2428
static /*const*/ struct file_operations sv_dmfm_fops = {
2429
        owner:          THIS_MODULE,
2430
        llseek:         no_llseek,
2431
        ioctl:          sv_dmfm_ioctl,
2432
        open:           sv_dmfm_open,
2433
        release:        sv_dmfm_release,
2434
};
2435
 
2436
/* --------------------------------------------------------------------- */
2437
 
2438
/* maximum number of devices; only used for command line params */
2439
#define NR_DEVICE 5
2440
 
2441
static int reverb[NR_DEVICE] = { 0, };
2442
 
2443
#if 0
2444
static int wavetable[NR_DEVICE] = { 0, };
2445
#endif
2446
 
2447
static unsigned int devindex = 0;
2448
 
2449
MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i");
2450
MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM");
2451
#if 0
2452
MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i");
2453
MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled");
2454
#endif
2455
 
2456
MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
2457
MODULE_DESCRIPTION("S3 SonicVibes Driver");
2458
MODULE_LICENSE("GPL");
2459
 
2460
 
2461
/* --------------------------------------------------------------------- */
2462
 
2463
static struct initvol {
2464
        int mixch;
2465
        int vol;
2466
} initvol[] __initdata = {
2467
        { SOUND_MIXER_WRITE_RECLEV, 0x4040 },
2468
        { SOUND_MIXER_WRITE_LINE1, 0x4040 },
2469
        { SOUND_MIXER_WRITE_CD, 0x4040 },
2470
        { SOUND_MIXER_WRITE_LINE, 0x4040 },
2471
        { SOUND_MIXER_WRITE_MIC, 0x4040 },
2472
        { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
2473
        { SOUND_MIXER_WRITE_LINE2, 0x4040 },
2474
        { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
2475
        { SOUND_MIXER_WRITE_PCM, 0x4040 }
2476
};
2477
 
2478
#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
2479
                                 (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
2480
 
2481
static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
2482
{
2483
        static char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
2484
        struct sv_state *s;
2485
        mm_segment_t fs;
2486
        int i, val, ret;
2487
        char *ddmaname;
2488
        unsigned ddmanamelen;
2489
 
2490
        if ((ret=pci_enable_device(pcidev)))
2491
                return ret;
2492
 
2493
        if (!RSRCISIOREGION(pcidev, RESOURCE_SB) ||
2494
            !RSRCISIOREGION(pcidev, RESOURCE_ENH) ||
2495
            !RSRCISIOREGION(pcidev, RESOURCE_SYNTH) ||
2496
            !RSRCISIOREGION(pcidev, RESOURCE_MIDI) ||
2497
            !RSRCISIOREGION(pcidev, RESOURCE_GAME))
2498
                return -ENODEV;
2499
        if (pcidev->irq == 0)
2500
                return -ENODEV;
2501
        if (pci_set_dma_mask(pcidev, 0x00ffffff)) {
2502
                printk(KERN_WARNING "sonicvibes: architecture does not support 24bit PCI busmaster DMA\n");
2503
                return -ENODEV;
2504
        }
2505
        /* try to allocate a DDMA resource if not already available */
2506
        if (!RSRCISIOREGION(pcidev, RESOURCE_DDMA)) {
2507
                pcidev->resource[RESOURCE_DDMA].start = 0;
2508
                pcidev->resource[RESOURCE_DDMA].end = 2*SV_EXTENT_DMA-1;
2509
                pcidev->resource[RESOURCE_DDMA].flags = PCI_BASE_ADDRESS_SPACE_IO | IORESOURCE_IO;
2510
                ddmanamelen = strlen(sv_ddma_name)+1;
2511
                if (!(ddmaname = kmalloc(ddmanamelen, GFP_KERNEL)))
2512
                        return -1;
2513
                memcpy(ddmaname, sv_ddma_name, ddmanamelen);
2514
                pcidev->resource[RESOURCE_DDMA].name = ddmaname;
2515
                if (pci_assign_resource(pcidev, RESOURCE_DDMA)) {
2516
                        pcidev->resource[RESOURCE_DDMA].name = NULL;
2517
                        kfree(ddmaname);
2518
                        printk(KERN_ERR "sv: cannot allocate DDMA controller io ports\n");
2519
                        return -EBUSY;
2520
                }
2521
        }
2522
        if (!(s = kmalloc(sizeof(struct sv_state), GFP_KERNEL))) {
2523
                printk(KERN_WARNING "sv: out of memory\n");
2524
                return -ENOMEM;
2525
        }
2526
        memset(s, 0, sizeof(struct sv_state));
2527
        init_waitqueue_head(&s->dma_adc.wait);
2528
        init_waitqueue_head(&s->dma_dac.wait);
2529
        init_waitqueue_head(&s->open_wait);
2530
        init_waitqueue_head(&s->midi.iwait);
2531
        init_waitqueue_head(&s->midi.owait);
2532
        init_MUTEX(&s->open_sem);
2533
        spin_lock_init(&s->lock);
2534
        s->magic = SV_MAGIC;
2535
        s->dev = pcidev;
2536
        s->iosb = pci_resource_start(pcidev, RESOURCE_SB);
2537
        s->ioenh = pci_resource_start(pcidev, RESOURCE_ENH);
2538
        s->iosynth = pci_resource_start(pcidev, RESOURCE_SYNTH);
2539
        s->iomidi = pci_resource_start(pcidev, RESOURCE_MIDI);
2540
        s->iodmaa = pci_resource_start(pcidev, RESOURCE_DDMA);
2541
        s->iodmac = pci_resource_start(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA;
2542
        s->gameport.io = pci_resource_start(pcidev, RESOURCE_GAME);
2543
        pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9);  /* enable and use extended mode */
2544
        pci_write_config_dword(pcidev, 0x48, s->iodmac | 9);  /* enable */
2545
        printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#x %#x %#x\n",
2546
               s->iosb, s->ioenh, s->iosynth, s->iomidi, s->gameport.io, s->iodmaa, s->iodmac);
2547
        s->irq = pcidev->irq;
2548
 
2549
        /* hack */
2550
        pci_write_config_dword(pcidev, 0x60, wavetable_mem >> 12);  /* wavetable base address */
2551
 
2552
        ret = -EBUSY;
2553
        if (!request_region(s->ioenh, SV_EXTENT_ENH, "S3 SonicVibes PCM")) {
2554
                printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1);
2555
                goto err_region5;
2556
        }
2557
        if (!request_region(s->iodmaa, SV_EXTENT_DMA, "S3 SonicVibes DMAA")) {
2558
                printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmaa, s->iodmaa+SV_EXTENT_DMA-1);
2559
                goto err_region4;
2560
        }
2561
        if (!request_region(s->iodmac, SV_EXTENT_DMA, "S3 SonicVibes DMAC")) {
2562
                printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmac, s->iodmac+SV_EXTENT_DMA-1);
2563
                goto err_region3;
2564
        }
2565
        if (!request_region(s->iomidi, SV_EXTENT_MIDI, "S3 SonicVibes Midi")) {
2566
                printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1);
2567
                goto err_region2;
2568
        }
2569
        if (!request_region(s->iosynth, SV_EXTENT_SYNTH, "S3 SonicVibes Synth")) {
2570
                printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1);
2571
                goto err_region1;
2572
        }
2573
        if (s->gameport.io && !request_region(s->gameport.io, SV_EXTENT_GAME, "ESS Solo1")) {
2574
                printk(KERN_ERR "sv: gameport io ports in use\n");
2575
                s->gameport.io = 0;
2576
        }
2577
        /* initialize codec registers */
2578
        outb(0x80, s->ioenh + SV_CODEC_CONTROL); /* assert reset */
2579
        udelay(50);
2580
        outb(0x00, s->ioenh + SV_CODEC_CONTROL); /* deassert reset */
2581
        udelay(50);
2582
        outb(SV_CCTRL_INTADRIVE | SV_CCTRL_ENHANCED /*| SV_CCTRL_WAVETABLE */
2583
             | (reverb[devindex] ? SV_CCTRL_REVERB : 0), s->ioenh + SV_CODEC_CONTROL);
2584
        inb(s->ioenh + SV_CODEC_STATUS); /* clear ints */
2585
        wrindir(s, SV_CIDRIVECONTROL, 0);  /* drive current 16mA */
2586
        wrindir(s, SV_CIENABLE, s->enable = 0);  /* disable DMAA and DMAC */
2587
        outb(~(SV_CINTMASK_DMAA | SV_CINTMASK_DMAC), s->ioenh + SV_CODEC_INTMASK);
2588
        /* outb(0xff, s->iodmaa + SV_DMA_RESET); */
2589
        /* outb(0xff, s->iodmac + SV_DMA_RESET); */
2590
        inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */
2591
        wrindir(s, SV_CIADCCLKSOURCE, 0); /* use pll as ADC clock source */
2592
        wrindir(s, SV_CIANALOGPWRDOWN, 0); /* power up the analog parts of the device */
2593
        wrindir(s, SV_CIDIGITALPWRDOWN, 0); /* power up the digital parts of the device */
2594
        setpll(s, SV_CIADCPLLM, 8000);
2595
        wrindir(s, SV_CISRSSPACE, 0x80); /* SRS off */
2596
        wrindir(s, SV_CIPCMSR0, (8000 * 65536 / FULLRATE) & 0xff);
2597
        wrindir(s, SV_CIPCMSR1, ((8000 * 65536 / FULLRATE) >> 8) & 0xff);
2598
        wrindir(s, SV_CIADCOUTPUT, 0);
2599
        /* request irq */
2600
        if ((ret=request_irq(s->irq,sv_interrupt,SA_SHIRQ,"S3 SonicVibes",s))) {
2601
                printk(KERN_ERR "sv: irq %u in use\n", s->irq);
2602
                goto err_irq;
2603
        }
2604
        printk(KERN_INFO "sv: found adapter at io %#lx irq %u dmaa %#06x dmac %#06x revision %u\n",
2605
               s->ioenh, s->irq, s->iodmaa, s->iodmac, rdindir(s, SV_CIREVISION));
2606
        /* register devices */
2607
        if ((s->dev_audio = register_sound_dsp(&sv_audio_fops, -1)) < 0) {
2608
                ret = s->dev_audio;
2609
                goto err_dev1;
2610
        }
2611
        if ((s->dev_mixer = register_sound_mixer(&sv_mixer_fops, -1)) < 0) {
2612
                ret = s->dev_mixer;
2613
                goto err_dev2;
2614
        }
2615
        if ((s->dev_midi = register_sound_midi(&sv_midi_fops, -1)) < 0) {
2616
                ret = s->dev_midi;
2617
                goto err_dev3;
2618
        }
2619
        if ((s->dev_dmfm = register_sound_special(&sv_dmfm_fops, 15 /* ?? */)) < 0) {
2620
                ret = s->dev_dmfm;
2621
                goto err_dev4;
2622
        }
2623
        pci_set_master(pcidev);  /* enable bus mastering */
2624
        /* initialize the chips */
2625
        fs = get_fs();
2626
        set_fs(KERNEL_DS);
2627
        val = SOUND_MASK_LINE|SOUND_MASK_SYNTH;
2628
        mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
2629
        for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
2630
                val = initvol[i].vol;
2631
                mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
2632
        }
2633
        set_fs(fs);
2634
        /* register gameport */
2635
        gameport_register_port(&s->gameport);
2636
        /* store it in the driver field */
2637
        pci_set_drvdata(pcidev, s);
2638
        /* put it into driver list */
2639
        list_add_tail(&s->devs, &devs);
2640
        /* increment devindex */
2641
        if (devindex < NR_DEVICE-1)
2642
                devindex++;
2643
        return 0;
2644
 
2645
 err_dev4:
2646
        unregister_sound_midi(s->dev_midi);
2647
 err_dev3:
2648
        unregister_sound_mixer(s->dev_mixer);
2649
 err_dev2:
2650
        unregister_sound_dsp(s->dev_audio);
2651
 err_dev1:
2652
        printk(KERN_ERR "sv: cannot register misc device\n");
2653
        free_irq(s->irq, s);
2654
 err_irq:
2655
        if (s->gameport.io)
2656
                release_region(s->gameport.io, SV_EXTENT_GAME);
2657
        release_region(s->iosynth, SV_EXTENT_SYNTH);
2658
 err_region1:
2659
        release_region(s->iomidi, SV_EXTENT_MIDI);
2660
 err_region2:
2661
        release_region(s->iodmac, SV_EXTENT_DMA);
2662
 err_region3:
2663
        release_region(s->iodmaa, SV_EXTENT_DMA);
2664
 err_region4:
2665
        release_region(s->ioenh, SV_EXTENT_ENH);
2666
 err_region5:
2667
        kfree(s);
2668
        return ret;
2669
}
2670
 
2671
static void __devinit sv_remove(struct pci_dev *dev)
2672
{
2673
        struct sv_state *s = pci_get_drvdata(dev);
2674
 
2675
        if (!s)
2676
                return;
2677
        list_del(&s->devs);
2678
        outb(~0, s->ioenh + SV_CODEC_INTMASK);  /* disable ints */
2679
        synchronize_irq();
2680
        inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */
2681
        wrindir(s, SV_CIENABLE, 0);     /* disable DMAA and DMAC */
2682
        /*outb(0, s->iodmaa + SV_DMA_RESET);*/
2683
        /*outb(0, s->iodmac + SV_DMA_RESET);*/
2684
        free_irq(s->irq, s);
2685
        if (s->gameport.io) {
2686
                gameport_unregister_port(&s->gameport);
2687
                release_region(s->gameport.io, SV_EXTENT_GAME);
2688
        }
2689
        release_region(s->iodmac, SV_EXTENT_DMA);
2690
        release_region(s->iodmaa, SV_EXTENT_DMA);
2691
        release_region(s->ioenh, SV_EXTENT_ENH);
2692
        release_region(s->iomidi, SV_EXTENT_MIDI);
2693
        release_region(s->iosynth, SV_EXTENT_SYNTH);
2694
        unregister_sound_dsp(s->dev_audio);
2695
        unregister_sound_mixer(s->dev_mixer);
2696
        unregister_sound_midi(s->dev_midi);
2697
        unregister_sound_special(s->dev_dmfm);
2698
        kfree(s);
2699
        pci_set_drvdata(dev, NULL);
2700
}
2701
 
2702
static struct pci_device_id id_table[] __devinitdata = {
2703
       { PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SONICVIBES, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
2704
       { 0, }
2705
};
2706
 
2707
MODULE_DEVICE_TABLE(pci, id_table);
2708
 
2709
static struct pci_driver sv_driver = {
2710
       name: "sonicvibes",
2711
       id_table: id_table,
2712
       probe: sv_probe,
2713
       remove: sv_remove
2714
};
2715
 
2716
static int __init init_sonicvibes(void)
2717
{
2718
        if (!pci_present())   /* No PCI bus in this machine! */
2719
                return -ENODEV;
2720
        printk(KERN_INFO "sv: version v0.31 time " __TIME__ " " __DATE__ "\n");
2721
#if 0
2722
        if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
2723
                printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
2724
#endif
2725
        return pci_module_init(&sv_driver);
2726
}
2727
 
2728
static void __exit cleanup_sonicvibes(void)
2729
{
2730
        printk(KERN_INFO "sv: unloading\n");
2731
        pci_unregister_driver(&sv_driver);
2732
        if (wavetable_mem)
2733
                free_pages(wavetable_mem, 20-PAGE_SHIFT);
2734
}
2735
 
2736
module_init(init_sonicvibes);
2737
module_exit(cleanup_sonicvibes);
2738
 
2739
/* --------------------------------------------------------------------- */
2740
 
2741
#ifndef MODULE
2742
 
2743
/* format is: sonicvibes=[reverb] sonicvibesdmaio=dmaioaddr */
2744
 
2745
static int __init sonicvibes_setup(char *str)
2746
{
2747
        static unsigned __initdata nr_dev = 0;
2748
 
2749
        if (nr_dev >= NR_DEVICE)
2750
                return 0;
2751
#if 0
2752
        if (get_option(&str, &reverb[nr_dev]) == 2)
2753
                (void)get_option(&str, &wavetable[nr_dev]);
2754
#else
2755
        (void)get_option(&str, &reverb[nr_dev]);
2756
#endif
2757
 
2758
        nr_dev++;
2759
        return 1;
2760
}
2761
 
2762
__setup("sonicvibes=", sonicvibes_setup);
2763
 
2764
#endif /* MODULE */

powered by: WebSVN 2.1.0

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