This source file includes following definitions.
- pss_outpw
- pss_inpw
- PSS_write
- pss_setaddr
- pss_checkint
- pss_setint
- pss_setsbint
- pss_setsbdma
- pss_setwssdma
- pss_setspeaker
- pss_init1848
- pss_configure_registers_to_look_like_sb
- attach_pss
- probe_pss
- pss_reattach
- pss_reset_dsp
- pss_download_boot
- pss_open
- pss_release
- pss_read
- pss_write
- pss_ioctl
- pss_select
- pss_init
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 #include "sound_config.h"
49
50 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PSS)
51
52 #ifndef PSS_MSS_BASE
53 #define PSS_MSS_BASE 0
54 #endif
55
56 #ifndef PSS_MPU_BASE
57 #define PSS_MPU_BASE 0
58 #endif
59
60 #ifndef PSS_MPU_IRQ
61 #define PSS_MPU_IRQ 0
62 #endif
63
64 #undef DEB
65 #define DEB(x) x
66
67 #include "pss.h"
68
69 static int pss_ok = 0;
70 static int sb_ok = 0;
71
72 static int pss_base;
73 static int pss_irq;
74 static int pss_dma;
75
76 static int gamePort = 0;
77
78 static int sbInt;
79 static int cdPol;
80 static int cdAddr = 0;
81 static int cdInt = 10;
82
83
84 static int wssAddr = PSS_MSS_BASE;
85 static int midiAddr = PSS_MPU_BASE;
86 static int midiInt = PSS_MPU_IRQ;
87
88 static int SoundPortAddress;
89 static int SoundPortData;
90 static int speaker = 1;
91
92
93 static struct pss_speaker default_speaker =
94 {0, 0, 0, PSS_STEREO};
95
96 DEFINE_WAIT_QUEUE (pss_sleeper, pss_sleep_flag);
97
98 #include "synth-ld.h"
99
100 static int pss_download_boot (unsigned char *block, int size);
101 static int pss_reset_dsp (void);
102
103 static inline void
104 pss_outpw (unsigned short port, unsigned short value)
105 {
106 __asm__ __volatile__ ("outw %w0, %w1"
107 :
108 :"a" (value), "d" (port));
109 }
110
111 static inline unsigned int
112 pss_inpw (unsigned short port)
113 {
114 unsigned int _v;
115 __asm__ __volatile__ ("inw %w1,%w0"
116 :"=a" (_v):"d" (port), "0" (0));
117
118 return _v;
119 }
120
121 static void
122 PSS_write (int data)
123 {
124 int i, limit;
125
126 limit = GET_TIME () + 10;
127
128
129
130
131
132
133
134
135 for (i = 0; i < 5000000 && GET_TIME () < limit; i++)
136 {
137 if (pss_inpw (pss_base + PSS_STATUS) & PSS_WRITE_EMPTY)
138 {
139 pss_outpw (pss_base + PSS_DATA, data);
140 return;
141 }
142 }
143 printk ("PSS: DSP Command (%04x) Timeout.\n", data);
144 printk ("IRQ conflict???\n");
145 }
146
147
148 static void
149 pss_setaddr (int addr, int configAddr)
150 {
151 int val;
152
153 val = pss_inpw (configAddr);
154 val &= ADDR_MASK;
155 val |= (addr << 4);
156 pss_outpw (configAddr, val);
157 }
158
159
160
161
162
163
164
165 static int
166 pss_checkint (int intNum)
167 {
168 int val;
169 int ret;
170 int i;
171
172
173 switch (intNum)
174 {
175 case 3:
176 val = pss_inpw (pss_base + PSS_CONFIG);
177 val &= INT_MASK;
178 val |= INT_3_BITS;
179 pss_outpw (pss_base + PSS_CONFIG, val);
180 break;
181 case 5:
182 val = pss_inpw (pss_base + PSS_CONFIG);
183 val &= INT_MASK;
184 val |= INT_5_BITS;
185 pss_outpw (pss_base + PSS_CONFIG, val);
186 break;
187 case 7:
188 val = pss_inpw (pss_base + PSS_CONFIG);
189 val &= INT_MASK;
190 val |= INT_7_BITS;
191 pss_outpw (pss_base + PSS_CONFIG, val);
192 break;
193 case 9:
194 val = pss_inpw (pss_base + PSS_CONFIG);
195 val &= INT_MASK;
196 val |= INT_9_BITS;
197 pss_outpw (pss_base + PSS_CONFIG, val);
198 break;
199 case 10:
200 val = pss_inpw (pss_base + PSS_CONFIG);
201 val &= INT_MASK;
202 val |= INT_10_BITS;
203 pss_outpw (pss_base + PSS_CONFIG, val);
204 break;
205 case 11:
206 val = pss_inpw (pss_base + PSS_CONFIG);
207 val &= INT_MASK;
208 val |= INT_11_BITS;
209 pss_outpw (pss_base + PSS_CONFIG, val);
210 break;
211 case 12:
212 val = pss_inpw (pss_base + PSS_CONFIG);
213 val &= INT_MASK;
214 val |= INT_12_BITS;
215 pss_outpw (pss_base + PSS_CONFIG, val);
216 break;
217 default:
218 printk ("unknown interrupt selected. %d\n", intNum);
219 return 0;
220 }
221
222
223 val = pss_inpw (pss_base + PSS_CONFIG);
224 val |= INT_TEST_BIT;
225 pss_outpw (pss_base + PSS_CONFIG, val);
226
227
228
229 ret = 0;
230 for (i = 0; i < 5; i++)
231 {
232 val = pss_inpw (pss_base + PSS_CONFIG);
233 if (val & INT_TEST_PASS)
234 {
235 ret = 1;
236 break;
237 }
238 }
239
240 val = pss_inpw (pss_base + PSS_CONFIG);
241 val &= INT_TEST_BIT_MASK;
242 val &= INT_MASK;
243 pss_outpw (pss_base + PSS_CONFIG, val);
244 return (ret);
245 }
246
247
248
249
250
251
252 static void
253 pss_setint (int intNum, int configAddress)
254 {
255 int val;
256
257 switch (intNum)
258 {
259 case 0:
260 val = pss_inpw (configAddress);
261 val &= INT_MASK;
262 pss_outpw (configAddress, val);
263 break;
264 case 3:
265 val = pss_inpw (configAddress);
266 val &= INT_MASK;
267 val |= INT_3_BITS;
268 pss_outpw (configAddress, val);
269 break;
270 case 5:
271 val = pss_inpw (configAddress);
272 val &= INT_MASK;
273 val |= INT_5_BITS;
274 pss_outpw (configAddress, val);
275 break;
276 case 7:
277 val = pss_inpw (configAddress);
278 val &= INT_MASK;
279 val |= INT_7_BITS;
280 pss_outpw (configAddress, val);
281 break;
282 case 9:
283 val = pss_inpw (configAddress);
284 val &= INT_MASK;
285 val |= INT_9_BITS;
286 pss_outpw (configAddress, val);
287 break;
288 case 10:
289 val = pss_inpw (configAddress);
290 val &= INT_MASK;
291 val |= INT_10_BITS;
292 pss_outpw (configAddress, val);
293 break;
294 case 11:
295 val = pss_inpw (configAddress);
296 val &= INT_MASK;
297 val |= INT_11_BITS;
298 pss_outpw (configAddress, val);
299 break;
300 case 12:
301 val = pss_inpw (configAddress);
302 val &= INT_MASK;
303 val |= INT_12_BITS;
304 pss_outpw (configAddress, val);
305 break;
306 default:
307 printk ("pss_setint unknown int\n");
308 }
309 }
310
311
312
313
314
315
316
317
318 static void
319 pss_setsbint (int intNum)
320 {
321 int val;
322 int sbConfigAddress;
323
324 sbConfigAddress = pss_base + SB_CONFIG;
325 switch (intNum)
326 {
327 case 3:
328 val = pss_inpw (sbConfigAddress);
329 val &= INT_MASK;
330 val |= INT_3_BITS;
331 pss_outpw (sbConfigAddress, val);
332 break;
333 case 5:
334 val = pss_inpw (sbConfigAddress);
335 val &= INT_MASK;
336 val |= INT_5_BITS;
337 pss_outpw (sbConfigAddress, val);
338 break;
339 case 7:
340 val = pss_inpw (sbConfigAddress);
341 val &= INT_MASK;
342 val |= INT_7_BITS;
343 pss_outpw (sbConfigAddress, val);
344 break;
345 default:
346 printk ("pss_setsbint: unknown_int\n");
347 }
348 }
349
350
351
352
353
354
355
356 static void
357 pss_setsbdma (int dmaNum)
358 {
359 int val;
360 int sbConfigAddress;
361
362 sbConfigAddress = pss_base + SB_CONFIG;
363
364 switch (dmaNum)
365 {
366 case 1:
367 val = pss_inpw (sbConfigAddress);
368 val &= DMA_MASK;
369 val |= DMA_1_BITS;
370 pss_outpw (sbConfigAddress, val);
371 break;
372 default:
373 printk ("Personal Sound System ERROR! pss_setsbdma: unknown_dma\n");
374 }
375 }
376
377
378
379
380
381
382
383 static void
384 pss_setwssdma (int dmaNum)
385 {
386 int val;
387 int wssConfigAddress;
388
389 wssConfigAddress = pss_base + PSS_WSS_CONFIG;
390
391 switch (dmaNum)
392 {
393 case 0:
394 val = pss_inpw (wssConfigAddress);
395 val &= DMA_MASK;
396 val |= DMA_0_BITS;
397 pss_outpw (wssConfigAddress, val);
398 break;
399 case 1:
400 val = pss_inpw (wssConfigAddress);
401 val &= DMA_MASK;
402 val |= DMA_1_BITS;
403 pss_outpw (wssConfigAddress, val);
404 break;
405 case 3:
406 val = pss_inpw (wssConfigAddress);
407 val &= DMA_MASK;
408 val |= DMA_3_BITS;
409 pss_outpw (wssConfigAddress, val);
410 break;
411 default:
412 printk ("Personal Sound System ERROR! pss_setwssdma: unknown_dma\n");
413 }
414 }
415
416
417
418
419
420
421 void
422 pss_setspeaker (struct pss_speaker *spk)
423 {
424 PSS_write (SET_MASTER_COMMAND);
425 if (spk->volume > PHILLIPS_VOL_MAX)
426 spk->volume = PHILLIPS_VOL_MAX;
427 if (spk->volume < PHILLIPS_VOL_MIN)
428 spk->volume = PHILLIPS_VOL_MIN;
429
430 PSS_write (MASTER_VOLUME_LEFT
431 | (PHILLIPS_VOL_CONSTANT + spk->volume / PHILLIPS_VOL_STEP));
432 PSS_write (SET_MASTER_COMMAND);
433 PSS_write (MASTER_VOLUME_RIGHT
434 | (PHILLIPS_VOL_CONSTANT + spk->volume / PHILLIPS_VOL_STEP));
435
436 if (spk->bass > PHILLIPS_BASS_MAX)
437 spk->bass = PHILLIPS_BASS_MAX;
438 if (spk->bass < PHILLIPS_BASS_MIN)
439 spk->bass = PHILLIPS_BASS_MIN;
440 PSS_write (SET_MASTER_COMMAND);
441 PSS_write (MASTER_BASS
442 | (PHILLIPS_BASS_CONSTANT + spk->bass / PHILLIPS_BASS_STEP));
443
444 if (spk->treb > PHILLIPS_TREBLE_MAX)
445 spk->treb = PHILLIPS_TREBLE_MAX;
446 if (spk->treb < PHILLIPS_TREBLE_MIN)
447 spk->treb = PHILLIPS_TREBLE_MIN;
448 PSS_write (SET_MASTER_COMMAND);
449 PSS_write (MASTER_TREBLE
450 | (PHILLIPS_TREBLE_CONSTANT + spk->treb / PHILLIPS_TREBLE_STEP));
451
452 PSS_write (SET_MASTER_COMMAND);
453 PSS_write (MASTER_SWITCH | spk->mode);
454 }
455
456 static void
457 pss_init1848 (void)
458 {
459
460 while (INB (SoundPortAddress) & SP_IN_INIT);
461
462
463 OUTB (SoundPortAddress, SP_TEST_AND_INIT);
464 while (INB (SoundPortData) & AUTO_CAL_IN_PROG);
465 }
466
467 static int
468 pss_configure_registers_to_look_like_sb (void)
469 {
470 pss_setaddr (wssAddr, pss_base + PSS_WSS_CONFIG);
471
472 SoundPortAddress = wssAddr + 4;
473 SoundPortData = wssAddr + 5;
474
475 DEB (printk ("Turning Game Port %s.\n",
476 gamePort ? "On" : "Off"));
477
478
479 if (gamePort)
480 pss_outpw (pss_base + PSS_STATUS,
481 pss_inpw (pss_base + PSS_STATUS) | GAME_BIT);
482 else
483 pss_outpw (pss_base + PSS_STATUS,
484 pss_inpw (pss_base + PSS_STATUS) & GAME_BIT_MASK);
485
486
487 DEB (printk ("PSS attaching base %x irq %d dma %d\n",
488 pss_base, pss_irq, pss_dma));
489
490
491 pss_outpw (pss_base + SB_CONFIG, 0);
492
493 if (pss_irq != 0)
494 {
495 DEB (printk ("PSS Emulating Sound Blaster ADDR %04x\n", pss_base));
496 DEB (printk ("PSS SBC: attaching base %x irq %d dma %d\n",
497 SBC_BASE, SBC_IRQ, SBC_DMA));
498
499 if (pss_checkint (SBC_IRQ) == 0)
500 {
501 printk ("PSS! attach: int_error\n");
502 return 0;
503 }
504
505 pss_setsbint (SBC_IRQ);
506 pss_setsbdma (SBC_DMA);
507 sb_ok = 1;
508 }
509 else
510 {
511 sb_ok = 0;
512 printk ("PSS: sound blaster error init\n");
513 }
514
515
516 pss_outpw (pss_base + CD_CONFIG, 0);
517
518 if (cdAddr != 0)
519 {
520 DEB (printk ("PSS:CD drive %x irq: %d", cdAddr, cdInt));
521 if (cdInt != 0)
522 {
523 if (pss_checkint (cdInt) == 0)
524 {
525 printk ("Can't allocate cdInt %d\n", cdInt);
526 }
527 else
528 {
529 int val;
530
531 printk ("CD poll ");
532 pss_setaddr (cdAddr, pss_base + CD_CONFIG);
533 pss_setint (cdInt, pss_base + CD_CONFIG);
534
535
536
537
538
539
540
541 val = pss_inpw (pss_base + CD_CONFIG);
542 pss_outpw (pss_base + CD_CONFIG, 0);
543 val &= CD_POL_MASK;
544 if (cdPol)
545 val |= CD_POL_BIT;
546 pss_outpw (pss_base + CD_CONFIG, val);
547 }
548 }
549 }
550
551
552 pss_outpw (pss_base + MIDI_CONFIG, 0);
553 if (midiAddr != 0)
554 {
555 printk ("midi init %x %d\n", midiAddr, midiInt);
556 if (pss_checkint (midiInt) == 0)
557 {
558 printk ("midi init int error %x %d\n", midiAddr, midiInt);
559 }
560 else
561 {
562 pss_setaddr (midiAddr, pss_base + MIDI_CONFIG);
563 pss_setint (midiInt, pss_base + MIDI_CONFIG);
564 }
565 }
566 return 1;
567 }
568
569 long
570 attach_pss (long mem_start, struct address_info *hw_config)
571 {
572 if (pss_ok)
573 {
574 if (hw_config)
575 {
576 printk (" <PSS-ESC614>");
577 }
578
579 return mem_start;
580 }
581
582 pss_ok = 1;
583
584 if (pss_configure_registers_to_look_like_sb () == 0)
585 return mem_start;
586
587 if (sb_ok)
588 if (pss_synthLen
589 && pss_download_boot (pss_synth, pss_synthLen))
590 {
591 if (speaker)
592 pss_setspeaker (&default_speaker);
593 pss_ok = 1;
594 }
595 else
596 pss_reset_dsp ();
597
598 return mem_start;
599 }
600
601 int
602 probe_pss (struct address_info *hw_config)
603 {
604 pss_base = hw_config->io_base;
605 pss_irq = hw_config->irq;
606 pss_dma = hw_config->dma;
607
608 if ((pss_inpw (pss_base + 4) & 0xff00) == 0x4500)
609 {
610 attach_pss (0, hw_config);
611 return 1;
612 }
613 printk (" fail base %x irq %d dma %d\n", pss_base, pss_irq, pss_dma);
614 return 0;
615 }
616
617
618 static int
619 pss_reattach (void)
620 {
621 pss_ok = 0;
622 attach_pss (0, 0);
623 return 1;
624 }
625
626 static int
627 pss_reset_dsp ()
628 {
629 unsigned long i, limit = GET_TIME () + 10;
630
631 pss_outpw (pss_base + PSS_CONTROL, 0x2000);
632
633 for (i = 0; i < 32768 && GET_TIME () < limit; i++)
634 pss_inpw (pss_base + PSS_CONTROL);
635
636 pss_outpw (pss_base + PSS_CONTROL, 0x0000);
637
638 return 1;
639 }
640
641
642 static int
643 pss_download_boot (unsigned char *block, int size)
644 {
645 int i, limit, val, count;
646
647 printk ("PSS: downloading boot code synth.ld... ");
648
649
650 pss_outpw (pss_base + PSS_DATA, 0x00fe);
651
652 limit = GET_TIME () + 10;
653
654 for (i = 0; i < 32768 && GET_TIME () < limit; i++)
655 if (pss_inpw (pss_base + PSS_DATA) == 0x5500)
656 break;
657
658 pss_outpw (pss_base + PSS_DATA, *block++);
659
660 pss_reset_dsp ();
661 printk ("start ");
662
663 count = 1;
664 while (1)
665 {
666 int j;
667
668 for (j = 0; j < 327670; j++)
669 {
670
671 if (pss_inpw (pss_base + PSS_STATUS) & PSS_FLAG3)
672 break;
673 }
674
675 if (j == 327670)
676 {
677
678 if (count >= size)
679 break;
680 else
681 {
682 printk ("\nPSS: DownLoad timeout problems, byte %d=%d\n",
683 count, size);
684 return 0;
685 }
686 }
687
688 pss_outpw (pss_base + PSS_DATA, *block++);
689 count++;
690 }
691
692
693 pss_outpw (pss_base + PSS_DATA, 0);
694
695 limit = GET_TIME () + 10;
696 for (i = 0; i < 32768 && GET_TIME () < limit; i++)
697 val = pss_inpw (pss_base + PSS_STATUS);
698
699 printk ("downloaded\n");
700
701 limit = GET_TIME () + 10;
702 for (i = 0; i < 32768 && GET_TIME () < limit; i++)
703 {
704 val = pss_inpw (pss_base + PSS_STATUS);
705 if (val & 0x4000)
706 break;
707 }
708
709
710 for (i = 0; i < 32000; i++)
711 {
712 val = pss_inpw (pss_base + PSS_STATUS_REG);
713 if (val & PSS_READ_FULL)
714 break;
715 }
716 if (i == 32000)
717 return 0;
718
719 val = pss_inpw (pss_base + PSS_DATA_REG);
720
721 return 1;
722 }
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751 #define CODE_BUFFER_LEN (64*1024)
752 static char *code_buffer;
753 static int code_length;
754
755 static int lock_pss = 0;
756
757 int
758 pss_open (int dev, struct fileinfo *file)
759 {
760 int mode;
761
762 DEB (printk ("pss_open\n"));
763
764 if (pss_ok == 0)
765 return RET_ERROR (EIO);
766
767 if (lock_pss)
768 return 0;
769
770 lock_pss = 1;
771
772 dev = dev >> 4;
773 mode = file->mode & O_ACCMODE;
774 if (mode == O_WRONLY)
775 {
776 printk ("pss-open for WRONLY\n");
777 code_length = 0;
778 }
779
780 RESET_WAIT_QUEUE (pss_sleeper, pss_sleep_flag);
781 return 1;
782 }
783
784 void
785 pss_release (int dev, struct fileinfo *file)
786 {
787 int mode;
788
789 DEB (printk ("pss_release\n"));
790 if (pss_ok == 0)
791 return RET_ERROR (EIO);
792
793 dev = dev >> 4;
794 mode = file->mode & O_ACCMODE;
795 if (mode == O_WRONLY && code_length > 0)
796 {
797 #ifdef linux
798
799 __asm__ ("sti");
800 #endif
801 if (!pss_download_boot (code_buffer, code_length))
802 {
803 pss_reattach ();
804 }
805 }
806 lock_pss = 0;
807 }
808
809 int
810 pss_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
811 {
812 int c, p;
813
814 DEB (printk ("pss_read\n"));
815 if (pss_ok == 0)
816 return RET_ERROR (EIO);
817
818 dev = dev >> 4;
819 p = 0;
820 c = count;
821
822 return count - c;
823 }
824
825 int
826 pss_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
827 {
828 DEB (printk ("pss_write\n"));
829 if (pss_ok == 0)
830 return RET_ERROR (EIO);
831 dev = dev >> 4;
832
833 if (count)
834 {
835 COPY_FROM_USER (&code_buffer[code_length], buf, 0, count);
836 code_length += count;
837 }
838 return count;
839 }
840
841
842 int
843 pss_ioctl (int dev, struct fileinfo *file,
844 unsigned int cmd, unsigned int arg)
845 {
846 DEB (printk ("pss_ioctl dev=%d cmd=%x\n", dev, cmd));
847 if (pss_ok == 0)
848 return RET_ERROR (EIO);
849
850 dev = dev >> 4;
851
852 switch (cmd)
853 {
854 case SNDCTL_PSS_RESET:
855 pss_reattach ();
856 return 1;
857
858 case SNDCTL_PSS_SETUP_REGISTERS:
859 pss_configure_registers_to_look_like_sb ();
860 return 1;
861
862 case SNDCTL_PSS_SPEAKER:
863 {
864 struct pss_speaker params;
865 COPY_FROM_USER (¶ms, (char *) arg, 0, sizeof (struct pss_speaker));
866
867 pss_setspeaker (¶ms);
868 return 0;
869 }
870 default:
871 return RET_ERROR (EIO);
872 }
873 }
874
875
876
877
878
879
880
881
882
883
884
885 pss_select (int dev, struct fileinfo * file, int sel_type, select_table * wait)
886 {
887 return 0;
888 if (pss_ok == 0)
889 return RET_ERROR (EIO);
890
891 dev = dev >> 4;
892
893 switch (sel_type)
894 {
895 case SEL_IN:
896 select_wait (&pss_sleeper, wait);
897 return 0;
898 break;
899
900 case SEL_OUT:
901 select_wait (&pss_sleeper, wait);
902 return 0;
903 break;
904
905 case SEL_EX:
906 return 0;
907 }
908
909 return 0;
910 }
911
912 long
913 pss_init (long mem_start)
914 {
915 DEB (printk ("pss_init\n"));
916 if (pss_ok)
917 {
918 code_buffer = mem_start;
919 mem_start += CODE_BUFFER_LEN;
920 }
921 return mem_start;
922 }
923
924 #endif