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