This source file includes following definitions.
- pas_read
- pas_write
- pas2_msg
- pasintr
- pas_set_intr
- pas_remove_intr
- config_pas_hw
- detect_pas_hw
- attach_pas_card
- probe_pas
- unload_pas
1 #define _PAS2_CARD_C_
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/config.h>
31
32
33 #include "sound_config.h"
34
35 #if defined(CONFIG_PAS)
36
37 #define DEFINE_TRANSLATIONS
38 #include "pas.h"
39
40
41
42
43
44
45 int translat_code;
46 static int pas_intr_mask = 0;
47 static int pas_irq = 0;
48
49 int *pas_osp;
50
51 char pas_model;
52 static char *pas_model_names[] =
53 {"", "Pro AudioSpectrum+", "CDPC", "Pro AudioSpectrum 16", "Pro AudioSpectrum 16D"};
54
55
56
57
58
59
60
61
62
63
64 extern void mix_write (unsigned char data, int ioaddr);
65
66 unsigned char
67 pas_read (int ioaddr)
68 {
69 return inb (ioaddr ^ translat_code);
70 }
71
72 void
73 pas_write (unsigned char data, int ioaddr)
74 {
75 outb (data, ioaddr ^ translat_code);
76 }
77
78 void
79 pas2_msg (char *foo)
80 {
81 printk (" PAS2: %s.\n", foo);
82 }
83
84
85
86 void
87 pasintr (int irq, void *dev_id, struct pt_regs *dummy)
88 {
89 int status;
90
91 status = pas_read (INTERRUPT_STATUS);
92 pas_write (status, INTERRUPT_STATUS);
93
94
95
96 if (status & I_S_PCM_SAMPLE_BUFFER_IRQ)
97 {
98 #ifdef CONFIG_AUDIO
99 pas_pcm_interrupt (status, 1);
100 #endif
101 status &= ~I_S_PCM_SAMPLE_BUFFER_IRQ;
102 }
103 if (status & I_S_MIDI_IRQ)
104 {
105 #ifdef CONFIG_MIDI
106 pas_midi_interrupt ();
107 #endif
108 status &= ~I_S_MIDI_IRQ;
109 }
110
111 }
112
113 int
114 pas_set_intr (int mask)
115 {
116 if (!mask)
117 return 0;
118
119 pas_intr_mask |= mask;
120
121 pas_write (pas_intr_mask, INTERRUPT_MASK);
122 return 0;
123 }
124
125 int
126 pas_remove_intr (int mask)
127 {
128 if (!mask)
129 return 0;
130
131 pas_intr_mask &= ~mask;
132 pas_write (pas_intr_mask, INTERRUPT_MASK);
133
134 return 0;
135 }
136
137
138
139
140
141 int
142 config_pas_hw (struct address_info *hw_config)
143 {
144 char ok = 1;
145 unsigned int_ptrs;
146
147 pas_irq = hw_config->irq;
148
149 pas_write (0x00, INTERRUPT_MASK);
150
151 pas_write (0x36, SAMPLE_COUNTER_CONTROL);
152
153
154
155
156 pas_write (0x36, SAMPLE_RATE_TIMER);
157
158
159 pas_write (0, SAMPLE_RATE_TIMER);
160
161 pas_write (0x74, SAMPLE_COUNTER_CONTROL);
162
163
164
165
166 pas_write (0x74, SAMPLE_BUFFER_COUNTER);
167
168
169
170 pas_write (0, SAMPLE_BUFFER_COUNTER);
171
172 pas_write (F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER | F_F_MIXER_UNMUTE | 1, FILTER_FREQUENCY);
173 pas_write (P_C_PCM_DMA_ENABLE | P_C_PCM_MONO | P_C_PCM_DAC_MODE | P_C_MIXER_CROSS_L_TO_L | P_C_MIXER_CROSS_R_TO_R, PCM_CONTROL);
174 pas_write (S_M_PCM_RESET | S_M_FM_RESET | S_M_SB_RESET | S_M_MIXER_RESET
175
176
177 , SERIAL_MIXER);
178
179 pas_write (I_C_1_BOOT_RESET_ENABLE
180 #ifdef PAS_JOYSTICK_ENABLE
181 | I_C_1_JOYSTICK_ENABLE
182 #endif
183 ,IO_CONFIGURATION_1);
184
185 if (pas_irq < 0 || pas_irq > 15)
186 {
187 printk ("PAS2: Invalid IRQ %d", pas_irq);
188 ok = 0;
189 }
190 else
191 {
192 int_ptrs = pas_read (IO_CONFIGURATION_3);
193 int_ptrs |= I_C_3_PCM_IRQ_translate[pas_irq] & 0xf;
194 pas_write (int_ptrs, IO_CONFIGURATION_3);
195 if (!I_C_3_PCM_IRQ_translate[pas_irq])
196 {
197 printk ("PAS2: Invalid IRQ %d", pas_irq);
198 ok = 0;
199 }
200 else
201 {
202 if (snd_set_irq_handler (pas_irq, pasintr, "PAS16", hw_config->osp) < 0)
203 ok = 0;
204 }
205 }
206
207 if (hw_config->dma < 0 || hw_config->dma > 7)
208 {
209 printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
210 ok = 0;
211 }
212 else
213 {
214 pas_write (I_C_2_PCM_DMA_translate[hw_config->dma], IO_CONFIGURATION_2);
215 if (!I_C_2_PCM_DMA_translate[hw_config->dma])
216 {
217 printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
218 ok = 0;
219 }
220 else
221 {
222 if (sound_alloc_dma (hw_config->dma, "PAS16"))
223 {
224 printk ("pas2_card.c: Can't allocate DMA channel\n");
225 ok = 0;
226 }
227 }
228 }
229
230
231
232
233
234 #ifdef SYMPHONY_PAS
235 outb (0x05, 0xa8);
236 outb (0x60, 0xa9);
237 #endif
238
239 #ifdef BROKEN_BUS_CLOCK
240 pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND | S_C_1_FM_EMULATE_CLOCK, SYSTEM_CONFIGURATION_1);
241 #else
242
243
244
245 pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND, SYSTEM_CONFIGURATION_1);
246 #endif
247 pas_write (0x18, SYSTEM_CONFIGURATION_3);
248
249
250
251 pas_write (F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY);
252
253
254
255
256
257
258
259 pas_write (8, PRESCALE_DIVIDER);
260
261 mix_write (P_M_MV508_ADDRESS | 5, PARALLEL_MIXER);
262 mix_write (5, PARALLEL_MIXER);
263
264 #if !defined(DISABLE_SB_EMULATION) && defined(CONFIG_SB)
265
266 {
267 struct address_info *sb_config;
268
269 if ((sb_config = sound_getconf (SNDCARD_SB)))
270 {
271 unsigned char irq_dma;
272
273
274
275
276
277
278
279
280
281
282 pas_write (0x02, COMPATIBILITY_ENABLE);
283
284
285
286
287 pas_write ((sb_config->io_base >> 4) & 0x0f, EMULATION_ADDRESS);
288
289 if (!E_C_SB_DMA_translate[sb_config->dma])
290 printk ("\n\nPAS16 Warning: Invalid SB DMA %d\n\n",
291 sb_config->dma);
292
293 if (!E_C_SB_IRQ_translate[sb_config->irq])
294 printk ("\n\nPAS16 Warning: Invalid SB IRQ %d\n\n",
295 sb_config->irq);
296
297 irq_dma = E_C_SB_DMA_translate[sb_config->dma] |
298 E_C_SB_IRQ_translate[sb_config->irq];
299
300 pas_write (irq_dma, EMULATION_CONFIGURATION);
301 }
302 else
303 pas_write (0x00, COMPATIBILITY_ENABLE);
304 }
305 #else
306 pas_write (0x00, COMPATIBILITY_ENABLE);
307 #endif
308
309 if (!ok)
310 pas2_msg ("Driver not enabled");
311
312 return ok;
313 }
314
315 int
316 detect_pas_hw (struct address_info *hw_config)
317 {
318 unsigned char board_id, foo;
319
320
321
322
323
324
325
326
327 outb (0xBC, MASTER_DECODE);
328
329
330 outb (hw_config->io_base >> 2, MASTER_DECODE);
331
332
333 translat_code = PAS_DEFAULT_BASE ^ hw_config->io_base;
334 pas_write (1, WAIT_STATE);
335
336
337
338 board_id = pas_read (INTERRUPT_MASK);
339
340 if (board_id == 0xff)
341 return 0;
342
343
344
345
346
347
348
349 foo = board_id ^ 0xe0;
350
351 pas_write (foo, INTERRUPT_MASK);
352 foo = inb (INTERRUPT_MASK);
353 pas_write (board_id, INTERRUPT_MASK);
354
355 if (board_id != foo)
356
357
358 return 0;
359
360 pas_model = pas_read (CHIP_REV);
361
362 return pas_model;
363 }
364
365 long
366 attach_pas_card (long mem_start, struct address_info *hw_config)
367 {
368 pas_irq = hw_config->irq;
369 pas_osp = hw_config->osp;
370
371 if (detect_pas_hw (hw_config))
372 {
373
374 if ((pas_model = pas_read (CHIP_REV)))
375 {
376 char temp[100];
377
378 sprintf (temp,
379 "%s rev %d", pas_model_names[(int) pas_model],
380 pas_read (BOARD_REV_ID));
381 conf_printf (temp, hw_config);
382 }
383
384 if (config_pas_hw (hw_config))
385 {
386
387 #ifdef CONFIG_AUDIO
388 mem_start = pas_pcm_init (mem_start, hw_config);
389 #endif
390
391 #if !defined(DISABLE_SB_EMULATION) && defined(CONFIG_SB)
392
393 sb_dsp_disable_midi ();
394
395
396
397 #endif
398
399
400 #ifdef CONFIG_MIDI
401 mem_start = pas_midi_init (mem_start);
402 #endif
403
404 pas_init_mixer ();
405 }
406 }
407
408 return mem_start;
409 }
410
411 int
412 probe_pas (struct address_info *hw_config)
413 {
414 pas_osp = hw_config->osp;
415 return detect_pas_hw (hw_config);
416 }
417
418 void
419 unload_pas (struct address_info *hw_config)
420 {
421 sound_free_dma (hw_config->dma);
422 snd_release_irq (hw_config->irq);
423 }
424
425 #endif