This source file includes following definitions.
- probe_pss
- set_irq
- set_io_base
- set_dma
- pss_reset_dsp
- pss_put_dspword
- pss_get_dspword
- pss_download_boot
- attach_pss
- probe_pss_mpu
- pss_coproc_open
- pss_coproc_close
- pss_coproc_reset
- download_boot_block
- pss_coproc_ioctl
- attach_pss_mpu
- probe_pss_mss
- attach_pss_mss
- unload_pss
- unload_pss_mpu
- unload_pss_mss
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 #include "sound_config.h"
31
32 #if defined (CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PSS) && !defined(EXCLUDE_AUDIO)
33
34
35
36
37 #define REG(x) (devc->base+x)
38 #define PSS_DATA 0
39 #define PSS_STATUS 2
40 #define PSS_CONTROL 2
41 #define PSS_ID 4
42 #define PSS_IRQACK 4
43 #define PSS_PIO 0x1a
44
45
46
47
48 #define CONF_PSS 0x10
49 #define CONF_WSS 0x12
50 #define CONF_SB 0x13
51 #define CONF_CDROM 0x16
52 #define CONF_MIDI 0x18
53
54
55
56
57 #define PSS_FLAG3 0x0800
58 #define PSS_FLAG2 0x0400
59 #define PSS_FLAG1 0x1000
60 #define PSS_FLAG0 0x0800
61 #define PSS_WRITE_EMPTY 0x8000
62 #define PSS_READ_FULL 0x4000
63
64 #include "coproc.h"
65
66 #ifdef PSS_HAVE_LD
67 #include "synth-ld.h"
68 #else
69 static int pss_synthLen = 0;
70 static unsigned char pss_synth[1] =
71 {0};
72
73 #endif
74
75 typedef struct pss_config
76 {
77 int base;
78 int irq;
79 int dma;
80 sound_os_info *osp;
81 }
82
83 pss_config;
84
85 static pss_config pss_data;
86 static pss_config *devc = &pss_data;
87
88 static int pss_initialized = 0;
89 static int nonstandard_microcode = 0;
90
91 int
92 probe_pss (struct address_info *hw_config)
93 {
94 unsigned short id;
95 int irq, dma;
96
97 devc->base = hw_config->io_base;
98 irq = devc->irq = hw_config->irq;
99 dma = devc->dma = hw_config->dma;
100 devc->osp = hw_config->osp;
101
102 if (devc->base != 0x220 && devc->base != 0x240)
103 if (devc->base != 0x230 && devc->base != 0x250)
104 return 0;
105
106 if (check_region (devc->base, 16))
107 {
108 printk ("PSS: I/O port conflict\n");
109 return 0;
110 }
111
112 if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
113 irq != 10 && irq != 11 && irq != 12)
114 return 0;
115
116 if (dma != 5 && dma != 6 && dma != 7)
117 return 0;
118
119 id = inw (REG (PSS_ID));
120 if ((id >> 8) != 'E')
121 {
122
123 return 0;
124 }
125
126 return 1;
127 }
128
129 static int
130 set_irq (pss_config * devc, int dev, int irq)
131 {
132 static unsigned short irq_bits[16] =
133 {
134 0x0000, 0x0000, 0x0000, 0x0008,
135 0x0000, 0x0010, 0x0000, 0x0018,
136 0x0000, 0x0020, 0x0028, 0x0030,
137 0x0038, 0x0000, 0x0000, 0x0000
138 };
139
140 unsigned short tmp, bits;
141
142 if (irq < 0 || irq > 15)
143 return 0;
144
145 tmp = inw (REG (dev)) & ~0x38;
146
147 if ((bits = irq_bits[irq]) == 0 && irq != 0)
148 {
149 printk ("PSS: Invalid IRQ %d\n", irq);
150 return 0;
151 }
152
153 outw (tmp | bits, REG (dev));
154 return 1;
155 }
156
157 static int
158 set_io_base (pss_config * devc, int dev, int base)
159 {
160 unsigned short tmp = inw (REG (dev)) & 0x003f;
161 unsigned short bits = (base & 0x0ffc) << 4;
162
163 outw (bits | tmp, REG (dev));
164
165 return 1;
166 }
167
168 static int
169 set_dma (pss_config * devc, int dev, int dma)
170 {
171 static unsigned short dma_bits[8] =
172 {
173 0x0001, 0x0002, 0x0000, 0x0003,
174 0x0000, 0x0005, 0x0006, 0x0007
175 };
176
177 unsigned short tmp, bits;
178
179 if (dma < 0 || dma > 7)
180 return 0;
181
182 tmp = inw (REG (dev)) & ~0x07;
183
184 if ((bits = dma_bits[dma]) == 0 && dma != 4)
185 {
186 printk ("PSS: Invalid DMA %d\n", dma);
187 return 0;
188 }
189
190 outw (tmp | bits, REG (dev));
191 return 1;
192 }
193
194 static int
195 pss_reset_dsp (pss_config * devc)
196 {
197 unsigned long i, limit = jiffies + 10;
198
199 outw (0x2000, REG (PSS_CONTROL));
200
201 for (i = 0; i < 32768 && jiffies < limit; i++)
202 inw (REG (PSS_CONTROL));
203
204 outw (0x0000, REG (PSS_CONTROL));
205
206 return 1;
207 }
208
209 static int
210 pss_put_dspword (pss_config * devc, unsigned short word)
211 {
212 int i, val;
213
214 for (i = 0; i < 327680; i++)
215 {
216 val = inw (REG (PSS_STATUS));
217 if (val & PSS_WRITE_EMPTY)
218 {
219 outw (word, REG (PSS_DATA));
220 return 1;
221 }
222 }
223 return 0;
224 }
225
226 static int
227 pss_get_dspword (pss_config * devc, unsigned short *word)
228 {
229 int i, val;
230
231 for (i = 0; i < 327680; i++)
232 {
233 val = inw (REG (PSS_STATUS));
234 if (val & PSS_READ_FULL)
235 {
236 *word = inw (REG (PSS_DATA));
237 return 1;
238 }
239 }
240
241 return 0;
242 }
243
244 static int
245 pss_download_boot (pss_config * devc, unsigned char *block, int size, int flags)
246 {
247 int i, limit, val, count;
248
249 if (flags & CPF_FIRST)
250 {
251
252 outw (0x00fe, REG (PSS_DATA));
253
254 limit = jiffies + 10;
255
256 for (i = 0; i < 32768 && jiffies < limit; i++)
257 if (inw (REG (PSS_DATA)) == 0x5500)
258 break;
259
260 outw (*block++, REG (PSS_DATA));
261
262 pss_reset_dsp (devc);
263 }
264
265 count = 1;
266 while (1)
267 {
268 int j;
269
270 for (j = 0; j < 327670; j++)
271 {
272
273 if (inw (REG (PSS_STATUS)) & PSS_FLAG3)
274 break;
275 }
276
277 if (j == 327670)
278 {
279
280 if (count >= size && flags & CPF_LAST)
281 break;
282 else
283 {
284 printk ("\nPSS: DownLoad timeout problems, byte %d=%d\n",
285 count, size);
286 return 0;
287 }
288 }
289
290 outw (*block++, REG (PSS_DATA));
291 count++;
292 }
293
294 if (flags & CPF_LAST)
295 {
296
297 outw (0, REG (PSS_DATA));
298
299 limit = jiffies + 10;
300 for (i = 0; i < 32768 && jiffies < limit; i++)
301 val = inw (REG (PSS_STATUS));
302
303 limit = jiffies + 10;
304 for (i = 0; i < 32768 && jiffies < limit; i++)
305 {
306 val = inw (REG (PSS_STATUS));
307 if (val & 0x4000)
308 break;
309 }
310
311
312 for (i = 0; i < 32000; i++)
313 {
314 val = inw (REG (PSS_STATUS));
315 if (val & PSS_READ_FULL)
316 break;
317 }
318 if (i == 32000)
319 return 0;
320
321 val = inw (REG (PSS_DATA));
322
323 }
324
325 return 1;
326 }
327
328 long
329 attach_pss (long mem_start, struct address_info *hw_config)
330 {
331 unsigned short id;
332
333 devc->base = hw_config->io_base;
334 devc->irq = hw_config->irq;
335 devc->dma = hw_config->dma;
336 devc->osp = hw_config->osp;
337
338 if (!probe_pss (hw_config))
339 return mem_start;
340
341 id = inw (REG (PSS_ID)) & 0x00ff;
342
343
344
345
346 outw (0x0000, REG (CONF_PSS));
347 outw (0x0000, REG (CONF_WSS));
348 outw (0x0000, REG (CONF_SB));
349 outw (0x0000, REG (CONF_MIDI));
350 outw (0x0000, REG (CONF_CDROM));
351
352 #if YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
353 if (sound_alloc_dma (hw_config->dma, "PSS"))
354 {
355 printk ("pss.c: Can't allocate DMA channel\n");
356 return mem_start;
357 }
358
359 if (!set_irq (devc, CONF_PSS, devc->irq))
360 {
361 printk ("PSS: IRQ error\n");
362 return mem_start;
363 }
364
365 if (!set_dma (devc, CONF_PSS, devc->dma))
366 {
367 printk ("PSS: DRQ error\n");
368 return mem_start;
369 }
370 #endif
371
372 pss_initialized = 1;
373 printk (" <ECHO-PSS Rev. %d>", id);
374
375 return mem_start;
376 }
377
378 int
379 probe_pss_mpu (struct address_info *hw_config)
380 {
381 int timeout;
382
383 if (!pss_initialized)
384 return 0;
385
386 if (check_region (hw_config->io_base, 2))
387 {
388 printk ("PSS: MPU I/O port conflict\n");
389 return 0;
390 }
391
392 if (!set_io_base (devc, CONF_MIDI, hw_config->io_base))
393 {
394 printk ("PSS: MIDI base error.\n");
395 return 0;
396 }
397
398 if (!set_irq (devc, CONF_MIDI, hw_config->irq))
399 {
400 printk ("PSS: MIDI IRQ error.\n");
401 return 0;
402 }
403
404 if (!pss_synthLen)
405 {
406 printk ("PSS: Can't enable MPU. MIDI synth microcode not available.\n");
407 return 0;
408 }
409
410 if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
411 {
412 printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
413 return 0;
414 }
415
416
417
418
419
420
421 for (timeout = 900000; timeout > 0; timeout--)
422 {
423 if ((inb (hw_config->io_base + 1) & 0x80) == 0)
424 inb (hw_config->io_base);
425 else
426 break;
427 }
428
429 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
430 return probe_mpu401 (hw_config);
431 #else
432 return 0
433 #endif
434 }
435
436 static int
437 pss_coproc_open (void *dev_info, int sub_device)
438 {
439 switch (sub_device)
440 {
441 case COPR_MIDI:
442
443 if (pss_synthLen == 0)
444 {
445 printk ("PSS: MIDI synth microcode not available.\n");
446 return -EIO;
447 }
448
449 if (nonstandard_microcode)
450 if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
451 {
452 printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
453 return -EIO;
454 }
455 nonstandard_microcode = 0;
456 break;
457
458 default:;
459 }
460 return 0;
461 }
462
463 static void
464 pss_coproc_close (void *dev_info, int sub_device)
465 {
466 return;
467 }
468
469 static void
470 pss_coproc_reset (void *dev_info)
471 {
472 if (pss_synthLen)
473 if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
474 {
475 printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
476 }
477 nonstandard_microcode = 0;
478 }
479
480 static int
481 download_boot_block (void *dev_info, copr_buffer * buf)
482 {
483 if (buf->len <= 0 || buf->len > sizeof (buf->data))
484 return -EINVAL;
485
486 if (!pss_download_boot (devc, buf->data, buf->len, buf->flags))
487 {
488 printk ("PSS: Unable to load microcode block to DSP.\n");
489 return -EIO;
490 }
491 nonstandard_microcode = 1;
492
493 return 0;
494 }
495
496 static int
497 pss_coproc_ioctl (void *dev_info, unsigned int cmd, ioctl_arg arg, int local)
498 {
499
500
501 switch (cmd)
502 {
503 case SNDCTL_COPR_RESET:
504 pss_coproc_reset (dev_info);
505 return 0;
506 break;
507
508 case SNDCTL_COPR_LOAD:
509 {
510 copr_buffer *buf;
511 int err;
512
513 buf = (copr_buffer *) kmalloc (sizeof (copr_buffer), GFP_KERNEL);
514 if (buf == NULL)
515 return -ENOSPC;
516
517 memcpy_fromfs ((char *) buf, &(((char *) arg)[0]), sizeof (*buf));
518 err = download_boot_block (dev_info, buf);
519 kfree (buf);
520 return err;
521 }
522 break;
523
524 case SNDCTL_COPR_RDATA:
525 {
526 copr_debug_buf buf;
527 unsigned long flags;
528 unsigned short tmp;
529
530 memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
531
532 save_flags (flags);
533 cli ();
534 if (!pss_put_dspword (devc, 0x00d0))
535 {
536 restore_flags (flags);
537 return -EIO;
538 }
539
540 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
541 {
542 restore_flags (flags);
543 return -EIO;
544 }
545
546 if (!pss_get_dspword (devc, &tmp))
547 {
548 restore_flags (flags);
549 return -EIO;
550 }
551
552 buf.parm1 = tmp;
553 restore_flags (flags);
554
555 memcpy_tofs ((&((char *) arg)[0]), &buf, sizeof (buf));
556 return 0;
557 }
558 break;
559
560 case SNDCTL_COPR_WDATA:
561 {
562 copr_debug_buf buf;
563 unsigned long flags;
564 unsigned short tmp;
565
566 memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
567
568 save_flags (flags);
569 cli ();
570 if (!pss_put_dspword (devc, 0x00d1))
571 {
572 restore_flags (flags);
573 return -EIO;
574 }
575
576 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
577 {
578 restore_flags (flags);
579 return -EIO;
580 }
581
582 tmp = (unsigned int) buf.parm2 & 0xffff;
583 if (!pss_put_dspword (devc, tmp))
584 {
585 restore_flags (flags);
586 return -EIO;
587 }
588
589 restore_flags (flags);
590 return 0;
591 }
592 break;
593
594 case SNDCTL_COPR_WCODE:
595 {
596 copr_debug_buf buf;
597 unsigned long flags;
598 unsigned short tmp;
599
600 memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
601
602 save_flags (flags);
603 cli ();
604 if (!pss_put_dspword (devc, 0x00d3))
605 {
606 restore_flags (flags);
607 return -EIO;
608 }
609
610 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
611 {
612 restore_flags (flags);
613 return -EIO;
614 }
615
616 tmp = ((unsigned int) buf.parm2 >> 8) & 0xffff;
617 if (!pss_put_dspword (devc, tmp))
618 {
619 restore_flags (flags);
620 return -EIO;
621 }
622
623 tmp = (unsigned int) buf.parm2 & 0x00ff;
624 if (!pss_put_dspword (devc, tmp))
625 {
626 restore_flags (flags);
627 return -EIO;
628 }
629
630 restore_flags (flags);
631 return 0;
632 }
633 break;
634
635 case SNDCTL_COPR_RCODE:
636 {
637 copr_debug_buf buf;
638 unsigned long flags;
639 unsigned short tmp;
640
641 memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
642
643 save_flags (flags);
644 cli ();
645 if (!pss_put_dspword (devc, 0x00d2))
646 {
647 restore_flags (flags);
648 return -EIO;
649 }
650
651 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
652 {
653 restore_flags (flags);
654 return -EIO;
655 }
656
657 if (!pss_get_dspword (devc, &tmp))
658 {
659 restore_flags (flags);
660 return -EIO;
661 }
662
663 buf.parm1 = tmp << 8;
664
665 if (!pss_get_dspword (devc, &tmp))
666 {
667 restore_flags (flags);
668 return -EIO;
669 }
670
671 buf.parm1 |= tmp & 0x00ff;
672
673 restore_flags (flags);
674
675 memcpy_tofs ((&((char *) arg)[0]), &buf, sizeof (buf));
676 return 0;
677 }
678 break;
679
680 default:
681 return -EINVAL;
682 }
683
684 return -EINVAL;
685 }
686
687 static coproc_operations pss_coproc_operations =
688 {
689 "ADSP-2115",
690 pss_coproc_open,
691 pss_coproc_close,
692 pss_coproc_ioctl,
693 pss_coproc_reset,
694 &pss_data
695 };
696
697 long
698 attach_pss_mpu (long mem_start, struct address_info *hw_config)
699 {
700 int prev_devs;
701 long ret;
702
703 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
704 prev_devs = num_midis;
705 ret = attach_mpu401 (mem_start, hw_config);
706
707 if (num_midis == (prev_devs + 1))
708 midi_devs[prev_devs]->coproc = &pss_coproc_operations;
709 #endif
710 return ret;
711 }
712
713 int
714 probe_pss_mss (struct address_info *hw_config)
715 {
716 int timeout;
717
718 if (!pss_initialized)
719 return 0;
720
721 if (check_region (hw_config->io_base, 8))
722 {
723 printk ("PSS: WSS I/O port conflict\n");
724 return 0;
725 }
726
727 if (!set_io_base (devc, CONF_WSS, hw_config->io_base))
728 {
729 printk ("PSS: WSS base error.\n");
730 return 0;
731 }
732
733 if (!set_irq (devc, CONF_WSS, hw_config->irq))
734 {
735 printk ("PSS: WSS IRQ error.\n");
736 return 0;
737 }
738
739 if (!set_dma (devc, CONF_WSS, hw_config->dma))
740 {
741 printk ("PSS: WSS DRQ error\n");
742 return 0;
743 }
744
745
746
747
748
749
750
751 for (timeout = 0;
752 timeout < 100000 && (inb (hw_config->io_base + 3) & 0x3f) != 0x04;
753 timeout++);
754
755 return probe_ms_sound (hw_config);
756 }
757
758 long
759 attach_pss_mss (long mem_start, struct address_info *hw_config)
760 {
761 int prev_devs;
762 long ret;
763
764 prev_devs = num_audiodevs;
765 ret = attach_ms_sound (mem_start, hw_config);
766
767 if (num_audiodevs == (prev_devs + 1))
768 audio_devs[prev_devs]->coproc = &pss_coproc_operations;
769
770 return ret;
771 }
772
773 void
774 unload_pss (struct address_info *hw_config)
775 {
776 }
777
778 void
779 unload_pss_mpu (struct address_info *hw_config)
780 {
781 unload_mpu401 (hw_config);
782 }
783
784 void
785 unload_pss_mss (struct address_info *hw_config)
786 {
787 unload_ms_sound (hw_config);
788 }
789
790 #endif