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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [sound/] [oss/] [msnd_pinnacle.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*********************************************************************
2
 *
3
 * Turtle Beach MultiSound Sound Card Driver for Linux
4
 * Linux 2.0/2.2 Version
5
 *
6
 * msnd_pinnacle.c / msnd_classic.c
7
 *
8
 * -- If MSND_CLASSIC is defined:
9
 *
10
 *     -> driver for Turtle Beach Classic/Monterey/Tahiti
11
 *
12
 * -- Else
13
 *
14
 *     -> driver for Turtle Beach Pinnacle/Fiji
15
 *
16
 * Copyright (C) 1998 Andrew Veliath
17
 *
18
 * This program is free software; you can redistribute it and/or modify
19
 * it under the terms of the GNU General Public License as published by
20
 * the Free Software Foundation; either version 2 of the License, or
21
 * (at your option) any later version.
22
 *
23
 * This program is distributed in the hope that it will be useful,
24
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
 * GNU General Public License for more details.
27
 *
28
 * You should have received a copy of the GNU General Public License
29
 * along with this program; if not, write to the Free Software
30
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31
 *
32
 * $Id: msnd_pinnacle.c,v 1.8 2000/12/30 00:33:21 sycamore Exp $
33
 *
34
 * 12-3-2000  Modified IO port validation  Steve Sycamore
35
 *
36
 *
37
 * $$$: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv $$$ $
38
 *
39
 ********************************************************************/
40
 
41
#include <linux/kernel.h>
42
#include <linux/module.h>
43
#include <linux/slab.h>
44
#include <linux/types.h>
45
#include <linux/delay.h>
46
#include <linux/init.h>
47
#include <linux/interrupt.h>
48
#include <linux/smp_lock.h>
49
#include <asm/irq.h>
50
#include <asm/io.h>
51
#include "sound_config.h"
52
#include "sound_firmware.h"
53
#ifdef MSND_CLASSIC
54
# ifndef __alpha__
55
#  define SLOWIO
56
# endif
57
#endif
58
#include "msnd.h"
59
#ifdef MSND_CLASSIC
60
#  ifdef CONFIG_MSNDCLAS_HAVE_BOOT
61
#    define HAVE_DSPCODEH
62
#  endif
63
#  include "msnd_classic.h"
64
#  define LOGNAME                       "msnd_classic"
65
#else
66
#  ifdef CONFIG_MSNDPIN_HAVE_BOOT
67
#    define HAVE_DSPCODEH
68
#  endif
69
#  include "msnd_pinnacle.h"
70
#  define LOGNAME                       "msnd_pinnacle"
71
#endif
72
 
73
#ifndef CONFIG_MSND_WRITE_NDELAY
74
#  define CONFIG_MSND_WRITE_NDELAY      1
75
#endif
76
 
77
#define get_play_delay_jiffies(size)    ((size) * HZ *                  \
78
                                         dev.play_sample_size / 8 /     \
79
                                         dev.play_sample_rate /         \
80
                                         dev.play_channels)
81
 
82
#define get_rec_delay_jiffies(size)     ((size) * HZ *                  \
83
                                         dev.rec_sample_size / 8 /      \
84
                                         dev.rec_sample_rate /          \
85
                                         dev.rec_channels)
86
 
87
static multisound_dev_t                 dev;
88
 
89
#ifndef HAVE_DSPCODEH
90
static char                             *dspini, *permini;
91
static int                              sizeof_dspini, sizeof_permini;
92
#endif
93
 
94
static int                              dsp_full_reset(void);
95
static void                             dsp_write_flush(void);
96
 
97
static __inline__ int chk_send_dsp_cmd(multisound_dev_t *dev, register BYTE cmd)
98
{
99
        if (msnd_send_dsp_cmd(dev, cmd) == 0)
100
                return 0;
101
        dsp_full_reset();
102
        return msnd_send_dsp_cmd(dev, cmd);
103
}
104
 
105
static void reset_play_queue(void)
106
{
107
        int n;
108
        LPDAQD lpDAQ;
109
 
110
        dev.last_playbank = -1;
111
        writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wHead);
112
        writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wTail);
113
 
114
        for (n = 0, lpDAQ = dev.base + DAPQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) {
115
                writew(PCTODSP_BASED((DWORD)(DAP_BUFF_SIZE * n)), lpDAQ + DAQDS_wStart);
116
                writew(0, lpDAQ + DAQDS_wSize);
117
                writew(1, lpDAQ + DAQDS_wFormat);
118
                writew(dev.play_sample_size, lpDAQ + DAQDS_wSampleSize);
119
                writew(dev.play_channels, lpDAQ + DAQDS_wChannels);
120
                writew(dev.play_sample_rate, lpDAQ + DAQDS_wSampleRate);
121
                writew(HIMT_PLAY_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg);
122
                writew(n, lpDAQ + DAQDS_wFlags);
123
        }
124
}
125
 
126
static void reset_record_queue(void)
127
{
128
        int n;
129
        LPDAQD lpDAQ;
130
        unsigned long flags;
131
 
132
        dev.last_recbank = 2;
133
        writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DARQ + JQS_wHead);
134
        writew(PCTODSP_OFFSET(dev.last_recbank * DAQDS__size), dev.DARQ + JQS_wTail);
135
 
136
        /* Critical section: bank 1 access */
137
        spin_lock_irqsave(&dev.lock, flags);
138
        msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS);
139
        memset_io(dev.base, 0, DAR_BUFF_SIZE * 3);
140
        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
141
        spin_unlock_irqrestore(&dev.lock, flags);
142
 
143
        for (n = 0, lpDAQ = dev.base + DARQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) {
144
                writew(PCTODSP_BASED((DWORD)(DAR_BUFF_SIZE * n)) + 0x4000, lpDAQ + DAQDS_wStart);
145
                writew(DAR_BUFF_SIZE, lpDAQ + DAQDS_wSize);
146
                writew(1, lpDAQ + DAQDS_wFormat);
147
                writew(dev.rec_sample_size, lpDAQ + DAQDS_wSampleSize);
148
                writew(dev.rec_channels, lpDAQ + DAQDS_wChannels);
149
                writew(dev.rec_sample_rate, lpDAQ + DAQDS_wSampleRate);
150
                writew(HIMT_RECORD_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg);
151
                writew(n, lpDAQ + DAQDS_wFlags);
152
        }
153
}
154
 
155
static void reset_queues(void)
156
{
157
        if (dev.mode & FMODE_WRITE) {
158
                msnd_fifo_make_empty(&dev.DAPF);
159
                reset_play_queue();
160
        }
161
        if (dev.mode & FMODE_READ) {
162
                msnd_fifo_make_empty(&dev.DARF);
163
                reset_record_queue();
164
        }
165
}
166
 
167
static int dsp_set_format(struct file *file, int val)
168
{
169
        int data, i;
170
        LPDAQD lpDAQ, lpDARQ;
171
 
172
        lpDAQ = dev.base + DAPQ_DATA_BUFF;
173
        lpDARQ = dev.base + DARQ_DATA_BUFF;
174
 
175
        switch (val) {
176
        case AFMT_U8:
177
        case AFMT_S16_LE:
178
                data = val;
179
                break;
180
        default:
181
                data = DEFSAMPLESIZE;
182
                break;
183
        }
184
 
185
        for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
186
                if (file->f_mode & FMODE_WRITE)
187
                        writew(data, lpDAQ + DAQDS_wSampleSize);
188
                if (file->f_mode & FMODE_READ)
189
                        writew(data, lpDARQ + DAQDS_wSampleSize);
190
        }
191
        if (file->f_mode & FMODE_WRITE)
192
                dev.play_sample_size = data;
193
        if (file->f_mode & FMODE_READ)
194
                dev.rec_sample_size = data;
195
 
196
        return data;
197
}
198
 
199
static int dsp_get_frag_size(void)
200
{
201
        int size;
202
        size = dev.fifosize / 4;
203
        if (size > 32 * 1024)
204
                size = 32 * 1024;
205
        return size;
206
}
207
 
208
static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
209
{
210
        int val, i, data, tmp;
211
        LPDAQD lpDAQ, lpDARQ;
212
        audio_buf_info abinfo;
213
        unsigned long flags;
214
        int __user *p = (int __user *)arg;
215
 
216
        lpDAQ = dev.base + DAPQ_DATA_BUFF;
217
        lpDARQ = dev.base + DARQ_DATA_BUFF;
218
 
219
        switch (cmd) {
220
        case SNDCTL_DSP_SUBDIVIDE:
221
        case SNDCTL_DSP_SETFRAGMENT:
222
        case SNDCTL_DSP_SETDUPLEX:
223
        case SNDCTL_DSP_POST:
224
                return 0;
225
 
226
        case SNDCTL_DSP_GETIPTR:
227
        case SNDCTL_DSP_GETOPTR:
228
        case SNDCTL_DSP_MAPINBUF:
229
        case SNDCTL_DSP_MAPOUTBUF:
230
                return -EINVAL;
231
 
232
        case SNDCTL_DSP_GETOSPACE:
233
                if (!(file->f_mode & FMODE_WRITE))
234
                        return -EINVAL;
235
                spin_lock_irqsave(&dev.lock, flags);
236
                abinfo.fragsize = dsp_get_frag_size();
237
                abinfo.bytes = dev.DAPF.n - dev.DAPF.len;
238
                abinfo.fragstotal = dev.DAPF.n / abinfo.fragsize;
239
                abinfo.fragments = abinfo.bytes / abinfo.fragsize;
240
                spin_unlock_irqrestore(&dev.lock, flags);
241
                return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
242
 
243
        case SNDCTL_DSP_GETISPACE:
244
                if (!(file->f_mode & FMODE_READ))
245
                        return -EINVAL;
246
                spin_lock_irqsave(&dev.lock, flags);
247
                abinfo.fragsize = dsp_get_frag_size();
248
                abinfo.bytes = dev.DARF.n - dev.DARF.len;
249
                abinfo.fragstotal = dev.DARF.n / abinfo.fragsize;
250
                abinfo.fragments = abinfo.bytes / abinfo.fragsize;
251
                spin_unlock_irqrestore(&dev.lock, flags);
252
                return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
253
 
254
        case SNDCTL_DSP_RESET:
255
                dev.nresets = 0;
256
                reset_queues();
257
                return 0;
258
 
259
        case SNDCTL_DSP_SYNC:
260
                dsp_write_flush();
261
                return 0;
262
 
263
        case SNDCTL_DSP_GETBLKSIZE:
264
                tmp = dsp_get_frag_size();
265
                if (put_user(tmp, p))
266
                        return -EFAULT;
267
                return 0;
268
 
269
        case SNDCTL_DSP_GETFMTS:
270
                val = AFMT_S16_LE | AFMT_U8;
271
                if (put_user(val, p))
272
                        return -EFAULT;
273
                return 0;
274
 
275
        case SNDCTL_DSP_SETFMT:
276
                if (get_user(val, p))
277
                        return -EFAULT;
278
 
279
                if (file->f_mode & FMODE_WRITE)
280
                        data = val == AFMT_QUERY
281
                                ? dev.play_sample_size
282
                                : dsp_set_format(file, val);
283
                else
284
                        data = val == AFMT_QUERY
285
                                ? dev.rec_sample_size
286
                                : dsp_set_format(file, val);
287
 
288
                if (put_user(data, p))
289
                        return -EFAULT;
290
                return 0;
291
 
292
        case SNDCTL_DSP_NONBLOCK:
293
                if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags) &&
294
                    file->f_mode & FMODE_WRITE)
295
                        dev.play_ndelay = 1;
296
                if (file->f_mode & FMODE_READ)
297
                        dev.rec_ndelay = 1;
298
                return 0;
299
 
300
        case SNDCTL_DSP_GETCAPS:
301
                val = DSP_CAP_DUPLEX | DSP_CAP_BATCH;
302
                if (put_user(val, p))
303
                        return -EFAULT;
304
                return 0;
305
 
306
        case SNDCTL_DSP_SPEED:
307
                if (get_user(val, p))
308
                        return -EFAULT;
309
 
310
                if (val < 8000)
311
                        val = 8000;
312
 
313
                if (val > 48000)
314
                        val = 48000;
315
 
316
                data = val;
317
 
318
                for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
319
                        if (file->f_mode & FMODE_WRITE)
320
                                writew(data, lpDAQ + DAQDS_wSampleRate);
321
                        if (file->f_mode & FMODE_READ)
322
                                writew(data, lpDARQ + DAQDS_wSampleRate);
323
                }
324
                if (file->f_mode & FMODE_WRITE)
325
                        dev.play_sample_rate = data;
326
                if (file->f_mode & FMODE_READ)
327
                        dev.rec_sample_rate = data;
328
 
329
                if (put_user(data, p))
330
                        return -EFAULT;
331
                return 0;
332
 
333
        case SNDCTL_DSP_CHANNELS:
334
        case SNDCTL_DSP_STEREO:
335
                if (get_user(val, p))
336
                        return -EFAULT;
337
 
338
                if (cmd == SNDCTL_DSP_CHANNELS) {
339
                        switch (val) {
340
                        case 1:
341
                        case 2:
342
                                data = val;
343
                                break;
344
                        default:
345
                                val = data = 2;
346
                                break;
347
                        }
348
                } else {
349
                        switch (val) {
350
                        case 0:
351
                                data = 1;
352
                                break;
353
                        default:
354
                                val = 1;
355
                        case 1:
356
                                data = 2;
357
                                break;
358
                        }
359
                }
360
 
361
                for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
362
                        if (file->f_mode & FMODE_WRITE)
363
                                writew(data, lpDAQ + DAQDS_wChannels);
364
                        if (file->f_mode & FMODE_READ)
365
                                writew(data, lpDARQ + DAQDS_wChannels);
366
                }
367
                if (file->f_mode & FMODE_WRITE)
368
                        dev.play_channels = data;
369
                if (file->f_mode & FMODE_READ)
370
                        dev.rec_channels = data;
371
 
372
                if (put_user(val, p))
373
                        return -EFAULT;
374
                return 0;
375
        }
376
 
377
        return -EINVAL;
378
}
379
 
380
static int mixer_get(int d)
381
{
382
        if (d > 31)
383
                return -EINVAL;
384
 
385
        switch (d) {
386
        case SOUND_MIXER_VOLUME:
387
        case SOUND_MIXER_PCM:
388
        case SOUND_MIXER_LINE:
389
        case SOUND_MIXER_IMIX:
390
        case SOUND_MIXER_LINE1:
391
#ifndef MSND_CLASSIC
392
        case SOUND_MIXER_MIC:
393
        case SOUND_MIXER_SYNTH:
394
#endif
395
                return (dev.left_levels[d] >> 8) * 100 / 0xff |
396
                        (((dev.right_levels[d] >> 8) * 100 / 0xff) << 8);
397
        default:
398
                return 0;
399
        }
400
}
401
 
402
#define update_volm(a,b)                                                \
403
        writew((dev.left_levels[a] >> 1) *                              \
404
               readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff,  \
405
               dev.SMA + SMA_##b##Left);                                \
406
        writew((dev.right_levels[a] >> 1)  *                    \
407
               readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff, \
408
               dev.SMA + SMA_##b##Right);
409
 
410
#define update_potm(d,s,ar)                                             \
411
        writeb((dev.left_levels[d] >> 8) *                              \
412
               readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff,  \
413
               dev.SMA + SMA_##s##Left);                                \
414
        writeb((dev.right_levels[d] >> 8) *                             \
415
               readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff, \
416
               dev.SMA + SMA_##s##Right);                               \
417
        if (msnd_send_word(&dev, 0, 0, ar) == 0)                   \
418
                chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
419
 
420
#define update_pot(d,s,ar)                              \
421
        writeb(dev.left_levels[d] >> 8,         \
422
               dev.SMA + SMA_##s##Left);                \
423
        writeb(dev.right_levels[d] >> 8,                \
424
               dev.SMA + SMA_##s##Right);               \
425
        if (msnd_send_word(&dev, 0, 0, ar) == 0)   \
426
                chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
427
 
428
static int mixer_set(int d, int value)
429
{
430
        int left = value & 0x000000ff;
431
        int right = (value & 0x0000ff00) >> 8;
432
        int bLeft, bRight;
433
        int wLeft, wRight;
434
        int updatemaster = 0;
435
 
436
        if (d > 31)
437
                return -EINVAL;
438
 
439
        bLeft = left * 0xff / 100;
440
        wLeft = left * 0xffff / 100;
441
 
442
        bRight = right * 0xff / 100;
443
        wRight = right * 0xffff / 100;
444
 
445
        dev.left_levels[d] = wLeft;
446
        dev.right_levels[d] = wRight;
447
 
448
        switch (d) {
449
                /* master volume unscaled controls */
450
        case SOUND_MIXER_LINE:                  /* line pot control */
451
                /* scaled by IMIX in digital mix */
452
                writeb(bLeft, dev.SMA + SMA_bInPotPosLeft);
453
                writeb(bRight, dev.SMA + SMA_bInPotPosRight);
454
                if (msnd_send_word(&dev, 0, 0, HDEXAR_IN_SET_POTS) == 0)
455
                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
456
                break;
457
#ifndef MSND_CLASSIC
458
        case SOUND_MIXER_MIC:                   /* mic pot control */
459
                /* scaled by IMIX in digital mix */
460
                writeb(bLeft, dev.SMA + SMA_bMicPotPosLeft);
461
                writeb(bRight, dev.SMA + SMA_bMicPotPosRight);
462
                if (msnd_send_word(&dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0)
463
                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
464
                break;
465
#endif
466
        case SOUND_MIXER_VOLUME:                /* master volume */
467
                writew(wLeft, dev.SMA + SMA_wCurrMastVolLeft);
468
                writew(wRight, dev.SMA + SMA_wCurrMastVolRight);
469
                /* fall through */
470
 
471
        case SOUND_MIXER_LINE1:                 /* aux pot control */
472
                /* scaled by master volume */
473
                /* fall through */
474
 
475
                /* digital controls */
476
        case SOUND_MIXER_SYNTH:                 /* synth vol (dsp mix) */
477
        case SOUND_MIXER_PCM:                   /* pcm vol (dsp mix) */
478
        case SOUND_MIXER_IMIX:                  /* input monitor (dsp mix) */
479
                /* scaled by master volume */
480
                updatemaster = 1;
481
                break;
482
 
483
        default:
484
                return 0;
485
        }
486
 
487
        if (updatemaster) {
488
                /* update master volume scaled controls */
489
                update_volm(SOUND_MIXER_PCM, wCurrPlayVol);
490
                update_volm(SOUND_MIXER_IMIX, wCurrInVol);
491
#ifndef MSND_CLASSIC
492
                update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);
493
#endif
494
                update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);
495
        }
496
 
497
        return mixer_get(d);
498
}
499
 
500
static void mixer_setup(void)
501
{
502
        update_pot(SOUND_MIXER_LINE, bInPotPos, HDEXAR_IN_SET_POTS);
503
        update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);
504
        update_volm(SOUND_MIXER_PCM, wCurrPlayVol);
505
        update_volm(SOUND_MIXER_IMIX, wCurrInVol);
506
#ifndef MSND_CLASSIC
507
        update_pot(SOUND_MIXER_MIC, bMicPotPos, HDEXAR_MIC_SET_POTS);
508
        update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);
509
#endif
510
}
511
 
512
static unsigned long set_recsrc(unsigned long recsrc)
513
{
514
        if (dev.recsrc == recsrc)
515
                return dev.recsrc;
516
#ifdef HAVE_NORECSRC
517
        else if (recsrc == 0)
518
                dev.recsrc = 0;
519
#endif
520
        else
521
                dev.recsrc ^= recsrc;
522
 
523
#ifndef MSND_CLASSIC
524
        if (dev.recsrc & SOUND_MASK_IMIX) {
525
                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)
526
                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
527
        }
528
        else if (dev.recsrc & SOUND_MASK_SYNTH) {
529
                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_SYNTH_IN) == 0)
530
                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
531
        }
532
        else if ((dev.recsrc & SOUND_MASK_DIGITAL1) && test_bit(F_HAVEDIGITAL, &dev.flags)) {
533
                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_DAT_IN) == 0)
534
                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
535
        }
536
        else {
537
#ifdef HAVE_NORECSRC
538
                /* Select no input (?) */
539
                dev.recsrc = 0;
540
#else
541
                dev.recsrc = SOUND_MASK_IMIX;
542
                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)
543
                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
544
#endif
545
        }
546
#endif /* MSND_CLASSIC */
547
 
548
        return dev.recsrc;
549
}
550
 
551
static unsigned long force_recsrc(unsigned long recsrc)
552
{
553
        dev.recsrc = 0;
554
        return set_recsrc(recsrc);
555
}
556
 
557
#define set_mixer_info()                                                        \
558
                memset(&info, 0, sizeof(info));                                  \
559
                strlcpy(info.id, "MSNDMIXER", sizeof(info.id));                 \
560
                strlcpy(info.name, "MultiSound Mixer", sizeof(info.name));
561
 
562
static int mixer_ioctl(unsigned int cmd, unsigned long arg)
563
{
564
        if (cmd == SOUND_MIXER_INFO) {
565
                mixer_info info;
566
                set_mixer_info();
567
                info.modify_counter = dev.mixer_mod_count;
568
                if (copy_to_user((void __user *)arg, &info, sizeof(info)))
569
                        return -EFAULT;
570
                return 0;
571
        } else if (cmd == SOUND_OLD_MIXER_INFO) {
572
                _old_mixer_info info;
573
                set_mixer_info();
574
                if (copy_to_user((void __user *)arg, &info, sizeof(info)))
575
                        return -EFAULT;
576
                return 0;
577
        } else if (cmd == SOUND_MIXER_PRIVATE1) {
578
                dev.nresets = 0;
579
                dsp_full_reset();
580
                return 0;
581
        } else if (((cmd >> 8) & 0xff) == 'M') {
582
                int val = 0;
583
 
584
                if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
585
                        switch (cmd & 0xff) {
586
                        case SOUND_MIXER_RECSRC:
587
                                if (get_user(val, (int __user *)arg))
588
                                        return -EFAULT;
589
                                val = set_recsrc(val);
590
                                break;
591
 
592
                        default:
593
                                if (get_user(val, (int __user *)arg))
594
                                        return -EFAULT;
595
                                val = mixer_set(cmd & 0xff, val);
596
                                break;
597
                        }
598
                        ++dev.mixer_mod_count;
599
                        return put_user(val, (int __user *)arg);
600
                } else {
601
                        switch (cmd & 0xff) {
602
                        case SOUND_MIXER_RECSRC:
603
                                val = dev.recsrc;
604
                                break;
605
 
606
                        case SOUND_MIXER_DEVMASK:
607
                        case SOUND_MIXER_STEREODEVS:
608
                                val =   SOUND_MASK_PCM |
609
                                        SOUND_MASK_LINE |
610
                                        SOUND_MASK_IMIX |
611
                                        SOUND_MASK_LINE1 |
612
#ifndef MSND_CLASSIC
613
                                        SOUND_MASK_MIC |
614
                                        SOUND_MASK_SYNTH |
615
#endif
616
                                        SOUND_MASK_VOLUME;
617
                                break;
618
 
619
                        case SOUND_MIXER_RECMASK:
620
#ifdef MSND_CLASSIC
621
                                val =   0;
622
#else
623
                                val =   SOUND_MASK_IMIX |
624
                                        SOUND_MASK_SYNTH;
625
                                if (test_bit(F_HAVEDIGITAL, &dev.flags))
626
                                        val |= SOUND_MASK_DIGITAL1;
627
#endif
628
                                break;
629
 
630
                        case SOUND_MIXER_CAPS:
631
                                val =   SOUND_CAP_EXCL_INPUT;
632
                                break;
633
 
634
                        default:
635
                                if ((val = mixer_get(cmd & 0xff)) < 0)
636
                                        return -EINVAL;
637
                                break;
638
                        }
639
                }
640
 
641
                return put_user(val, (int __user *)arg);
642
        }
643
 
644
        return -EINVAL;
645
}
646
 
647
static int dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
648
{
649
        int minor = iminor(inode);
650
 
651
        if (cmd == OSS_GETVERSION) {
652
                int sound_version = SOUND_VERSION;
653
                return put_user(sound_version, (int __user *)arg);
654
        }
655
 
656
        if (minor == dev.dsp_minor)
657
                return dsp_ioctl(file, cmd, arg);
658
        else if (minor == dev.mixer_minor)
659
                return mixer_ioctl(cmd, arg);
660
 
661
        return -EINVAL;
662
}
663
 
664
static void dsp_write_flush(void)
665
{
666
        if (!(dev.mode & FMODE_WRITE) || !test_bit(F_WRITING, &dev.flags))
667
                return;
668
        set_bit(F_WRITEFLUSH, &dev.flags);
669
        interruptible_sleep_on_timeout(
670
                &dev.writeflush,
671
                get_play_delay_jiffies(dev.DAPF.len));
672
        clear_bit(F_WRITEFLUSH, &dev.flags);
673
        if (!signal_pending(current)) {
674
                current->state = TASK_INTERRUPTIBLE;
675
                schedule_timeout(get_play_delay_jiffies(DAP_BUFF_SIZE));
676
        }
677
        clear_bit(F_WRITING, &dev.flags);
678
}
679
 
680
static void dsp_halt(struct file *file)
681
{
682
        if ((file ? file->f_mode : dev.mode) & FMODE_READ) {
683
                clear_bit(F_READING, &dev.flags);
684
                chk_send_dsp_cmd(&dev, HDEX_RECORD_STOP);
685
                msnd_disable_irq(&dev);
686
                if (file) {
687
                        printk(KERN_DEBUG LOGNAME ": Stopping read for %p\n", file);
688
                        dev.mode &= ~FMODE_READ;
689
                }
690
                clear_bit(F_AUDIO_READ_INUSE, &dev.flags);
691
        }
692
        if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) {
693
                if (test_bit(F_WRITING, &dev.flags)) {
694
                        dsp_write_flush();
695
                        chk_send_dsp_cmd(&dev, HDEX_PLAY_STOP);
696
                }
697
                msnd_disable_irq(&dev);
698
                if (file) {
699
                        printk(KERN_DEBUG LOGNAME ": Stopping write for %p\n", file);
700
                        dev.mode &= ~FMODE_WRITE;
701
                }
702
                clear_bit(F_AUDIO_WRITE_INUSE, &dev.flags);
703
        }
704
}
705
 
706
static int dsp_release(struct file *file)
707
{
708
        dsp_halt(file);
709
        return 0;
710
}
711
 
712
static int dsp_open(struct file *file)
713
{
714
        if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) {
715
                set_bit(F_AUDIO_WRITE_INUSE, &dev.flags);
716
                clear_bit(F_WRITING, &dev.flags);
717
                msnd_fifo_make_empty(&dev.DAPF);
718
                reset_play_queue();
719
                if (file) {
720
                        printk(KERN_DEBUG LOGNAME ": Starting write for %p\n", file);
721
                        dev.mode |= FMODE_WRITE;
722
                }
723
                msnd_enable_irq(&dev);
724
        }
725
        if ((file ? file->f_mode : dev.mode) & FMODE_READ) {
726
                set_bit(F_AUDIO_READ_INUSE, &dev.flags);
727
                clear_bit(F_READING, &dev.flags);
728
                msnd_fifo_make_empty(&dev.DARF);
729
                reset_record_queue();
730
                if (file) {
731
                        printk(KERN_DEBUG LOGNAME ": Starting read for %p\n", file);
732
                        dev.mode |= FMODE_READ;
733
                }
734
                msnd_enable_irq(&dev);
735
        }
736
        return 0;
737
}
738
 
739
static void set_default_play_audio_parameters(void)
740
{
741
        dev.play_sample_size = DEFSAMPLESIZE;
742
        dev.play_sample_rate = DEFSAMPLERATE;
743
        dev.play_channels = DEFCHANNELS;
744
}
745
 
746
static void set_default_rec_audio_parameters(void)
747
{
748
        dev.rec_sample_size = DEFSAMPLESIZE;
749
        dev.rec_sample_rate = DEFSAMPLERATE;
750
        dev.rec_channels = DEFCHANNELS;
751
}
752
 
753
static void set_default_audio_parameters(void)
754
{
755
        set_default_play_audio_parameters();
756
        set_default_rec_audio_parameters();
757
}
758
 
759
static int dev_open(struct inode *inode, struct file *file)
760
{
761
        int minor = iminor(inode);
762
        int err = 0;
763
 
764
        if (minor == dev.dsp_minor) {
765
                if ((file->f_mode & FMODE_WRITE &&
766
                     test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) ||
767
                    (file->f_mode & FMODE_READ &&
768
                     test_bit(F_AUDIO_READ_INUSE, &dev.flags)))
769
                        return -EBUSY;
770
 
771
                if ((err = dsp_open(file)) >= 0) {
772
                        dev.nresets = 0;
773
                        if (file->f_mode & FMODE_WRITE) {
774
                                set_default_play_audio_parameters();
775
                                if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags))
776
                                        dev.play_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;
777
                                else
778
                                        dev.play_ndelay = 0;
779
                        }
780
                        if (file->f_mode & FMODE_READ) {
781
                                set_default_rec_audio_parameters();
782
                                dev.rec_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;
783
                        }
784
                }
785
        }
786
        else if (minor == dev.mixer_minor) {
787
                /* nothing */
788
        } else
789
                err = -EINVAL;
790
 
791
        return err;
792
}
793
 
794
static int dev_release(struct inode *inode, struct file *file)
795
{
796
        int minor = iminor(inode);
797
        int err = 0;
798
 
799
        lock_kernel();
800
        if (minor == dev.dsp_minor)
801
                err = dsp_release(file);
802
        else if (minor == dev.mixer_minor) {
803
                /* nothing */
804
        } else
805
                err = -EINVAL;
806
        unlock_kernel();
807
        return err;
808
}
809
 
810
static __inline__ int pack_DARQ_to_DARF(register int bank)
811
{
812
        register int size, timeout = 3;
813
        register WORD wTmp;
814
        LPDAQD DAQD;
815
 
816
        /* Increment the tail and check for queue wrap */
817
        wTmp = readw(dev.DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size);
818
        if (wTmp > readw(dev.DARQ + JQS_wSize))
819
                wTmp = 0;
820
        while (wTmp == readw(dev.DARQ + JQS_wHead) && timeout--)
821
                udelay(1);
822
        writew(wTmp, dev.DARQ + JQS_wTail);
823
 
824
        /* Get our digital audio queue struct */
825
        DAQD = bank * DAQDS__size + dev.base + DARQ_DATA_BUFF;
826
 
827
        /* Get length of data */
828
        size = readw(DAQD + DAQDS_wSize);
829
 
830
        /* Read data from the head (unprotected bank 1 access okay
831
           since this is only called inside an interrupt) */
832
        msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS);
833
        msnd_fifo_write_io(
834
                &dev.DARF,
835
                dev.base + bank * DAR_BUFF_SIZE,
836
                size);
837
        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
838
 
839
        return 1;
840
}
841
 
842
static __inline__ int pack_DAPF_to_DAPQ(register int start)
843
{
844
        register WORD DAPQ_tail;
845
        register int protect = start, nbanks = 0;
846
        LPDAQD DAQD;
847
 
848
        DAPQ_tail = readw(dev.DAPQ + JQS_wTail);
849
        while (DAPQ_tail != readw(dev.DAPQ + JQS_wHead) || start) {
850
                register int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size);
851
                register int n;
852
                unsigned long flags;
853
 
854
                /* Write the data to the new tail */
855
                if (protect) {
856
                        /* Critical section: protect fifo in non-interrupt */
857
                        spin_lock_irqsave(&dev.lock, flags);
858
                        n = msnd_fifo_read_io(
859
                                &dev.DAPF,
860
                                dev.base + bank_num * DAP_BUFF_SIZE,
861
                                DAP_BUFF_SIZE);
862
                        spin_unlock_irqrestore(&dev.lock, flags);
863
                } else {
864
                        n = msnd_fifo_read_io(
865
                                &dev.DAPF,
866
                                dev.base + bank_num * DAP_BUFF_SIZE,
867
                                DAP_BUFF_SIZE);
868
                }
869
                if (!n)
870
                        break;
871
 
872
                if (start)
873
                        start = 0;
874
 
875
                /* Get our digital audio queue struct */
876
                DAQD = bank_num * DAQDS__size + dev.base + DAPQ_DATA_BUFF;
877
 
878
                /* Write size of this bank */
879
                writew(n, DAQD + DAQDS_wSize);
880
                ++nbanks;
881
 
882
                /* Then advance the tail */
883
                DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size);
884
                writew(DAPQ_tail, dev.DAPQ + JQS_wTail);
885
                /* Tell the DSP to play the bank */
886
                msnd_send_dsp_cmd(&dev, HDEX_PLAY_START);
887
        }
888
        return nbanks;
889
}
890
 
891
static int dsp_read(char __user *buf, size_t len)
892
{
893
        int count = len;
894
        char *page = (char *)__get_free_page(GFP_KERNEL);
895
 
896
        if (!page)
897
                return -ENOMEM;
898
 
899
        while (count > 0) {
900
                int n, k;
901
                unsigned long flags;
902
 
903
                k = PAGE_SIZE;
904
                if (k > count)
905
                        k = count;
906
 
907
                /* Critical section: protect fifo in non-interrupt */
908
                spin_lock_irqsave(&dev.lock, flags);
909
                n = msnd_fifo_read(&dev.DARF, page, k);
910
                spin_unlock_irqrestore(&dev.lock, flags);
911
                if (copy_to_user(buf, page, n)) {
912
                        free_page((unsigned long)page);
913
                        return -EFAULT;
914
                }
915
                buf += n;
916
                count -= n;
917
 
918
                if (n == k && count)
919
                        continue;
920
 
921
                if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) {
922
                        dev.last_recbank = -1;
923
                        if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0)
924
                                set_bit(F_READING, &dev.flags);
925
                }
926
 
927
                if (dev.rec_ndelay) {
928
                        free_page((unsigned long)page);
929
                        return count == len ? -EAGAIN : len - count;
930
                }
931
 
932
                if (count > 0) {
933
                        set_bit(F_READBLOCK, &dev.flags);
934
                        if (!interruptible_sleep_on_timeout(
935
                                &dev.readblock,
936
                                get_rec_delay_jiffies(DAR_BUFF_SIZE)))
937
                                clear_bit(F_READING, &dev.flags);
938
                        clear_bit(F_READBLOCK, &dev.flags);
939
                        if (signal_pending(current)) {
940
                                free_page((unsigned long)page);
941
                                return -EINTR;
942
                        }
943
                }
944
        }
945
        free_page((unsigned long)page);
946
        return len - count;
947
}
948
 
949
static int dsp_write(const char __user *buf, size_t len)
950
{
951
        int count = len;
952
        char *page = (char *)__get_free_page(GFP_KERNEL);
953
 
954
        if (!page)
955
                return -ENOMEM;
956
 
957
        while (count > 0) {
958
                int n, k;
959
                unsigned long flags;
960
 
961
                k = PAGE_SIZE;
962
                if (k > count)
963
                        k = count;
964
 
965
                if (copy_from_user(page, buf, k)) {
966
                        free_page((unsigned long)page);
967
                        return -EFAULT;
968
                }
969
 
970
                /* Critical section: protect fifo in non-interrupt */
971
                spin_lock_irqsave(&dev.lock, flags);
972
                n = msnd_fifo_write(&dev.DAPF, page, k);
973
                spin_unlock_irqrestore(&dev.lock, flags);
974
                buf += n;
975
                count -= n;
976
 
977
                if (count && n == k)
978
                        continue;
979
 
980
                if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) {
981
                        dev.last_playbank = -1;
982
                        if (pack_DAPF_to_DAPQ(1) > 0)
983
                                set_bit(F_WRITING, &dev.flags);
984
                }
985
 
986
                if (dev.play_ndelay) {
987
                        free_page((unsigned long)page);
988
                        return count == len ? -EAGAIN : len - count;
989
                }
990
 
991
                if (count > 0) {
992
                        set_bit(F_WRITEBLOCK, &dev.flags);
993
                        interruptible_sleep_on_timeout(
994
                                &dev.writeblock,
995
                                get_play_delay_jiffies(DAP_BUFF_SIZE));
996
                        clear_bit(F_WRITEBLOCK, &dev.flags);
997
                        if (signal_pending(current)) {
998
                                free_page((unsigned long)page);
999
                                return -EINTR;
1000
                        }
1001
                }
1002
        }
1003
 
1004
        free_page((unsigned long)page);
1005
        return len - count;
1006
}
1007
 
1008
static ssize_t dev_read(struct file *file, char __user *buf, size_t count, loff_t *off)
1009
{
1010
        int minor = iminor(file->f_path.dentry->d_inode);
1011
        if (minor == dev.dsp_minor)
1012
                return dsp_read(buf, count);
1013
        else
1014
                return -EINVAL;
1015
}
1016
 
1017
static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
1018
{
1019
        int minor = iminor(file->f_path.dentry->d_inode);
1020
        if (minor == dev.dsp_minor)
1021
                return dsp_write(buf, count);
1022
        else
1023
                return -EINVAL;
1024
}
1025
 
1026
static __inline__ void eval_dsp_msg(register WORD wMessage)
1027
{
1028
        switch (HIBYTE(wMessage)) {
1029
        case HIMT_PLAY_DONE:
1030
                if (dev.last_playbank == LOBYTE(wMessage) || !test_bit(F_WRITING, &dev.flags))
1031
                        break;
1032
                dev.last_playbank = LOBYTE(wMessage);
1033
 
1034
                if (pack_DAPF_to_DAPQ(0) <= 0) {
1035
                        if (!test_bit(F_WRITEBLOCK, &dev.flags)) {
1036
                                if (test_and_clear_bit(F_WRITEFLUSH, &dev.flags))
1037
                                        wake_up_interruptible(&dev.writeflush);
1038
                        }
1039
                        clear_bit(F_WRITING, &dev.flags);
1040
                }
1041
 
1042
                if (test_bit(F_WRITEBLOCK, &dev.flags))
1043
                        wake_up_interruptible(&dev.writeblock);
1044
                break;
1045
 
1046
        case HIMT_RECORD_DONE:
1047
                if (dev.last_recbank == LOBYTE(wMessage))
1048
                        break;
1049
                dev.last_recbank = LOBYTE(wMessage);
1050
 
1051
                pack_DARQ_to_DARF(dev.last_recbank);
1052
 
1053
                if (test_bit(F_READBLOCK, &dev.flags))
1054
                        wake_up_interruptible(&dev.readblock);
1055
                break;
1056
 
1057
        case HIMT_DSP:
1058
                switch (LOBYTE(wMessage)) {
1059
#ifndef MSND_CLASSIC
1060
                case HIDSP_PLAY_UNDER:
1061
#endif
1062
                case HIDSP_INT_PLAY_UNDER:
1063
/*                      printk(KERN_DEBUG LOGNAME ": Play underflow\n"); */
1064
                        clear_bit(F_WRITING, &dev.flags);
1065
                        break;
1066
 
1067
                case HIDSP_INT_RECORD_OVER:
1068
/*                      printk(KERN_DEBUG LOGNAME ": Record overflow\n"); */
1069
                        clear_bit(F_READING, &dev.flags);
1070
                        break;
1071
 
1072
                default:
1073
/*                      printk(KERN_DEBUG LOGNAME ": DSP message %d 0x%02x\n",
1074
                        LOBYTE(wMessage), LOBYTE(wMessage)); */
1075
                        break;
1076
                }
1077
                break;
1078
 
1079
        case HIMT_MIDI_IN_UCHAR:
1080
                if (dev.midi_in_interrupt)
1081
                        (*dev.midi_in_interrupt)(&dev);
1082
                break;
1083
 
1084
        default:
1085
/*              printk(KERN_DEBUG LOGNAME ": HIMT message %d 0x%02x\n", HIBYTE(wMessage), HIBYTE(wMessage)); */
1086
                break;
1087
        }
1088
}
1089
 
1090
static irqreturn_t intr(int irq, void *dev_id)
1091
{
1092
        /* Send ack to DSP */
1093
        msnd_inb(dev.io + HP_RXL);
1094
 
1095
        /* Evaluate queued DSP messages */
1096
        while (readw(dev.DSPQ + JQS_wTail) != readw(dev.DSPQ + JQS_wHead)) {
1097
                register WORD wTmp;
1098
 
1099
                eval_dsp_msg(readw(dev.pwDSPQData + 2*readw(dev.DSPQ + JQS_wHead)));
1100
 
1101
                if ((wTmp = readw(dev.DSPQ + JQS_wHead) + 1) > readw(dev.DSPQ + JQS_wSize))
1102
                        writew(0, dev.DSPQ + JQS_wHead);
1103
                else
1104
                        writew(wTmp, dev.DSPQ + JQS_wHead);
1105
        }
1106
        return IRQ_HANDLED;
1107
}
1108
 
1109
static const struct file_operations dev_fileops = {
1110
        .owner          = THIS_MODULE,
1111
        .read           = dev_read,
1112
        .write          = dev_write,
1113
        .ioctl          = dev_ioctl,
1114
        .open           = dev_open,
1115
        .release        = dev_release,
1116
};
1117
 
1118
static int reset_dsp(void)
1119
{
1120
        int timeout = 100;
1121
 
1122
        msnd_outb(HPDSPRESET_ON, dev.io + HP_DSPR);
1123
        mdelay(1);
1124
#ifndef MSND_CLASSIC
1125
        dev.info = msnd_inb(dev.io + HP_INFO);
1126
#endif
1127
        msnd_outb(HPDSPRESET_OFF, dev.io + HP_DSPR);
1128
        mdelay(1);
1129
        while (timeout-- > 0) {
1130
                if (msnd_inb(dev.io + HP_CVR) == HP_CVR_DEF)
1131
                        return 0;
1132
                mdelay(1);
1133
        }
1134
        printk(KERN_ERR LOGNAME ": Cannot reset DSP\n");
1135
 
1136
        return -EIO;
1137
}
1138
 
1139
static int __init probe_multisound(void)
1140
{
1141
#ifndef MSND_CLASSIC
1142
        char *xv, *rev = NULL;
1143
        char *pin = "Pinnacle", *fiji = "Fiji";
1144
        char *pinfiji = "Pinnacle/Fiji";
1145
#endif
1146
 
1147
        if (!request_region(dev.io, dev.numio, "probing")) {
1148
                printk(KERN_ERR LOGNAME ": I/O port conflict\n");
1149
                return -ENODEV;
1150
        }
1151
 
1152
        if (reset_dsp() < 0) {
1153
                release_region(dev.io, dev.numio);
1154
                return -ENODEV;
1155
        }
1156
 
1157
#ifdef MSND_CLASSIC
1158
        dev.name = "Classic/Tahiti/Monterey";
1159
        printk(KERN_INFO LOGNAME ": %s, "
1160
#else
1161
        switch (dev.info >> 4) {
1162
        case 0xf: xv = "<= 1.15"; break;
1163
        case 0x1: xv = "1.18/1.2"; break;
1164
        case 0x2: xv = "1.3"; break;
1165
        case 0x3: xv = "1.4"; break;
1166
        default: xv = "unknown"; break;
1167
        }
1168
 
1169
        switch (dev.info & 0x7) {
1170
        case 0x0: rev = "I"; dev.name = pin; break;
1171
        case 0x1: rev = "F"; dev.name = pin; break;
1172
        case 0x2: rev = "G"; dev.name = pin; break;
1173
        case 0x3: rev = "H"; dev.name = pin; break;
1174
        case 0x4: rev = "E"; dev.name = fiji; break;
1175
        case 0x5: rev = "C"; dev.name = fiji; break;
1176
        case 0x6: rev = "D"; dev.name = fiji; break;
1177
        case 0x7:
1178
                rev = "A-B (Fiji) or A-E (Pinnacle)";
1179
                dev.name = pinfiji;
1180
                break;
1181
        }
1182
        printk(KERN_INFO LOGNAME ": %s revision %s, Xilinx version %s, "
1183
#endif /* MSND_CLASSIC */
1184
               "I/O 0x%x-0x%x, IRQ %d, memory mapped to %p-%p\n",
1185
               dev.name,
1186
#ifndef MSND_CLASSIC
1187
               rev, xv,
1188
#endif
1189
               dev.io, dev.io + dev.numio - 1,
1190
               dev.irq,
1191
               dev.base, dev.base + 0x7fff);
1192
 
1193
        release_region(dev.io, dev.numio);
1194
        return 0;
1195
}
1196
 
1197
static int init_sma(void)
1198
{
1199
        static int initted;
1200
        WORD mastVolLeft, mastVolRight;
1201
        unsigned long flags;
1202
 
1203
#ifdef MSND_CLASSIC
1204
        msnd_outb(dev.memid, dev.io + HP_MEMM);
1205
#endif
1206
        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
1207
        if (initted) {
1208
                mastVolLeft = readw(dev.SMA + SMA_wCurrMastVolLeft);
1209
                mastVolRight = readw(dev.SMA + SMA_wCurrMastVolRight);
1210
        } else
1211
                mastVolLeft = mastVolRight = 0;
1212
        memset_io(dev.base, 0, 0x8000);
1213
 
1214
        /* Critical section: bank 1 access */
1215
        spin_lock_irqsave(&dev.lock, flags);
1216
        msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS);
1217
        memset_io(dev.base, 0, 0x8000);
1218
        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
1219
        spin_unlock_irqrestore(&dev.lock, flags);
1220
 
1221
        dev.pwDSPQData = (dev.base + DSPQ_DATA_BUFF);
1222
        dev.pwMODQData = (dev.base + MODQ_DATA_BUFF);
1223
        dev.pwMIDQData = (dev.base + MIDQ_DATA_BUFF);
1224
 
1225
        /* Motorola 56k shared memory base */
1226
        dev.SMA = dev.base + SMA_STRUCT_START;
1227
 
1228
        /* Digital audio play queue */
1229
        dev.DAPQ = dev.base + DAPQ_OFFSET;
1230
        msnd_init_queue(dev.DAPQ, DAPQ_DATA_BUFF, DAPQ_BUFF_SIZE);
1231
 
1232
        /* Digital audio record queue */
1233
        dev.DARQ = dev.base + DARQ_OFFSET;
1234
        msnd_init_queue(dev.DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE);
1235
 
1236
        /* MIDI out queue */
1237
        dev.MODQ = dev.base + MODQ_OFFSET;
1238
        msnd_init_queue(dev.MODQ, MODQ_DATA_BUFF, MODQ_BUFF_SIZE);
1239
 
1240
        /* MIDI in queue */
1241
        dev.MIDQ = dev.base + MIDQ_OFFSET;
1242
        msnd_init_queue(dev.MIDQ, MIDQ_DATA_BUFF, MIDQ_BUFF_SIZE);
1243
 
1244
        /* DSP -> host message queue */
1245
        dev.DSPQ = dev.base + DSPQ_OFFSET;
1246
        msnd_init_queue(dev.DSPQ, DSPQ_DATA_BUFF, DSPQ_BUFF_SIZE);
1247
 
1248
        /* Setup some DSP values */
1249
#ifndef MSND_CLASSIC
1250
        writew(1, dev.SMA + SMA_wCurrPlayFormat);
1251
        writew(dev.play_sample_size, dev.SMA + SMA_wCurrPlaySampleSize);
1252
        writew(dev.play_channels, dev.SMA + SMA_wCurrPlayChannels);
1253
        writew(dev.play_sample_rate, dev.SMA + SMA_wCurrPlaySampleRate);
1254
#endif
1255
        writew(dev.play_sample_rate, dev.SMA + SMA_wCalFreqAtoD);
1256
        writew(mastVolLeft, dev.SMA + SMA_wCurrMastVolLeft);
1257
        writew(mastVolRight, dev.SMA + SMA_wCurrMastVolRight);
1258
#ifndef MSND_CLASSIC
1259
        writel(0x00010000, dev.SMA + SMA_dwCurrPlayPitch);
1260
        writel(0x00000001, dev.SMA + SMA_dwCurrPlayRate);
1261
#endif
1262
        writew(0x303, dev.SMA + SMA_wCurrInputTagBits);
1263
 
1264
        initted = 1;
1265
 
1266
        return 0;
1267
}
1268
 
1269
static int __init calibrate_adc(WORD srate)
1270
{
1271
        writew(srate, dev.SMA + SMA_wCalFreqAtoD);
1272
        if (dev.calibrate_signal == 0)
1273
                writew(readw(dev.SMA + SMA_wCurrHostStatusFlags)
1274
                       | 0x0001, dev.SMA + SMA_wCurrHostStatusFlags);
1275
        else
1276
                writew(readw(dev.SMA + SMA_wCurrHostStatusFlags)
1277
                       & ~0x0001, dev.SMA + SMA_wCurrHostStatusFlags);
1278
        if (msnd_send_word(&dev, 0, 0, HDEXAR_CAL_A_TO_D) == 0 &&
1279
            chk_send_dsp_cmd(&dev, HDEX_AUX_REQ) == 0) {
1280
                current->state = TASK_INTERRUPTIBLE;
1281
                schedule_timeout(HZ / 3);
1282
                return 0;
1283
        }
1284
        printk(KERN_WARNING LOGNAME ": ADC calibration failed\n");
1285
 
1286
        return -EIO;
1287
}
1288
 
1289
static int upload_dsp_code(void)
1290
{
1291
        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
1292
#ifndef HAVE_DSPCODEH
1293
        INITCODESIZE = mod_firmware_load(INITCODEFILE, &INITCODE);
1294
        if (!INITCODE) {
1295
                printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE);
1296
                return -EBUSY;
1297
        }
1298
 
1299
        PERMCODESIZE = mod_firmware_load(PERMCODEFILE, &PERMCODE);
1300
        if (!PERMCODE) {
1301
                printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE);
1302
                vfree(INITCODE);
1303
                return -EBUSY;
1304
        }
1305
#endif
1306
        memcpy_toio(dev.base, PERMCODE, PERMCODESIZE);
1307
        if (msnd_upload_host(&dev, INITCODE, INITCODESIZE) < 0) {
1308
                printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n");
1309
                return -ENODEV;
1310
        }
1311
#ifdef HAVE_DSPCODEH
1312
        printk(KERN_INFO LOGNAME ": DSP firmware uploaded (resident)\n");
1313
#else
1314
        printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n");
1315
#endif
1316
 
1317
#ifndef HAVE_DSPCODEH
1318
        vfree(INITCODE);
1319
        vfree(PERMCODE);
1320
#endif
1321
 
1322
        return 0;
1323
}
1324
 
1325
#ifdef MSND_CLASSIC
1326
static void reset_proteus(void)
1327
{
1328
        msnd_outb(HPPRORESET_ON, dev.io + HP_PROR);
1329
        mdelay(TIME_PRO_RESET);
1330
        msnd_outb(HPPRORESET_OFF, dev.io + HP_PROR);
1331
        mdelay(TIME_PRO_RESET_DONE);
1332
}
1333
#endif
1334
 
1335
static int initialize(void)
1336
{
1337
        int err, timeout;
1338
 
1339
#ifdef MSND_CLASSIC
1340
        msnd_outb(HPWAITSTATE_0, dev.io + HP_WAIT);
1341
        msnd_outb(HPBITMODE_16, dev.io + HP_BITM);
1342
 
1343
        reset_proteus();
1344
#endif
1345
        if ((err = init_sma()) < 0) {
1346
                printk(KERN_WARNING LOGNAME ": Cannot initialize SMA\n");
1347
                return err;
1348
        }
1349
 
1350
        if ((err = reset_dsp()) < 0)
1351
                return err;
1352
 
1353
        if ((err = upload_dsp_code()) < 0) {
1354
                printk(KERN_WARNING LOGNAME ": Cannot upload DSP code\n");
1355
                return err;
1356
        }
1357
 
1358
        timeout = 200;
1359
        while (readw(dev.base)) {
1360
                mdelay(1);
1361
                if (!timeout--) {
1362
                        printk(KERN_DEBUG LOGNAME ": DSP reset timeout\n");
1363
                        return -EIO;
1364
                }
1365
        }
1366
 
1367
        mixer_setup();
1368
 
1369
        return 0;
1370
}
1371
 
1372
static int dsp_full_reset(void)
1373
{
1374
        int rv;
1375
 
1376
        if (test_bit(F_RESETTING, &dev.flags) || ++dev.nresets > 10)
1377
                return 0;
1378
 
1379
        set_bit(F_RESETTING, &dev.flags);
1380
        printk(KERN_INFO LOGNAME ": DSP reset\n");
1381
        dsp_halt(NULL);                 /* Unconditionally halt */
1382
        if ((rv = initialize()))
1383
                printk(KERN_WARNING LOGNAME ": DSP reset failed\n");
1384
        force_recsrc(dev.recsrc);
1385
        dsp_open(NULL);
1386
        clear_bit(F_RESETTING, &dev.flags);
1387
 
1388
        return rv;
1389
}
1390
 
1391
static int __init attach_multisound(void)
1392
{
1393
        int err;
1394
 
1395
        if ((err = request_irq(dev.irq, intr, 0, dev.name, &dev)) < 0) {
1396
                printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", dev.irq);
1397
                return err;
1398
        }
1399
        request_region(dev.io, dev.numio, dev.name);
1400
 
1401
        if ((err = dsp_full_reset()) < 0) {
1402
                release_region(dev.io, dev.numio);
1403
                free_irq(dev.irq, &dev);
1404
                return err;
1405
        }
1406
 
1407
        if ((err = msnd_register(&dev)) < 0) {
1408
                printk(KERN_ERR LOGNAME ": Unable to register MultiSound\n");
1409
                release_region(dev.io, dev.numio);
1410
                free_irq(dev.irq, &dev);
1411
                return err;
1412
        }
1413
 
1414
        if ((dev.dsp_minor = register_sound_dsp(&dev_fileops, -1)) < 0) {
1415
                printk(KERN_ERR LOGNAME ": Unable to register DSP operations\n");
1416
                msnd_unregister(&dev);
1417
                release_region(dev.io, dev.numio);
1418
                free_irq(dev.irq, &dev);
1419
                return dev.dsp_minor;
1420
        }
1421
 
1422
        if ((dev.mixer_minor = register_sound_mixer(&dev_fileops, -1)) < 0) {
1423
                printk(KERN_ERR LOGNAME ": Unable to register mixer operations\n");
1424
                unregister_sound_mixer(dev.mixer_minor);
1425
                msnd_unregister(&dev);
1426
                release_region(dev.io, dev.numio);
1427
                free_irq(dev.irq, &dev);
1428
                return dev.mixer_minor;
1429
        }
1430
 
1431
        dev.ext_midi_dev = dev.hdr_midi_dev = -1;
1432
 
1433
        disable_irq(dev.irq);
1434
        calibrate_adc(dev.play_sample_rate);
1435
#ifndef MSND_CLASSIC
1436
        force_recsrc(SOUND_MASK_IMIX);
1437
#endif
1438
 
1439
        return 0;
1440
}
1441
 
1442
static void __exit unload_multisound(void)
1443
{
1444
        release_region(dev.io, dev.numio);
1445
        free_irq(dev.irq, &dev);
1446
        unregister_sound_mixer(dev.mixer_minor);
1447
        unregister_sound_dsp(dev.dsp_minor);
1448
        msnd_unregister(&dev);
1449
}
1450
 
1451
#ifndef MSND_CLASSIC
1452
 
1453
/* Pinnacle/Fiji Logical Device Configuration */
1454
 
1455
static int __init msnd_write_cfg(int cfg, int reg, int value)
1456
{
1457
        msnd_outb(reg, cfg);
1458
        msnd_outb(value, cfg + 1);
1459
        if (value != msnd_inb(cfg + 1)) {
1460
                printk(KERN_ERR LOGNAME ": msnd_write_cfg: I/O error\n");
1461
                return -EIO;
1462
        }
1463
        return 0;
1464
}
1465
 
1466
static int __init msnd_write_cfg_io0(int cfg, int num, WORD io)
1467
{
1468
        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1469
                return -EIO;
1470
        if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
1471
                return -EIO;
1472
        if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
1473
                return -EIO;
1474
        return 0;
1475
}
1476
 
1477
static int __init msnd_write_cfg_io1(int cfg, int num, WORD io)
1478
{
1479
        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1480
                return -EIO;
1481
        if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
1482
                return -EIO;
1483
        if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
1484
                return -EIO;
1485
        return 0;
1486
}
1487
 
1488
static int __init msnd_write_cfg_irq(int cfg, int num, WORD irq)
1489
{
1490
        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1491
                return -EIO;
1492
        if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
1493
                return -EIO;
1494
        if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
1495
                return -EIO;
1496
        return 0;
1497
}
1498
 
1499
static int __init msnd_write_cfg_mem(int cfg, int num, int mem)
1500
{
1501
        WORD wmem;
1502
 
1503
        mem >>= 8;
1504
        mem &= 0xfff;
1505
        wmem = (WORD)mem;
1506
        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1507
                return -EIO;
1508
        if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
1509
                return -EIO;
1510
        if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
1511
                return -EIO;
1512
        if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT)))
1513
                return -EIO;
1514
        return 0;
1515
}
1516
 
1517
static int __init msnd_activate_logical(int cfg, int num)
1518
{
1519
        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1520
                return -EIO;
1521
        if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
1522
                return -EIO;
1523
        return 0;
1524
}
1525
 
1526
static int __init msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem)
1527
{
1528
        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1529
                return -EIO;
1530
        if (msnd_write_cfg_io0(cfg, num, io0))
1531
                return -EIO;
1532
        if (msnd_write_cfg_io1(cfg, num, io1))
1533
                return -EIO;
1534
        if (msnd_write_cfg_irq(cfg, num, irq))
1535
                return -EIO;
1536
        if (msnd_write_cfg_mem(cfg, num, mem))
1537
                return -EIO;
1538
        if (msnd_activate_logical(cfg, num))
1539
                return -EIO;
1540
        return 0;
1541
}
1542
 
1543
typedef struct msnd_pinnacle_cfg_device {
1544
        WORD io0, io1, irq;
1545
        int mem;
1546
} msnd_pinnacle_cfg_t[4];
1547
 
1548
static int __init msnd_pinnacle_cfg_devices(int cfg, int reset, msnd_pinnacle_cfg_t device)
1549
{
1550
        int i;
1551
 
1552
        /* Reset devices if told to */
1553
        if (reset) {
1554
                printk(KERN_INFO LOGNAME ": Resetting all devices\n");
1555
                for (i = 0; i < 4; ++i)
1556
                        if (msnd_write_cfg_logical(cfg, i, 0, 0, 0, 0))
1557
                                return -EIO;
1558
        }
1559
 
1560
        /* Configure specified devices */
1561
        for (i = 0; i < 4; ++i) {
1562
 
1563
                switch (i) {
1564
                case 0:          /* DSP */
1565
                        if (!(device[i].io0 && device[i].irq && device[i].mem))
1566
                                continue;
1567
                        break;
1568
                case 1:         /* MPU */
1569
                        if (!(device[i].io0 && device[i].irq))
1570
                                continue;
1571
                        printk(KERN_INFO LOGNAME
1572
                               ": Configuring MPU to I/O 0x%x IRQ %d\n",
1573
                               device[i].io0, device[i].irq);
1574
                        break;
1575
                case 2:         /* IDE */
1576
                        if (!(device[i].io0 && device[i].io1 && device[i].irq))
1577
                                continue;
1578
                        printk(KERN_INFO LOGNAME
1579
                               ": Configuring IDE to I/O 0x%x, 0x%x IRQ %d\n",
1580
                               device[i].io0, device[i].io1, device[i].irq);
1581
                        break;
1582
                case 3:         /* Joystick */
1583
                        if (!(device[i].io0))
1584
                                continue;
1585
                        printk(KERN_INFO LOGNAME
1586
                               ": Configuring joystick to I/O 0x%x\n",
1587
                               device[i].io0);
1588
                        break;
1589
                }
1590
 
1591
                /* Configure the device */
1592
                if (msnd_write_cfg_logical(cfg, i, device[i].io0, device[i].io1, device[i].irq, device[i].mem))
1593
                        return -EIO;
1594
        }
1595
 
1596
        return 0;
1597
}
1598
#endif
1599
 
1600
#ifdef MODULE
1601
MODULE_AUTHOR                           ("Andrew Veliath <andrewtv@usa.net>");
1602
MODULE_DESCRIPTION                      ("Turtle Beach " LONGNAME " Linux Driver");
1603
MODULE_LICENSE("GPL");
1604
 
1605
static int io __initdata =              -1;
1606
static int irq __initdata =             -1;
1607
static int mem __initdata =             -1;
1608
static int write_ndelay __initdata =    -1;
1609
 
1610
#ifndef MSND_CLASSIC
1611
/* Pinnacle/Fiji non-PnP Config Port */
1612
static int cfg __initdata =             -1;
1613
 
1614
/* Extra Peripheral Configuration */
1615
static int reset __initdata = 0;
1616
static int mpu_io __initdata = 0;
1617
static int mpu_irq __initdata = 0;
1618
static int ide_io0 __initdata = 0;
1619
static int ide_io1 __initdata = 0;
1620
static int ide_irq __initdata = 0;
1621
static int joystick_io __initdata = 0;
1622
 
1623
/* If we have the digital daugherboard... */
1624
static int digital __initdata = 0;
1625
#endif
1626
 
1627
static int fifosize __initdata =        DEFFIFOSIZE;
1628
static int calibrate_signal __initdata = 0;
1629
 
1630
#else /* not a module */
1631
 
1632
static int write_ndelay __initdata =    -1;
1633
 
1634
#ifdef MSND_CLASSIC
1635
static int io __initdata =              CONFIG_MSNDCLAS_IO;
1636
static int irq __initdata =             CONFIG_MSNDCLAS_IRQ;
1637
static int mem __initdata =             CONFIG_MSNDCLAS_MEM;
1638
#else /* Pinnacle/Fiji */
1639
 
1640
static int io __initdata =              CONFIG_MSNDPIN_IO;
1641
static int irq __initdata =             CONFIG_MSNDPIN_IRQ;
1642
static int mem __initdata =             CONFIG_MSNDPIN_MEM;
1643
 
1644
/* Pinnacle/Fiji non-PnP Config Port */
1645
#ifdef CONFIG_MSNDPIN_NONPNP
1646
#  ifndef CONFIG_MSNDPIN_CFG
1647
#    define CONFIG_MSNDPIN_CFG          0x250
1648
#  endif
1649
#else
1650
#  ifdef CONFIG_MSNDPIN_CFG
1651
#    undef CONFIG_MSNDPIN_CFG
1652
#  endif
1653
#  define CONFIG_MSNDPIN_CFG            -1
1654
#endif
1655
static int cfg __initdata =             CONFIG_MSNDPIN_CFG;
1656
/* If not a module, we don't need to bother with reset=1 */
1657
static int reset;
1658
 
1659
/* Extra Peripheral Configuration (Default: Disable) */
1660
#ifndef CONFIG_MSNDPIN_MPU_IO
1661
#  define CONFIG_MSNDPIN_MPU_IO         0
1662
#endif
1663
static int mpu_io __initdata =          CONFIG_MSNDPIN_MPU_IO;
1664
 
1665
#ifndef CONFIG_MSNDPIN_MPU_IRQ
1666
#  define CONFIG_MSNDPIN_MPU_IRQ        0
1667
#endif
1668
static int mpu_irq __initdata =         CONFIG_MSNDPIN_MPU_IRQ;
1669
 
1670
#ifndef CONFIG_MSNDPIN_IDE_IO0
1671
#  define CONFIG_MSNDPIN_IDE_IO0        0
1672
#endif
1673
static int ide_io0 __initdata =         CONFIG_MSNDPIN_IDE_IO0;
1674
 
1675
#ifndef CONFIG_MSNDPIN_IDE_IO1
1676
#  define CONFIG_MSNDPIN_IDE_IO1        0
1677
#endif
1678
static int ide_io1 __initdata =         CONFIG_MSNDPIN_IDE_IO1;
1679
 
1680
#ifndef CONFIG_MSNDPIN_IDE_IRQ
1681
#  define CONFIG_MSNDPIN_IDE_IRQ        0
1682
#endif
1683
static int ide_irq __initdata =         CONFIG_MSNDPIN_IDE_IRQ;
1684
 
1685
#ifndef CONFIG_MSNDPIN_JOYSTICK_IO
1686
#  define CONFIG_MSNDPIN_JOYSTICK_IO    0
1687
#endif
1688
static int joystick_io __initdata =     CONFIG_MSNDPIN_JOYSTICK_IO;
1689
 
1690
/* Have SPDIF (Digital) Daughterboard */
1691
#ifndef CONFIG_MSNDPIN_DIGITAL
1692
#  define CONFIG_MSNDPIN_DIGITAL        0
1693
#endif
1694
static int digital __initdata =         CONFIG_MSNDPIN_DIGITAL;
1695
 
1696
#endif /* MSND_CLASSIC */
1697
 
1698
#ifndef CONFIG_MSND_FIFOSIZE
1699
#  define CONFIG_MSND_FIFOSIZE          DEFFIFOSIZE
1700
#endif
1701
static int fifosize __initdata =        CONFIG_MSND_FIFOSIZE;
1702
 
1703
#ifndef CONFIG_MSND_CALSIGNAL
1704
#  define CONFIG_MSND_CALSIGNAL         0
1705
#endif
1706
static int
1707
calibrate_signal __initdata =           CONFIG_MSND_CALSIGNAL;
1708
#endif /* MODULE */
1709
 
1710
module_param                            (io, int, 0);
1711
module_param                            (irq, int, 0);
1712
module_param                            (mem, int, 0);
1713
module_param                            (write_ndelay, int, 0);
1714
module_param                            (fifosize, int, 0);
1715
module_param                            (calibrate_signal, int, 0);
1716
#ifndef MSND_CLASSIC
1717
module_param                            (digital, bool, 0);
1718
module_param                            (cfg, int, 0);
1719
module_param                            (reset, int, 0);
1720
module_param                            (mpu_io, int, 0);
1721
module_param                            (mpu_irq, int, 0);
1722
module_param                            (ide_io0, int, 0);
1723
module_param                            (ide_io1, int, 0);
1724
module_param                            (ide_irq, int, 0);
1725
module_param                            (joystick_io, int, 0);
1726
#endif
1727
 
1728
static int __init msnd_init(void)
1729
{
1730
        int err;
1731
#ifndef MSND_CLASSIC
1732
        static msnd_pinnacle_cfg_t pinnacle_devs;
1733
#endif /* MSND_CLASSIC */
1734
 
1735
        printk(KERN_INFO LOGNAME ": Turtle Beach " LONGNAME " Linux Driver Version "
1736
               VERSION ", Copyright (C) 1998 Andrew Veliath\n");
1737
 
1738
        if (io == -1 || irq == -1 || mem == -1)
1739
                printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
1740
 
1741
#ifdef MSND_CLASSIC
1742
        if (io == -1 ||
1743
            !(io == 0x290 ||
1744
              io == 0x260 ||
1745
              io == 0x250 ||
1746
              io == 0x240 ||
1747
              io == 0x230 ||
1748
              io == 0x220 ||
1749
              io == 0x210 ||
1750
              io == 0x3e0)) {
1751
                printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, or 0x3E0\n");
1752
                return -EINVAL;
1753
        }
1754
#else
1755
        if (io == -1 ||
1756
                io < 0x100 ||
1757
                io > 0x3e0 ||
1758
                (io % 0x10) != 0) {
1759
                        printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must within the range 0x100 to 0x3E0 and must be evenly divisible by 0x10\n");
1760
                        return -EINVAL;
1761
        }
1762
#endif /* MSND_CLASSIC */
1763
 
1764
        if (irq == -1 ||
1765
            !(irq == 5 ||
1766
              irq == 7 ||
1767
              irq == 9 ||
1768
              irq == 10 ||
1769
              irq == 11 ||
1770
              irq == 12)) {
1771
                printk(KERN_ERR LOGNAME ": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n");
1772
                return -EINVAL;
1773
        }
1774
 
1775
        if (mem == -1 ||
1776
            !(mem == 0xb0000 ||
1777
              mem == 0xc8000 ||
1778
              mem == 0xd0000 ||
1779
              mem == 0xd8000 ||
1780
              mem == 0xe0000 ||
1781
              mem == 0xe8000)) {
1782
                printk(KERN_ERR LOGNAME ": \"mem\" - must be set to "
1783
                       "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n");
1784
                return -EINVAL;
1785
        }
1786
 
1787
#ifdef MSND_CLASSIC
1788
        switch (irq) {
1789
        case 5: dev.irqid = HPIRQ_5; break;
1790
        case 7: dev.irqid = HPIRQ_7; break;
1791
        case 9: dev.irqid = HPIRQ_9; break;
1792
        case 10: dev.irqid = HPIRQ_10; break;
1793
        case 11: dev.irqid = HPIRQ_11; break;
1794
        case 12: dev.irqid = HPIRQ_12; break;
1795
        }
1796
 
1797
        switch (mem) {
1798
        case 0xb0000: dev.memid = HPMEM_B000; break;
1799
        case 0xc8000: dev.memid = HPMEM_C800; break;
1800
        case 0xd0000: dev.memid = HPMEM_D000; break;
1801
        case 0xd8000: dev.memid = HPMEM_D800; break;
1802
        case 0xe0000: dev.memid = HPMEM_E000; break;
1803
        case 0xe8000: dev.memid = HPMEM_E800; break;
1804
        }
1805
#else
1806
        if (cfg == -1) {
1807
                printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
1808
        } else if (cfg != 0x250 && cfg != 0x260 && cfg != 0x270) {
1809
                printk(KERN_INFO LOGNAME ": Config port must be 0x250, 0x260 or 0x270 (or unspecified for PnP mode)\n");
1810
                return -EINVAL;
1811
        } else {
1812
                printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%x\n", cfg);
1813
 
1814
                /* DSP */
1815
                pinnacle_devs[0].io0 = io;
1816
                pinnacle_devs[0].irq = irq;
1817
                pinnacle_devs[0].mem = mem;
1818
 
1819
                /* The following are Pinnacle specific */
1820
 
1821
                /* MPU */
1822
                pinnacle_devs[1].io0 = mpu_io;
1823
                pinnacle_devs[1].irq = mpu_irq;
1824
 
1825
                /* IDE */
1826
                pinnacle_devs[2].io0 = ide_io0;
1827
                pinnacle_devs[2].io1 = ide_io1;
1828
                pinnacle_devs[2].irq = ide_irq;
1829
 
1830
                /* Joystick */
1831
                pinnacle_devs[3].io0 = joystick_io;
1832
 
1833
                if (!request_region(cfg, 2, "Pinnacle/Fiji Config")) {
1834
                        printk(KERN_ERR LOGNAME ": Config port 0x%x conflict\n", cfg);
1835
                        return -EIO;
1836
                }
1837
 
1838
                if (msnd_pinnacle_cfg_devices(cfg, reset, pinnacle_devs)) {
1839
                        printk(KERN_ERR LOGNAME ": Device configuration error\n");
1840
                        release_region(cfg, 2);
1841
                        return -EIO;
1842
                }
1843
                release_region(cfg, 2);
1844
        }
1845
#endif /* MSND_CLASSIC */
1846
 
1847
        if (fifosize < 16)
1848
                fifosize = 16;
1849
 
1850
        if (fifosize > 1024)
1851
                fifosize = 1024;
1852
 
1853
        set_default_audio_parameters();
1854
#ifdef MSND_CLASSIC
1855
        dev.type = msndClassic;
1856
#else
1857
        dev.type = msndPinnacle;
1858
#endif
1859
        dev.io = io;
1860
        dev.numio = DSP_NUMIO;
1861
        dev.irq = irq;
1862
        dev.base = ioremap(mem, 0x8000);
1863
        dev.fifosize = fifosize * 1024;
1864
        dev.calibrate_signal = calibrate_signal ? 1 : 0;
1865
        dev.recsrc = 0;
1866
        dev.dspq_data_buff = DSPQ_DATA_BUFF;
1867
        dev.dspq_buff_size = DSPQ_BUFF_SIZE;
1868
        if (write_ndelay == -1)
1869
                write_ndelay = CONFIG_MSND_WRITE_NDELAY;
1870
        if (write_ndelay)
1871
                clear_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
1872
        else
1873
                set_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
1874
#ifndef MSND_CLASSIC
1875
        if (digital)
1876
                set_bit(F_HAVEDIGITAL, &dev.flags);
1877
#endif
1878
        init_waitqueue_head(&dev.writeblock);
1879
        init_waitqueue_head(&dev.readblock);
1880
        init_waitqueue_head(&dev.writeflush);
1881
        msnd_fifo_init(&dev.DAPF);
1882
        msnd_fifo_init(&dev.DARF);
1883
        spin_lock_init(&dev.lock);
1884
        printk(KERN_INFO LOGNAME ": %u byte audio FIFOs (x2)\n", dev.fifosize);
1885
        if ((err = msnd_fifo_alloc(&dev.DAPF, dev.fifosize)) < 0) {
1886
                printk(KERN_ERR LOGNAME ": Couldn't allocate write FIFO\n");
1887
                return err;
1888
        }
1889
 
1890
        if ((err = msnd_fifo_alloc(&dev.DARF, dev.fifosize)) < 0) {
1891
                printk(KERN_ERR LOGNAME ": Couldn't allocate read FIFO\n");
1892
                msnd_fifo_free(&dev.DAPF);
1893
                return err;
1894
        }
1895
 
1896
        if ((err = probe_multisound()) < 0) {
1897
                printk(KERN_ERR LOGNAME ": Probe failed\n");
1898
                msnd_fifo_free(&dev.DAPF);
1899
                msnd_fifo_free(&dev.DARF);
1900
                return err;
1901
        }
1902
 
1903
        if ((err = attach_multisound()) < 0) {
1904
                printk(KERN_ERR LOGNAME ": Attach failed\n");
1905
                msnd_fifo_free(&dev.DAPF);
1906
                msnd_fifo_free(&dev.DARF);
1907
                return err;
1908
        }
1909
 
1910
        return 0;
1911
}
1912
 
1913
static void __exit msdn_cleanup(void)
1914
{
1915
        unload_multisound();
1916
        msnd_fifo_free(&dev.DAPF);
1917
        msnd_fifo_free(&dev.DARF);
1918
}
1919
 
1920
module_init(msnd_init);
1921
module_exit(msdn_cleanup);

powered by: WebSVN 2.1.0

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