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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * sound/sscape.c
3
 *
4
 * Low level driver for Ensoniq SoundScape
5
 *
6
 *
7
 * Copyright (C) by Hannu Savolainen 1993-1997
8
 *
9
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11
 * for more info.
12
 *
13
 *
14
 * Thomas Sailer        : ioctl code reworked (vmalloc/vfree removed)
15
 * Sergey Smitienko     : ensoniq p'n'p support
16
 * Christoph Hellwig    : adapted to module_init/module_exit
17
 * Bartlomiej Zolnierkiewicz : added __init to attach_sscape()
18
 * Chris Rankin         : Specify that this module owns the coprocessor
19
 * Arnaldo C. de Melo   : added missing restore_flags in sscape_pnp_upload_file
20
 */
21
 
22
#include <linux/init.h>
23
#include <linux/module.h>
24
 
25
#include "sound_config.h"
26
#include "sound_firmware.h"
27
 
28
#include <linux/types.h>
29
#include <linux/errno.h>
30
#include <linux/signal.h>
31
#include <linux/fcntl.h>
32
#include <linux/ctype.h>
33
#include <linux/stddef.h>
34
#include <linux/kmod.h>
35
#include <asm/dma.h>
36
#include <asm/io.h>
37
#include <asm/segment.h>
38
#include <linux/wait.h>
39
#include <linux/slab.h>
40
#include <linux/ioport.h>
41
#include <linux/delay.h>
42
#include <linux/proc_fs.h>
43
#include <linux/wrapper.h>
44
 
45
#include "coproc.h"
46
 
47
#include "ad1848.h"
48
#include "mpu401.h"
49
 
50
/*
51
 *    I/O ports
52
 */
53
#define MIDI_DATA       0
54
#define MIDI_CTRL       1
55
#define HOST_CTRL       2
56
#define TX_READY        0x02
57
#define RX_READY        0x01
58
#define HOST_DATA       3
59
#define ODIE_ADDR       4
60
#define ODIE_DATA       5
61
 
62
/*
63
 *    Indirect registers
64
 */
65
 
66
#define GA_INTSTAT_REG  0
67
#define GA_INTENA_REG   1
68
#define GA_DMAA_REG     2
69
#define GA_DMAB_REG     3
70
#define GA_INTCFG_REG   4
71
#define GA_DMACFG_REG   5
72
#define GA_CDCFG_REG    6
73
#define GA_SMCFGA_REG   7
74
#define GA_SMCFGB_REG   8
75
#define GA_HMCTL_REG    9
76
 
77
/*
78
 * DMA channel identifiers (A and B)
79
 */
80
 
81
#define SSCAPE_DMA_A    0
82
#define SSCAPE_DMA_B    1
83
 
84
#define PORT(name)      (devc->base+name)
85
 
86
/*
87
 * Host commands recognized by the OBP microcode
88
 */
89
 
90
#define CMD_GEN_HOST_ACK        0x80
91
#define CMD_GEN_MPU_ACK         0x81
92
#define CMD_GET_BOARD_TYPE      0x82
93
#define CMD_SET_CONTROL         0x88    /* Old firmware only */
94
#define CMD_GET_CONTROL         0x89    /* Old firmware only */
95
#define CTL_MASTER_VOL          0
96
#define CTL_MIC_MODE            2
97
#define CTL_SYNTH_VOL           4
98
#define CTL_WAVE_VOL            7
99
#define CMD_SET_EXTMIDI         0x8a
100
#define CMD_GET_EXTMIDI         0x8b
101
#define CMD_SET_MT32            0x8c
102
#define CMD_GET_MT32            0x8d
103
 
104
#define CMD_ACK                 0x80
105
 
106
#define IC_ODIE                 1
107
#define IC_OPUS                 2
108
 
109
typedef struct sscape_info
110
{
111
        int     base, irq, dma;
112
 
113
        int     codec, codec_irq;       /* required to setup pnp cards*/
114
        int     codec_type;
115
        int     ic_type;
116
        char*   raw_buf;
117
        unsigned long   raw_buf_phys;
118
        int     buffsize;               /* -------------------------- */
119
 
120
        int     ok;     /* Properly detected */
121
        int     failed;
122
        int     dma_allocated;
123
        int     codec_audiodev;
124
        int     opened;
125
        int     *osp;
126
        int     my_audiodev;
127
} sscape_info;
128
 
129
static struct sscape_info adev_info = {
130
 
131
};
132
 
133
static struct sscape_info *devc = &adev_info;
134
static int sscape_mididev = -1;
135
 
136
/* Some older cards have assigned interrupt bits differently than new ones */
137
static char valid_interrupts_old[] = {
138
        9, 7, 5, 15
139
};
140
 
141
static char valid_interrupts_new[] = {
142
        9, 5, 7, 10
143
};
144
 
145
static char *valid_interrupts = valid_interrupts_new;
146
 
147
/*
148
 *      See the bottom of the driver. This can be set by spea =0/1.
149
 */
150
 
151
#ifdef REVEAL_SPEA
152
static char old_hardware = 1;
153
#else
154
static char old_hardware = 0;
155
#endif
156
 
157
static void sleep(unsigned howlong)
158
{
159
        current->state = TASK_INTERRUPTIBLE;
160
        schedule_timeout(howlong);
161
}
162
 
163
static unsigned char sscape_read(struct sscape_info *devc, int reg)
164
{
165
        unsigned long flags;
166
        unsigned char val;
167
 
168
        save_flags(flags);
169
        cli();
170
        outb(reg, PORT(ODIE_ADDR));
171
        val = inb(PORT(ODIE_DATA));
172
        restore_flags(flags);
173
        return val;
174
}
175
 
176
static void sscape_write(struct sscape_info *devc, int reg, int data)
177
{
178
        unsigned long flags;
179
 
180
        save_flags(flags);
181
        cli();
182
        outb(reg, PORT(ODIE_ADDR));
183
        outb(data, PORT(ODIE_DATA));
184
        restore_flags(flags);
185
}
186
 
187
static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
188
{
189
        unsigned char res;
190
        unsigned long flags;
191
 
192
        save_flags(flags);
193
        cli();
194
        outb( reg, devc -> codec);
195
        res = inb (devc -> codec + 1);
196
        restore_flags(flags);
197
        return res;
198
 
199
}
200
 
201
static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigned char data)
202
{
203
        unsigned long flags;
204
 
205
        save_flags(flags);
206
        cli();
207
        outb( reg, devc -> codec);
208
        outb( data, devc -> codec + 1);
209
        restore_flags(flags);
210
}
211
 
212
static void host_open(struct sscape_info *devc)
213
{
214
        outb((0x00), PORT(HOST_CTRL));  /* Put the board to the host mode */
215
}
216
 
217
static void host_close(struct sscape_info *devc)
218
{
219
        outb((0x03), PORT(HOST_CTRL));  /* Put the board to the MIDI mode */
220
}
221
 
222
static int host_write(struct sscape_info *devc, unsigned char *data, int count)
223
{
224
        unsigned long flags;
225
        int i, timeout_val;
226
 
227
        save_flags(flags);
228
        cli();
229
 
230
        /*
231
         * Send the command and data bytes
232
         */
233
 
234
        for (i = 0; i < count; i++)
235
        {
236
                for (timeout_val = 10000; timeout_val > 0; timeout_val--)
237
                        if (inb(PORT(HOST_CTRL)) & TX_READY)
238
                                break;
239
 
240
                if (timeout_val <= 0)
241
                {
242
                            restore_flags(flags);
243
                            return 0;
244
                }
245
                outb(data[i], PORT(HOST_DATA));
246
        }
247
        restore_flags(flags);
248
        return 1;
249
}
250
 
251
static int host_read(struct sscape_info *devc)
252
{
253
        unsigned long flags;
254
        int timeout_val;
255
        unsigned char data;
256
 
257
        save_flags(flags);
258
        cli();
259
 
260
        /*
261
         * Read a byte
262
         */
263
 
264
        for (timeout_val = 10000; timeout_val > 0; timeout_val--)
265
                if (inb(PORT(HOST_CTRL)) & RX_READY)
266
                        break;
267
 
268
        if (timeout_val <= 0)
269
        {
270
                restore_flags(flags);
271
                return -1;
272
        }
273
        data = inb(PORT(HOST_DATA));
274
        restore_flags(flags);
275
        return data;
276
}
277
 
278
#if 0 /* unused */
279
static int host_command1(struct sscape_info *devc, int cmd)
280
{
281
        unsigned char buf[10];
282
        buf[0] = (unsigned char) (cmd & 0xff);
283
        return host_write(devc, buf, 1);
284
}
285
#endif /* unused */
286
 
287
 
288
static int host_command2(struct sscape_info *devc, int cmd, int parm1)
289
{
290
        unsigned char buf[10];
291
 
292
        buf[0] = (unsigned char) (cmd & 0xff);
293
        buf[1] = (unsigned char) (parm1 & 0xff);
294
 
295
        return host_write(devc, buf, 2);
296
}
297
 
298
static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
299
{
300
        unsigned char buf[10];
301
 
302
        buf[0] = (unsigned char) (cmd & 0xff);
303
        buf[1] = (unsigned char) (parm1 & 0xff);
304
        buf[2] = (unsigned char) (parm2 & 0xff);
305
        return host_write(devc, buf, 3);
306
}
307
 
308
static void set_mt32(struct sscape_info *devc, int value)
309
{
310
        host_open(devc);
311
        host_command2(devc, CMD_SET_MT32, value ? 1 : 0);
312
        if (host_read(devc) != CMD_ACK)
313
        {
314
                /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
315
        }
316
        host_close(devc);
317
}
318
 
319
static void set_control(struct sscape_info *devc, int ctrl, int value)
320
{
321
        host_open(devc);
322
        host_command3(devc, CMD_SET_CONTROL, ctrl, value);
323
        if (host_read(devc) != CMD_ACK)
324
        {
325
                /* printk( "SNDSCAPE: Setting control (%d) failed\n",  ctrl); */
326
        }
327
        host_close(devc);
328
}
329
 
330
static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
331
{
332
        unsigned char temp;
333
 
334
        if (dma_chan != SSCAPE_DMA_A)
335
        {
336
                printk(KERN_WARNING "soundscape: Tried to use DMA channel  != A. Why?\n");
337
                return;
338
        }
339
        audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
340
        DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
341
        audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;
342
 
343
        temp = devc->dma << 4;  /* Setup DMA channel select bits */
344
        if (devc->dma <= 3)
345
                temp |= 0x80;   /* 8 bit DMA channel */
346
 
347
        temp |= 1;              /* Trigger DMA */
348
        sscape_write(devc, GA_DMAA_REG, temp);
349
        temp &= 0xfe;           /* Clear DMA trigger */
350
        sscape_write(devc, GA_DMAA_REG, temp);
351
}
352
 
353
static int verify_mpu(struct sscape_info *devc)
354
{
355
        /*
356
         * The SoundScape board could be in three modes (MPU, 8250 and host).
357
         * If the card is not in the MPU mode, enabling the MPU driver will
358
         * cause infinite loop (the driver believes that there is always some
359
         * received data in the buffer.
360
         *
361
         * Detect this by looking if there are more than 10 received MIDI bytes
362
         * (0x00) in the buffer.
363
         */
364
 
365
        int i;
366
 
367
        for (i = 0; i < 10; i++)
368
        {
369
                if (inb(devc->base + HOST_CTRL) & 0x80)
370
                        return 1;
371
 
372
                if (inb(devc->base) != 0x00)
373
                        return 1;
374
        }
375
        printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
376
        return 0;
377
}
378
 
379
static int sscape_coproc_open(void *dev_info, int sub_device)
380
{
381
        if (sub_device == COPR_MIDI)
382
        {
383
                set_mt32(devc, 0);
384
                if (!verify_mpu(devc))
385
                        return -EIO;
386
        }
387
        return 0;
388
}
389
 
390
static void sscape_coproc_close(void *dev_info, int sub_device)
391
{
392
        struct sscape_info *devc = dev_info;
393
        unsigned long   flags;
394
 
395
        save_flags(flags);
396
        cli();
397
        if (devc->dma_allocated)
398
        {
399
                sscape_write(devc, GA_DMAA_REG, 0x20);  /* DMA channel disabled */
400
                devc->dma_allocated = 0;
401
        }
402
        restore_flags(flags);
403
        return;
404
}
405
 
406
static void sscape_coproc_reset(void *dev_info)
407
{
408
}
409
 
410
static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
411
{
412
        unsigned long flags;
413
        unsigned char temp;
414
        volatile int done, timeout_val;
415
        static unsigned char codec_dma_bits = 0;
416
 
417
        if (flag & CPF_FIRST)
418
        {
419
                /*
420
                 * First block. Have to allocate DMA and to reset the board
421
                 * before continuing.
422
                 */
423
 
424
                save_flags(flags);
425
                cli();
426
                codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
427
 
428
                if (devc->dma_allocated == 0)
429
                        devc->dma_allocated = 1;
430
 
431
                restore_flags(flags);
432
 
433
                sscape_write(devc, GA_HMCTL_REG,
434
                        (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f);       /*Reset */
435
 
436
                for (timeout_val = 10000; timeout_val > 0; timeout_val--)
437
                        sscape_read(devc, GA_HMCTL_REG);        /* Delay */
438
 
439
                /* Take board out of reset */
440
                sscape_write(devc, GA_HMCTL_REG,
441
                        (temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
442
        }
443
        /*
444
         * Transfer one code block using DMA
445
         */
446
        if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
447
        {
448
                printk(KERN_WARNING "soundscape: DMA buffer not available\n");
449
                return 0;
450
        }
451
        memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
452
 
453
        save_flags(flags);
454
        cli();
455
 
456
        /******** INTERRUPTS DISABLED NOW ********/
457
 
458
        do_dma(devc, SSCAPE_DMA_A,
459
               audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
460
               size, DMA_MODE_WRITE);
461
 
462
        /*
463
         * Wait until transfer completes.
464
         */
465
 
466
        done = 0;
467
        timeout_val = 30;
468
        while (!done && timeout_val-- > 0)
469
        {
470
                int resid;
471
 
472
                if (HZ / 50)
473
                        sleep(HZ / 50);
474
                clear_dma_ff(devc->dma);
475
                if ((resid = get_dma_residue(devc->dma)) == 0)
476
                        done = 1;
477
        }
478
 
479
        restore_flags(flags);
480
        if (!done)
481
                return 0;
482
 
483
        if (flag & CPF_LAST)
484
        {
485
                /*
486
                 * Take the board out of reset
487
                 */
488
                outb((0x00), PORT(HOST_CTRL));
489
                outb((0x00), PORT(MIDI_CTRL));
490
 
491
                temp = sscape_read(devc, GA_HMCTL_REG);
492
                temp |= 0x40;
493
                sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */
494
 
495
                /*
496
                 * Wait until the ODB wakes up
497
                 */
498
 
499
                save_flags(flags);
500
                cli();
501
                done = 0;
502
                timeout_val = 5 * HZ;
503
                while (!done && timeout_val-- > 0)
504
                {
505
                        unsigned char x;
506
 
507
                        sleep(1);
508
                        x = inb(PORT(HOST_DATA));
509
                        if (x == 0xff || x == 0xfe)             /* OBP startup acknowledge */
510
                        {
511
                                DDB(printk("Soundscape: Acknowledge = %x\n", x));
512
                                done = 1;
513
                        }
514
                }
515
                sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
516
 
517
                restore_flags(flags);
518
                if (!done)
519
                {
520
                        printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
521
                        return 0;
522
                }
523
                save_flags(flags);
524
                cli();
525
                done = 0;
526
                timeout_val = 5 * HZ;
527
                while (!done && timeout_val-- > 0)
528
                {
529
                        sleep(1);
530
                        if (inb(PORT(HOST_DATA)) == 0xfe)       /* Host startup acknowledge */
531
                                done = 1;
532
                }
533
                restore_flags(flags);
534
                if (!done)
535
                {
536
                        printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
537
                        return 0;
538
                }
539
                printk(KERN_INFO "SoundScape board initialized OK\n");
540
                set_control(devc, CTL_MASTER_VOL, 100);
541
                set_control(devc, CTL_SYNTH_VOL, 100);
542
 
543
#ifdef SSCAPE_DEBUG3
544
                /*
545
                 * Temporary debugging aid. Print contents of the registers after
546
                 * downloading the code.
547
                 */
548
                {
549
                        int i;
550
 
551
                        for (i = 0; i < 13; i++)
552
                                printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
553
                }
554
#endif
555
 
556
        }
557
        return 1;
558
}
559
 
560
static int download_boot_block(void *dev_info, copr_buffer * buf)
561
{
562
        if (buf->len <= 0 || buf->len > sizeof(buf->data))
563
                return -EINVAL;
564
 
565
        if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
566
        {
567
                printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
568
                return -EIO;
569
        }
570
        return 0;
571
}
572
 
573
static int sscape_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
574
{
575
        copr_buffer *buf;
576
        int err;
577
 
578
        switch (cmd)
579
        {
580
                case SNDCTL_COPR_RESET:
581
                        sscape_coproc_reset(dev_info);
582
                        return 0;
583
 
584
                case SNDCTL_COPR_LOAD:
585
                        buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
586
                        if (buf == NULL)
587
                                return -ENOSPC;
588
                        if (copy_from_user(buf, arg, sizeof(copr_buffer)))
589
                        {
590
                                vfree(buf);
591
                                return -EFAULT;
592
                        }
593
                        err = download_boot_block(dev_info, buf);
594
                        vfree(buf);
595
                        return err;
596
 
597
                default:
598
                        return -EINVAL;
599
        }
600
}
601
 
602
static coproc_operations sscape_coproc_operations =
603
{
604
        "SoundScape M68K",
605
        THIS_MODULE,
606
        sscape_coproc_open,
607
        sscape_coproc_close,
608
        sscape_coproc_ioctl,
609
        sscape_coproc_reset,
610
        &adev_info
611
};
612
 
613
static int sscape_detected = 0;
614
static int sscape_is_pnp   = 0;
615
 
616
void __init attach_sscape(struct address_info *hw_config)
617
{
618
#ifndef SSCAPE_REGS
619
        /*
620
         * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
621
         * These values are card
622
         * dependent. If you have another SoundScape based card, you have to
623
         * find the correct values. Do the following:
624
         *  - Compile this driver with SSCAPE_DEBUG1 defined.
625
         *  - Shut down and power off your machine.
626
         *  - Boot with DOS so that the SSINIT.EXE program is run.
627
         *  - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
628
         *    when detecting the SoundScape.
629
         *  - Modify the following list to use the values printed during boot.
630
         *    Undefine the SSCAPE_DEBUG1
631
         */
632
#define SSCAPE_REGS { \
633
/* I0 */        0x00, \
634
/* I1 */        0xf0, /* Note! Ignored. Set always to 0xf0 */ \
635
/* I2 */        0x20, /* Note! Ignored. Set always to 0x20 */ \
636
/* I3 */        0x20, /* Note! Ignored. Set always to 0x20 */ \
637
/* I4 */        0xf5, /* Ignored */ \
638
/* I5 */        0x10, \
639
/* I6 */        0x00, \
640
/* I7 */        0x2e, /* I7 MEM config A. Likely to vary between models */ \
641
/* I8 */        0x00, /* I8 MEM config B. Likely to vary between models */ \
642
/* I9 */        0x40 /* Ignored */ \
643
        }
644
#endif
645
 
646
        unsigned long   flags;
647
        static unsigned char regs[10] = SSCAPE_REGS;
648
 
649
        int i, irq_bits = 0xff;
650
 
651
        if (sscape_detected != hw_config->io_base)
652
                return;
653
 
654
        request_region(devc->base + 2, 6, "SoundScape");
655
        if (old_hardware)
656
        {
657
                valid_interrupts = valid_interrupts_old;
658
                conf_printf("Ensoniq SoundScape (old)", hw_config);
659
        }
660
        else
661
                conf_printf("Ensoniq SoundScape", hw_config);
662
 
663
        for (i = 0; i < sizeof(valid_interrupts); i++)
664
        {
665
                if (hw_config->irq == valid_interrupts[i])
666
                {
667
                        irq_bits = i;
668
                        break;
669
                }
670
        }
671
        if (hw_config->irq > 15 || ((regs[4] = irq_bits) == 0xff))
672
        {
673
                printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
674
                return;
675
        }
676
 
677
        if (!sscape_is_pnp) {
678
 
679
            save_flags(flags);
680
            cli();
681
            for (i = 1; i < 10; i++)
682
            {
683
                switch (i)
684
                {
685
                        case 1: /* Host interrupt enable */
686
                                sscape_write(devc, i, 0xf0);    /* All interrupts enabled */
687
                                break;
688
 
689
                        case 2: /* DMA A status/trigger register */
690
                        case 3: /* DMA B status/trigger register */
691
                                sscape_write(devc, i, 0x20);    /* DMA channel disabled */
692
                                break;
693
 
694
                        case 4: /* Host interrupt config reg */
695
                                sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
696
                                break;
697
 
698
                        case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */
699
                                sscape_write(devc, i, (regs[i] & 0x3f) | (sscape_read(devc, i) & 0xc0));
700
                                break;
701
 
702
                        case 6: /* CD-ROM config (WSS codec actually) */
703
                                sscape_write(devc, i, regs[i]);
704
                                break;
705
 
706
                        case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
707
                                sscape_write(devc, i, (sscape_read(devc, i) & 0xf0) | 0x08);
708
                                break;
709
 
710
                        default:
711
                                sscape_write(devc, i, regs[i]);
712
                }
713
            }
714
            restore_flags(flags);
715
        }
716
#ifdef SSCAPE_DEBUG2
717
        /*
718
         * Temporary debugging aid. Print contents of the registers after
719
         * changing them.
720
         */
721
        {
722
                int i;
723
 
724
                for (i = 0; i < 13; i++)
725
                        printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
726
        }
727
#endif
728
 
729
        if (probe_mpu401(hw_config))
730
                hw_config->always_detect = 1;
731
        hw_config->name = "SoundScape";
732
 
733
        hw_config->irq *= -1;   /* Negative value signals IRQ sharing */
734
        attach_mpu401(hw_config, THIS_MODULE);
735
        hw_config->irq *= -1;   /* Restore it */
736
 
737
        if (hw_config->slots[1] != -1)  /* The MPU driver installed itself */
738
        {
739
                sscape_mididev = hw_config->slots[1];
740
                midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
741
        }
742
        sscape_write(devc, GA_INTENA_REG, 0x80);        /* Master IRQ enable */
743
        devc->ok = 1;
744
        devc->failed = 0;
745
}
746
 
747
static int detect_ga(sscape_info * devc)
748
{
749
        unsigned char save;
750
 
751
        DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
752
 
753
        if (check_region(devc->base, 8))
754
                return 0;
755
 
756
        /*
757
         * First check that the address register of "ODIE" is
758
         * there and that it has exactly 4 writable bits.
759
         * First 4 bits
760
         */
761
 
762
        if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
763
        {
764
                DDB(printk("soundscape: Detect error A\n"));
765
                return 0;
766
        }
767
        outb((0x00), PORT(ODIE_ADDR));
768
        if (inb(PORT(ODIE_ADDR)) != 0x00)
769
        {
770
                DDB(printk("soundscape: Detect error B\n"));
771
                return 0;
772
        }
773
        outb((0xff), PORT(ODIE_ADDR));
774
        if (inb(PORT(ODIE_ADDR)) != 0x0f)
775
        {
776
                DDB(printk("soundscape: Detect error C\n"));
777
                return 0;
778
        }
779
        outb((save), PORT(ODIE_ADDR));
780
 
781
        /*
782
         * Now verify that some indirect registers return zero on some bits.
783
         * This may break the driver with some future revisions of "ODIE" but...
784
         */
785
 
786
        if (sscape_read(devc, 0) & 0x0c)
787
        {
788
                DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
789
                return 0;
790
        }
791
        if (sscape_read(devc, 1) & 0x0f)
792
        {
793
                DDB(printk("soundscape: Detect error E\n"));
794
                return 0;
795
        }
796
        if (sscape_read(devc, 5) & 0x0f)
797
        {
798
                DDB(printk("soundscape: Detect error F\n"));
799
                return 0;
800
        }
801
        return 1;
802
}
803
 
804
static  int sscape_read_host_ctrl(sscape_info* devc)
805
{
806
        return host_read(devc);
807
}
808
 
809
static  void sscape_write_host_ctrl2(sscape_info *devc, int a, int b)
810
{
811
        host_command2(devc, a, b);
812
}
813
 
814
static int sscape_alloc_dma(sscape_info *devc)
815
{
816
        char *start_addr, *end_addr;
817
        int dma_pagesize;
818
        int sz, size;
819
        struct page *page;
820
 
821
        if (devc->raw_buf != NULL) return 0;     /* Already done */
822
        dma_pagesize = (devc->dma < 4) ? (64 * 1024) : (128 * 1024);
823
        devc->raw_buf = NULL;
824
        devc->buffsize = 8192*4;
825
        if (devc->buffsize > dma_pagesize) devc->buffsize = dma_pagesize;
826
        start_addr = NULL;
827
        /*
828
         * Now loop until we get a free buffer. Try to get smaller buffer if
829
         * it fails. Don't accept smaller than 8k buffer for performance
830
         * reasons.
831
         */
832
        while (start_addr == NULL && devc->buffsize > PAGE_SIZE) {
833
                for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
834
                devc->buffsize = PAGE_SIZE * (1 << sz);
835
                start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz);
836
                if (start_addr == NULL) devc->buffsize /= 2;
837
        }
838
 
839
        if (start_addr == NULL) {
840
                printk(KERN_ERR "sscape pnp init error: Couldn't allocate DMA buffer\n");
841
                return 0;
842
        } else {
843
                /* make some checks */
844
                end_addr = start_addr + devc->buffsize - 1;
845
                /* now check if it fits into the same dma-pagesize */
846
 
847
                if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
848
                    || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
849
                        printk(KERN_ERR "sscape pnp: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, devc->buffsize);
850
                        return 0;
851
                }
852
        }
853
        devc->raw_buf = start_addr;
854
        devc->raw_buf_phys = virt_to_bus(start_addr);
855
 
856
        for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
857
                mem_map_reserve(page);
858
        return 1;
859
}
860
 
861
static void sscape_free_dma(sscape_info *devc)
862
{
863
        int sz, size;
864
        unsigned long start_addr, end_addr;
865
        struct page *page;
866
 
867
        if (devc->raw_buf == NULL) return;
868
        for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
869
        start_addr = (unsigned long) devc->raw_buf;
870
        end_addr = start_addr + devc->buffsize;
871
 
872
        for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
873
                mem_map_unreserve(page);
874
 
875
        free_pages((unsigned long) devc->raw_buf, sz);
876
        devc->raw_buf = NULL;
877
}
878
 
879
/* Intel version !!!!!!!!! */
880
 
881
static int sscape_start_dma(int chan, unsigned long physaddr, int count, int dma_mode)
882
{
883
        unsigned long flags;
884
 
885
        flags = claim_dma_lock();
886
        disable_dma(chan);
887
        clear_dma_ff(chan);
888
        set_dma_mode(chan, dma_mode);
889
        set_dma_addr(chan, physaddr);
890
        set_dma_count(chan, count);
891
        enable_dma(chan);
892
        release_dma_lock(flags);
893
        return 0;
894
}
895
 
896
static void sscape_pnp_start_dma(sscape_info* devc, int arg )
897
{
898
        int reg;
899
        if (arg == 0) reg = 2;
900
        else reg = 3;
901
 
902
        sscape_write(devc, reg, sscape_read( devc, reg) | 0x01);
903
        sscape_write(devc, reg, sscape_read( devc, reg) & 0xFE);
904
}
905
 
906
static int sscape_pnp_wait_dma (sscape_info* devc, int arg )
907
{
908
        int             reg;
909
        unsigned long   i;
910
        unsigned char   d;
911
 
912
        if (arg == 0) reg = 2;
913
        else reg = 3;
914
 
915
        sleep ( 1 );
916
        i = 0;
917
        do {
918
                d = sscape_read(devc, reg) & 1;
919
                if ( d == 1)  break;
920
                i++;
921
        } while (i < 500000);
922
        d = sscape_read(devc, reg) & 1;
923
        return d;
924
}
925
 
926
static  int     sscape_pnp_alloc_dma(sscape_info* devc)
927
{
928
        /* printk(KERN_INFO "sscape: requesting dma\n"); */
929
        if (request_dma(devc -> dma, "sscape")) return 0;
930
        /* printk(KERN_INFO "sscape: dma channel allocated\n"); */
931
        if (!sscape_alloc_dma(devc)) {
932
                free_dma(devc -> dma);
933
                return 0;
934
        };
935
        return 1;
936
}
937
 
938
static  void    sscape_pnp_free_dma(sscape_info* devc)
939
{
940
        sscape_free_dma( devc);
941
        free_dma(devc -> dma );
942
        /* printk(KERN_INFO "sscape: dma released\n"); */
943
}
944
 
945
static  int     sscape_pnp_upload_file(sscape_info* devc, char* fn)
946
{
947
        int             done = 0;
948
        int             timeout_val;
949
        char*           data,*dt;
950
        int             len,l;
951
        unsigned long   flags;
952
 
953
        sscape_write( devc, 9, sscape_read(devc, 9 )  & 0x3F );
954
        sscape_write( devc, 2, (devc -> dma << 4) | 0x80 );
955
        sscape_write( devc, 3, 0x20 );
956
        sscape_write( devc, 9, sscape_read( devc, 9 )  | 0x80 );
957
 
958
        len = mod_firmware_load(fn, &data);
959
        if (len == 0) {
960
                    printk(KERN_ERR "sscape: file not found: %s\n", fn);
961
                    return 0;
962
        }
963
        dt = data;
964
        save_flags(flags);
965
        cli();
966
        while ( len > 0 ) {
967
                if (len > devc -> buffsize) l = devc->buffsize;
968
                else l = len;
969
                len -= l;
970
                memcpy(devc->raw_buf, dt, l); dt += l;
971
                sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48);
972
                sscape_pnp_start_dma ( devc, 0 );
973
                if (sscape_pnp_wait_dma ( devc, 0 ) == 0) {
974
                        restore_flags(flags);
975
                        return 0;
976
                }
977
        }
978
 
979
        restore_flags(flags);
980
        vfree(data);
981
 
982
        outb(0, devc -> base + 2);
983
        outb(0, devc -> base);
984
 
985
        sscape_write ( devc, 9, sscape_read( devc, 9 ) | 0x40);
986
 
987
        timeout_val = 5 * HZ;
988
        while (!done && timeout_val-- > 0)
989
        {
990
                unsigned char x;
991
                sleep(1);
992
                x = inb( devc -> base + 3);
993
                if (x == 0xff || x == 0xfe)             /* OBP startup acknowledge */
994
                {
995
                        //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
996
                        done = 1;
997
                }
998
        }
999
        timeout_val = 5 * HZ;
1000
        done = 0;
1001
        while (!done && timeout_val-- > 0)
1002
        {
1003
                unsigned char x;
1004
                sleep(1);
1005
                x = inb( devc -> base + 3);
1006
                if (x == 0xfe)          /* OBP startup acknowledge */
1007
                {
1008
                        //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
1009
                        done = 1;
1010
                }
1011
        }
1012
 
1013
        if ( !done ) printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
1014
 
1015
        sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
1016
        sscape_write( devc, 3, (devc -> dma << 4) + 0x80);
1017
        return 1;
1018
}
1019
 
1020
static void __init sscape_pnp_init_hw(sscape_info* devc)
1021
{
1022
        unsigned char midi_irq = 0, sb_irq = 0;
1023
        unsigned i;
1024
        static  char code_file_name[23] = "/sndscape/sndscape.cox";
1025
 
1026
        int sscape_sb_enable            = 0;
1027
        int sscape_joystic_enable       = 0x7f;
1028
        int sscape_mic_enable           = 0;
1029
        int sscape_ext_midi             = 0;
1030
 
1031
        if ( !sscape_pnp_alloc_dma(devc) ) {
1032
                printk(KERN_ERR "sscape: faild to allocate dma\n");
1033
                return;
1034
        }
1035
 
1036
        for (i = 0; i < 4; i++) {
1037
                if ( devc -> irq   == valid_interrupts[i] )
1038
                        midi_irq = i;
1039
                if ( devc -> codec_irq == valid_interrupts[i] )
1040
                        sb_irq = i;
1041
        }
1042
 
1043
        sscape_write( devc, 5, 0x50);
1044
        sscape_write( devc, 7, 0x2e);
1045
        sscape_write( devc, 8, 0x00);
1046
 
1047
        sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
1048
        sscape_write( devc, 3, ( devc -> dma << 4) | 0x80);
1049
 
1050
        if ( sscape_sb_enable )
1051
                sscape_write (devc, 4, 0xF0 | (sb_irq << 2) | midi_irq);
1052
        else
1053
                sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
1054
 
1055
        i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
1056
        if ( sscape_sb_enable )
1057
                i |= devc->ic_type == IC_ODIE ? 0x05 : 0x07;
1058
        if (sscape_joystic_enable) i |= 8;
1059
 
1060
        sscape_write (devc, 9, i);
1061
        sscape_write (devc, 6, 0x80);
1062
        sscape_write (devc, 1, 0x80);
1063
 
1064
        if (devc -> codec_type == 2) {
1065
                sscape_pnp_write_codec( devc, 0x0C, 0x50);
1066
                sscape_pnp_write_codec( devc, 0x10, sscape_pnp_read_codec( devc, 0x10) & 0x3F);
1067
                sscape_pnp_write_codec( devc, 0x11, sscape_pnp_read_codec( devc, 0x11) | 0xC0);
1068
                sscape_pnp_write_codec( devc, 29, 0x20);
1069
        }
1070
 
1071
        if (sscape_pnp_upload_file(devc, "/sndscape/scope.cod") == 0 ) {
1072
                printk(KERN_ERR "sscape: faild to upload file /sndscape/scope.cod\n");
1073
                sscape_pnp_free_dma(devc);
1074
                return;
1075
        }
1076
 
1077
        i = sscape_read_host_ctrl( devc );
1078
 
1079
        if ( (i & 0x0F) >  7 ) {
1080
                printk(KERN_ERR "sscape: scope.cod faild\n");
1081
                sscape_pnp_free_dma(devc);
1082
                return;
1083
        }
1084
        if ( i & 0x10 ) sscape_write( devc, 7, 0x2F);
1085
        code_file_name[21] = (char) ( i & 0x0F) + 0x30;
1086
        if (sscape_pnp_upload_file( devc, code_file_name) == 0) {
1087
                printk(KERN_ERR "sscape: faild to upload file %s\n", code_file_name);
1088
                sscape_pnp_free_dma(devc);
1089
                return;
1090
        }
1091
 
1092
        if (devc->ic_type != IC_ODIE) {
1093
                sscape_pnp_write_codec( devc, 10, (sscape_pnp_read_codec(devc, 10) & 0x7f) |
1094
                 ( sscape_mic_enable == 0 ? 0x00 : 0x80) );
1095
        }
1096
        sscape_write_host_ctrl2( devc, 0x84, 0x64 );  /* MIDI volume */
1097
        sscape_write_host_ctrl2( devc, 0x86, 0x64 );  /* MIDI volume?? */
1098
        sscape_write_host_ctrl2( devc, 0x8A, sscape_ext_midi);
1099
 
1100
        sscape_pnp_write_codec ( devc, 6, 0x3f ); //WAV_VOL
1101
        sscape_pnp_write_codec ( devc, 7, 0x3f ); //WAV_VOL
1102
        sscape_pnp_write_codec ( devc, 2, 0x1F ); //WD_CDXVOLL
1103
        sscape_pnp_write_codec ( devc, 3, 0x1F ); //WD_CDXVOLR
1104
 
1105
        if (devc -> codec_type == 1) {
1106
                sscape_pnp_write_codec ( devc, 4, 0x1F );
1107
                sscape_pnp_write_codec ( devc, 5, 0x1F );
1108
                sscape_write_host_ctrl2( devc, 0x88, sscape_mic_enable);
1109
        } else {
1110
                int t;
1111
                sscape_pnp_write_codec ( devc, 0x10, 0x1F << 1);
1112
                sscape_pnp_write_codec ( devc, 0x11, 0xC0 | (0x1F << 1));
1113
 
1114
                t = sscape_pnp_read_codec( devc, 0x00) & 0xDF;
1115
                if ( (sscape_mic_enable == 0)) t |= 0;
1116
                else t |= 0x20;
1117
                sscape_pnp_write_codec ( devc, 0x00, t);
1118
                t = sscape_pnp_read_codec( devc, 0x01) & 0xDF;
1119
                if ( (sscape_mic_enable == 0) ) t |= 0;
1120
                else t |= 0x20;
1121
                sscape_pnp_write_codec ( devc, 0x01, t);
1122
                sscape_pnp_write_codec ( devc, 0x40 | 29 , 0x20);
1123
                outb(0, devc -> codec);
1124
        }
1125
        if (devc -> ic_type == IC_OPUS ) {
1126
                int i = sscape_read( devc, 9 );
1127
                sscape_write( devc, 9, i | 3 );
1128
                sscape_write( devc, 3, 0x40);
1129
 
1130
                if (check_region(0x228, 1)) {
1131
                            outb(0, 0x228);
1132
                            release_region(0x228,1);
1133
                }
1134
                sscape_write( devc, 3, (devc -> dma << 4) | 0x80);
1135
                sscape_write( devc, 9, i );
1136
        }
1137
 
1138
        host_close ( devc );
1139
        sscape_pnp_free_dma(devc);
1140
}
1141
 
1142
static int __init detect_sscape_pnp(sscape_info* devc)
1143
{
1144
        long     i, irq_bits = 0xff;
1145
        unsigned int d;
1146
 
1147
        DDB(printk("Entered detect_sscape_pnp(%x)\n", devc->base));
1148
 
1149
        if (check_region(devc->base, 8)) {
1150
                printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->base);
1151
                return 0;
1152
        }
1153
 
1154
        if (check_region(devc->codec, 2)) {
1155
                printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec);
1156
                return 0;
1157
        }
1158
 
1159
        if ( (inb( devc -> base + 2) & 0x78) != 0) return 0;
1160
 
1161
        d = inb ( devc -> base + 4) & 0xF0;
1162
        if (  (d & 0x80) != 0)  return 0;
1163
 
1164
        if (d == 0) {
1165
                        devc->codec_type = 1;
1166
                        devc->ic_type = IC_ODIE;
1167
        }
1168
        else if ( (d & 0x60) != 0) {
1169
                        devc->codec_type = 2;
1170
                        devc->ic_type = IC_OPUS;
1171
        }
1172
        else if ( (d & 0x40) != 0) {
1173
                        devc->codec_type = 2;
1174
                        devc->ic_type = IC_ODIE;
1175
        }
1176
        else return 0;
1177
 
1178
        sscape_is_pnp = 1;
1179
 
1180
        outb(0xFA, devc -> base+4);
1181
        if  ((inb( devc -> base+4) & 0x9F) != 0x0A)
1182
                return 0;
1183
        outb(0xFE, devc -> base+4);
1184
        if  ( (inb(devc -> base+4) & 0x9F) != 0x0E)
1185
                return 0;
1186
        if  ( (inb(devc -> base+5) & 0x9F) != 0x0E)
1187
                return 0;
1188
 
1189
        if (devc->codec_type == 2) {
1190
                if (devc -> codec != devc -> base + 8)
1191
                        printk("soundscape warning: incorrect codec port specified\n");
1192
                devc -> codec = devc -> base + 8;
1193
                d = 0x10 | (sscape_read(devc, 9)  & 0xCF);
1194
                sscape_write(devc, 9, d);
1195
                sscape_write(devc, 6, 0x80);
1196
        } else {
1197
                //todo: check codec is not base + 8
1198
        }
1199
 
1200
        d  = (sscape_read(devc, 9) & 0x3F) | 0xC0;
1201
        sscape_write(devc, 9, d);
1202
 
1203
        for (i = 0; i < 550000; i++)
1204
                if ( !(inb(devc -> codec) & 0x80) ) break;
1205
 
1206
        d = inb(devc -> codec);
1207
        if (d & 0x80)
1208
                return 0;
1209
        if ( inb(devc -> codec + 2) == 0xFF)
1210
                return 0;
1211
 
1212
        sscape_write(devc, 9, sscape_read(devc, 9)  & 0x3F );
1213
 
1214
        d  = inb(devc -> codec) & 0x80;
1215
        if ( d == 0) {
1216
                printk(KERN_INFO "soundscape: hardware detected\n");
1217
                valid_interrupts = valid_interrupts_new;
1218
        } else  {
1219
                printk(KERN_INFO "soundscape: board looks like media fx\n");
1220
                valid_interrupts = valid_interrupts_old;
1221
                old_hardware = 1;
1222
        }
1223
 
1224
        sscape_write( devc, 9, 0xC0 | (sscape_read(devc, 9)  & 0x3F) );
1225
 
1226
        for (i = 0; i < 550000; i++)
1227
                if ( !(inb(devc -> codec) & 0x80))
1228
                        break;
1229
 
1230
        sscape_pnp_init_hw(devc);
1231
 
1232
        for (i = 0; i < sizeof(valid_interrupts); i++)
1233
        {
1234
                if (devc->codec_irq == valid_interrupts[i]) {
1235
                        irq_bits = i;
1236
                        break;
1237
                }
1238
        }
1239
        sscape_write(devc, GA_INTENA_REG, 0x00);
1240
        sscape_write(devc, GA_DMACFG_REG, 0x50);
1241
        sscape_write(devc, GA_DMAA_REG, 0x70);
1242
        sscape_write(devc, GA_DMAB_REG, 0x20);
1243
        sscape_write(devc, GA_INTCFG_REG, 0xf0);
1244
        sscape_write(devc, GA_CDCFG_REG, 0x89 | (devc->dma << 4) | (irq_bits << 1));
1245
 
1246
        sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 0) | 0x20);
1247
        sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 1) | 0x20);
1248
 
1249
        return 1;
1250
}
1251
 
1252
static int __init probe_sscape(struct address_info *hw_config)
1253
{
1254
 
1255
        if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
1256
                return 0;
1257
 
1258
        devc->base = hw_config->io_base;
1259
        devc->irq = hw_config->irq;
1260
        devc->dma = hw_config->dma;
1261
        devc->osp = hw_config->osp;
1262
 
1263
#ifdef SSCAPE_DEBUG1
1264
        /*
1265
         * Temporary debugging aid. Print contents of the registers before
1266
         * changing them.
1267
         */
1268
        {
1269
                int i;
1270
 
1271
                for (i = 0; i < 13; i++)
1272
                        printk("I%d = %02x (old value)\n", i, sscape_read(devc, i));
1273
        }
1274
#endif
1275
        devc->failed = 1;
1276
 
1277
        if (!detect_ga(devc)) {
1278
                if (detect_sscape_pnp(devc)) {
1279
                        sscape_detected = hw_config->io_base;
1280
                        return 1;
1281
                }
1282
                else return 0;
1283
        }
1284
 
1285
        if (old_hardware)       /* Check that it's really an old Spea/Reveal card. */
1286
        {
1287
                unsigned char   tmp;
1288
                int             cc;
1289
 
1290
                if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
1291
                {
1292
                        sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
1293
                        for (cc = 0; cc < 200000; ++cc)
1294
                                inb(devc->base + ODIE_ADDR);
1295
                }
1296
        }
1297
        sscape_detected = hw_config->io_base;
1298
        return 1;
1299
}
1300
 
1301
static int __init probe_ss_ms_sound(struct address_info *hw_config)
1302
{
1303
        int i, irq_bits = 0xff;
1304
        int ad_flags = 0;
1305
 
1306
        if (devc->failed)
1307
        {
1308
                printk(KERN_ERR "soundscape: Card not detected\n");
1309
                return 0;
1310
        }
1311
        if (devc->ok == 0)
1312
        {
1313
                printk(KERN_ERR "soundscape: Invalid initialization order.\n");
1314
                return 0;
1315
        }
1316
        for (i = 0; i < sizeof(valid_interrupts); i++)
1317
        {
1318
                if (hw_config->irq == valid_interrupts[i])
1319
                {
1320
                        irq_bits = i;
1321
                        break;
1322
                }
1323
        }
1324
        if (hw_config->irq > 15 || irq_bits == 0xff)
1325
        {
1326
                printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
1327
                return 0;
1328
        }
1329
 
1330
        if (!sscape_is_pnp) {
1331
                if (old_hardware)
1332
                        ad_flags = 0x12345677;  /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1333
                return ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
1334
        }
1335
        else {
1336
                if (old_hardware)
1337
                        ad_flags = 0x12345677;  /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1338
                else
1339
                        ad_flags = 0x87654321;  /* Tell that we have a soundscape pnp with 1845 chip */
1340
                return ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
1341
        }
1342
}
1343
 
1344
static void __init attach_ss_ms_sound(struct address_info *hw_config)
1345
{
1346
        /*
1347
         * This routine configures the SoundScape card for use with the
1348
         * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
1349
         * config registers of the "ODIE".
1350
         */
1351
 
1352
        int i, irq_bits = 0xff;
1353
 
1354
 
1355
        if (!sscape_is_pnp)  /*pnp is already setup*/
1356
        {
1357
                /*
1358
                 * Setup the DMA polarity.
1359
                 */
1360
                sscape_write(devc, GA_DMACFG_REG, 0x50);
1361
 
1362
                /*
1363
                 * Take the gate-array off of the DMA channel.
1364
                 */
1365
                sscape_write(devc, GA_DMAB_REG, 0x20);
1366
 
1367
                /*
1368
                 * Init the AD1848 (CD-ROM) config reg.
1369
                 */
1370
                for (i = 0; i < sizeof(valid_interrupts); i++)
1371
                {
1372
                        if (hw_config->irq == valid_interrupts[i])
1373
                        {
1374
                                irq_bits = i;
1375
                                break;
1376
                        }
1377
                }
1378
                sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1));
1379
        }
1380
 
1381
        if (hw_config->irq == devc->irq)
1382
                printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
1383
 
1384
        hw_config->slots[0] = ad1848_init(
1385
                        sscape_is_pnp ? "SoundScape" : "SoundScape PNP",
1386
                        hw_config->io_base,
1387
                        hw_config->irq,
1388
                        hw_config->dma,
1389
                        hw_config->dma,
1390
                        0,
1391
                        devc->osp,
1392
                        THIS_MODULE);
1393
 
1394
 
1395
        if (hw_config->slots[0] != -1)   /* The AD1848 driver installed itself */
1396
        {
1397
                audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
1398
                devc->codec_audiodev = hw_config->slots[0];
1399
                devc->my_audiodev = hw_config->slots[0];
1400
 
1401
                /* Set proper routings here (what are they) */
1402
                AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
1403
        }
1404
 
1405
#ifdef SSCAPE_DEBUG5
1406
        /*
1407
         * Temporary debugging aid. Print contents of the registers
1408
         * after the AD1848 device has been initialized.
1409
         */
1410
        {
1411
                int i;
1412
 
1413
                for (i = 0; i < 13; i++)
1414
                        printk("I%d = %02x\n", i, sscape_read(devc, i));
1415
        }
1416
#endif
1417
 
1418
}
1419
 
1420
static void __exit unload_sscape(struct address_info *hw_config)
1421
{
1422
        release_region(devc->base + 2, 6);
1423
        unload_mpu401(hw_config);
1424
}
1425
 
1426
static void __exit unload_ss_ms_sound(struct address_info *hw_config)
1427
{
1428
        ad1848_unload(hw_config->io_base,
1429
                      hw_config->irq,
1430
                      devc->dma,
1431
                      devc->dma,
1432
                      0);
1433
        sound_unload_audiodev(hw_config->slots[0]);
1434
}
1435
 
1436
static struct address_info cfg;
1437
static struct address_info cfg_mpu;
1438
 
1439
static int __initdata spea = -1;
1440
static int __initdata mss = 0;
1441
static int __initdata dma = -1;
1442
static int __initdata irq = -1;
1443
static int __initdata io = -1;
1444
static int __initdata mpu_irq = -1;
1445
static int __initdata mpu_io = -1;
1446
 
1447
MODULE_PARM(dma, "i");
1448
MODULE_PARM(irq, "i");
1449
MODULE_PARM(io, "i");
1450
MODULE_PARM(spea, "i");         /* spea=0/1 set the old_hardware */
1451
MODULE_PARM(mpu_irq, "i");
1452
MODULE_PARM(mpu_io, "i");
1453
MODULE_PARM(mss, "i");
1454
 
1455
static int __init init_sscape(void)
1456
{
1457
        printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
1458
 
1459
        cfg.irq = irq;
1460
        cfg.dma = dma;
1461
        cfg.io_base = io;
1462
 
1463
        cfg_mpu.irq = mpu_irq;
1464
        cfg_mpu.io_base = mpu_io;
1465
        /* WEH - Try to get right dma channel */
1466
        cfg_mpu.dma = dma;
1467
 
1468
        devc->codec = cfg.io_base;
1469
        devc->codec_irq = cfg.irq;
1470
        devc->codec_type = 0;
1471
        devc->ic_type = 0;
1472
        devc->raw_buf = NULL;
1473
 
1474
        if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
1475
                printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
1476
                return -EINVAL;
1477
        }
1478
 
1479
        if (cfg_mpu.irq == -1 && cfg_mpu.io_base != -1) {
1480
                printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
1481
                return -EINVAL;
1482
        }
1483
 
1484
        if(spea != -1) {
1485
                old_hardware = spea;
1486
                printk(KERN_INFO "Forcing %s hardware support.\n",
1487
                        spea?"new":"old");
1488
        }
1489
        if (probe_sscape(&cfg_mpu) == 0)
1490
                return -ENODEV;
1491
 
1492
        attach_sscape(&cfg_mpu);
1493
 
1494
        mss = probe_ss_ms_sound(&cfg);
1495
 
1496
        if (mss)
1497
                attach_ss_ms_sound(&cfg);
1498
 
1499
        return 0;
1500
}
1501
 
1502
static void __exit cleanup_sscape(void)
1503
{
1504
        if (mss)
1505
                unload_ss_ms_sound(&cfg);
1506
        unload_sscape(&cfg_mpu);
1507
}
1508
 
1509
module_init(init_sscape);
1510
module_exit(cleanup_sscape);
1511
 
1512
#ifndef MODULE
1513
static int __init setup_sscape(char *str)
1514
{
1515
        /* io, irq, dma, mpu_io, mpu_irq */
1516
        int ints[6];
1517
 
1518
        str = get_options(str, ARRAY_SIZE(ints), ints);
1519
 
1520
        io      = ints[1];
1521
        irq     = ints[2];
1522
        dma     = ints[3];
1523
        mpu_io  = ints[4];
1524
        mpu_irq = ints[5];
1525
 
1526
        return 1;
1527
}
1528
 
1529
__setup("sscape=", setup_sscape);
1530
#endif
1531
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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