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