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/] [aedsp16.c] - Blame information for rev 3

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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