This source file includes following definitions.
- pas_read
- pas_write
- pas2_msg
- pasintr
- set_pas_irq
- pas_set_intr
- pas_remove_intr
- config_pas_hw
- detect_pas_hw
- attach_pas_card
- probe_pas
1 #define _PAS2_CARD_C_
2 #define SND_SA_INTERRUPT
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
32 #include "sound_config.h"
33
34 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PAS)
35
36 #define DEFINE_TRANSLATIONS
37 #include "pas.h"
38
39
40
41
42
43
44 int translat_code;
45 static int pas_intr_mask = 0;
46 static int pas_irq = 0;
47
48 static char pas_model;
49 static char *pas_model_names[] =
50 {"", "Pro AudioSpectrum+", "CDPC", "Pro AudioSpectrum 16"};
51
52
53
54
55
56 unsigned char
57 pas_read (int ioaddr)
58 {
59 return INB (ioaddr ^ translat_code);
60 }
61
62 void
63 pas_write (unsigned char data, int ioaddr)
64 {
65 OUTB (data, ioaddr ^ translat_code);
66 }
67
68 void
69 pas2_msg (char *foo)
70 {
71 printk (" PAS2: %s.\n", foo);
72 }
73
74
75
76 void
77 pasintr (int unused)
78 {
79 int status;
80
81 status = pas_read (INTERRUPT_STATUS);
82 pas_write (status, INTERRUPT_STATUS);
83
84 if (status & I_S_PCM_SAMPLE_BUFFER_IRQ)
85 {
86 #ifndef EXCLUDE_AUDIO
87 pas_pcm_interrupt (status, 1);
88 #endif
89 status &= ~I_S_PCM_SAMPLE_BUFFER_IRQ;
90 }
91 if (status & I_S_MIDI_IRQ)
92 {
93 #ifndef EXCLUDE_MIDI
94 #ifdef EXCLUDE_PRO_MIDI
95 pas_midi_interrupt ();
96 #endif
97 #endif
98 status &= ~I_S_MIDI_IRQ;
99 }
100
101 }
102
103 static int
104 set_pas_irq (int interrupt_level)
105 {
106 #ifdef linux
107 int retcode;
108 struct sigaction sa;
109
110 pas_write (0xff, INTERRUPT_STATUS);
111
112 sa.sa_handler = pasintr;
113
114 #ifdef SND_SA_INTERRUPT
115 sa.sa_flags = SA_INTERRUPT;
116 #else
117 sa.sa_flags = 0;
118 #endif
119
120 sa.sa_mask = 0;
121 sa.sa_restorer = NULL;
122
123 retcode = irqaction (interrupt_level, &sa);
124
125 if (retcode < 0)
126 {
127 printk ("ProAudioSpectrum: IRQ%d already in use\n", interrupt_level);
128 }
129 return retcode;
130 #else
131
132 #endif
133 }
134
135 int
136 pas_set_intr (int mask)
137 {
138 int err;
139
140 if (!mask)
141 return 0;
142
143 if (!pas_intr_mask)
144 {
145 if ((err = set_pas_irq (pas_irq)) < 0)
146 return err;
147 }
148 pas_intr_mask |= mask;
149
150 pas_write (pas_intr_mask, INTERRUPT_MASK);
151 return 0;
152 }
153
154 int
155 pas_remove_intr (int mask)
156 {
157 if (!mask)
158 return 0;
159
160 pas_intr_mask &= ~mask;
161 pas_write (pas_intr_mask, INTERRUPT_MASK);
162
163 if (!pas_intr_mask)
164 {
165 RELEASE_IRQ (pas_irq);
166 }
167 return 0;
168 }
169
170
171
172
173
174 int
175 config_pas_hw (struct address_info *hw_config)
176 {
177 char ok = 1;
178
179 pas_irq = hw_config->irq;
180
181 pas_write (0x00, INTERRUPT_MASK);
182
183 pas_write (0x36, SAMPLE_COUNTER_CONTROL);
184
185
186 pas_write (0x36, SAMPLE_RATE_TIMER);
187 pas_write (0, SAMPLE_RATE_TIMER);
188
189 pas_write (0x74, SAMPLE_COUNTER_CONTROL);
190
191
192 pas_write (0x74, SAMPLE_BUFFER_COUNTER);
193
194 pas_write (0, SAMPLE_BUFFER_COUNTER);
195
196 pas_write (F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER | F_F_MIXER_UNMUTE | 1, FILTER_FREQUENCY);
197 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);
198 pas_write (S_M_PCM_RESET | S_M_FM_RESET | S_M_SB_RESET | S_M_MIXER_RESET , SERIAL_MIXER);
199
200 pas_write (I_C_1_BOOT_RESET_ENABLE, IO_CONFIGURATION_1);
201
202 if (pas_irq < 0 || pas_irq > 15)
203 {
204 printk ("PAS2: Invalid IRQ %d", pas_irq);
205 ok = 0;
206 }
207 else
208 {
209 pas_write (I_C_3_PCM_IRQ_translate[pas_irq], IO_CONFIGURATION_3);
210 if (!I_C_3_PCM_IRQ_translate[pas_irq])
211 {
212 printk ("PAS2: Invalid IRQ %d", pas_irq);
213 ok = 0;
214 }
215 }
216
217 if (hw_config->dma < 0 || hw_config->dma > 7)
218 {
219 printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
220 ok = 0;
221 }
222 else
223 {
224 pas_write (I_C_2_PCM_DMA_translate[hw_config->dma], IO_CONFIGURATION_2);
225 if (!I_C_2_PCM_DMA_translate[hw_config->dma])
226 {
227 printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
228 ok = 0;
229 }
230 }
231
232 #ifdef BROKEN_BUS_CLOCK
233 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);
234 #else
235
236 pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND, SYSTEM_CONFIGURATION_1);
237 #endif
238
239 pas_write (0x18, SYSTEM_CONFIGURATION_3);
240
241 pas_write (F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY);
242
243
244
245 if (pas_model == PAS_16)
246 pas_write (8, PRESCALE_DIVIDER);
247 else
248 pas_write (0, PRESCALE_DIVIDER);
249
250 pas_write (P_M_MV508_ADDRESS | 5, PARALLEL_MIXER);
251 pas_write (5, PARALLEL_MIXER);
252
253 #if !defined(EXCLUDE_SB_EMULATION) || !defined(EXCLUDE_SB)
254
255
256
257
258 pas_write (0x02, COMPATIBILITY_ENABLE);
259
260
261 pas_write ((SBC_BASE >> 4) & 0x0f, EMULATION_ADDRESS);
262 #endif
263
264 if (!ok)
265 pas2_msg ("Driver not enabled");
266
267 return ok;
268 }
269
270 int
271 detect_pas_hw (struct address_info *hw_config)
272 {
273 unsigned char board_id, foo;
274
275
276
277
278
279
280
281
282 OUTB (0xBC, MASTER_DECODE);
283 OUTB (hw_config->io_base >> 2, MASTER_DECODE);
284 translat_code = PAS_DEFAULT_BASE ^ hw_config->io_base;
285 pas_write (1, WAIT_STATE);
286
287 board_id = pas_read (INTERRUPT_MASK);
288
289 if (board_id == 0xff)
290 return 0;
291
292
293
294
295
296
297
298 foo = board_id ^ 0xe0;
299
300 pas_write (foo, INTERRUPT_MASK);
301 foo = INB (INTERRUPT_MASK);
302 pas_write (board_id, INTERRUPT_MASK);
303
304 if (board_id != foo)
305 return 0;
306
307 if ((pas_model = O_M_1_to_card[pas_read (OPERATION_MODE_1) & 0x0f]));
308
309 return pas_model;
310 }
311
312 long
313 attach_pas_card (long mem_start, struct address_info *hw_config)
314 {
315 pas_irq = hw_config->irq;
316
317 if (detect_pas_hw (hw_config))
318 {
319
320 if ((pas_model = O_M_1_to_card[pas_read (OPERATION_MODE_1) & 0x0f]))
321 {
322 printk (" <%s rev %d>", pas_model_names[(int) pas_model], pas_read (BOARD_REV_ID));
323 }
324
325 if (config_pas_hw (hw_config))
326 {
327
328 #ifndef EXCLUDE_AUDIO
329 mem_start = pas_pcm_init (mem_start, hw_config);
330 #endif
331
332 # if !defined(EXCLUDE_SB_EMULATION) && !defined(EXCLUDE_SB)
333
334 sb_dsp_disable_midi ();
335
336 # endif
337
338 #ifndef EXCLUDE_YM3812
339 enable_opl3_mode (0x388, 0x38a, 0);
340 #endif
341
342 #ifndef EXCLUDE_MIDI
343 #ifdef EXCLUDE_PRO_MIDI
344 mem_start = pas_midi_init (mem_start);
345 #endif
346 #endif
347
348 pas_init_mixer ();
349 }
350 }
351
352 printk ("\n");
353 return mem_start;
354 }
355
356 int
357 probe_pas (struct address_info *hw_config)
358 {
359 return detect_pas_hw (hw_config);
360 }
361
362 #endif