This source file includes following definitions.
- sb_dsp_command01
- wait_data_avail
- read_dsp
- dsp_ini2
- dsp_set_speed
- dsp_set_stereo
- dsp_set_bits
- sb16_dsp_ioctl
- sb16_dsp_open
- sb16_dsp_close
- sb16_dsp_output_block
- sb16_dsp_start_input
- sb16_dsp_prepare_for_input
- sb16_dsp_prepare_for_output
- dsp_cleanup
- sb16_dsp_reset
- sb16_dsp_halt
- set_irq_hw
- sb16_dsp_init
- sb16_dsp_detect
- sb16_dsp_interrupt
1
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
32 #define DEB(x)
33 #define DEB1(x)
34
35
36
37 #include "sound_config.h"
38 #include "sb.h"
39 #include "sb_mixer.h"
40
41 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_AUDIO) && !defined(EXCLUDE_SBPRO)
42
43 extern int sbc_base;
44
45 static int sb16_dsp_ok = 0;
46 static int dsp_16bit = 0;
47 static int dsp_stereo = 0;
48 static int dsp_current_speed = 8000;
49 static int dsp_busy = 0;
50 static int dma16, dma8;
51 static unsigned long dsp_count = 0;
52
53 static int irq_mode = IMODE_NONE;
54
55 static int my_dev = 0;
56
57 static volatile int intr_active = 0;
58
59 static int sb16_dsp_open (int dev, int mode);
60 static void sb16_dsp_close (int dev);
61 static void sb16_dsp_output_block (int dev, unsigned long buf, int count,int intrflag, int dma_restart);
62 static void sb16_dsp_start_input (int dev, unsigned long buf, int count,int intrflag, int dma_restart);
63 static int sb16_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg,int local);
64 static int sb16_dsp_prepare_for_input (int dev, int bsize, int bcount);
65 static int sb16_dsp_prepare_for_output (int dev, int bsize, int bcount);
66 static void sb16_dsp_reset (int dev);
67 static void sb16_dsp_halt (int dev);
68 static int dsp_set_speed (int);
69 static int dsp_set_stereo (int);
70 static void dsp_cleanup (void);
71 int sb_reset_dsp (void);
72
73 static struct audio_operations sb16_dsp_operations =
74 {
75 "SoundBlaster 16",
76 sb16_dsp_open,
77 sb16_dsp_close,
78 sb16_dsp_output_block,
79 sb16_dsp_start_input,
80 sb16_dsp_ioctl,
81 sb16_dsp_prepare_for_input,
82 sb16_dsp_prepare_for_output,
83 sb16_dsp_reset,
84 sb16_dsp_halt,
85 NULL,
86 NULL
87 };
88
89 static int sb_dsp_command01 (unsigned char val)
90 {
91 int i=1<<16;
92
93 while(--i & (!INB (DSP_STATUS) & 0x80));
94 if(!i)
95 printk("SB16 sb_dsp_command01 Timeout\n");
96 return sb_dsp_command(val);
97 }
98
99 static int wait_data_avail(int t)
100 {
101 int loopc=5000000;
102 t+=GET_TIME();
103 do {
104 if(INB(DSP_DATA_AVAIL) & 0x80)
105 return 1;
106 } while(--loopc && GET_TIME()<t);
107 printk("!data_avail l=%d\n",loopc);
108 return 0;
109 }
110
111 static int read_dsp(int t)
112 {
113 if(!wait_data_avail(t))
114 return -1;
115 else
116 return INB(DSP_READ);
117 }
118
119 static int dsp_ini2(void)
120 {
121 #if 0
122
123 sb_dsp_command(0xe2);
124 sb_dsp_command(0x76);
125 sb_dsp_command(0xe2);
126 sb_dsp_command(0x30);
127 sb_dsp_command(0xe4);
128 sb_dsp_command(0xaa);
129 sb_dsp_command(0xe8);
130 if(read_dsp(100)!=0xaa)
131 printk("Error dsp_ini2\n");
132 #endif
133 return 0;
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165 static int dsp_set_speed(int mode)
166 {
167 DEB(printk("dsp_set_speed(%d)\n",mode));
168 if (mode)
169 {
170 if (mode < 5000) mode = 5000;
171 if (mode > 44100) mode = 44100;
172 dsp_current_speed=mode;
173 }
174 return mode;
175 }
176
177 static int dsp_set_stereo(int mode)
178 {
179 DEB(printk("dsp_set_stereo(%d)\n",mode));
180
181 dsp_stereo=mode;
182
183 return mode;
184 }
185
186 static int dsp_set_bits(int arg) {
187 DEB(printk("dsp_set_bits(%d)\n",arg));
188
189 if (arg)
190 switch(arg) {
191 case 8:
192 dsp_16bit=0; break;
193 case 16:
194 dsp_16bit=1; break;
195 default:
196 return RET_ERROR(EINVAL);
197 }
198 return dsp_16bit? 16:8;
199 }
200
201 static int
202 sb16_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg,int local)
203 {
204 switch (cmd) {
205 case SOUND_PCM_WRITE_RATE:
206 if(local)
207 return dsp_set_speed(arg);
208 return IOCTL_OUT (arg, dsp_set_speed (IOCTL_IN (arg)));
209
210 case SOUND_PCM_READ_RATE:
211 if(local)
212 return dsp_current_speed;
213 return IOCTL_OUT (arg, dsp_current_speed);
214
215 case SNDCTL_DSP_STEREO:
216 if (local)
217 return dsp_set_stereo(arg);
218 return IOCTL_OUT (arg, dsp_set_stereo(IOCTL_IN(arg)));
219
220 case SOUND_PCM_WRITE_CHANNELS:
221 if (local)
222 return dsp_set_stereo(arg-1)+1;
223 return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
224
225 case SOUND_PCM_READ_CHANNELS:
226 if (local)
227 return dsp_stereo+1;
228 return IOCTL_OUT (arg, dsp_stereo+1);
229
230 case SNDCTL_DSP_SAMPLESIZE:
231 if (local)
232 return dsp_set_bits (arg);
233 return IOCTL_OUT (arg, dsp_set_bits (IOCTL_IN (arg)));
234
235 case SOUND_PCM_READ_BITS:
236 if (local)
237 return dsp_16bit?16:8;
238 return IOCTL_OUT (arg, dsp_16bit?16:8);
239
240 case SOUND_PCM_WRITE_FILTER:
241 if (IOCTL_IN (arg) > 1)
242 return IOCTL_OUT (arg, RET_ERROR (EINVAL));
243 default:
244 return RET_ERROR (EINVAL);
245 }
246
247 return RET_ERROR (EINVAL);
248 }
249
250 static int
251 sb16_dsp_open (int dev, int mode)
252 {
253 int retval;
254
255 DEB(printk("sb16_dsp_open()\n"));
256 if (!sb16_dsp_ok)
257 {
258 printk ("SB16 Error: SoundBlaster board not installed\n");
259 return RET_ERROR(ENODEV);
260 }
261
262 if (intr_active)
263 return RET_ERROR(EBUSY);
264
265 retval = sb_get_irq ();
266 if (retval<0)
267 return retval;
268
269 if (ALLOC_DMA_CHN (dma8))
270 {
271 printk ("SB16: Unable to grab DMA%d\n", dma8);
272 sb_free_irq();
273 return RET_ERROR(EBUSY);
274 }
275
276 if (dma16 != dma8)
277 if (ALLOC_DMA_CHN (dma16))
278 {
279 printk ("SB16: Unable to grab DMA%d\n", dma16);
280 sb_free_irq();
281 RELEASE_DMA_CHN (dma8);
282 return RET_ERROR(EBUSY);
283 }
284
285 dsp_ini2();
286
287 irq_mode = IMODE_NONE;
288 dsp_busy = 1;
289
290 return 0;
291 }
292
293 static void
294 sb16_dsp_close (int dev)
295 {
296 unsigned long flags;
297 DEB(printk("sb16_dsp_close()\n"));
298 sb_dsp_command01(0xd9);
299 sb_dsp_command01(0xd5);
300
301 DISABLE_INTR (flags);
302 RELEASE_DMA_CHN (dma8);
303
304 if (dma16 != dma8)
305 RELEASE_DMA_CHN (dma16);
306 sb_free_irq ();
307 dsp_cleanup ();
308 dsp_busy = 0;
309 RESTORE_INTR (flags);
310 }
311
312 static void
313 sb16_dsp_output_block (int dev, unsigned long buf, int count,int intrflag, int dma_restart)
314 {
315 unsigned long flags, cnt;
316
317 cnt = count;
318 if (dsp_16bit)
319 cnt >>= 1;
320 cnt--;
321
322 #ifdef DEB_DMARES
323 printk("output_block: %x %d %d\n",buf,count,intrflag);
324 if(intrflag) {
325 int pos,chan=sound_dsp_dmachan[dev];
326 DISABLE_INTR (flags);
327 clear_dma_ff(chan);
328 disable_dma(chan);
329 pos=get_dma_residue(chan);
330 enable_dma(chan);
331 RESTORE_INTR (flags);
332 printk("dmapos=%d %x\n",pos,pos);
333 }
334 #endif
335 if (sound_dma_automode[dev] &&
336 intrflag &&
337 cnt == dsp_count) {
338 irq_mode = IMODE_OUTPUT;
339 intr_active = 1;
340 return;
341 }
342 DISABLE_INTR (flags);
343
344 if (dma_restart)
345 {
346 sb16_dsp_halt(dev);
347 DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
348 }
349 sb_dsp_command (0x41);
350 sb_dsp_command ((unsigned char)((dsp_current_speed >> 8) & 0xff));
351 sb_dsp_command ((unsigned char)(dsp_current_speed & 0xff));
352 sb_dsp_command ((unsigned char)(dsp_16bit ? 0xb6 : 0xc6));
353 sb_dsp_command ((unsigned char)((dsp_stereo ? 0x20 : 0) +
354 (dsp_16bit ? 0x10:0)));
355 sb_dsp_command01 ((unsigned char)(cnt&0xff));
356 sb_dsp_command ((unsigned char)(cnt>>8));
357
358
359
360 RESTORE_INTR (flags);
361 dsp_count=cnt;
362 irq_mode = IMODE_OUTPUT;
363 intr_active = 1;
364 }
365
366 static void
367 sb16_dsp_start_input (int dev, unsigned long buf, int count,int intrflag, int dma_restart)
368 {
369 unsigned long flags, cnt;
370
371 cnt = count;
372 if (dsp_16bit)
373 cnt >>= 1;
374 cnt--;
375
376 #ifdef DEB_DMARES
377 printk("start_input: %x %d %d\n",buf,count,intrflag);
378 if(intrflag) {
379 int pos,chan=sound_dsp_dmachan[dev];
380 DISABLE_INTR (flags);
381 clear_dma_ff(chan);
382 disable_dma(chan);
383 pos=get_dma_residue(chan);
384 enable_dma(chan);
385 RESTORE_INTR (flags);
386 printk("dmapos=%d %x\n",pos,pos);
387 }
388 #endif
389 if (sound_dma_automode[dev] &&
390 intrflag &&
391 cnt == dsp_count) {
392 irq_mode = IMODE_INPUT;
393 intr_active = 1;
394 return;
395 }
396 DISABLE_INTR (flags);
397
398 if (dma_restart)
399 {
400 sb16_dsp_halt(dev);
401 DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
402 }
403
404 sb_dsp_command (0x42);
405 sb_dsp_command ((unsigned char)((dsp_current_speed >> 8) & 0xff));
406 sb_dsp_command ((unsigned char)(dsp_current_speed & 0xff));
407 sb_dsp_command ((unsigned char)(dsp_16bit ? 0xbe : 0xce));
408 sb_dsp_command ((unsigned char)((dsp_stereo ? 0x20 : 0) +
409 (dsp_16bit ? 0x10:0)));
410 sb_dsp_command01 ((unsigned char)(cnt&0xff));
411 sb_dsp_command ((unsigned char)(cnt>>8));
412
413
414
415 RESTORE_INTR (flags);
416 dsp_count=cnt;
417 irq_mode = IMODE_INPUT;
418 intr_active = 1;
419 }
420
421 static int
422 sb16_dsp_prepare_for_input (int dev, int bsize, int bcount)
423 {
424 sound_dsp_dmachan[my_dev] = dsp_16bit? dma16:dma8;
425 dsp_count = 0;
426 dsp_cleanup ();
427 return 0;
428 }
429
430 static int
431 sb16_dsp_prepare_for_output (int dev, int bsize, int bcount)
432 {
433 sound_dsp_dmachan[my_dev] = dsp_16bit? dma16:dma8;
434 dsp_count = 0;
435 dsp_cleanup ();
436 return 0;
437 }
438
439 static void
440 dsp_cleanup (void)
441 {
442 irq_mode = IMODE_NONE;
443 intr_active = 0;
444 }
445
446 static void
447 sb16_dsp_reset (int dev)
448 {
449 unsigned long flags;
450
451 DISABLE_INTR (flags);
452
453 sb_reset_dsp ();
454 dsp_cleanup ();
455
456 RESTORE_INTR (flags);
457 }
458
459 static void
460 sb16_dsp_halt (int dev)
461 {
462 sb_dsp_command01(0xd9);
463 sb_dsp_command01(0xd5);
464 }
465
466 static void
467 set_irq_hw(int level) {
468 int ival;
469 switch(level) {
470 case 5:
471 ival=2; break;
472 case 7:
473 ival=4; break;
474 case 10:
475 ival=8; break;
476 default:
477 printk("SB16_IRQ_LEVEL %d does not exist\n",level);
478 return;
479 }
480 sb_setmixer(IRQ_NR,ival);
481 }
482
483 long
484 sb16_dsp_init (long mem_start, struct address_info *hw_config)
485 {
486 int i, major, minor;
487
488 major = minor = 0;
489 sb_dsp_command (0xe1);
490
491 for (i = 1000; i; i--) {
492 if (INB (DSP_DATA_AVAIL) & 0x80)
493 {
494 if (major == 0)
495 major = INB (DSP_READ);
496 else
497 {
498 minor = INB (DSP_READ);
499 break;
500 }
501 }
502 }
503
504 #ifndef SCO
505 sprintf (sb16_dsp_operations.name, "SoundBlaster 16 %d.%d", major, minor);
506 #endif
507
508 printk (" <%s>", sb16_dsp_operations.name);
509
510 if (num_dspdevs < MAX_DSP_DEV)
511 {
512 dsp_devs[my_dev = num_dspdevs++] = &sb16_dsp_operations;
513 sound_dsp_dmachan[my_dev] = hw_config->dma;
514 sound_buffcounts[my_dev] = 1;
515 sound_buffsizes[my_dev] = DSP_BUFFSIZE;
516 sound_dma_automode[my_dev] = 1;
517 }
518 else
519 printk ("SB: Too many DSP devices available\n");
520 sb16_dsp_ok = 1;
521 return mem_start;
522 }
523
524 int
525 sb16_dsp_detect (struct address_info *hw_config)
526 {
527 struct address_info *sb_config;
528
529 if (sb16_dsp_ok)
530 return 1;
531
532 if (!(sb_config=sound_getconf(SNDCARD_SB)))
533 {
534 printk("SB16 Error: Plain SB not configured\n");
535 return 0;
536 }
537
538 if (sbc_base != hw_config->io_base)
539 printk("Warning! SB16 I/O != SB I/O\n");
540
541
542
543
544
545 if (!sb_reset_dsp ())
546 return 0;
547
548 if (hw_config->irq != sb_config->irq)
549 {
550 printk("SB16 Error: Invalid IRQ number %d/%d\n",
551 sb_config->irq, hw_config->irq);
552 return 0;
553 }
554
555 if (hw_config->dma < 4)
556 if (hw_config->dma != sb_config->dma)
557 {
558 printk("SB16 Error: Invalid DMA channel %d/%d\n",
559 sb_config->dma, hw_config->dma);
560 return 0;
561 }
562
563 dma16 = hw_config->dma;
564 dma8 = sb_config->dma;
565 set_irq_hw(hw_config->irq);
566 sb_setmixer(DMA_NR, (1<<hw_config->dma) | (1<<sb_config->dma));
567
568 DEB(printk ("SoundBlaster 16: IRQ %d DMA %d OK\n",hw_config->irq,hw_config->dma));
569
570
571
572
573 sb16_dsp_ok = 1;
574 return 1;
575 }
576
577 void
578 sb16_dsp_interrupt (int unused)
579 {
580 int data;
581 data = INB (DSP_DATA_AVL16);
582
583 if (intr_active)
584 switch (irq_mode)
585 {
586 case IMODE_OUTPUT:
587 intr_active = 0;
588 DMAbuf_outputintr (my_dev, 1);
589 break;
590
591 case IMODE_INPUT:
592 intr_active = 0;
593 DMAbuf_inputintr (my_dev);
594 break;
595
596 default:
597 printk ("SoundBlaster: Unexpected interrupt\n");
598 }
599 }
600 #endif