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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * sound/gus_card.c
3
 *
4
 * Detection routine for the Gravis Ultrasound.
5
 *
6
 * Copyright (C) by Hannu Savolainen 1993-1997
7
 *
8
 *
9
 * Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious
10
 *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
11
 * Christoph Hellwig: Adapted to module_init/module_exit, simple cleanups.
12
 *
13
 * Status:
14
 *              Tested...
15
 */
16
 
17
 
18
#include <linux/config.h>
19
#include <linux/init.h>
20
#include <linux/module.h>
21
 
22
#include "sound_config.h"
23
 
24
#include "gus.h"
25
#include "gus_hw.h"
26
 
27
void            gusintr(int irq, void *dev_id, struct pt_regs *dummy);
28
 
29
int             gus_base = 0, gus_irq = 0, gus_dma = 0;
30
int             gus_no_wave_dma = 0;
31
extern int      gus_wave_volume;
32
extern int      gus_pcm_volume;
33
extern int      have_gus_max;
34
int             gus_pnp_flag = 0;
35
#ifdef CONFIG_SOUND_GUS16
36
static int      db16 = 0;        /* Has a Gus16 AD1848 on it */
37
#endif
38
 
39
static void __init attach_gus(struct address_info *hw_config)
40
{
41
        gus_wave_init(hw_config);
42
 
43
        request_region(hw_config->io_base, 16, "GUS");
44
        request_region(hw_config->io_base + 0x100, 12, "GUS");  /* 0x10c-> is MAX */
45
 
46
        if (sound_alloc_dma(hw_config->dma, "GUS"))
47
                printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma);
48
        if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
49
                if (sound_alloc_dma(hw_config->dma2, "GUS(2)"))
50
                        printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma2);
51
        gus_midi_init(hw_config);
52
        if(request_irq(hw_config->irq, gusintr, 0,  "Gravis Ultrasound", hw_config)<0)
53
                printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);
54
 
55
        return;
56
}
57
 
58
static int __init probe_gus(struct address_info *hw_config)
59
{
60
        int             irq;
61
        int             io_addr;
62
 
63
        if (hw_config->card_subtype == 1)
64
                gus_pnp_flag = 1;
65
 
66
        irq = hw_config->irq;
67
 
68
        if (hw_config->card_subtype == 0)        /* GUS/MAX/ACE */
69
                if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
70
                    irq != 11 && irq != 12 && irq != 15)
71
                  {
72
                          printk(KERN_ERR "GUS: Unsupported IRQ %d\n", irq);
73
                          return 0;
74
                  }
75
        if (check_region(hw_config->io_base, 16))
76
                printk(KERN_ERR "GUS: I/O range conflict (1)\n");
77
        else if (check_region(hw_config->io_base + 0x100, 16))
78
                printk(KERN_ERR "GUS: I/O range conflict (2)\n");
79
        else if (gus_wave_detect(hw_config->io_base))
80
                return 1;
81
 
82
#ifndef EXCLUDE_GUS_IODETECT
83
 
84
        /*
85
         * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
86
         */
87
 
88
        for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
89
                if (io_addr != hw_config->io_base)      /*
90
                                                         * Already tested
91
                                                         */
92
                        if (!check_region(io_addr, 16))
93
                                if (!check_region(io_addr + 0x100, 16))
94
                                        if (gus_wave_detect(io_addr))
95
                                          {
96
                                                  hw_config->io_base = io_addr;
97
                                                  return 1;
98
                                          }
99
#endif
100
 
101
        printk("NO GUS card found !\n");
102
        return 0;
103
}
104
 
105
static void __exit unload_gus(struct address_info *hw_config)
106
{
107
        DDB(printk("unload_gus(%x)\n", hw_config->io_base));
108
 
109
        gus_wave_unload(hw_config);
110
 
111
        release_region(hw_config->io_base, 16);
112
        release_region(hw_config->io_base + 0x100, 12);         /* 0x10c-> is MAX */
113
        free_irq(hw_config->irq, hw_config);
114
 
115
        sound_free_dma(hw_config->dma);
116
 
117
        if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
118
                sound_free_dma(hw_config->dma2);
119
}
120
 
121
void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
122
{
123
        unsigned char src;
124
        extern int gus_timer_enabled;
125
 
126
        sti();
127
 
128
#ifdef CONFIG_SOUND_GUSMAX
129
        if (have_gus_max) {
130
                struct address_info *hw_config = dev_id;
131
                adintr(irq, (void *)hw_config->slots[1], NULL);
132
        }
133
#endif
134
#ifdef CONFIG_SOUND_GUS16
135
        if (db16) {
136
                struct address_info *hw_config = dev_id;
137
                adintr(irq, (void *)hw_config->slots[3], NULL);
138
        }
139
#endif
140
 
141
        while (1)
142
        {
143
                if (!(src = inb(u_IrqStatus)))
144
                        return;
145
 
146
                if (src & DMA_TC_IRQ)
147
                {
148
                        guswave_dma_irq();
149
                }
150
                if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
151
                {
152
                        gus_midi_interrupt(0);
153
                }
154
                if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
155
                {
156
                        if (gus_timer_enabled)
157
                                sound_timer_interrupt();
158
                        gus_write8(0x45, 0);     /* Ack IRQ */
159
                        gus_timer_command(4, 0x80);             /* Reset IRQ flags */
160
                }
161
                if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
162
                        gus_voice_irq();
163
        }
164
}
165
 
166
/*
167
 *      Some extra code for the 16 bit sampling option
168
 */
169
 
170
#ifdef CONFIG_SOUND_GUS16
171
 
172
static int __init probe_gus_db16(struct address_info *hw_config)
173
{
174
        return ad1848_detect(hw_config->io_base, NULL, hw_config->osp);
175
}
176
 
177
static void __init attach_gus_db16(struct address_info *hw_config)
178
{
179
        gus_pcm_volume = 100;
180
        gus_wave_volume = 90;
181
 
182
        hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", hw_config->io_base,
183
                                          hw_config->irq,
184
                                          hw_config->dma,
185
                                          hw_config->dma, 0,
186
                                          hw_config->osp,
187
                                          THIS_MODULE);
188
}
189
 
190
static void __exit unload_gus_db16(struct address_info *hw_config)
191
{
192
 
193
        ad1848_unload(hw_config->io_base,
194
                      hw_config->irq,
195
                      hw_config->dma,
196
                      hw_config->dma, 0);
197
        sound_unload_audiodev(hw_config->slots[3]);
198
}
199
#endif
200
 
201
#ifdef CONFIG_SOUND_GUS16
202
static int gus16 = 0;
203
#endif
204
#ifdef CONFIG_SOUND_GUSMAX
205
static int no_wave_dma = 0;/* Set if no dma is to be used for the
206
                                   wave table (GF1 chip) */
207
#endif
208
 
209
 
210
/*
211
 *    Note DMA2 of -1 has the right meaning in the GUS driver as well
212
 *      as here.
213
 */
214
 
215
static struct address_info cfg;
216
 
217
static int __initdata io = -1;
218
static int __initdata irq = -1;
219
static int __initdata dma = -1;
220
static int __initdata dma16 = -1;       /* Set this for modules that need it */
221
static int __initdata type = 0;          /* 1 for PnP */
222
 
223
MODULE_PARM(io, "i");
224
MODULE_PARM(irq, "i");
225
MODULE_PARM(dma, "i");
226
MODULE_PARM(dma16, "i");
227
MODULE_PARM(type, "i");
228
#ifdef CONFIG_SOUND_GUSMAX
229
MODULE_PARM(no_wave_dma, "i");
230
#endif
231
#ifdef CONFIG_SOUND_GUS16
232
MODULE_PARM(db16, "i");
233
MODULE_PARM(gus16, "i");
234
#endif
235
MODULE_LICENSE("GPL");
236
 
237
static int __init init_gus(void)
238
{
239
        printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
240
 
241
        cfg.io_base = io;
242
        cfg.irq = irq;
243
        cfg.dma = dma;
244
        cfg.dma2 = dma16;
245
        cfg.card_subtype = type;
246
#ifdef CONFIG_SOUND_GUSMAX
247
        gus_no_wave_dma = no_wave_dma;
248
#endif
249
 
250
        if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
251
                printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");
252
                return -EINVAL;
253
        }
254
 
255
#ifdef CONFIG_SOUND_GUS16
256
        if (probe_gus_db16(&cfg) && gus16) {
257
                /* FIXME: This can't work, can it ? -- Christoph */
258
                attach_gus_db16(&cfg);
259
                db16 = 1;
260
        }
261
#endif
262
        if (!probe_gus(&cfg))
263
                return -ENODEV;
264
        attach_gus(&cfg);
265
 
266
        return 0;
267
}
268
 
269
static void __exit cleanup_gus(void)
270
{
271
#ifdef CONFIG_SOUND_GUS16
272
        if (db16)
273
                unload_gus_db16(&cfg);
274
#endif
275
        unload_gus(&cfg);
276
}
277
 
278
module_init(init_gus);
279
module_exit(cleanup_gus);
280
 
281
#ifndef MODULE
282
static int __init setup_gus(char *str)
283
{
284
        /* io, irq, dma, dma2 */
285
        int ints[5];
286
 
287
        str = get_options(str, ARRAY_SIZE(ints), ints);
288
 
289
        io      = ints[1];
290
        irq     = ints[2];
291
        dma     = ints[3];
292
        dma16   = ints[4];
293
 
294
        return 1;
295
}
296
 
297
__setup("gus=", setup_gus);
298
#endif

powered by: WebSVN 2.1.0

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