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 copr_msg *buf;
524 unsigned long flags;
525 unsigned short *data;
526 unsigned short tmp;
527 int i;
528
529 buf = (copr_msg *) kmalloc (sizeof (copr_msg), GFP_KERNEL);
530 if (buf == NULL)
531 return -ENOSPC;
532
533 memcpy_fromfs ((char *) buf, &(((char *) arg)[0]), sizeof (*buf));
534
535 data = (unsigned short *) (buf->data);
536
537
538
539 save_flags (flags);
540 cli ();
541
542 for (i = 0; i < buf->len; i++)
543 {
544 tmp = *data++;
545 if (!pss_put_dspword (devc, tmp))
546 {
547 restore_flags (flags);
548 buf->len = i;
549 memcpy_tofs ((&((char *) arg)[0]), &buf, sizeof (buf));
550 kfree (buf);
551 return -EIO;
552 }
553 }
554
555 restore_flags (flags);
556 kfree (buf);
557
558 return 0;
559 }
560 break;
561
562
563 case SNDCTL_COPR_RCVMSG:
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
575 memcpy_fromfs ((char *) buf, &(((char *) arg)[0]), sizeof (*buf));
576
577 data = (unsigned short *) buf->data;
578
579 save_flags (flags);
580 cli ();
581
582 for (i = 0; i < buf->len; i++)
583 {
584 if (!pss_get_dspword (devc, data++))
585 {
586 buf->len = i;
587 err = -EIO;
588 break;
589 }
590 }
591
592 restore_flags (flags);
593
594 memcpy_tofs ((&((char *) arg)[0]), &buf, sizeof (buf));
595 kfree (buf);
596
597 return err;
598 }
599 break;
600
601
602 case SNDCTL_COPR_RDATA:
603 {
604 copr_debug_buf buf;
605 unsigned long flags;
606 unsigned short tmp;
607
608 memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
609
610 save_flags (flags);
611 cli ();
612 if (!pss_put_dspword (devc, 0x00d0))
613 {
614 restore_flags (flags);
615 return -EIO;
616 }
617
618 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
619 {
620 restore_flags (flags);
621 return -EIO;
622 }
623
624 if (!pss_get_dspword (devc, &tmp))
625 {
626 restore_flags (flags);
627 return -EIO;
628 }
629
630 buf.parm1 = tmp;
631 restore_flags (flags);
632
633 memcpy_tofs ((&((char *) arg)[0]), &buf, sizeof (buf));
634 return 0;
635 }
636 break;
637
638 case SNDCTL_COPR_WDATA:
639 {
640 copr_debug_buf buf;
641 unsigned long flags;
642 unsigned short tmp;
643
644 memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
645
646 save_flags (flags);
647 cli ();
648 if (!pss_put_dspword (devc, 0x00d1))
649 {
650 restore_flags (flags);
651 return -EIO;
652 }
653
654 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
655 {
656 restore_flags (flags);
657 return -EIO;
658 }
659
660 tmp = (unsigned int) buf.parm2 & 0xffff;
661 if (!pss_put_dspword (devc, tmp))
662 {
663 restore_flags (flags);
664 return -EIO;
665 }
666
667 restore_flags (flags);
668 return 0;
669 }
670 break;
671
672 case SNDCTL_COPR_WCODE:
673 {
674 copr_debug_buf buf;
675 unsigned long flags;
676 unsigned short tmp;
677
678 memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
679
680 save_flags (flags);
681 cli ();
682 if (!pss_put_dspword (devc, 0x00d3))
683 {
684 restore_flags (flags);
685 return -EIO;
686 }
687
688 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
689 {
690 restore_flags (flags);
691 return -EIO;
692 }
693
694 tmp = (unsigned int) buf.parm2 & 0x00ff;
695 if (!pss_put_dspword (devc, tmp))
696 {
697 restore_flags (flags);
698 return -EIO;
699 }
700
701 tmp = ((unsigned int) buf.parm2 >> 8) & 0xffff;
702 if (!pss_put_dspword (devc, tmp))
703 {
704 restore_flags (flags);
705 return -EIO;
706 }
707
708 restore_flags (flags);
709 return 0;
710 }
711 break;
712
713 case SNDCTL_COPR_RCODE:
714 {
715 copr_debug_buf buf;
716 unsigned long flags;
717 unsigned short tmp;
718
719 memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
720
721 save_flags (flags);
722 cli ();
723 if (!pss_put_dspword (devc, 0x00d2))
724 {
725 restore_flags (flags);
726 return -EIO;
727 }
728
729 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
730 {
731 restore_flags (flags);
732 return -EIO;
733 }
734
735 if (!pss_get_dspword (devc, &tmp))
736 {
737 restore_flags (flags);
738 return -EIO;
739 }
740
741 buf.parm1 = tmp << 8;
742
743 if (!pss_get_dspword (devc, &tmp))
744 {
745 restore_flags (flags);
746 return -EIO;
747 }
748
749 buf.parm1 |= tmp & 0x00ff;
750
751 restore_flags (flags);
752
753 memcpy_tofs ((&((char *) arg)[0]), &buf, sizeof (buf));
754 return 0;
755 }
756 break;
757
758 default:
759 return -EINVAL;
760 }
761
762 return -EINVAL;
763 }
764
765 static coproc_operations pss_coproc_operations =
766 {
767 "ADSP-2115",
768 pss_coproc_open,
769 pss_coproc_close,
770 pss_coproc_ioctl,
771 pss_coproc_reset,
772 &pss_data
773 };
774
775 long
776 attach_pss_mpu (long mem_start, struct address_info *hw_config)
777 {
778 long ret;
779
780 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
781 {
782 int prev_devs;
783 prev_devs = num_midis;
784 ret = attach_mpu401 (mem_start, hw_config);
785
786 if (num_midis == (prev_devs + 1))
787 midi_devs[prev_devs]->coproc = &pss_coproc_operations;
788 }
789 #endif
790 return ret;
791 }
792
793 int
794 probe_pss_mss (struct address_info *hw_config)
795 {
796 int timeout;
797
798 if (!pss_initialized)
799 return 0;
800
801 if (check_region (hw_config->io_base, 8))
802 {
803 printk ("PSS: WSS I/O port conflict\n");
804 return 0;
805 }
806
807 if (!set_io_base (devc, CONF_WSS, hw_config->io_base))
808 {
809 printk ("PSS: WSS base error.\n");
810 return 0;
811 }
812
813 if (!set_irq (devc, CONF_WSS, hw_config->irq))
814 {
815 printk ("PSS: WSS IRQ error.\n");
816 return 0;
817 }
818
819 if (!set_dma (devc, CONF_WSS, hw_config->dma))
820 {
821 printk ("PSS: WSS DRQ error\n");
822 return 0;
823 }
824
825
826
827
828
829
830
831 for (timeout = 0;
832 timeout < 100000 && (inb (hw_config->io_base + 3) & 0x3f) != 0x04;
833 timeout++);
834
835 outb (0x0b, hw_config->io_base + 4);
836 return probe_ms_sound (hw_config);
837 }
838
839 long
840 attach_pss_mss (long mem_start, struct address_info *hw_config)
841 {
842 int prev_devs;
843 long ret;
844
845 prev_devs = num_audiodevs;
846 ret = attach_ms_sound (mem_start, hw_config);
847
848 if (num_audiodevs == (prev_devs + 1))
849 audio_devs[prev_devs]->coproc = &pss_coproc_operations;
850
851 return ret;
852 }
853
854 void
855 unload_pss (struct address_info *hw_config)
856 {
857 }
858
859 void
860 unload_pss_mpu (struct address_info *hw_config)
861 {
862 unload_mpu401 (hw_config);
863 }
864
865 void
866 unload_pss_mss (struct address_info *hw_config)
867 {
868 unload_ms_sound (hw_config);
869 }
870
871 #endif