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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * sound/opl3sa2.c
3
 *
4
 * A low level driver for Yamaha OPL3-SA2 and SA3 cards.
5
 * NOTE: All traces of the name OPL3-SAx have now (December 2000) been
6
 *       removed from the driver code, as an email exchange with Yamaha
7
 *       provided the information that the YMF-719 is indeed just a
8
 *       re-badged 715.
9
 *
10
 * Copyright 1998-2001 Scott Murray <scott@spiteful.org>
11
 *
12
 * Originally based on the CS4232 driver (in cs4232.c) by Hannu Savolainen
13
 * and others.  Now incorporates code/ideas from pss.c, also by Hannu
14
 * Savolainen.  Both of those files are distributed with the following
15
 * license:
16
 *
17
 * "Copyright (C) by Hannu Savolainen 1993-1997
18
 *
19
 *  OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
20
 *  Version 2 (June 1991). See the "COPYING" file distributed with this software
21
 *  for more info."
22
 *
23
 * As such, in accordance with the above license, this file, opl3sa2.c, is
24
 * distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 (June 1991).
25
 * See the "COPYING" file distributed with this software for more information.
26
 *
27
 * Change History
28
 * --------------
29
 * Scott Murray            Original driver (Jun 14, 1998)
30
 * Paul J.Y. Lahaie        Changed probing / attach code order
31
 * Scott Murray            Added mixer support (Dec 03, 1998)
32
 * Scott Murray            Changed detection code to be more forgiving,
33
 *                         added force option as last resort,
34
 *                         fixed ioctl return values. (Dec 30, 1998)
35
 * Scott Murray            Simpler detection code should work all the time now
36
 *                         (with thanks to Ben Hutchings for the heuristic),
37
 *                         removed now unnecessary force option. (Jan 5, 1999)
38
 * Christoph Hellwig       Adapted to module_init/module_exit (Mar 4, 2000)
39
 * Scott Murray            Reworked SA2 versus SA3 mixer code, updated chipset
40
 *                         version detection code (again!). (Dec 5, 2000)
41
 * Scott Murray            Adjusted master volume mixer scaling. (Dec 6, 2000)
42
 * Scott Murray            Based on a patch by Joel Yliluoma (aka Bisqwit),
43
 *                         integrated wide mixer and adjusted mic, bass, treble
44
 *                         scaling. (Dec 6, 2000)
45
 * Scott Murray            Based on a patch by Peter Englmaier, integrated
46
 *                         ymode and loopback options. (Dec 6, 2000)
47
 * Scott Murray            Inspired by a patch by Peter Englmaier, and based on
48
 *                         what ALSA does, added initialization code for the
49
 *                         default DMA and IRQ settings. (Dec 6, 2000)
50
 * Scott Murray            Added some more checks to the card detection code,
51
 *                         based on what ALSA does. (Dec 12, 2000)
52
 * Scott Murray            Inspired by similar patches from John Fremlin,
53
 *                         Jim Radford, Mike Rolig, and Ingmar Steen, added 2.4
54
 *                         ISA PnP API support, mainly based on bits from
55
 *                         sb_card.c and awe_wave.c. (Dec 12, 2000)
56
 * Scott Murray            Some small cleanups to the init code output.
57
 *                         (Jan 7, 2001)
58
 * Zwane Mwaikambo         Added PM support. (Dec 4 2001)
59
 * Zwane Mwaikambo         Code, data structure cleanups. (Feb 15 2002)
60
 *
61
 */
62
 
63
#include <linux/config.h>
64
#include <linux/init.h>
65
#include <linux/module.h>
66
#include <linux/isapnp.h>
67
#include <linux/pm.h>
68
#include <linux/delay.h>
69
#include "sound_config.h"
70
 
71
#include "ad1848.h"
72
#include "mpu401.h"
73
 
74
#define OPL3SA2_MODULE_NAME     "opl3sa2"
75
#define PFX                     OPL3SA2_MODULE_NAME ": "
76
 
77
/* Useful control port indexes: */
78
#define OPL3SA2_PM           0x01
79
#define OPL3SA2_SYS_CTRL     0x02
80
#define OPL3SA2_IRQ_CONFIG   0x03
81
#define OPL3SA2_DMA_CONFIG   0x06
82
#define OPL3SA2_MASTER_LEFT  0x07
83
#define OPL3SA2_MASTER_RIGHT 0x08
84
#define OPL3SA2_MIC          0x09
85
#define OPL3SA2_MISC         0x0A
86
 
87
#define OPL3SA3_WIDE         0x14
88
#define OPL3SA3_BASS         0x15
89
#define OPL3SA3_TREBLE       0x16
90
 
91
/* Useful constants: */
92
#define DEFAULT_VOLUME 50
93
#define DEFAULT_MIC    50
94
#define DEFAULT_TIMBRE 0
95
 
96
/* Power saving modes */
97
#define OPL3SA2_PM_MODE0        0x00
98
#define OPL3SA2_PM_MODE1        0x04    /* PSV */
99
#define OPL3SA2_PM_MODE2        0x05    /* PSV | PDX */
100
#define OPL3SA2_PM_MODE3        0x27    /* ADOWN | PSV | PDN | PDX */
101
 
102
/* For checking against what the card returns: */
103
#define VERSION_UNKNOWN 0
104
#define VERSION_YMF711  1
105
#define VERSION_YMF715  2
106
#define VERSION_YMF715B 3
107
#define VERSION_YMF715E 4
108
/* also assuming that anything > 4 but <= 7 is a 715E */
109
 
110
/* Chipset type constants for use below */
111
#define CHIPSET_UNKNOWN -1
112
#define CHIPSET_OPL3SA2 0
113
#define CHIPSET_OPL3SA3 1
114
static const char *CHIPSET_TABLE[] = {"OPL3-SA2", "OPL3-SA3"};
115
 
116
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
117
#define OPL3SA2_CARDS_MAX 4
118
#else
119
#define OPL3SA2_CARDS_MAX 1
120
#endif
121
 
122
/* This should be pretty obvious */
123
static int opl3sa2_cards_num; /* = 0 */
124
 
125
typedef struct {
126
        /* device resources */
127
        unsigned short cfg_port;
128
        struct address_info cfg;
129
        struct address_info cfg_mss;
130
        struct address_info cfg_mpu;
131
 
132
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
133
        /* PnP Stuff */
134
        struct pci_dev* pdev;
135
        int activated;                  /* Whether said devices have been activated */
136
#endif
137
 
138
#ifdef CONFIG_PM
139
        unsigned int    in_suspend;
140
        struct pm_dev   *pmdev;
141
#endif
142
        unsigned int    card;
143
        int             chipset;        /* What's my version(s)? */
144
        char            *chipset_name;
145
 
146
        /* mixer data */
147
        int             mixer;
148
        unsigned int    volume_l;
149
        unsigned int    volume_r;
150
        unsigned int    mic;
151
        unsigned int    bass_l;
152
        unsigned int    bass_r;
153
        unsigned int    treble_l;
154
        unsigned int    treble_r;
155
        unsigned int    wide_l;
156
        unsigned int    wide_r;
157
} opl3sa2_state_t;
158
static opl3sa2_state_t opl3sa2_state[OPL3SA2_CARDS_MAX];
159
 
160
/* Our parameters */
161
static int __initdata io        = -1;
162
static int __initdata mss_io    = -1;
163
static int __initdata mpu_io    = -1;
164
static int __initdata irq       = -1;
165
static int __initdata dma       = -1;
166
static int __initdata dma2      = -1;
167
static int __initdata ymode     = -1;
168
static int __initdata loopback  = -1;
169
 
170
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
171
/* PnP specific parameters */
172
static int __initdata isapnp = 1;
173
static int __initdata multiple = 1;
174
 
175
#else
176
static int __initdata isapnp; /* = 0 */
177
static int __initdata multiple; /* = 0 */
178
#endif
179
 
180
MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver).");
181
MODULE_AUTHOR("Scott Murray <scott@spiteful.org>");
182
MODULE_LICENSE("GPL");
183
 
184
 
185
MODULE_PARM(io, "i");
186
MODULE_PARM_DESC(io, "Set I/O base of OPL3-SA2 or SA3 card (usually 0x370.  Address must be even and must be from 0x100 to 0xFFE)");
187
 
188
MODULE_PARM(mss_io, "i");
189
MODULE_PARM_DESC(mss_io, "Set MSS (audio) I/O base (0x530, 0xE80, or other. Address must end in 0 or 4 and must be from 0x530 to 0xF48)");
190
 
191
MODULE_PARM(mpu_io, "i");
192
MODULE_PARM_DESC(mpu_io, "Set MIDI I/O base (0x330 or other. Address must be even and must be from 0x300 to 0x334)");
193
 
194
MODULE_PARM(irq, "i");
195
MODULE_PARM_DESC(mss_irq, "Set MSS (audio) IRQ (5, 7, 9, 10, 11, 12)");
196
 
197
MODULE_PARM(dma, "i");
198
MODULE_PARM_DESC(dma, "Set MSS (audio) first DMA channel (0, 1, 3)");
199
 
200
MODULE_PARM(dma2, "i");
201
MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");
202
 
203
MODULE_PARM(ymode, "i");
204
MODULE_PARM_DESC(ymode, "Set Yamaha 3D enhancement mode (0 = Desktop/Normal, 1 = Notebook PC (1), 2 = Notebook PC (2), 3 = Hi-Fi)");
205
 
206
MODULE_PARM(loopback, "i");
207
MODULE_PARM_DESC(loopback, "Set A/D input source. Useful for echo cancellation (0 = Mic Rch (default), 1 = Mono output loopback)");
208
 
209
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
210
MODULE_PARM(isapnp, "i");
211
MODULE_PARM_DESC(isapnp, "When set to 0, ISA PnP support will be disabled");
212
 
213
MODULE_PARM(multiple, "i");
214
MODULE_PARM_DESC(multiple, "When set to 0, will not search for multiple cards");
215
#endif
216
 
217
 
218
/*
219
 * Standard read and write functions
220
*/
221
 
222
static inline void opl3sa2_write(unsigned short port,
223
                                 unsigned char  index,
224
                                 unsigned char  data)
225
{
226
        outb_p(index, port);
227
        outb(data, port + 1);
228
}
229
 
230
 
231
static inline void opl3sa2_read(unsigned short port,
232
                                unsigned char  index,
233
                                unsigned char* data)
234
{
235
        outb_p(index, port);
236
        *data = inb(port + 1);
237
}
238
 
239
 
240
/*
241
 * All of the mixer functions...
242
 */
243
 
244
static void opl3sa2_set_volume(opl3sa2_state_t* devc, int left, int right)
245
{
246
        static unsigned char scale[101] = {
247
                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e,
248
                0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c,
249
                0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b,
250
                0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09,
251
                0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08,
252
                0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
253
                0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
254
                0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
255
                0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01,
256
                0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
257
                0x00
258
        };
259
        unsigned char vol;
260
 
261
        vol = scale[left];
262
 
263
        /* If level is zero, turn on mute */
264
        if(!left)
265
                vol |= 0x80;
266
 
267
        opl3sa2_write(devc->cfg_port, OPL3SA2_MASTER_LEFT, vol);
268
 
269
        vol = scale[right];
270
 
271
        /* If level is zero, turn on mute */
272
        if(!right)
273
                vol |= 0x80;
274
 
275
        opl3sa2_write(devc->cfg_port, OPL3SA2_MASTER_RIGHT, vol);
276
}
277
 
278
 
279
static void opl3sa2_set_mic(opl3sa2_state_t* devc, int level)
280
{
281
        unsigned char vol = 0x1F;
282
 
283
        if((level >= 0) && (level <= 100))
284
                vol = 0x1F - (unsigned char) (32 * level / 101);
285
 
286
        /* If level is zero, turn on mute */
287
        if(!level)
288
                vol |= 0x80;
289
 
290
        opl3sa2_write(devc->cfg_port, OPL3SA2_MIC, vol);
291
}
292
 
293
 
294
static void opl3sa3_set_bass(opl3sa2_state_t* devc, int left, int right)
295
{
296
        unsigned char bass;
297
 
298
        bass = left ? ((unsigned char) (8 * left / 101)) : 0;
299
        bass |= (right ? ((unsigned char) (8 * right / 101)) : 0) << 4;
300
 
301
        opl3sa2_write(devc->cfg_port, OPL3SA3_BASS, bass);
302
}
303
 
304
 
305
static void opl3sa3_set_treble(opl3sa2_state_t* devc, int left, int right)
306
{
307
        unsigned char treble;
308
 
309
        treble = left ? ((unsigned char) (8 * left / 101)) : 0;
310
        treble |= (right ? ((unsigned char) (8 * right / 101)) : 0) << 4;
311
 
312
        opl3sa2_write(devc->cfg_port, OPL3SA3_TREBLE, treble);
313
}
314
 
315
 
316
static void opl3sa3_set_wide(opl3sa2_state_t* devc, int left, int right)
317
{
318
        unsigned char wide;
319
 
320
        wide = left ? ((unsigned char) (8 * left / 101)) : 0;
321
        wide |= (right ? ((unsigned char) (8 * right / 101)) : 0) << 4;
322
 
323
        opl3sa2_write(devc->cfg_port, OPL3SA3_WIDE, wide);
324
}
325
 
326
 
327
static void opl3sa2_mixer_reset(opl3sa2_state_t* devc)
328
{
329
        if(devc) {
330
                opl3sa2_set_volume(devc, DEFAULT_VOLUME, DEFAULT_VOLUME);
331
                devc->volume_l = devc->volume_r = DEFAULT_VOLUME;
332
 
333
                opl3sa2_set_mic(devc, DEFAULT_MIC);
334
                devc->mic = DEFAULT_MIC;
335
 
336
                if(devc->chipset == CHIPSET_OPL3SA3) {
337
                        opl3sa3_set_bass(devc, DEFAULT_TIMBRE, DEFAULT_TIMBRE);
338
                        devc->bass_l = devc->bass_r = DEFAULT_TIMBRE;
339
                        opl3sa3_set_treble(devc, DEFAULT_TIMBRE, DEFAULT_TIMBRE);
340
                        devc->treble_l = devc->treble_r = DEFAULT_TIMBRE;
341
                }
342
        }
343
}
344
 
345
 
346
static void opl3sa2_mixer_restore(opl3sa2_state_t* devc)
347
{
348
        if (devc) {
349
                opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r);
350
                opl3sa2_set_mic(devc, devc->mic);
351
 
352
                if (devc->chipset == CHIPSET_OPL3SA3) {
353
                        opl3sa3_set_bass(devc, devc->bass_l, devc->bass_r);
354
                        opl3sa3_set_treble(devc, devc->treble_l, devc->treble_r);
355
                }
356
        }
357
}
358
 
359
 
360
static inline void arg_to_vol_mono(unsigned int vol, int* value)
361
{
362
        int left;
363
 
364
        left = vol & 0x00ff;
365
        if (left > 100)
366
                left = 100;
367
        *value = left;
368
}
369
 
370
 
371
static inline void arg_to_vol_stereo(unsigned int vol, int* aleft, int* aright)
372
{
373
        arg_to_vol_mono(vol, aleft);
374
        arg_to_vol_mono(vol >> 8, aright);
375
}
376
 
377
 
378
static inline int ret_vol_mono(int vol)
379
{
380
        return ((vol << 8) | vol);
381
}
382
 
383
 
384
static inline int ret_vol_stereo(int left, int right)
385
{
386
        return ((right << 8) | left);
387
}
388
 
389
 
390
static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
391
{
392
        int cmdf = cmd & 0xff;
393
 
394
        opl3sa2_state_t* devc = (opl3sa2_state_t *) mixer_devs[dev]->devc;
395
 
396
        switch(cmdf) {
397
                case SOUND_MIXER_VOLUME:
398
                case SOUND_MIXER_MIC:
399
                case SOUND_MIXER_DEVMASK:
400
                case SOUND_MIXER_STEREODEVS:
401
                case SOUND_MIXER_RECMASK:
402
                case SOUND_MIXER_RECSRC:
403
                case SOUND_MIXER_CAPS:
404
                        break;
405
 
406
                default:
407
                        return -EINVAL;
408
        }
409
 
410
        if(((cmd >> 8) & 0xff) != 'M')
411
                return -EINVAL;
412
 
413
        if(_SIOC_DIR (cmd) & _SIOC_WRITE) {
414
                switch (cmdf) {
415
                        case SOUND_MIXER_VOLUME:
416
                                arg_to_vol_stereo(*(unsigned int*)arg,
417
                                                  &devc->volume_l, &devc->volume_r);
418
                                opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r);
419
                                *(int*)arg = ret_vol_stereo(devc->volume_l, devc->volume_r);
420
                                return 0;
421
 
422
                        case SOUND_MIXER_MIC:
423
                                arg_to_vol_mono(*(unsigned int*)arg, &devc->mic);
424
                                opl3sa2_set_mic(devc, devc->mic);
425
                                *(int*)arg = ret_vol_mono(devc->mic);
426
                                return 0;
427
 
428
                        default:
429
                                return -EINVAL;
430
                }
431
        }
432
        else {
433
                /*
434
                 * Return parameters
435
                 */
436
                switch (cmdf) {
437
                        case SOUND_MIXER_DEVMASK:
438
                                *(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_MIC);
439
                                return 0;
440
 
441
                        case SOUND_MIXER_STEREODEVS:
442
                                *(int*)arg = SOUND_MASK_VOLUME;
443
                                return 0;
444
 
445
                        case SOUND_MIXER_RECMASK:
446
                                /* No recording devices */
447
                                return (*(int*)arg = 0);
448
 
449
                        case SOUND_MIXER_CAPS:
450
                                *(int*)arg = SOUND_CAP_EXCL_INPUT;
451
                                return 0;
452
 
453
                        case SOUND_MIXER_RECSRC:
454
                                /* No recording source */
455
                                return (*(int*)arg = 0);
456
 
457
                        case SOUND_MIXER_VOLUME:
458
                                *(int*)arg = ret_vol_stereo(devc->volume_l, devc->volume_r);
459
                                return 0;
460
 
461
                        case SOUND_MIXER_MIC:
462
                                *(int*)arg = ret_vol_mono(devc->mic);
463
                                return 0;
464
 
465
                        default:
466
                                return -EINVAL;
467
                }
468
        }
469
}
470
/* opl3sa2_mixer_ioctl end */
471
 
472
 
473
static int opl3sa3_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
474
{
475
        int cmdf = cmd & 0xff;
476
 
477
        opl3sa2_state_t* devc = (opl3sa2_state_t *) mixer_devs[dev]->devc;
478
 
479
        switch(cmdf) {
480
                case SOUND_MIXER_BASS:
481
                case SOUND_MIXER_TREBLE:
482
                case SOUND_MIXER_DIGITAL1:
483
                case SOUND_MIXER_DEVMASK:
484
                case SOUND_MIXER_STEREODEVS:
485
                        break;
486
 
487
                default:
488
                        return opl3sa2_mixer_ioctl(dev, cmd, arg);
489
        }
490
 
491
        if(((cmd >> 8) & 0xff) != 'M')
492
                return -EINVAL;
493
 
494
        if(_SIOC_DIR (cmd) & _SIOC_WRITE) {
495
                switch (cmdf) {
496
                        case SOUND_MIXER_BASS:
497
                                arg_to_vol_stereo(*(unsigned int*)arg,
498
                                                  &devc->bass_l, &devc->bass_r);
499
                                opl3sa3_set_bass(devc, devc->bass_l, devc->bass_r);
500
                                *(int*)arg = ret_vol_stereo(devc->bass_l, devc->bass_r);
501
                                return 0;
502
 
503
                        case SOUND_MIXER_TREBLE:
504
                                arg_to_vol_stereo(*(unsigned int*)arg,
505
                                                  &devc->treble_l, &devc->treble_r);
506
                                opl3sa3_set_treble(devc, devc->treble_l, devc->treble_r);
507
                                *(int*)arg = ret_vol_stereo(devc->treble_l, devc->treble_r);
508
                                return 0;
509
 
510
                        case SOUND_MIXER_DIGITAL1:
511
                                arg_to_vol_stereo(*(unsigned int*)arg,
512
                                                  &devc->wide_l, &devc->wide_r);
513
                                opl3sa3_set_wide(devc, devc->wide_l, devc->wide_r);
514
                                *(int*)arg = ret_vol_stereo(devc->wide_l, devc->wide_r);
515
                                return 0;
516
 
517
                        default:
518
                                return -EINVAL;
519
                }
520
        }
521
        else
522
        {
523
                /*
524
                 * Return parameters
525
                 */
526
                switch (cmdf) {
527
                        case SOUND_MIXER_DEVMASK:
528
                                *(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_MIC |
529
                                              SOUND_MASK_BASS | SOUND_MASK_TREBLE |
530
                                              SOUND_MASK_DIGITAL1);
531
                                return 0;
532
 
533
                        case SOUND_MIXER_STEREODEVS:
534
                                *(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_BASS |
535
                                              SOUND_MASK_TREBLE | SOUND_MASK_DIGITAL1);
536
                                return 0;
537
 
538
                        case SOUND_MIXER_BASS:
539
                                *(int*)arg = ret_vol_stereo(devc->bass_l, devc->bass_r);
540
                                return 0;
541
 
542
                        case SOUND_MIXER_TREBLE:
543
                                *(int*)arg = ret_vol_stereo(devc->treble_l, devc->treble_r);
544
                                return 0;
545
 
546
                        case SOUND_MIXER_DIGITAL1:
547
                                *(int*)arg = ret_vol_stereo(devc->wide_l, devc->wide_r);
548
                                return 0;
549
 
550
                        default:
551
                                return -EINVAL;
552
                }
553
        }
554
}
555
/* opl3sa3_mixer_ioctl end */
556
 
557
 
558
static struct mixer_operations opl3sa2_mixer_operations =
559
{
560
        owner:  THIS_MODULE,
561
        id:     "OPL3-SA2",
562
        name:   "Yamaha OPL3-SA2",
563
        ioctl:  opl3sa2_mixer_ioctl
564
};
565
 
566
static struct mixer_operations opl3sa3_mixer_operations =
567
{
568
        owner:  THIS_MODULE,
569
        id:     "OPL3-SA3",
570
        name:   "Yamaha OPL3-SA3",
571
        ioctl:  opl3sa3_mixer_ioctl
572
};
573
 
574
/* End of mixer-related stuff */
575
 
576
 
577
/*
578
 * Component probe, attach, unload functions
579
 */
580
 
581
static inline int __init probe_opl3sa2_mpu(struct address_info* hw_config)
582
{
583
        return probe_mpu401(hw_config);
584
}
585
 
586
 
587
static inline void __init attach_opl3sa2_mpu(struct address_info* hw_config)
588
{
589
        attach_mpu401(hw_config, THIS_MODULE);
590
}
591
 
592
 
593
static inline void __exit unload_opl3sa2_mpu(struct address_info *hw_config)
594
{
595
        unload_mpu401(hw_config);
596
}
597
 
598
 
599
static inline int __init probe_opl3sa2_mss(struct address_info* hw_config)
600
{
601
        return probe_ms_sound(hw_config);
602
}
603
 
604
 
605
static void __init attach_opl3sa2_mss(struct address_info* hw_config)
606
{
607
        int initial_mixers;
608
 
609
        initial_mixers = num_mixers;
610
        attach_ms_sound(hw_config, THIS_MODULE);        /* Slot 0 */
611
        if(hw_config->slots[0] != -1) {
612
                /* Did the MSS driver install? */
613
                if(num_mixers == (initial_mixers + 1)) {
614
                        /* The MSS mixer is installed, reroute mixers appropiately */
615
                        AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
616
                        AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
617
                        AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
618
                }
619
                else {
620
                        printk(KERN_ERR PFX "MSS mixer not installed?\n");
621
                }
622
        }
623
}
624
 
625
 
626
static inline void __exit unload_opl3sa2_mss(struct address_info* hw_config)
627
{
628
        unload_ms_sound(hw_config);
629
}
630
 
631
 
632
static int __init probe_opl3sa2(struct address_info* hw_config, int card)
633
{
634
        unsigned char misc;
635
        unsigned char tmp;
636
        unsigned char version;
637
 
638
        /*
639
         * Try and allocate our I/O port range.
640
         */
641
        if(!request_region(hw_config->io_base, 2, OPL3SA2_MODULE_NAME)) {
642
                printk(KERN_ERR PFX "Control I/O port %#x not free\n",
643
                       hw_config->io_base);
644
                goto out_nodev;
645
        }
646
 
647
        /*
648
         * Check if writing to the read-only version bits of the miscellaneous
649
         * register succeeds or not (it should not).
650
         */
651
        opl3sa2_read(hw_config->io_base, OPL3SA2_MISC, &misc);
652
        opl3sa2_write(hw_config->io_base, OPL3SA2_MISC, misc ^ 0x07);
653
        opl3sa2_read(hw_config->io_base, OPL3SA2_MISC, &tmp);
654
        if(tmp != misc) {
655
                printk(KERN_ERR PFX "Control I/O port %#x is not a YMF7xx chipset!\n",
656
                       hw_config->io_base);
657
                goto out_region;
658
        }
659
 
660
        /*
661
         * Check if the MIC register is accessible.
662
         */
663
        opl3sa2_read(hw_config->io_base, OPL3SA2_MIC, &tmp);
664
        opl3sa2_write(hw_config->io_base, OPL3SA2_MIC, 0x8a);
665
        opl3sa2_read(hw_config->io_base, OPL3SA2_MIC, &tmp);
666
        if((tmp & 0x9f) != 0x8a) {
667
                printk(KERN_ERR
668
                       PFX "Control I/O port %#x is not a YMF7xx chipset!\n",
669
                       hw_config->io_base);
670
                goto out_region;
671
        }
672
        opl3sa2_write(hw_config->io_base, OPL3SA2_MIC, tmp);
673
 
674
        /*
675
         * Determine chipset type (SA2 or SA3)
676
         *
677
         * This is done by looking at the chipset version in the lower 3 bits
678
         * of the miscellaneous register.
679
         */
680
        version = misc & 0x07;
681
        printk(KERN_DEBUG PFX "chipset version = %#x\n", version);
682
        switch(version) {
683
                case 0:
684
                        opl3sa2_state[card].chipset = CHIPSET_UNKNOWN;
685
                        printk(KERN_ERR
686
                               PFX "Unknown Yamaha audio controller version\n");
687
                        break;
688
 
689
                case VERSION_YMF711:
690
                        opl3sa2_state[card].chipset = CHIPSET_OPL3SA2;
691
                        printk(KERN_INFO PFX "Found OPL3-SA2 (YMF711)\n");
692
                        break;
693
 
694
                case VERSION_YMF715:
695
                        opl3sa2_state[card].chipset = CHIPSET_OPL3SA3;
696
                        printk(KERN_INFO
697
                               PFX "Found OPL3-SA3 (YMF715 or YMF719)\n");
698
                        break;
699
 
700
                case VERSION_YMF715B:
701
                        opl3sa2_state[card].chipset = CHIPSET_OPL3SA3;
702
                        printk(KERN_INFO
703
                               PFX "Found OPL3-SA3 (YMF715B or YMF719B)\n");
704
                        break;
705
 
706
                case VERSION_YMF715E:
707
                default:
708
                        opl3sa2_state[card].chipset = CHIPSET_OPL3SA3;
709
                        printk(KERN_INFO
710
                               PFX "Found OPL3-SA3 (YMF715E or YMF719E)\n");
711
                        break;
712
        }
713
 
714
        if(opl3sa2_state[card].chipset != CHIPSET_UNKNOWN) {
715
                /* Generate a pretty name */
716
                opl3sa2_state[card].chipset_name = (char *)CHIPSET_TABLE[opl3sa2_state[card].chipset];
717
                return 0;
718
        }
719
 
720
out_region:
721
        release_region(hw_config->io_base, 2);
722
out_nodev:
723
        return -ENODEV;
724
}
725
 
726
 
727
static void __init attach_opl3sa2(struct address_info* hw_config, int card)
728
{
729
 
730
        /* Initialize IRQ configuration to IRQ-B: -, IRQ-A: WSS+MPU+OPL3 */
731
        opl3sa2_write(hw_config->io_base, OPL3SA2_IRQ_CONFIG, 0x0d);
732
 
733
        /* Initialize DMA configuration */
734
        if(hw_config->dma2 == hw_config->dma) {
735
                /* Want DMA configuration DMA-B: -, DMA-A: WSS-P+WSS-R */
736
                opl3sa2_write(hw_config->io_base, OPL3SA2_DMA_CONFIG, 0x03);
737
        }
738
        else {
739
                /* Want DMA configuration DMA-B: WSS-R, DMA-A: WSS-P */
740
                opl3sa2_write(hw_config->io_base, OPL3SA2_DMA_CONFIG, 0x21);
741
        }
742
}
743
 
744
 
745
static void __init attach_opl3sa2_mixer(struct address_info *hw_config, int card)
746
{
747
        struct mixer_operations* mixer_operations;
748
        opl3sa2_state_t* devc = &opl3sa2_state[card];
749
 
750
        /* Install master mixer */
751
        if(devc->chipset == CHIPSET_OPL3SA3) {
752
                mixer_operations = &opl3sa3_mixer_operations;
753
        }
754
        else {
755
                mixer_operations = &opl3sa2_mixer_operations;
756
        }
757
 
758
        devc->cfg_port = hw_config->io_base;
759
        devc->mixer = sound_install_mixer(MIXER_DRIVER_VERSION,
760
                                          mixer_operations->name,
761
                                          mixer_operations,
762
                                          sizeof(struct mixer_operations),
763
                                          devc);
764
        if(devc->mixer < 0) {
765
                printk(KERN_ERR PFX "Could not install %s master mixer\n",
766
                         mixer_operations->name);
767
        }
768
        else {
769
                        opl3sa2_mixer_reset(devc);
770
        }
771
}
772
 
773
 
774
static void __init opl3sa2_clear_slots(struct address_info* hw_config)
775
{
776
        int i;
777
 
778
        for(i = 0; i < 6; i++) {
779
                hw_config->slots[i] = -1;
780
        }
781
}
782
 
783
 
784
static void __init opl3sa2_set_ymode(struct address_info* hw_config, int ymode)
785
{
786
        /*
787
         * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and
788
         * it's supported.
789
         *
790
         * 0: Desktop (aka normal)   5-12 cm speakers
791
         * 1: Notebook PC mode 1     3 cm speakers
792
         * 2: Notebook PC mode 2     1.5 cm speakers
793
         * 3: Hi-fi                  16-38 cm speakers
794
         */
795
        if(ymode >= 0 && ymode <= 3) {
796
                unsigned char sys_ctrl;
797
 
798
                opl3sa2_read(hw_config->io_base, OPL3SA2_SYS_CTRL, &sys_ctrl);
799
                sys_ctrl = (sys_ctrl & 0xcf) | ((ymode & 3) << 4);
800
                opl3sa2_write(hw_config->io_base, OPL3SA2_SYS_CTRL, sys_ctrl);
801
        }
802
        else {
803
                printk(KERN_ERR PFX "not setting ymode, it must be one of 0,1,2,3\n");
804
        }
805
}
806
 
807
 
808
static void __init opl3sa2_set_loopback(struct address_info* hw_config, int loopback)
809
{
810
        if(loopback >= 0 && loopback <= 1) {
811
                unsigned char misc;
812
 
813
                opl3sa2_read(hw_config->io_base, OPL3SA2_MISC, &misc);
814
                misc = (misc & 0xef) | ((loopback & 1) << 4);
815
                opl3sa2_write(hw_config->io_base, OPL3SA2_MISC, misc);
816
        }
817
        else {
818
                printk(KERN_ERR PFX "not setting loopback, it must be either 0 or 1\n");
819
        }
820
}
821
 
822
 
823
static void __exit unload_opl3sa2(struct address_info* hw_config, int card)
824
{
825
        /* Release control ports */
826
        release_region(hw_config->io_base, 2);
827
 
828
        /* Unload mixer */
829
        if(opl3sa2_state[card].mixer >= 0)
830
                sound_unload_mixerdev(opl3sa2_state[card].mixer);
831
}
832
 
833
 
834
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
835
 
836
struct isapnp_device_id isapnp_opl3sa2_list[] __initdata = {
837
        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
838
                ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021),
839
 
840
        {0}
841
};
842
 
843
MODULE_DEVICE_TABLE(isapnp, isapnp_opl3sa2_list);
844
 
845
static int __init opl3sa2_isapnp_probe(struct address_info* hw_cfg,
846
                                       struct address_info* mss_cfg,
847
                                       struct address_info* mpu_cfg,
848
                                       int card)
849
{
850
        static struct pci_dev* dev;
851
        int ret;
852
 
853
        /* Find and configure device */
854
        dev = isapnp_find_dev(NULL,
855
                              ISAPNP_VENDOR('Y','M','H'),
856
                              ISAPNP_FUNCTION(0x0021),
857
                              dev);
858
        if(dev == NULL) {
859
                return -ENODEV;
860
        }
861
 
862
        /*
863
         * If device is active, assume configured with /proc/isapnp
864
         * and use anyway. Any other way to check this?
865
         */
866
        ret = dev->prepare(dev);
867
        if(ret && ret != -EBUSY) {
868
                printk(KERN_ERR PFX "ISA PnP found device that could not be autoconfigured.\n");
869
                return -ENODEV;
870
        }
871
        if(ret == -EBUSY) {
872
                opl3sa2_state[card].activated = 1;
873
        }
874
        else {
875
                if(dev->activate(dev) < 0) {
876
                        printk(KERN_WARNING PFX "ISA PnP activate failed\n");
877
                        opl3sa2_state[card].activated = 0;
878
                        return -ENODEV;
879
                }
880
 
881
                printk(KERN_DEBUG
882
                       PFX "Activated ISA PnP card %d (active=%d)\n",
883
                       card, dev->active);
884
 
885
        }
886
 
887
        /* Our own config: */
888
        hw_cfg->io_base = dev->resource[4].start;
889
        hw_cfg->irq     = dev->irq_resource[0].start;
890
        hw_cfg->dma     = dev->dma_resource[0].start;
891
        hw_cfg->dma2    = dev->dma_resource[1].start;
892
 
893
        /* The MSS config: */
894
        mss_cfg->io_base      = dev->resource[1].start;
895
        mss_cfg->irq          = dev->irq_resource[0].start;
896
        mss_cfg->dma          = dev->dma_resource[0].start;
897
        mss_cfg->dma2         = dev->dma_resource[1].start;
898
        mss_cfg->card_subtype = 1; /* No IRQ or DMA setup */
899
 
900
        mpu_cfg->io_base       = dev->resource[3].start;
901
        mpu_cfg->irq           = dev->irq_resource[0].start;
902
        mpu_cfg->dma           = -1;
903
        mpu_cfg->dma2          = -1;
904
        mpu_cfg->always_detect = 1; /* It's there, so use shared IRQs */
905
 
906
        /* Call me paranoid: */
907
        opl3sa2_clear_slots(hw_cfg);
908
        opl3sa2_clear_slots(mss_cfg);
909
        opl3sa2_clear_slots(mpu_cfg);
910
 
911
        opl3sa2_state[card].pdev = dev;
912
 
913
        return 0;
914
}
915
#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
916
 
917
/* End of component functions */
918
 
919
#ifdef CONFIG_PM
920
/* Power Management support functions */
921
static int opl3sa2_suspend(struct pm_dev *pdev, unsigned char pm_mode)
922
{
923
        unsigned long flags;
924
        opl3sa2_state_t *p;
925
 
926
        if (!pdev)
927
                return -EINVAL;
928
 
929
        save_flags(flags);
930
        cli();
931
 
932
        p = (opl3sa2_state_t *) pdev->data;
933
 
934
        switch (pm_mode) {
935
        case 1:
936
                pm_mode = OPL3SA2_PM_MODE1;
937
                break;
938
        case 2:
939
                pm_mode = OPL3SA2_PM_MODE2;
940
                break;
941
        case 3:
942
                pm_mode = OPL3SA2_PM_MODE3;
943
                break;
944
        default:
945
                /* we don't know howto handle this... */
946
                restore_flags(flags);
947
                return -EBUSY;
948
        }
949
 
950
        p->in_suspend = 1;
951
        /* its supposed to automute before suspending, so we wont bother */
952
        opl3sa2_write(p->cfg_port, OPL3SA2_PM, pm_mode);
953
        /* wait a while for the clock oscillator to stabilise */
954
        mdelay(10);
955
 
956
        restore_flags(flags);
957
        return 0;
958
}
959
 
960
static int opl3sa2_resume(struct pm_dev *pdev)
961
{
962
        unsigned long flags;
963
        opl3sa2_state_t *p;
964
 
965
        if (!pdev)
966
                return -EINVAL;
967
 
968
        p = (opl3sa2_state_t *) pdev->data;
969
        save_flags(flags);
970
        cli();
971
 
972
        opl3sa2_write(p->cfg_port, OPL3SA2_PM, OPL3SA2_PM_MODE0);
973
        opl3sa2_mixer_restore(p);
974
        p->in_suspend = 0;
975
 
976
        restore_flags(flags);
977
        return 0;
978
}
979
 
980
static int opl3sa2_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
981
{
982
        unsigned char mode = (unsigned  long)data;
983
 
984
        switch (rqst) {
985
                case PM_SUSPEND:
986
                        return opl3sa2_suspend(pdev, mode);
987
 
988
                case PM_RESUME:
989
                        return opl3sa2_resume(pdev);
990
        }
991
        return 0;
992
}
993
#endif /* CONFIG_PM */
994
 
995
/*
996
 * Install OPL3-SA2 based card(s).
997
 *
998
 * Need to have ad1848 and mpu401 loaded ready.
999
 */
1000
static int __init init_opl3sa2(void)
1001
{
1002
        int card;
1003
        int max;
1004
 
1005
        /* Sanitize isapnp and multiple settings */
1006
        isapnp = isapnp != 0 ? 1 : 0;
1007
        multiple = multiple != 0 ? 1 : 0;
1008
 
1009
        max = (multiple && isapnp) ? OPL3SA2_CARDS_MAX : 1;
1010
        for(card = 0; card < max; card++, opl3sa2_cards_num++) {
1011
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
1012
                /*
1013
                 * Please remember that even with CONFIG_ISAPNP defined one
1014
                 * should still be able to disable PNP support for this
1015
                 * single driver!
1016
                 */
1017
                if(isapnp && opl3sa2_isapnp_probe(&opl3sa2_state[card].cfg,
1018
                                                  &opl3sa2_state[card].cfg_mss,
1019
                                                  &opl3sa2_state[card].cfg_mpu,
1020
                                                  card) < 0) {
1021
                        if(!opl3sa2_cards_num)
1022
                                printk(KERN_INFO PFX "No PnP cards found\n");
1023
                        if(io == -1)
1024
                                break;
1025
                        isapnp=0;
1026
                        printk(KERN_INFO PFX "Search for a card at 0x%d.\n", io);
1027
                        /* Fall through */
1028
                }
1029
#endif
1030
                /* If a user wants an I/O then assume they meant it */
1031
 
1032
                if(!isapnp) {
1033
                        if(io == -1 || irq == -1 || dma == -1 ||
1034
                           dma2 == -1 || mss_io == -1) {
1035
                                printk(KERN_ERR
1036
                                       PFX "io, mss_io, irq, dma, and dma2 must be set\n");
1037
                                return -EINVAL;
1038
                        }
1039
 
1040
                        /*
1041
                         * Our own config:
1042
                         * (NOTE: IRQ and DMA aren't used, so they're set to
1043
                         *  give pretty output from conf_printf. :)
1044
                         */
1045
                        opl3sa2_state[card].cfg.io_base = io;
1046
                        opl3sa2_state[card].cfg.irq     = irq;
1047
                        opl3sa2_state[card].cfg.dma     = dma;
1048
                        opl3sa2_state[card].cfg.dma2    = dma2;
1049
 
1050
                        /* The MSS config: */
1051
                        opl3sa2_state[card].cfg_mss.io_base      = mss_io;
1052
                        opl3sa2_state[card].cfg_mss.irq          = irq;
1053
                        opl3sa2_state[card].cfg_mss.dma          = dma;
1054
                        opl3sa2_state[card].cfg_mss.dma2         = dma2;
1055
                        opl3sa2_state[card].cfg_mss.card_subtype = 1; /* No IRQ or DMA setup */
1056
 
1057
                        opl3sa2_state[card].cfg_mpu.io_base       = mpu_io;
1058
                        opl3sa2_state[card].cfg_mpu.irq           = irq;
1059
                        opl3sa2_state[card].cfg_mpu.dma           = -1;
1060
                        opl3sa2_state[card].cfg_mpu.always_detect = 1; /* Use shared IRQs */
1061
 
1062
                        /* Call me paranoid: */
1063
                        opl3sa2_clear_slots(&opl3sa2_state[card].cfg);
1064
                        opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mss);
1065
                        opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mpu);
1066
                }
1067
 
1068
                if(probe_opl3sa2(&opl3sa2_state[card].cfg, card) ||
1069
                   !probe_opl3sa2_mss(&opl3sa2_state[card].cfg_mss)) {
1070
                        /*
1071
                         * If one or more cards are already registered, don't
1072
                         * return an error but print a warning.  Note, this
1073
                         * should never really happen unless the hardware or
1074
                         * ISA PnP screwed up.
1075
                         */
1076
                        if(opl3sa2_cards_num) {
1077
                                printk(KERN_WARNING
1078
                                       PFX "There was a problem probing one "
1079
                                       " of the ISA PNP cards, continuing\n");
1080
                                opl3sa2_cards_num--;
1081
                                continue;
1082
                        } else
1083
                                return -ENODEV;
1084
                }
1085
 
1086
                attach_opl3sa2(&opl3sa2_state[card].cfg, card);
1087
                conf_printf(opl3sa2_state[card].chipset_name, &opl3sa2_state[card].cfg);
1088
                attach_opl3sa2_mss(&opl3sa2_state[card].cfg_mss);
1089
                attach_opl3sa2_mixer(&opl3sa2_state[card].cfg, card);
1090
 
1091
                /* ewww =) */
1092
                opl3sa2_state[card].card = card;
1093
 
1094
#ifdef CONFIG_PM
1095
                /* register our power management capabilities */
1096
                opl3sa2_state[card].pmdev = pm_register(PM_ISA_DEV, card, opl3sa2_pm_callback);
1097
                if (opl3sa2_state[card].pmdev)
1098
                        opl3sa2_state[card].pmdev->data = &opl3sa2_state[card];
1099
#endif
1100
 
1101
                /*
1102
                 * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and
1103
                 * it's supported.
1104
                 */
1105
                if(ymode != -1) {
1106
                        if(opl3sa2_state[card].chipset == CHIPSET_OPL3SA2) {
1107
                                printk(KERN_ERR
1108
                                       PFX "ymode not supported on OPL3-SA2\n");
1109
                        }
1110
                        else {
1111
                                opl3sa2_set_ymode(&opl3sa2_state[card].cfg, ymode);
1112
                        }
1113
                }
1114
 
1115
 
1116
                /* Set A/D input to Mono loopback if asked to. */
1117
                if(loopback != -1) {
1118
                        opl3sa2_set_loopback(&opl3sa2_state[card].cfg, loopback);
1119
                }
1120
 
1121
                /* Attach MPU if we've been asked to do so */
1122
                if(opl3sa2_state[card].cfg_mpu.io_base != -1) {
1123
                        if(probe_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu)) {
1124
                                attach_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu);
1125
                        }
1126
                }
1127
        }
1128
 
1129
        if(isapnp) {
1130
                printk(KERN_NOTICE PFX "%d PnP card(s) found.\n", opl3sa2_cards_num);
1131
        }
1132
 
1133
        return 0;
1134
}
1135
 
1136
 
1137
/*
1138
 * Uninstall OPL3-SA2 based card(s).
1139
 */
1140
static void __exit cleanup_opl3sa2(void)
1141
{
1142
        int card;
1143
 
1144
        for(card = 0; card < opl3sa2_cards_num; card++) {
1145
#ifdef CONFIG_PM
1146
                if (opl3sa2_state[card].pmdev)
1147
                        pm_unregister(opl3sa2_state[card].pmdev);
1148
#endif
1149
                if(opl3sa2_state[card].cfg_mpu.slots[1] != -1) {
1150
                        unload_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu);
1151
                }
1152
                unload_opl3sa2_mss(&opl3sa2_state[card].cfg_mss);
1153
                unload_opl3sa2(&opl3sa2_state[card].cfg, card);
1154
 
1155
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
1156
                if(opl3sa2_state[card].activated && opl3sa2_state[card].pdev) {
1157
                        opl3sa2_state[card].pdev->deactivate(opl3sa2_state[card].pdev);
1158
 
1159
                        printk(KERN_DEBUG
1160
                               PFX "Deactivated ISA PnP card %d (active=%d)\n",
1161
                               card, opl3sa2_state[card].pdev->active);
1162
                }
1163
#endif
1164
        }
1165
}
1166
 
1167
module_init(init_opl3sa2);
1168
module_exit(cleanup_opl3sa2);
1169
 
1170
#ifndef MODULE
1171
static int __init setup_opl3sa2(char *str)
1172
{
1173
        /* io, irq, dma, dma2,... */
1174
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
1175
        int ints[11];
1176
#else
1177
        int ints[9];
1178
#endif
1179
        str = get_options(str, ARRAY_SIZE(ints), ints);
1180
 
1181
        io       = ints[1];
1182
        irq      = ints[2];
1183
        dma      = ints[3];
1184
        dma2     = ints[4];
1185
        mss_io   = ints[5];
1186
        mpu_io   = ints[6];
1187
        ymode    = ints[7];
1188
        loopback = ints[8];
1189
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
1190
        isapnp   = ints[9];
1191
        multiple = ints[10];
1192
#endif
1193
        return 1;
1194
}
1195
 
1196
__setup("opl3sa2=", setup_opl3sa2);
1197
#endif

powered by: WebSVN 2.1.0

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