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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
   drivers/sound/aedsp16.c
3
 
4
   Audio Excel DSP 16 software configuration routines
5
   Copyright (C) 1995,1996,1997,1998  Riccardo Facchetti (fizban@tin.it)
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 2 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
 
21
 */
22
/*
23
 * Include the main OSS Lite header file. It include all the os, OSS Lite, etc
24
 * headers needed by this source.
25
 */
26
#include <linux/config.h>
27
#include <linux/delay.h>
28
#include <linux/module.h>
29
#include <linux/init.h>
30
#include "sound_config.h"
31
 
32
/*
33
 * Sanity checks
34
 */
35
 
36
#if defined(CONFIG_SOUND_AEDSP16_SBPRO) && defined(CONFIG_SOUND_AEDSP16_MSS)
37
#error You have to enable only one of the MSS and SBPRO emulations.
38
#endif
39
 
40
/*
41
 
42
   READ THIS
43
 
44
   This module started to configure the Audio Excel DSP 16 Sound Card.
45
   Now works with the SC-6000 (old aedsp16) and new SC-6600 based cards.
46
 
47
   NOTE: I have NO idea about Audio Excel DSP 16 III. If someone owns this
48
   audio card and want to see the kernel support for it, please contact me.
49
 
50
   Audio Excel DSP 16 is an SB pro II, Microsoft Sound System and MPU-401
51
   compatible card.
52
   It is software-only configurable (no jumpers to hard-set irq/dma/mpu-irq),
53
   so before this module, the only way to configure the DSP under linux was
54
   boot the MS-DOS loading the sound.sys device driver (this driver soft-
55
   configure the sound board hardware by massaging someone of its registers),
56
   and then ctrl-alt-del to boot linux with the DSP configured by the DOS
57
   driver.
58
 
59
   This module works configuring your Audio Excel DSP 16's irq, dma and
60
   mpu-401-irq. The OSS Lite routines rely on the fact that if the
61
   hardware is there, they can detect it. The problem with AEDSP16 is
62
   that no hardware can be found by the probe routines if the sound card
63
   is not configured properly. Sometimes the kernel probe routines can find
64
   an SBPRO even when the card is not configured (this is the standard setup
65
   of the card), but the SBPRO emulation don't work well if the card is not
66
   properly initialized. For this reason
67
 
68
   aedsp16_init_board()
69
 
70
   routine is called before the OSS Lite probe routines try to detect the
71
   hardware.
72
 
73
   NOTE (READ THE NOTE TOO, IT CONTAIN USEFUL INFORMATIONS)
74
 
75
   NOTE: Now it works with SC-6000 and SC-6600 based audio cards. The new cards
76
   have no jumper switch at all. No more WSS or MPU-401 I/O port switches. They
77
   have to be configured by software.
78
 
79
   NOTE: The driver is merged with the new OSS Lite sound driver. It works
80
   as a lowlevel driver.
81
 
82
   The Audio Excel DSP 16 Sound Card emulates both SBPRO and MSS;
83
   the OSS Lite sound driver can be configured for SBPRO and MSS cards
84
   at the same time, but the aedsp16 can't be two cards!!
85
   When we configure it, we have to choose the SBPRO or the MSS emulation
86
   for AEDSP16. We also can install a *REAL* card of the other type (see [1]).
87
 
88
   NOTE: If someone can test the combination AEDSP16+MSS or AEDSP16+SBPRO
89
   please let me know if it works.
90
 
91
   The MPU-401 support can be compiled in together with one of the other
92
   two operating modes.
93
 
94
   NOTE: This is something like plug-and-play: we have only to plug
95
   the AEDSP16 board in the socket, and then configure and compile
96
   a kernel that uses the AEDSP16 software configuration capability.
97
   No jumper setting is needed!
98
 
99
   For example, if you want AEDSP16 to be an SBPro, on irq 10, dma 3
100
   you have just to make config the OSS Lite package, configuring
101
   the AEDSP16 sound card, then activating the SBPro emulation mode
102
   and at last configuring IRQ and DMA.
103
   Compile the kernel and run it.
104
 
105
   NOTE: This means for SC-6000 cards that you can choose irq and dma,
106
   but not the I/O addresses. To change I/O addresses you have to set
107
   them with jumpers. For SC-6600 cards you have no jumpers so you have
108
   to set up your full card configuration in the make config.
109
 
110
   You can change the irq/dma/mirq settings WITHOUT THE NEED to open
111
   your computer and massage the jumpers (there are no irq/dma/mirq
112
   jumpers to be configured anyway, only I/O BASE values have to be
113
   configured with jumpers)
114
 
115
   For some ununderstandable reason, the card default of irq 7, dma 1,
116
   don't work for me. Seems to be an IRQ or DMA conflict. Under heavy
117
   HDD work, the kernel start to erupt out a lot of messages like:
118
 
119
   'Sound: DMA timed out - IRQ/DRQ config error?'
120
 
121
   For what I can say, I have NOT any conflict at irq 7 (under linux I'm
122
   using the lp polling driver), and dma line 1 is unused as stated by
123
   /proc/dma. I can suppose this is a bug of AEDSP16. I know my hardware so
124
   I'm pretty sure I have not any conflict, but may be I'm wrong. Who knows!
125
   Anyway a setting of irq 10, dma 3 works really fine.
126
 
127
   NOTE: if someone can use AEDSP16 with irq 7, dma 1, please let me know
128
   the emulation mode, all the installed hardware and the hardware
129
   configuration (irq and dma settings of all the hardware).
130
 
131
   This init module should work with SBPRO+MSS, when one of the two is
132
   the AEDSP16 emulation and the other the real card. (see [1])
133
   For example:
134
 
135
   AEDSP16 (0x220) in SBPRO emu (0x220) + real MSS + other
136
   AEDSP16 (0x220) in MSS emu + real SBPRO (0x240) + other
137
 
138
   MPU401 should work. (see [2])
139
 
140
   [1]
141
       ---
142
       Date: Mon, 29 Jul 1997 08:35:40 +0100
143
       From: Mr S J Greenaway <sjg95@unixfe.rl.ac.uk>
144
 
145
       [...]
146
       Just to let you know got my Audio Excel (emulating a MSS) working
147
       with my original SB16, thanks for the driver!
148
       [...]
149
       ---
150
 
151
   [2] Not tested by me for lack of hardware.
152
 
153
   TODO, WISHES AND TECH
154
 
155
   - About I/O ports allocation -
156
 
157
   Request the 2x0h region (port base) in any case if we are using this card.
158
 
159
   NOTE: the "aedsp16 (base)" string with which we are requesting the aedsp16
160
   port base region (see code) does not mean necessarily that we are emulating
161
   sbpro.  Even if this region is the sbpro I/O ports region, we use this
162
   region to access the control registers of the card, and if emulating
163
   sbpro, I/O sbpro registers too. If we are emulating MSS, the sbpro
164
   registers are not used, in no way, to emulate an sbpro: they are
165
   used only for configuration purposes.
166
 
167
   Started Fri Mar 17 16:13:18 MET 1995
168
 
169
   v0.1 (ALPHA, was an user-level program called AudioExcelDSP16.c)
170
   - Initial code.
171
   v0.2 (ALPHA)
172
   - Cleanups.
173
   - Integrated with Linux voxware v 2.90-2 kernel sound driver.
174
   - SoundBlaster Pro mode configuration.
175
   - Microsoft Sound System mode configuration.
176
   - MPU-401 mode configuration.
177
   v0.3 (ALPHA)
178
   - Cleanups.
179
   - Rearranged the code to let aedsp16_init_board be more general.
180
   - Erased the REALLY_SLOW_IO. We don't need it. Erased the linux/io.h
181
   inclusion too. We rely on os.h
182
   - Used the  to get a variable
183
   len string (we are not sure about the len of Copyright string).
184
   This works with any SB and compatible.
185
   - Added the code to request_region at device init (should go in
186
   the main body of voxware).
187
   v0.4 (BETA)
188
   - Better configure.c patch for aedsp16 configuration (better
189
   logic of inclusion of AEDSP16 support)
190
   - Modified the conditional compilation to better support more than
191
   one sound card of the emulated type (read the NOTES above)
192
   - Moved the sb init routine from the attach to the very first
193
   probe in sb_card.c
194
   - Rearrangements and cleanups
195
   - Wiped out some unnecessary code and variables: this is kernel
196
   code so it is better save some TEXT and DATA
197
   - Fixed the request_region code. We must allocate the aedsp16 (sbpro)
198
   I/O ports in any case because they are used to access the DSP
199
   configuration registers and we can not allow anyone to get them.
200
   v0.5
201
   - cleanups on comments
202
   - prep for diffs against v3.0-proto-950402
203
   v0.6
204
   - removed the request_region()s when compiling the MODULE sound.o
205
   because we are not allowed (by the actual voxware structure) to
206
   release_region()
207
   v0.7 (pre ALPHA, not distributed)
208
   - started porting this module to kernel 1.3.84. Dummy probe/attach
209
   routines.
210
   v0.8 (ALPHA)
211
   - attached all the init routines.
212
   v0.9 (BETA)
213
   - Integrated with linux-pre2.0.7
214
   - Integrated with configuration scripts.
215
   - Cleaned up and beautyfied the code.
216
   v0.9.9 (BETA)
217
   - Thanks to Piercarlo Grandi: corrected the conditonal compilation code.
218
     Now only the code configured is compiled in, with some memory saving.
219
   v0.9.10
220
   - Integration into the sound/lowlevel/ section of the sound driver.
221
   - Re-organized the code.
222
   v0.9.11 (not distributed)
223
   - Rewritten the init interface-routines to initialize the AEDSP16 in
224
     one shot.
225
   - More cosmetics.
226
   - SC-6600 support.
227
   - More soft/hard configuration.
228
   v0.9.12
229
   - Refined the v0.9.11 code with conditional compilation to distinguish
230
     between SC-6000 and SC-6600 code.
231
   v1.0.0
232
   - Prep for merging with OSS Lite and Linux kernel 2.1.13
233
   - Corrected a bug in request/check/release region calls (thanks to the
234
     new kernel exception handling).
235
   v1.1
236
   - Revamped for integration with new modularized sound drivers: to enhance
237
     the flexibility of modular version, I have removed all the conditional
238
     compilation for SBPRO, MPU and MSS code. Now it is all managed with
239
     the ae_config structure.
240
   v1.2
241
   - Module informations added.
242
   - Removed aedsp16_delay_10msec(), now using mdelay(10)
243
   - All data and funcs moved to .*.init section.
244
   v1.3
245
   Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/09/27
246
   - got rid of check_region
247
 
248
   Known Problems:
249
   - Audio Excel DSP 16 III don't work with this driver.
250
 
251
   Credits:
252
   Many thanks to Gerald Britton <gbritton@CapAccess.org>. He helped me a
253
   lot in testing the 0.9.11 and 0.9.12 versions of this driver.
254
 
255
 */
256
 
257
 
258
#define VERSION "1.3"           /* Version of Audio Excel DSP 16 driver */
259
 
260
#undef  AEDSP16_DEBUG           /* Define this to 1 to enable debug code     */
261
#undef  AEDSP16_DEBUG_MORE      /* Define this to 1 to enable more debug     */
262
#undef  AEDSP16_INFO            /* Define this to 1 to enable info code      */
263
 
264
#if defined(AEDSP16_DEBUG)
265
# define DBG(x)  printk x
266
# if defined(AEDSP16_DEBUG_MORE)
267
#  define DBG1(x) printk x
268
# else
269
#  define DBG1(x)
270
# endif
271
#else
272
# define DBG(x)
273
# define DBG1(x)
274
#endif
275
 
276
/*
277
 * Misc definitions
278
 */
279
#define TRUE    1
280
#define FALSE   0
281
 
282
/*
283
 * Region Size for request/check/release region.
284
 */
285
#define IOBASE_REGION_SIZE      0x10
286
 
287
/*
288
 * Hardware related defaults
289
 */
290
#define DEF_AEDSP16_IOB 0x220   /* 0x220(default) 0x240                 */
291
#define DEF_AEDSP16_IRQ 7       /* 5 7(default) 9 10 11                 */
292
#define DEF_AEDSP16_MRQ 0       /* 5 7 9 10 0(default), 0 means disable */
293
#define DEF_AEDSP16_DMA 1       /* 0 1(default) 3                       */
294
 
295
/*
296
 * Commands of AEDSP16's DSP (SBPRO+special).
297
 * Some of them are COMMAND_xx, in the future they may change.
298
 */
299
#define WRITE_MDIRQ_CFG   0x50  /* Set M&I&DRQ mask (the real config)   */
300
#define COMMAND_52        0x52  /*                                      */
301
#define READ_HARD_CFG     0x58  /* Read Hardware Config (I/O base etc)  */
302
#define COMMAND_5C        0x5c  /*                                      */
303
#define COMMAND_60        0x60  /*                                      */
304
#define COMMAND_66        0x66  /*                                      */
305
#define COMMAND_6C        0x6c  /*                                      */
306
#define COMMAND_6E        0x6e  /*                                      */
307
#define COMMAND_88        0x88  /*                                      */
308
#define DSP_INIT_MSS      0x8c  /* Enable Microsoft Sound System mode   */
309
#define COMMAND_C5        0xc5  /*                                      */
310
#define GET_DSP_VERSION   0xe1  /* Get DSP Version                      */
311
#define GET_DSP_COPYRIGHT 0xe3  /* Get DSP Copyright                    */
312
 
313
/*
314
 * Offsets of AEDSP16 DSP I/O ports. The offset is added to base I/O port
315
 * to have the actual I/O port.
316
 * Register permissions are:
317
 * (wo) == Write Only
318
 * (ro) == Read  Only
319
 * (w-) == Write
320
 * (r-) == Read
321
 */
322
#define DSP_RESET    0x06       /* offset of DSP RESET             (wo) */
323
#define DSP_READ     0x0a       /* offset of DSP READ              (ro) */
324
#define DSP_WRITE    0x0c       /* offset of DSP WRITE             (w-) */
325
#define DSP_COMMAND  0x0c       /* offset of DSP COMMAND           (w-) */
326
#define DSP_STATUS   0x0c       /* offset of DSP STATUS            (r-) */
327
#define DSP_DATAVAIL 0x0e       /* offset of DSP DATA AVAILABLE    (ro) */
328
 
329
 
330
#define RETRY           10      /* Various retry values on I/O opera-   */
331
#define STATUSRETRY   1000      /* tions. Sometimes we have to          */
332
#define HARDRETRY   500000      /* wait for previous cmd to complete    */
333
 
334
/*
335
 * Size of character arrays that store name and version of sound card
336
 */
337
#define CARDNAMELEN 15          /* Size of the card's name in chars     */
338
#define CARDVERLEN  2           /* Size of the card's version in chars  */
339
 
340
#if defined(CONFIG_SC6600)
341
/*
342
 * Bitmapped flags of hard configuration
343
 */
344
/*
345
 * Decode macros (xl == low byte, xh = high byte)
346
 */
347
#define IOBASE(xl)              ((xl & 0x01)?0x240:0x220)
348
#define JOY(xl)                 (xl & 0x02)
349
#define MPUADDR(xl)             (                       \
350
                                (xl & 0x0C)?0x330:      \
351
                                (xl & 0x08)?0x320:      \
352
                                (xl & 0x04)?0x310:      \
353
                                                0x300)
354
#define WSSADDR(xl)             ((xl & 0x10)?0xE80:0x530)
355
#define CDROM(xh)               (xh & 0x20)
356
#define CDROMADDR(xh)           (((xh & 0x1F) << 4) + 0x200)
357
/*
358
 * Encode macros
359
 */
360
#define BLDIOBASE(xl, val) {            \
361
        xl &= ~0x01;                    \
362
        if (val == 0x240)               \
363
                xl |= 0x01;             \
364
        }
365
#define BLDJOY(xl, val) {               \
366
        xl &= ~0x02;                    \
367
        if (val == 1)                   \
368
                xl |= 0x02;             \
369
        }
370
#define BLDMPUADDR(xl, val) {           \
371
        xl &= ~0x0C;                    \
372
        switch (val) {                  \
373
                case 0x330:             \
374
                        xl |= 0x0C;     \
375
                        break;          \
376
                case 0x320:             \
377
                        xl |= 0x08;     \
378
                        break;          \
379
                case 0x310:             \
380
                        xl |= 0x04;     \
381
                        break;          \
382
                case 0x300:             \
383
                        xl |= 0x00;     \
384
                        break;          \
385
                default:                \
386
                        xl |= 0x00;     \
387
                        break;          \
388
                }                       \
389
        }
390
#define BLDWSSADDR(xl, val) {           \
391
        xl &= ~0x10;                    \
392
        if (val == 0xE80)               \
393
                xl |= 0x10;             \
394
        }
395
#define BLDCDROM(xh, val) {             \
396
        xh &= ~0x20;                    \
397
        if (val == 1)                   \
398
                xh |= 0x20;             \
399
        }
400
#define BLDCDROMADDR(xh, val) {         \
401
        int tmp = val;                  \
402
        tmp -= 0x200;                   \
403
        tmp >>= 4;                      \
404
        tmp &= 0x1F;                    \
405
        xh |= tmp;                      \
406
        xh &= 0x7F;                     \
407
        xh |= 0x40;                     \
408
        }
409
#endif /* CONFIG_SC6600 */
410
 
411
/*
412
 * Bit mapped flags for calling aedsp16_init_board(), and saving the current
413
 * emulation mode.
414
 */
415
#define INIT_NONE   (0   )
416
#define INIT_SBPRO  (1<<0)
417
#define INIT_MSS    (1<<1)
418
#define INIT_MPU401 (1<<2)
419
 
420
static int      soft_cfg __initdata = 0; /* bitmapped config */
421
static int      soft_cfg_mss __initdata = 0;     /* bitmapped mss config */
422
static int      ver[CARDVERLEN] __initdata = {0, 0};      /* DSP Ver:
423
                                                   hi->ver[0] lo->ver[1] */
424
 
425
#if defined(CONFIG_SC6600)
426
static int      hard_cfg[2]     /* lo<-hard_cfg[0] hi<-hard_cfg[1]      */
427
                     __initdata = { 0, 0};
428
#endif /* CONFIG_SC6600 */
429
 
430
#if defined(CONFIG_SC6600)
431
/* Decoded hard configuration */
432
struct  d_hcfg {
433
        int iobase;
434
        int joystick;
435
        int mpubase;
436
        int wssbase;
437
        int cdrom;
438
        int cdrombase;
439
};
440
 
441
struct d_hcfg decoded_hcfg __initdata = {0, };
442
 
443
#endif /* CONFIG_SC6600 */
444
 
445
/* orVals contain the values to be or'ed                                */
446
struct orVals {
447
        int     val;            /* irq|mirq|dma                         */
448
        int     or;             /* soft_cfg |= TheStruct.or             */
449
};
450
 
451
/* aedsp16_info contain the audio card configuration                  */
452
struct aedsp16_info {
453
        int base_io;            /* base I/O address for accessing card  */
454
        int irq;                /* irq value for DSP I/O                */
455
        int mpu_irq;            /* irq for mpu401 interface I/O         */
456
        int dma;                /* dma value for DSP I/O                */
457
        int mss_base;           /* base I/O for Microsoft Sound System  */
458
        int mpu_base;           /* base I/O for MPU-401 emulation       */
459
        int init;               /* Initialization status of the card    */
460
};
461
 
462
/*
463
 * Magic values that the DSP will eat when configuring irq/mirq/dma
464
 */
465
/* DSP IRQ conversion array             */
466
static struct orVals orIRQ[] __initdata = {
467
        {0x05, 0x28},
468
        {0x07, 0x08},
469
        {0x09, 0x10},
470
        {0x0a, 0x18},
471
        {0x0b, 0x20},
472
        {0x00, 0x00}
473
};
474
 
475
/* MPU-401 IRQ conversion array         */
476
static struct orVals orMIRQ[] __initdata = {
477
        {0x05, 0x04},
478
        {0x07, 0x44},
479
        {0x09, 0x84},
480
        {0x0a, 0xc4},
481
        {0x00, 0x00}
482
};
483
 
484
/* DMA Channels conversion array        */
485
static struct orVals orDMA[] __initdata = {
486
        {0x00, 0x01},
487
        {0x01, 0x02},
488
        {0x03, 0x03},
489
        {0x00, 0x00}
490
};
491
 
492
static struct aedsp16_info ae_config __initdata = {
493
        DEF_AEDSP16_IOB,
494
        DEF_AEDSP16_IRQ,
495
        DEF_AEDSP16_MRQ,
496
        DEF_AEDSP16_DMA,
497
        -1,
498
        -1,
499
        INIT_NONE
500
};
501
 
502
/*
503
 * Buffers to store audio card informations
504
 */
505
static char     DSPCopyright[CARDNAMELEN + 1] __initdata = {0, };
506
static char     DSPVersion[CARDVERLEN + 1] __initdata = {0, };
507
 
508
static int __init aedsp16_wait_data(int port)
509
{
510
        int             loop = STATUSRETRY;
511
        unsigned char   ret = 0;
512
 
513
        DBG1(("aedsp16_wait_data (0x%x): ", port));
514
 
515
        do {
516
                  ret = inb(port + DSP_DATAVAIL);
517
        /*
518
         * Wait for data available (bit 7 of ret == 1)
519
         */
520
          } while (!(ret & 0x80) && loop--);
521
 
522
        if (ret & 0x80) {
523
                DBG1(("success.\n"));
524
                return TRUE;
525
        }
526
 
527
        DBG1(("failure.\n"));
528
        return FALSE;
529
}
530
 
531
static int __init aedsp16_read(int port)
532
{
533
        int inbyte;
534
 
535
        DBG(("    Read DSP Byte (0x%x): ", port));
536
 
537
        if (aedsp16_wait_data(port) == FALSE) {
538
                DBG(("failure.\n"));
539
                return -1;
540
        }
541
 
542
        inbyte = inb(port + DSP_READ);
543
 
544
        DBG(("read [0x%x]/{%c}.\n", inbyte, inbyte));
545
 
546
        return inbyte;
547
}
548
 
549
static int __init aedsp16_test_dsp(int port)
550
{
551
        return ((aedsp16_read(port) == 0xaa) ? TRUE : FALSE);
552
}
553
 
554
static int __init aedsp16_dsp_reset(int port)
555
{
556
        /*
557
         * Reset DSP
558
         */
559
 
560
        DBG(("Reset DSP:\n"));
561
 
562
        outb(1, (port + DSP_RESET));
563
        udelay(10);
564
        outb(0, (port + DSP_RESET));
565
        udelay(10);
566
        udelay(10);
567
        if (aedsp16_test_dsp(port) == TRUE) {
568
                DBG(("success.\n"));
569
                return TRUE;
570
        } else
571
                DBG(("failure.\n"));
572
        return FALSE;
573
}
574
 
575
static int __init aedsp16_write(int port, int cmd)
576
{
577
        unsigned char   ret;
578
        int             loop = HARDRETRY;
579
 
580
        DBG(("    Write DSP Byte (0x%x) [0x%x]: ", port, cmd));
581
 
582
        do {
583
                ret = inb(port + DSP_STATUS);
584
                /*
585
                 * DSP ready to receive data if bit 7 of ret == 0
586
                 */
587
                if (!(ret & 0x80)) {
588
                        outb(cmd, port + DSP_COMMAND);
589
                        DBG(("success.\n"));
590
                        return 0;
591
                }
592
        } while (loop--);
593
 
594
        DBG(("timeout.\n"));
595
        printk("[AEDSP16] DSP Command (0x%x) timeout.\n", cmd);
596
 
597
        return -1;
598
}
599
 
600
#if defined(CONFIG_SC6600)
601
 
602
#if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
603
void __init aedsp16_pinfo(void) {
604
        DBG(("\n Base address:  %x\n", decoded_hcfg.iobase));
605
        DBG((" Joystick    : %s present\n", decoded_hcfg.joystick?"":" not"));
606
        DBG((" WSS addr    :  %x\n", decoded_hcfg.wssbase));
607
        DBG((" MPU-401 addr:  %x\n", decoded_hcfg.mpubase));
608
        DBG((" CDROM       : %s present\n", (decoded_hcfg.cdrom!=4)?"":" not"));
609
        DBG((" CDROMADDR   :  %x\n\n", decoded_hcfg.cdrombase));
610
}
611
#endif
612
 
613
void __init aedsp16_hard_decode(void) {
614
 
615
        DBG((" aedsp16_hard_decode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
616
 
617
/*
618
 * Decode Cfg Bytes.
619
 */
620
        decoded_hcfg.iobase     = IOBASE(hard_cfg[0]);
621
        decoded_hcfg.joystick   = JOY(hard_cfg[0]);
622
        decoded_hcfg.wssbase    = WSSADDR(hard_cfg[0]);
623
        decoded_hcfg.mpubase    = MPUADDR(hard_cfg[0]);
624
        decoded_hcfg.cdrom      = CDROM(hard_cfg[1]);
625
        decoded_hcfg.cdrombase  = CDROMADDR(hard_cfg[1]);
626
 
627
#if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
628
        printk(" Original sound card configuration:\n");
629
        aedsp16_pinfo();
630
#endif
631
 
632
/*
633
 * Now set up the real kernel configuration.
634
 */
635
        decoded_hcfg.iobase     = ae_config.base_io;
636
        decoded_hcfg.wssbase    = ae_config.mss_base;
637
        decoded_hcfg.mpubase    = ae_config.mpu_base;
638
 
639
#if defined(CONFIG_SC6600_JOY)
640
        decoded_hcfg.joystick   = CONFIG_SC6600_JOY; /* Enable */
641
#endif
642
#if defined(CONFIG_SC6600_CDROM)
643
        decoded_hcfg.cdrom      = CONFIG_SC6600_CDROM; /* 4:N-3:I-2:G-1:P-0:S */
644
#endif
645
#if defined(CONFIG_SC6600_CDROMBASE)
646
        decoded_hcfg.cdrombase  = CONFIG_SC6600_CDROMBASE; /* 0 Disable */
647
#endif
648
 
649
#if defined(AEDSP16_DEBUG)
650
        DBG((" New Values:\n"));
651
        aedsp16_pinfo();
652
#endif
653
 
654
        DBG(("success.\n"));
655
}
656
 
657
void __init aedsp16_hard_encode(void) {
658
 
659
        DBG((" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
660
 
661
        hard_cfg[0] = 0;
662
        hard_cfg[1] = 0;
663
 
664
        hard_cfg[0] |= 0x20;
665
 
666
        BLDIOBASE (hard_cfg[0], decoded_hcfg.iobase);
667
        BLDWSSADDR(hard_cfg[0], decoded_hcfg.wssbase);
668
        BLDMPUADDR(hard_cfg[0], decoded_hcfg.mpubase);
669
        BLDJOY(hard_cfg[0], decoded_hcfg.joystick);
670
        BLDCDROM(hard_cfg[1], decoded_hcfg.cdrom);
671
        BLDCDROMADDR(hard_cfg[1], decoded_hcfg.cdrombase);
672
 
673
#if defined(AEDSP16_DEBUG)
674
        aedsp16_pinfo();
675
#endif
676
 
677
        DBG((" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
678
        DBG(("success.\n"));
679
 
680
}
681
 
682
static int __init aedsp16_hard_write(int port) {
683
 
684
        DBG(("aedsp16_hard_write:\n"));
685
 
686
        if (aedsp16_write(port, COMMAND_6C)) {
687
                printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_6C);
688
                DBG(("failure.\n"));
689
                return FALSE;
690
        }
691
        if (aedsp16_write(port, COMMAND_5C)) {
692
                printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_5C);
693
                DBG(("failure.\n"));
694
                return FALSE;
695
        }
696
        if (aedsp16_write(port, hard_cfg[0])) {
697
                printk("[AEDSP16] DATA 0x%x: failed!\n", hard_cfg[0]);
698
                DBG(("failure.\n"));
699
                return FALSE;
700
        }
701
        if (aedsp16_write(port, hard_cfg[1])) {
702
                printk("[AEDSP16] DATA 0x%x: failed!\n", hard_cfg[1]);
703
                DBG(("failure.\n"));
704
                return FALSE;
705
        }
706
        if (aedsp16_write(port, COMMAND_C5)) {
707
                printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_C5);
708
                DBG(("failure.\n"));
709
                return FALSE;
710
        }
711
 
712
        DBG(("success.\n"));
713
 
714
        return TRUE;
715
}
716
 
717
static int __init aedsp16_hard_read(int port) {
718
 
719
        DBG(("aedsp16_hard_read:\n"));
720
 
721
        if (aedsp16_write(port, READ_HARD_CFG)) {
722
                printk("[AEDSP16] CMD 0x%x: failed!\n", READ_HARD_CFG);
723
                DBG(("failure.\n"));
724
                return FALSE;
725
        }
726
 
727
        if ((hard_cfg[0] = aedsp16_read(port)) == -1) {
728
                printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
729
                        READ_HARD_CFG);
730
                DBG(("failure.\n"));
731
                return FALSE;
732
        }
733
        if ((hard_cfg[1] = aedsp16_read(port)) == -1) {
734
                printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
735
                        READ_HARD_CFG);
736
                DBG(("failure.\n"));
737
                return FALSE;
738
        }
739
        if (aedsp16_read(port) == -1) {
740
                printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
741
                        READ_HARD_CFG);
742
                DBG(("failure.\n"));
743
                return FALSE;
744
        }
745
 
746
        DBG(("success.\n"));
747
 
748
        return TRUE;
749
}
750
 
751
static int __init aedsp16_ext_cfg_write(int port) {
752
 
753
        int extcfg, val;
754
 
755
        if (aedsp16_write(port, COMMAND_66)) {
756
                printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_66);
757
                return FALSE;
758
        }
759
 
760
        extcfg = 7;
761
        if (decoded_hcfg.cdrom != 2)
762
                extcfg = 0x0F;
763
        if ((decoded_hcfg.cdrom == 4) ||
764
            (decoded_hcfg.cdrom == 3))
765
                extcfg &= ~2;
766
        if (decoded_hcfg.cdrombase == 0)
767
                extcfg &= ~2;
768
        if (decoded_hcfg.mpubase == 0)
769
                extcfg &= ~1;
770
 
771
        if (aedsp16_write(port, extcfg)) {
772
                printk("[AEDSP16] Write extcfg: failed!\n");
773
                return FALSE;
774
        }
775
        if (aedsp16_write(port, 0)) {
776
                printk("[AEDSP16] Write extcfg: failed!\n");
777
                return FALSE;
778
        }
779
        if (decoded_hcfg.cdrom == 3) {
780
                if (aedsp16_write(port, COMMAND_52)) {
781
                        printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_52);
782
                        return FALSE;
783
                }
784
                if ((val = aedsp16_read(port)) == -1) {
785
                        printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n"
786
                                        , COMMAND_52);
787
                        return FALSE;
788
                }
789
                val &= 0x7F;
790
                if (aedsp16_write(port, COMMAND_60)) {
791
                        printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_60);
792
                        return FALSE;
793
                }
794
                if (aedsp16_write(port, val)) {
795
                        printk("[AEDSP16] Write val: failed!\n");
796
                        return FALSE;
797
                }
798
        }
799
 
800
        return TRUE;
801
}
802
 
803
#endif /* CONFIG_SC6600 */
804
 
805
static int __init aedsp16_cfg_write(int port) {
806
        if (aedsp16_write(port, WRITE_MDIRQ_CFG)) {
807
                printk("[AEDSP16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
808
                return FALSE;
809
        }
810
        if (aedsp16_write(port, soft_cfg)) {
811
                printk("[AEDSP16] Initialization of (M)IRQ and DMA: failed!\n");
812
                return FALSE;
813
        }
814
        return TRUE;
815
}
816
 
817
static int __init aedsp16_init_mss(int port)
818
{
819
        DBG(("aedsp16_init_mss:\n"));
820
 
821
        mdelay(10);
822
 
823
        if (aedsp16_write(port, DSP_INIT_MSS)) {
824
                printk("[AEDSP16] aedsp16_init_mss [0x%x]: failed!\n",
825
                                DSP_INIT_MSS);
826
                DBG(("failure.\n"));
827
                return FALSE;
828
        }
829
 
830
        mdelay(10);
831
 
832
        if (aedsp16_cfg_write(port) == FALSE)
833
                return FALSE;
834
 
835
        outb(soft_cfg_mss, ae_config.mss_base);
836
 
837
        DBG(("success.\n"));
838
 
839
        return TRUE;
840
}
841
 
842
static int __init aedsp16_setup_board(int port) {
843
        int     loop = RETRY;
844
 
845
#if defined(CONFIG_SC6600)
846
        int     val = 0;
847
 
848
        if (aedsp16_hard_read(port) == FALSE) {
849
                printk("[AEDSP16] aedsp16_hard_read: failed!\n");
850
                return FALSE;
851
        }
852
 
853
        if (aedsp16_write(port, COMMAND_52)) {
854
                printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_52);
855
                return FALSE;
856
        }
857
 
858
        if ((val = aedsp16_read(port)) == -1) {
859
                printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
860
                                COMMAND_52);
861
                return FALSE;
862
        }
863
#endif
864
 
865
        do {
866
                if (aedsp16_write(port, COMMAND_88)) {
867
                        printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_88);
868
                        return FALSE;
869
                }
870
                mdelay(10);
871
        } while ((aedsp16_wait_data(port) == FALSE) && loop--);
872
 
873
        if (aedsp16_read(port) == -1) {
874
                printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
875
                                COMMAND_88);
876
                return FALSE;
877
        }
878
 
879
#if !defined(CONFIG_SC6600)
880
        if (aedsp16_write(port, COMMAND_5C)) {
881
                printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_5C);
882
                return FALSE;
883
        }
884
#endif
885
 
886
        if (aedsp16_cfg_write(port) == FALSE)
887
                return FALSE;
888
 
889
#if defined(CONFIG_SC6600)
890
        if (aedsp16_write(port, COMMAND_60)) {
891
                printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_60);
892
                return FALSE;
893
        }
894
        if (aedsp16_write(port, val)) {
895
                printk("[AEDSP16] DATA 0x%x: failed!\n", val);
896
                return FALSE;
897
        }
898
        if (aedsp16_write(port, COMMAND_6E)) {
899
                printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_6E);
900
                return FALSE;
901
        }
902
        if (aedsp16_write(port, ver[0])) {
903
                printk("[AEDSP16] DATA 0x%x: failed!\n", ver[0]);
904
                return FALSE;
905
        }
906
        if (aedsp16_write(port, ver[1])) {
907
                printk("[AEDSP16] DATA 0x%x: failed!\n", ver[1]);
908
                return FALSE;
909
        }
910
 
911
        if (aedsp16_hard_write(port) == FALSE) {
912
                printk("[AEDSP16] aedsp16_hard_write: failed!\n");
913
                return FALSE;
914
        }
915
 
916
        if (aedsp16_write(port, COMMAND_5C)) {
917
                printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_5C);
918
                return FALSE;
919
        }
920
 
921
#if defined(THIS_IS_A_THING_I_HAVE_NOT_TESTED_YET)
922
        if (aedsp16_cfg_write(port) == FALSE)
923
                return FALSE;
924
#endif
925
 
926
#endif
927
 
928
        return TRUE;
929
}
930
 
931
static int __init aedsp16_stdcfg(int port) {
932
        if (aedsp16_write(port, WRITE_MDIRQ_CFG)) {
933
                printk("[AEDSP16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
934
                return FALSE;
935
        }
936
        /*
937
         * 0x0A == (IRQ 7, DMA 1, MIRQ 0)
938
         */
939
        if (aedsp16_write(port, 0x0A)) {
940
                printk("[AEDSP16] aedsp16_stdcfg: failed!\n");
941
                return FALSE;
942
        }
943
        return TRUE;
944
}
945
 
946
static int __init aedsp16_dsp_version(int port)
947
{
948
        int             len = 0;
949
        int             ret;
950
 
951
        DBG(("Get DSP Version:\n"));
952
 
953
        if (aedsp16_write(ae_config.base_io, GET_DSP_VERSION)) {
954
                printk("[AEDSP16] CMD 0x%x: failed!\n", GET_DSP_VERSION);
955
                DBG(("failed.\n"));
956
                return FALSE;
957
        }
958
 
959
        do {
960
                if ((ret = aedsp16_read(port)) == -1) {
961
                        DBG(("failed.\n"));
962
                        return FALSE;
963
                }
964
        /*
965
         * We already know how many int are stored (2), so we know when the
966
         * string is finished.
967
         */
968
                ver[len++] = ret;
969
          } while (len < CARDVERLEN);
970
        sprintf(DSPVersion, "%d.%d", ver[0], ver[1]);
971
 
972
        DBG(("success.\n"));
973
 
974
        return TRUE;
975
}
976
 
977
static int __init aedsp16_dsp_copyright(int port)
978
{
979
        int             len = 0;
980
        int             ret;
981
 
982
        DBG(("Get DSP Copyright:\n"));
983
 
984
        if (aedsp16_write(ae_config.base_io, GET_DSP_COPYRIGHT)) {
985
                printk("[AEDSP16] CMD 0x%x: failed!\n", GET_DSP_COPYRIGHT);
986
                DBG(("failed.\n"));
987
                return FALSE;
988
        }
989
 
990
        do {
991
                if ((ret = aedsp16_read(port)) == -1) {
992
        /*
993
         * If no more data available, return to the caller, no error if len>0.
994
         * We have no other way to know when the string is finished.
995
         */
996
                        if (len)
997
                                break;
998
                        else {
999
                                DBG(("failed.\n"));
1000
                                return FALSE;
1001
                        }
1002
                }
1003
 
1004
                DSPCopyright[len++] = ret;
1005
 
1006
          } while (len < CARDNAMELEN);
1007
 
1008
        DBG(("success.\n"));
1009
 
1010
        return TRUE;
1011
}
1012
 
1013
static void __init aedsp16_init_tables(void)
1014
{
1015
        int i = 0;
1016
 
1017
        memset(DSPCopyright, 0, CARDNAMELEN + 1);
1018
        memset(DSPVersion, 0, CARDVERLEN + 1);
1019
 
1020
        for (i = 0; orIRQ[i].or; i++)
1021
                if (orIRQ[i].val == ae_config.irq) {
1022
                        soft_cfg |= orIRQ[i].or;
1023
                        soft_cfg_mss |= orIRQ[i].or;
1024
                }
1025
 
1026
        for (i = 0; orMIRQ[i].or; i++)
1027
                if (orMIRQ[i].or == ae_config.mpu_irq)
1028
                        soft_cfg |= orMIRQ[i].or;
1029
 
1030
        for (i = 0; orDMA[i].or; i++)
1031
                if (orDMA[i].val == ae_config.dma) {
1032
                        soft_cfg |= orDMA[i].or;
1033
                        soft_cfg_mss |= orDMA[i].or;
1034
                }
1035
}
1036
 
1037
static int __init aedsp16_init_board(void)
1038
{
1039
        aedsp16_init_tables();
1040
 
1041
        if (aedsp16_dsp_reset(ae_config.base_io) == FALSE) {
1042
                printk("[AEDSP16] aedsp16_dsp_reset: failed!\n");
1043
                return FALSE;
1044
        }
1045
        if (aedsp16_dsp_copyright(ae_config.base_io) == FALSE) {
1046
                printk("[AEDSP16] aedsp16_dsp_copyright: failed!\n");
1047
                return FALSE;
1048
        }
1049
 
1050
        /*
1051
         * My AEDSP16 card return SC-6000 in DSPCopyright, so
1052
         * if we have something different, we have to be warned.
1053
         */
1054
        if (strcmp("SC-6000", DSPCopyright))
1055
                printk("[AEDSP16] Warning: non SC-6000 audio card!\n");
1056
 
1057
        if (aedsp16_dsp_version(ae_config.base_io) == FALSE) {
1058
                printk("[AEDSP16] aedsp16_dsp_version: failed!\n");
1059
                return FALSE;
1060
        }
1061
 
1062
        if (aedsp16_stdcfg(ae_config.base_io) == FALSE) {
1063
                printk("[AEDSP16] aedsp16_stdcfg: failed!\n");
1064
                return FALSE;
1065
        }
1066
 
1067
#if defined(CONFIG_SC6600)
1068
        if (aedsp16_hard_read(ae_config.base_io) == FALSE) {
1069
                printk("[AEDSP16] aedsp16_hard_read: failed!\n");
1070
                return FALSE;
1071
        }
1072
 
1073
        aedsp16_hard_decode();
1074
 
1075
        aedsp16_hard_encode();
1076
 
1077
        if (aedsp16_hard_write(ae_config.base_io) == FALSE) {
1078
                printk("[AEDSP16] aedsp16_hard_write: failed!\n");
1079
                return FALSE;
1080
        }
1081
 
1082
        if (aedsp16_ext_cfg_write(ae_config.base_io) == FALSE) {
1083
                printk("[AEDSP16] aedsp16_ext_cfg_write: failed!\n");
1084
                return FALSE;
1085
        }
1086
#endif /* CONFIG_SC6600 */
1087
 
1088
        if (aedsp16_setup_board(ae_config.base_io) == FALSE) {
1089
                printk("[AEDSP16] aedsp16_setup_board: failed!\n");
1090
                return FALSE;
1091
        }
1092
 
1093
        if (ae_config.mss_base != -1) {
1094
                if (ae_config.init & INIT_MSS) {
1095
                        if (aedsp16_init_mss(ae_config.base_io) == FALSE) {
1096
                                printk("[AEDSP16] Can not initialize"
1097
                                       "Microsoft Sound System mode.\n");
1098
                                return FALSE;
1099
                        }
1100
                }
1101
        }
1102
 
1103
#if !defined(MODULE) || defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
1104
 
1105
        printk("Audio Excel DSP 16 init v%s (%s %s) [",
1106
                VERSION, DSPCopyright,
1107
                DSPVersion);
1108
 
1109
        if (ae_config.mpu_base != -1) {
1110
                if (ae_config.init & INIT_MPU401) {
1111
                        printk("MPU401");
1112
                        if ((ae_config.init & INIT_MSS) ||
1113
                            (ae_config.init & INIT_SBPRO))
1114
                                printk(" ");
1115
                }
1116
        }
1117
 
1118
        if (ae_config.mss_base == -1) {
1119
                if (ae_config.init & INIT_SBPRO) {
1120
                        printk("SBPro");
1121
                        if (ae_config.init & INIT_MSS)
1122
                                printk(" ");
1123
                }
1124
        }
1125
 
1126
        if (ae_config.mss_base != -1)
1127
                if (ae_config.init & INIT_MSS)
1128
                        printk("MSS");
1129
 
1130
        printk("]\n");
1131
#endif /* MODULE || AEDSP16_INFO || AEDSP16_DEBUG */
1132
 
1133
        mdelay(10);
1134
 
1135
        return TRUE;
1136
}
1137
 
1138
static int __init init_aedsp16_sb(void)
1139
{
1140
        DBG(("init_aedsp16_sb: "));
1141
 
1142
/*
1143
 * If the card is already init'ed MSS, we can not init it to SBPRO too
1144
 * because the board can not emulate simultaneously MSS and SBPRO.
1145
 */
1146
        if (ae_config.init & INIT_MSS)
1147
                return FALSE;
1148
        if (ae_config.init & INIT_SBPRO)
1149
                return FALSE;
1150
 
1151
        ae_config.init |= INIT_SBPRO;
1152
 
1153
        DBG(("done.\n"));
1154
 
1155
        return TRUE;
1156
}
1157
 
1158
static void __init uninit_aedsp16_sb(void)
1159
{
1160
        DBG(("uninit_aedsp16_sb: "));
1161
 
1162
        ae_config.init &= ~INIT_SBPRO;
1163
 
1164
        DBG(("done.\n"));
1165
}
1166
 
1167
static int __init init_aedsp16_mss(void)
1168
{
1169
        DBG(("init_aedsp16_mss: "));
1170
 
1171
/*
1172
 * If the card is already init'ed SBPRO, we can not init it to MSS too
1173
 * because the board can not emulate simultaneously MSS and SBPRO.
1174
 */
1175
        if (ae_config.init & INIT_SBPRO)
1176
                return FALSE;
1177
        if (ae_config.init & INIT_MSS)
1178
                return FALSE;
1179
/*
1180
 * We must allocate the CONFIG_AEDSP16_BASE region too because these are the
1181
 * I/O ports to access card's control registers.
1182
 */
1183
        if (!(ae_config.init & INIT_MPU401)) {
1184
                if (!request_region(ae_config.base_io, IOBASE_REGION_SIZE,
1185
                                "aedsp16 (base)")) {
1186
                        printk(
1187
                        "AEDSP16 BASE I/O port region is already in use.\n");
1188
                        return FALSE;
1189
                }
1190
        }
1191
 
1192
        ae_config.init |= INIT_MSS;
1193
 
1194
        DBG(("done.\n"));
1195
 
1196
        return TRUE;
1197
}
1198
 
1199
static void __init uninit_aedsp16_mss(void)
1200
{
1201
        DBG(("uninit_aedsp16_mss: "));
1202
 
1203
        if ((!(ae_config.init & INIT_MPU401)) &&
1204
           (ae_config.init & INIT_MSS)) {
1205
                release_region(ae_config.base_io, IOBASE_REGION_SIZE);
1206
                DBG(("AEDSP16 base region released.\n"));
1207
        }
1208
 
1209
        ae_config.init &= ~INIT_MSS;
1210
        DBG(("done.\n"));
1211
}
1212
 
1213
static int __init init_aedsp16_mpu(void)
1214
{
1215
        DBG(("init_aedsp16_mpu: "));
1216
 
1217
        if (ae_config.init & INIT_MPU401)
1218
                return FALSE;
1219
 
1220
/*
1221
 * We must request the CONFIG_AEDSP16_BASE region too because these are the I/O
1222
 * ports to access card's control registers.
1223
 */
1224
        if (!(ae_config.init & (INIT_MSS | INIT_SBPRO))) {
1225
                if (!request_region(ae_config.base_io, IOBASE_REGION_SIZE,
1226
                                        "aedsp16 (base)")) {
1227
                        printk(
1228
                        "AEDSP16 BASE I/O port region is already in use.\n");
1229
                        return FALSE;
1230
                }
1231
        }
1232
 
1233
        ae_config.init |= INIT_MPU401;
1234
 
1235
        DBG(("done.\n"));
1236
 
1237
        return TRUE;
1238
}
1239
 
1240
static void __init uninit_aedsp16_mpu(void)
1241
{
1242
        DBG(("uninit_aedsp16_mpu: "));
1243
 
1244
        if ((!(ae_config.init & (INIT_MSS | INIT_SBPRO))) &&
1245
           (ae_config.init & INIT_MPU401)) {
1246
                release_region(ae_config.base_io, IOBASE_REGION_SIZE);
1247
                DBG(("AEDSP16 base region released.\n"));
1248
        }
1249
 
1250
        ae_config.init &= ~INIT_MPU401;
1251
 
1252
        DBG(("done.\n"));
1253
}
1254
 
1255
int __init init_aedsp16(void)
1256
{
1257
        int initialized = FALSE;
1258
 
1259
        DBG(("Initializing BASE[0x%x] IRQ[%d] DMA[%d] MIRQ[%d]\n",
1260
             ae_config.base_io,ae_config.irq,ae_config.dma,ae_config.mpu_irq));
1261
 
1262
        if (ae_config.mss_base == -1) {
1263
                if (init_aedsp16_sb() == FALSE) {
1264
                        uninit_aedsp16_sb();
1265
                } else {
1266
                        initialized = TRUE;
1267
                }
1268
        }
1269
 
1270
        if (ae_config.mpu_base != -1) {
1271
                if (init_aedsp16_mpu() == FALSE) {
1272
                        uninit_aedsp16_mpu();
1273
                } else {
1274
                        initialized = TRUE;
1275
                }
1276
        }
1277
 
1278
/*
1279
 * In the sequence of init routines, the MSS init MUST be the last!
1280
 * This because of the special register programming the MSS mode needs.
1281
 * A board reset would disable the MSS mode restoring the default SBPRO
1282
 * mode.
1283
 */
1284
        if (ae_config.mss_base != -1) {
1285
                if (init_aedsp16_mss() == FALSE) {
1286
                        uninit_aedsp16_mss();
1287
                } else {
1288
                        initialized = TRUE;
1289
                }
1290
        }
1291
 
1292
        if (initialized)
1293
                initialized = aedsp16_init_board();
1294
        return initialized;
1295
}
1296
 
1297
void __init uninit_aedsp16(void)
1298
{
1299
        if (ae_config.mss_base != -1)
1300
                uninit_aedsp16_mss();
1301
        else
1302
                uninit_aedsp16_sb();
1303
        if (ae_config.mpu_base != -1)
1304
                uninit_aedsp16_mpu();
1305
}
1306
 
1307
static int __initdata io = -1;
1308
static int __initdata irq = -1;
1309
static int __initdata dma = -1;
1310
static int __initdata mpu_irq = -1;
1311
static int __initdata mss_base = -1;
1312
static int __initdata mpu_base = -1;
1313
 
1314
MODULE_PARM(io, "i");
1315
MODULE_PARM_DESC(io, "I/O base address (0x220 0x240)");
1316
MODULE_PARM(irq, "i");
1317
MODULE_PARM_DESC(irq, "IRQ line (5 7 9 10 11)");
1318
MODULE_PARM(dma, "i");
1319
MODULE_PARM_DESC(dma, "dma line (0 1 3)");
1320
MODULE_PARM(mpu_irq, "i");
1321
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ line (5 7 9 10 0)");
1322
MODULE_PARM(mss_base, "i");
1323
MODULE_PARM_DESC(mss_base, "MSS emulation I/O base address (0x530 0xE80)");
1324
MODULE_PARM(mpu_base, "i");
1325
MODULE_PARM_DESC(mpu_base,"MPU-401 I/O base address (0x300 0x310 0x320 0x330)");
1326
MODULE_AUTHOR("Riccardo Facchetti <fizban@tin.it>");
1327
MODULE_DESCRIPTION("Audio Excel DSP 16 Driver Version " VERSION);
1328
MODULE_LICENSE("GPL");
1329
 
1330
static int __init do_init_aedsp16(void) {
1331
        printk("Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98\n");
1332
        if (io == -1 || dma == -1 || irq == -1) {
1333
                printk(KERN_INFO "aedsp16: I/O, IRQ and DMA are mandatory\n");
1334
                return -EINVAL;
1335
        }
1336
 
1337
        ae_config.base_io = io;
1338
        ae_config.irq = irq;
1339
        ae_config.dma = dma;
1340
 
1341
        ae_config.mss_base = mss_base;
1342
        ae_config.mpu_base = mpu_base;
1343
        ae_config.mpu_irq = mpu_irq;
1344
 
1345
        if (init_aedsp16() == FALSE) {
1346
                printk(KERN_ERR "aedsp16: initialization failed\n");
1347
                /*
1348
                 * XXX
1349
                 * What error should we return here ?
1350
                 */
1351
                return -EINVAL;
1352
        }
1353
        return 0;
1354
}
1355
 
1356
static void __exit cleanup_aedsp16(void) {
1357
        uninit_aedsp16();
1358
}
1359
 
1360
module_init(do_init_aedsp16);
1361
module_exit(cleanup_aedsp16);
1362
 
1363
#ifndef MODULE
1364
static int __init setup_aedsp16(char *str)
1365
{
1366
        /* io, irq, dma, mss_io, mpu_io, mpu_irq */
1367
        int ints[7];
1368
 
1369
        str = get_options(str, ARRAY_SIZE(ints), ints);
1370
 
1371
        io       = ints[1];
1372
        irq      = ints[2];
1373
        dma      = ints[3];
1374
        mss_base = ints[4];
1375
        mpu_base = ints[5];
1376
        mpu_irq  = ints[6];
1377
        return 1;
1378
}
1379
 
1380
__setup("aedsp16=", setup_aedsp16);
1381
#endif

powered by: WebSVN 2.1.0

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