Pull extend-notify-die into release branch
[linux-2.6] / sound / oss / pss.c
1 /*
2  * sound/pss.c
3  *
4  * The low level driver for the Personal Sound System (ECHO ESC614).
5  *
6  *
7  * Copyright (C) by Hannu Savolainen 1993-1997
8  *
9  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10  * Version 2 (June 1991). See the "COPYING" file distributed with this software
11  * for more info.
12  *
13  *
14  * Thomas Sailer        ioctl code reworked (vmalloc/vfree removed)
15  * Alan Cox             modularisation, clean up.
16  *
17  * 98-02-21: Vladimir Michl <vladimir.michl@upol.cz>
18  *          Added mixer device for Beethoven ADSP-16 (master volume,
19  *          bass, treble, synth), only for speakers.
20  *          Fixed bug in pss_write (exchange parameters)
21  *          Fixed config port of SB
22  *          Requested two regions for PSS (PSS mixer, PSS config)
23  *          Modified pss_download_boot
24  *          To probe_pss_mss added test for initialize AD1848
25  * 98-05-28: Vladimir Michl <vladimir.michl@upol.cz>
26  *          Fixed computation of mixer volumes
27  * 04-05-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
28  *          Added code that allows the user to enable his cdrom and/or 
29  *          joystick through the module parameters pss_cdrom_port and 
30  *          pss_enable_joystick.  pss_cdrom_port takes a port address as its
31  *          argument.  pss_enable_joystick takes either a 0 or a non-0 as its
32  *          argument.
33  * 04-06-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
34  *          Separated some code into new functions for easier reuse.  
35  *          Cleaned up and streamlined new code.  Added code to allow a user 
36  *          to only use this driver for enabling non-sound components 
37  *          through the new module parameter pss_no_sound (flag).  Added 
38  *          code that would allow a user to decide whether the driver should 
39  *          reset the configured hardware settings for the PSS board through 
40  *          the module parameter pss_keep_settings (flag).   This flag will 
41  *          allow a user to free up resources in use by this card if needbe, 
42  *          furthermore it allows him to use this driver to just enable the 
43  *          emulations and then be unloaded as it is no longer needed.  Both 
44  *          new settings are only available to this driver if compiled as a 
45  *          module.  The default settings of all new parameters are set to 
46  *          load the driver as it did in previous versions.
47  * 04-07-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
48  *          Added module parameter pss_firmware to allow the user to tell 
49  *          the driver where the fireware file is located.  The default 
50  *          setting is the previous hardcoded setting "/etc/sound/pss_synth".
51  * 00-03-03: Christoph Hellwig <chhellwig@infradead.org>
52  *          Adapted to module_init/module_exit
53  * 11-10-2000: Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
54  *          Added __init to probe_pss(), attach_pss() and probe_pss_mpu()
55  * 02-Jan-2001: Chris Rankin
56  *          Specify that this module owns the coprocessor
57  */
58
59
60 #include <linux/config.h>
61 #include <linux/init.h>
62 #include <linux/module.h>
63 #include <linux/spinlock.h>
64
65 #include "sound_config.h"
66 #include "sound_firmware.h"
67
68 #include "ad1848.h"
69 #include "mpu401.h"
70
71 /*
72  * PSS registers.
73  */
74 #define REG(x)  (devc->base+x)
75 #define PSS_DATA        0
76 #define PSS_STATUS      2
77 #define PSS_CONTROL     2
78 #define PSS_ID          4
79 #define PSS_IRQACK      4
80 #define PSS_PIO         0x1a
81
82 /*
83  * Config registers
84  */
85 #define CONF_PSS        0x10
86 #define CONF_WSS        0x12
87 #define CONF_SB         0x14
88 #define CONF_CDROM      0x16
89 #define CONF_MIDI       0x18
90
91 /*
92  * Status bits.
93  */
94 #define PSS_FLAG3     0x0800
95 #define PSS_FLAG2     0x0400
96 #define PSS_FLAG1     0x1000
97 #define PSS_FLAG0     0x0800
98 #define PSS_WRITE_EMPTY  0x8000
99 #define PSS_READ_FULL    0x4000
100
101 /*
102  * WSS registers
103  */
104 #define WSS_INDEX 4
105 #define WSS_DATA 5
106
107 /*
108  * WSS status bits
109  */
110 #define WSS_INITIALIZING 0x80
111 #define WSS_AUTOCALIBRATION 0x20
112
113 #define NO_WSS_MIXER    -1
114
115 #include "coproc.h"
116
117 #include "pss_boot.h"
118
119 /* If compiled into kernel, it enable or disable pss mixer */
120 #ifdef CONFIG_PSS_MIXER
121 static int pss_mixer = 1;
122 #else
123 static int pss_mixer;
124 #endif
125
126
127 typedef struct pss_mixerdata {
128         unsigned int volume_l;
129         unsigned int volume_r;
130         unsigned int bass;
131         unsigned int treble;
132         unsigned int synth;
133 } pss_mixerdata;
134
135 typedef struct pss_confdata {
136         int             base;
137         int             irq;
138         int             dma;
139         int            *osp;
140         pss_mixerdata   mixer;
141         int             ad_mixer_dev;
142 } pss_confdata;
143   
144 static pss_confdata pss_data;
145 static pss_confdata *devc = &pss_data;
146 static DEFINE_SPINLOCK(lock);
147
148 static int      pss_initialized;
149 static int      nonstandard_microcode;
150 static int      pss_cdrom_port = -1;    /* Parameter for the PSS cdrom port */
151 static int      pss_enable_joystick;    /* Parameter for enabling the joystick */
152 static coproc_operations pss_coproc_operations;
153
154 static void pss_write(pss_confdata *devc, int data)
155 {
156         unsigned long i, limit;
157
158         limit = jiffies + HZ/10;        /* The timeout is 0.1 seconds */
159         /*
160          * Note! the i<5000000 is an emergency exit. The dsp_command() is sometimes
161          * called while interrupts are disabled. This means that the timer is
162          * disabled also. However the timeout situation is a abnormal condition.
163          * Normally the DSP should be ready to accept commands after just couple of
164          * loops.
165          */
166
167         for (i = 0; i < 5000000 && time_before(jiffies, limit); i++)
168         {
169                 if (inw(REG(PSS_STATUS)) & PSS_WRITE_EMPTY)
170                 {
171                         outw(data, REG(PSS_DATA));
172                         return;
173                 }
174         }
175         printk(KERN_WARNING "PSS: DSP Command (%04x) Timeout.\n", data);
176 }
177
178 static int __init probe_pss(struct address_info *hw_config)
179 {
180         unsigned short id;
181         int irq, dma;
182
183         devc->base = hw_config->io_base;
184         irq = devc->irq = hw_config->irq;
185         dma = devc->dma = hw_config->dma;
186         devc->osp = hw_config->osp;
187
188         if (devc->base != 0x220 && devc->base != 0x240)
189                 if (devc->base != 0x230 && devc->base != 0x250)         /* Some cards use these */
190                         return 0;
191
192         if (!request_region(devc->base, 0x10, "PSS mixer, SB emulation")) {
193                 printk(KERN_ERR "PSS: I/O port conflict\n");
194                 return 0;
195         }
196         id = inw(REG(PSS_ID));
197         if ((id >> 8) != 'E') {
198                 printk(KERN_ERR "No PSS signature detected at 0x%x (0x%x)\n",  devc->base,  id); 
199                 release_region(devc->base, 0x10);
200                 return 0;
201         }
202         if (!request_region(devc->base + 0x10, 0x9, "PSS config")) {
203                 printk(KERN_ERR "PSS: I/O port conflict\n");
204                 release_region(devc->base, 0x10);
205                 return 0;
206         }
207         return 1;
208 }
209
210 static int set_irq(pss_confdata * devc, int dev, int irq)
211 {
212         static unsigned short irq_bits[16] =
213         {
214                 0x0000, 0x0000, 0x0000, 0x0008,
215                 0x0000, 0x0010, 0x0000, 0x0018,
216                 0x0000, 0x0020, 0x0028, 0x0030,
217                 0x0038, 0x0000, 0x0000, 0x0000
218         };
219
220         unsigned short  tmp, bits;
221
222         if (irq < 0 || irq > 15)
223                 return 0;
224
225         tmp = inw(REG(dev)) & ~0x38;    /* Load confreg, mask IRQ bits out */
226
227         if ((bits = irq_bits[irq]) == 0 && irq != 0)
228         {
229                 printk(KERN_ERR "PSS: Invalid IRQ %d\n", irq);
230                 return 0;
231         }
232         outw(tmp | bits, REG(dev));
233         return 1;
234 }
235
236 static int set_io_base(pss_confdata * devc, int dev, int base)
237 {
238         unsigned short  tmp = inw(REG(dev)) & 0x003f;
239         unsigned short  bits = (base & 0x0ffc) << 4;
240
241         outw(bits | tmp, REG(dev));
242
243         return 1;
244 }
245
246 static int set_dma(pss_confdata * devc, int dev, int dma)
247 {
248         static unsigned short dma_bits[8] =
249         {
250                 0x0001, 0x0002, 0x0000, 0x0003,
251                 0x0000, 0x0005, 0x0006, 0x0007
252         };
253
254         unsigned short  tmp, bits;
255
256         if (dma < 0 || dma > 7)
257                 return 0;
258
259         tmp = inw(REG(dev)) & ~0x07;    /* Load confreg, mask DMA bits out */
260
261         if ((bits = dma_bits[dma]) == 0 && dma != 4)
262         {
263                   printk(KERN_ERR "PSS: Invalid DMA %d\n", dma);
264                   return 0;
265         }
266         outw(tmp | bits, REG(dev));
267         return 1;
268 }
269
270 static int pss_reset_dsp(pss_confdata * devc)
271 {
272         unsigned long   i, limit = jiffies + HZ/10;
273
274         outw(0x2000, REG(PSS_CONTROL));
275         for (i = 0; i < 32768 && (limit-jiffies >= 0); i++)
276                 inw(REG(PSS_CONTROL));
277         outw(0x0000, REG(PSS_CONTROL));
278         return 1;
279 }
280
281 static int pss_put_dspword(pss_confdata * devc, unsigned short word)
282 {
283         int i, val;
284
285         for (i = 0; i < 327680; i++)
286         {
287                 val = inw(REG(PSS_STATUS));
288                 if (val & PSS_WRITE_EMPTY)
289                 {
290                         outw(word, REG(PSS_DATA));
291                         return 1;
292                 }
293         }
294         return 0;
295 }
296
297 static int pss_get_dspword(pss_confdata * devc, unsigned short *word)
298 {
299         int i, val;
300
301         for (i = 0; i < 327680; i++)
302         {
303                 val = inw(REG(PSS_STATUS));
304                 if (val & PSS_READ_FULL)
305                 {
306                         *word = inw(REG(PSS_DATA));
307                         return 1;
308                 }
309         }
310         return 0;
311 }
312
313 static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size, int flags)
314 {
315         int i, val, count;
316         unsigned long limit;
317
318         if (flags & CPF_FIRST)
319         {
320 /*_____ Warn DSP software that a boot is coming */
321                 outw(0x00fe, REG(PSS_DATA));
322
323                 limit = jiffies + HZ/10;
324                 for (i = 0; i < 32768 && time_before(jiffies, limit); i++)
325                         if (inw(REG(PSS_DATA)) == 0x5500)
326                                 break;
327
328                 outw(*block++, REG(PSS_DATA));
329                 pss_reset_dsp(devc);
330         }
331         count = 1;
332         while ((flags&CPF_LAST) || count<size )
333         {
334                 int j;
335
336                 for (j = 0; j < 327670; j++)
337                 {
338 /*_____ Wait for BG to appear */
339                         if (inw(REG(PSS_STATUS)) & PSS_FLAG3)
340                                 break;
341                 }
342
343                 if (j == 327670)
344                 {
345                         /* It's ok we timed out when the file was empty */
346                         if (count >= size && flags & CPF_LAST)
347                                 break;
348                         else
349                         {
350                                 printk("\n");
351                                 printk(KERN_ERR "PSS: Download timeout problems, byte %d=%d\n", count, size);
352                                 return 0;
353                         }
354                 }
355 /*_____ Send the next byte */
356                 if (count >= size) 
357                 {
358                         /* If not data in block send 0xffff */
359                         outw (0xffff, REG (PSS_DATA));
360                 }
361                 else
362                 {
363                         /*_____ Send the next byte */
364                         outw (*block++, REG (PSS_DATA));
365                 };
366                 count++;
367         }
368
369         if (flags & CPF_LAST)
370         {
371 /*_____ Why */
372                 outw(0, REG(PSS_DATA));
373
374                 limit = jiffies + HZ/10;
375                 for (i = 0; i < 32768 && (limit - jiffies >= 0); i++)
376                         val = inw(REG(PSS_STATUS));
377
378                 limit = jiffies + HZ/10;
379                 for (i = 0; i < 32768 && (limit-jiffies >= 0); i++)
380                 {
381                         val = inw(REG(PSS_STATUS));
382                         if (val & 0x4000)
383                                 break;
384                 }
385
386                 /* now read the version */
387                 for (i = 0; i < 32000; i++)
388                 {
389                         val = inw(REG(PSS_STATUS));
390                         if (val & PSS_READ_FULL)
391                                 break;
392                 }
393                 if (i == 32000)
394                         return 0;
395
396                 val = inw(REG(PSS_DATA));
397                 /* printk( "<PSS: microcode version %d.%d loaded>",  val/16,  val % 16); */
398         }
399         return 1;
400 }
401
402 /* Mixer */
403 static void set_master_volume(pss_confdata *devc, int left, int right)
404 {
405         static unsigned char log_scale[101] =  {
406                 0xdb, 0xe0, 0xe3, 0xe5, 0xe7, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee,
407                 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3,
408                 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7,
409                 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9,
410                 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb,
411                 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
412                 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
413                 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
414                 0xfe, 0xfe, 0xff, 0xff, 0xff
415         };
416         pss_write(devc, 0x0010);
417         pss_write(devc, log_scale[left] | 0x0000);
418         pss_write(devc, 0x0010);
419         pss_write(devc, log_scale[right] | 0x0100);
420 }
421
422 static void set_synth_volume(pss_confdata *devc, int volume)
423 {
424         int vol = ((0x8000*volume)/100L);
425         pss_write(devc, 0x0080);
426         pss_write(devc, vol);
427         pss_write(devc, 0x0081);
428         pss_write(devc, vol);
429 }
430
431 static void set_bass(pss_confdata *devc, int level)
432 {
433         int vol = (int)(((0xfd - 0xf0) * level)/100L) + 0xf0;
434         pss_write(devc, 0x0010);
435         pss_write(devc, vol | 0x0200);
436 };
437
438 static void set_treble(pss_confdata *devc, int level)
439 {       
440         int vol = (((0xfd - 0xf0) * level)/100L) + 0xf0;
441         pss_write(devc, 0x0010);
442         pss_write(devc, vol | 0x0300);
443 };
444
445 static void pss_mixer_reset(pss_confdata *devc)
446 {
447         set_master_volume(devc, 33, 33);
448         set_bass(devc, 50);
449         set_treble(devc, 50);
450         set_synth_volume(devc, 30);
451         pss_write (devc, 0x0010);
452         pss_write (devc, 0x0800 | 0xce);        /* Stereo */
453         
454         if(pss_mixer)
455         {
456                 devc->mixer.volume_l = devc->mixer.volume_r = 33;
457                 devc->mixer.bass = 50;
458                 devc->mixer.treble = 50;
459                 devc->mixer.synth = 30;
460         }
461 }
462
463 static int set_volume_mono(unsigned __user *p, int *aleft)
464 {
465         int left;
466         unsigned volume;
467         if (get_user(volume, p))
468                 return -EFAULT;
469         
470         left = volume & 0xff;
471         if (left > 100)
472                 left = 100;
473         *aleft = left;
474         return 0;
475 }
476
477 static int set_volume_stereo(unsigned __user *p, int *aleft, int *aright)
478 {
479         int left, right;
480         unsigned volume;
481         if (get_user(volume, p))
482                 return -EFAULT;
483
484         left = volume & 0xff;
485         if (left > 100)
486                 left = 100;
487         right = (volume >> 8) & 0xff;
488         if (right > 100)
489                 right = 100;
490         *aleft = left;
491         *aright = right;
492         return 0;
493 }
494
495 static int ret_vol_mono(int left)
496 {
497         return ((left << 8) | left);
498 }
499
500 static int ret_vol_stereo(int left, int right)
501 {
502         return ((right << 8) | left);
503 }
504
505 static int call_ad_mixer(pss_confdata *devc,unsigned int cmd, void __user *arg)
506 {
507         if (devc->ad_mixer_dev != NO_WSS_MIXER) 
508                 return mixer_devs[devc->ad_mixer_dev]->ioctl(devc->ad_mixer_dev, cmd, arg);
509         else 
510                 return -EINVAL;
511 }
512
513 static int pss_mixer_ioctl (int dev, unsigned int cmd, void __user *arg)
514 {
515         pss_confdata *devc = mixer_devs[dev]->devc;
516         int cmdf = cmd & 0xff;
517         
518         if ((cmdf != SOUND_MIXER_VOLUME) && (cmdf != SOUND_MIXER_BASS) &&
519                 (cmdf != SOUND_MIXER_TREBLE) && (cmdf != SOUND_MIXER_SYNTH) &&
520                 (cmdf != SOUND_MIXER_DEVMASK) && (cmdf != SOUND_MIXER_STEREODEVS) &&
521                 (cmdf != SOUND_MIXER_RECMASK) && (cmdf != SOUND_MIXER_CAPS) &&
522                 (cmdf != SOUND_MIXER_RECSRC)) 
523         {
524                 return call_ad_mixer(devc, cmd, arg);
525         }
526         
527         if (((cmd >> 8) & 0xff) != 'M') 
528                 return -EINVAL;
529                 
530         if (_SIOC_DIR (cmd) & _SIOC_WRITE)
531         {
532                 switch (cmdf)   
533                 {
534                         case SOUND_MIXER_RECSRC:
535                                 if (devc->ad_mixer_dev != NO_WSS_MIXER)
536                                         return call_ad_mixer(devc, cmd, arg);
537                                 else
538                                 {
539                                         int v;
540                                         if (get_user(v, (int __user *)arg))
541                                                 return -EFAULT;
542                                         if (v != 0)
543                                                 return -EINVAL;
544                                         return 0;
545                                 }
546                         case SOUND_MIXER_VOLUME:
547                                 if (set_volume_stereo(arg,
548                                         &devc->mixer.volume_l,
549                                         &devc->mixer.volume_r))
550                                         return -EFAULT;
551                                 set_master_volume(devc, devc->mixer.volume_l,
552                                         devc->mixer.volume_r);
553                                 return ret_vol_stereo(devc->mixer.volume_l,
554                                         devc->mixer.volume_r);
555                   
556                         case SOUND_MIXER_BASS:
557                                 if (set_volume_mono(arg, &devc->mixer.bass))
558                                         return -EFAULT;
559                                 set_bass(devc, devc->mixer.bass);
560                                 return ret_vol_mono(devc->mixer.bass);
561                   
562                         case SOUND_MIXER_TREBLE:
563                                 if (set_volume_mono(arg, &devc->mixer.treble))
564                                         return -EFAULT;
565                                 set_treble(devc, devc->mixer.treble);
566                                 return ret_vol_mono(devc->mixer.treble);
567                   
568                         case SOUND_MIXER_SYNTH:
569                                 if (set_volume_mono(arg, &devc->mixer.synth))
570                                         return -EFAULT;
571                                 set_synth_volume(devc, devc->mixer.synth);
572                                 return ret_vol_mono(devc->mixer.synth);
573                   
574                         default:
575                                 return -EINVAL;
576                 }
577         }
578         else                    
579         {
580                 int val, and_mask = 0, or_mask = 0;
581                 /*
582                  * Return parameters
583                  */
584                 switch (cmdf)
585                 {
586                         case SOUND_MIXER_DEVMASK:
587                                 if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
588                                         break;
589                                 and_mask = ~0;
590                                 or_mask = SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH;
591                                 break;
592                   
593                         case SOUND_MIXER_STEREODEVS:
594                                 if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
595                                         break;
596                                 and_mask = ~0;
597                                 or_mask = SOUND_MASK_VOLUME;
598                                 break;
599                   
600                         case SOUND_MIXER_RECMASK:
601                                 if (devc->ad_mixer_dev != NO_WSS_MIXER)
602                                         return call_ad_mixer(devc, cmd, arg);
603                                 break;
604
605                         case SOUND_MIXER_CAPS:
606                                 if (devc->ad_mixer_dev != NO_WSS_MIXER)
607                                         return call_ad_mixer(devc, cmd, arg);
608                                 or_mask = SOUND_CAP_EXCL_INPUT;
609                                 break;
610
611                         case SOUND_MIXER_RECSRC:
612                                 if (devc->ad_mixer_dev != NO_WSS_MIXER)
613                                         return call_ad_mixer(devc, cmd, arg);
614                                 break;
615
616                         case SOUND_MIXER_VOLUME:
617                                 or_mask =  ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r);
618                                 break;
619                           
620                         case SOUND_MIXER_BASS:
621                                 or_mask =  ret_vol_mono(devc->mixer.bass);
622                                 break;
623                           
624                         case SOUND_MIXER_TREBLE:
625                                 or_mask = ret_vol_mono(devc->mixer.treble);
626                                 break;
627                           
628                         case SOUND_MIXER_SYNTH:
629                                 or_mask = ret_vol_mono(devc->mixer.synth);
630                                 break;
631                         default:
632                                 return -EINVAL;
633                 }
634                 if (get_user(val, (int __user *)arg))
635                         return -EFAULT;
636                 val &= and_mask;
637                 val |= or_mask;
638                 if (put_user(val, (int __user *)arg))
639                         return -EFAULT;
640                 return val;
641         }
642 }
643
644 static struct mixer_operations pss_mixer_operations =
645 {
646         .owner  = THIS_MODULE,
647         .id     = "SOUNDPORT",
648         .name   = "PSS-AD1848",
649         .ioctl  = pss_mixer_ioctl
650 };
651
652 static void disable_all_emulations(void)
653 {
654         outw(0x0000, REG(CONF_PSS));    /* 0x0400 enables joystick */
655         outw(0x0000, REG(CONF_WSS));
656         outw(0x0000, REG(CONF_SB));
657         outw(0x0000, REG(CONF_MIDI));
658         outw(0x0000, REG(CONF_CDROM));
659 }
660
661 static void configure_nonsound_components(void)
662 {
663         /* Configure Joystick port */
664
665         if(pss_enable_joystick)
666         {
667                 outw(0x0400, REG(CONF_PSS));    /* 0x0400 enables joystick */
668                 printk(KERN_INFO "PSS: joystick enabled.\n");
669         }
670         else
671         {
672                 printk(KERN_INFO "PSS: joystick port not enabled.\n");
673         }
674
675         /* Configure CDROM port */
676
677         if(pss_cdrom_port == -1)        /* If cdrom port enablation wasn't requested */
678         {
679                 printk(KERN_INFO "PSS: CDROM port not enabled.\n");
680         }
681         else if(check_region(pss_cdrom_port, 2))
682         {
683                 printk(KERN_ERR "PSS: CDROM I/O port conflict.\n");
684         }
685         else if(!set_io_base(devc, CONF_CDROM, pss_cdrom_port))
686         {
687                 printk(KERN_ERR "PSS: CDROM I/O port could not be set.\n");
688         }
689         else                                    /* CDROM port successfully configured */
690         {
691                 printk(KERN_INFO "PSS: CDROM I/O port set to 0x%x.\n", pss_cdrom_port);
692         }
693 }
694
695 static int __init attach_pss(struct address_info *hw_config)
696 {
697         unsigned short  id;
698         char tmp[100];
699
700         devc->base = hw_config->io_base;
701         devc->irq = hw_config->irq;
702         devc->dma = hw_config->dma;
703         devc->osp = hw_config->osp;
704         devc->ad_mixer_dev = NO_WSS_MIXER;
705
706         if (!probe_pss(hw_config))
707                 return 0;
708
709         id = inw(REG(PSS_ID)) & 0x00ff;
710
711         /*
712          * Disable all emulations. Will be enabled later (if required).
713          */
714          
715         disable_all_emulations();
716
717 #ifdef YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
718         if (sound_alloc_dma(hw_config->dma, "PSS"))
719         {
720                 printk("pss.c: Can't allocate DMA channel.\n");
721                 release_region(hw_config->io_base, 0x10);
722                 release_region(hw_config->io_base+0x10, 0x9);
723                 return 0;
724         }
725         if (!set_irq(devc, CONF_PSS, devc->irq))
726         {
727                 printk("PSS: IRQ allocation error.\n");
728                 release_region(hw_config->io_base, 0x10);
729                 release_region(hw_config->io_base+0x10, 0x9);
730                 return 0;
731         }
732         if (!set_dma(devc, CONF_PSS, devc->dma))
733         {
734                 printk(KERN_ERR "PSS: DMA allocation error\n");
735                 release_region(hw_config->io_base, 0x10);
736                 release_region(hw_config->io_base+0x10, 0x9);
737                 return 0;
738         }
739 #endif
740
741         configure_nonsound_components();
742         pss_initialized = 1;
743         sprintf(tmp, "ECHO-PSS  Rev. %d", id);
744         conf_printf(tmp, hw_config);
745         return 1;
746 }
747
748 static int __init probe_pss_mpu(struct address_info *hw_config)
749 {
750         struct resource *ports;
751         int timeout;
752
753         if (!pss_initialized)
754                 return 0;
755
756         ports = request_region(hw_config->io_base, 2, "mpu401");
757
758         if (!ports) {
759                 printk(KERN_ERR "PSS: MPU I/O port conflict\n");
760                 return 0;
761         }
762         if (!set_io_base(devc, CONF_MIDI, hw_config->io_base)) {
763                 printk(KERN_ERR "PSS: MIDI base could not be set.\n");
764                 goto fail;
765         }
766         if (!set_irq(devc, CONF_MIDI, hw_config->irq)) {
767                 printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n");
768                 goto fail;
769         }
770         if (!pss_synthLen) {
771                 printk(KERN_ERR "PSS: Can't enable MPU. MIDI synth microcode not available.\n");
772                 goto fail;
773         }
774         if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
775                 printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
776                 goto fail;
777         }
778
779         /*
780          * Finally wait until the DSP algorithm has initialized itself and
781          * deactivates receive interrupt.
782          */
783
784         for (timeout = 900000; timeout > 0; timeout--)
785         {
786                 if ((inb(hw_config->io_base + 1) & 0x80) == 0)  /* Input data avail */
787                         inb(hw_config->io_base);        /* Discard it */
788                 else
789                         break;  /* No more input */
790         }
791
792         if (!probe_mpu401(hw_config, ports))
793                 goto fail;
794
795         attach_mpu401(hw_config, THIS_MODULE);  /* Slot 1 */
796         if (hw_config->slots[1] != -1)  /* The MPU driver installed itself */
797                 midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
798         return 1;
799 fail:
800         release_region(hw_config->io_base, 2);
801         return 0;
802 }
803
804 static int pss_coproc_open(void *dev_info, int sub_device)
805 {
806         switch (sub_device)
807         {
808                 case COPR_MIDI:
809                         if (pss_synthLen == 0)
810                         {
811                                 printk(KERN_ERR "PSS: MIDI synth microcode not available.\n");
812                                 return -EIO;
813                         }
814                         if (nonstandard_microcode)
815                                 if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
816                         {
817                                 printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
818                                 return -EIO;
819                         }
820                         nonstandard_microcode = 0;
821                         break;
822
823                 default:
824                         break;
825         }
826         return 0;
827 }
828
829 static void pss_coproc_close(void *dev_info, int sub_device)
830 {
831         return;
832 }
833
834 static void pss_coproc_reset(void *dev_info)
835 {
836         if (pss_synthLen)
837                 if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
838                 {
839                         printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
840                 }
841         nonstandard_microcode = 0;
842 }
843
844 static int download_boot_block(void *dev_info, copr_buffer * buf)
845 {
846         if (buf->len <= 0 || buf->len > sizeof(buf->data))
847                 return -EINVAL;
848
849         if (!pss_download_boot(devc, buf->data, buf->len, buf->flags))
850         {
851                 printk(KERN_ERR "PSS: Unable to load microcode block to DSP.\n");
852                 return -EIO;
853         }
854         nonstandard_microcode = 1;      /* The MIDI microcode has been overwritten */
855         return 0;
856 }
857
858 static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
859 {
860         copr_buffer *buf;
861         copr_msg *mbuf;
862         copr_debug_buf dbuf;
863         unsigned short tmp;
864         unsigned long flags;
865         unsigned short *data;
866         int i, err;
867         /* printk( "PSS coproc ioctl %x %x %d\n",  cmd,  arg,  local); */
868         
869         switch (cmd) 
870         {
871                 case SNDCTL_COPR_RESET:
872                         pss_coproc_reset(dev_info);
873                         return 0;
874
875                 case SNDCTL_COPR_LOAD:
876                         buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
877                         if (buf == NULL)
878                                 return -ENOSPC;
879                         if (copy_from_user(buf, arg, sizeof(copr_buffer))) {
880                                 vfree(buf);
881                                 return -EFAULT;
882                         }
883                         err = download_boot_block(dev_info, buf);
884                         vfree(buf);
885                         return err;
886                 
887                 case SNDCTL_COPR_SENDMSG:
888                         mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
889                         if (mbuf == NULL)
890                                 return -ENOSPC;
891                         if (copy_from_user(mbuf, arg, sizeof(copr_msg))) {
892                                 vfree(mbuf);
893                                 return -EFAULT;
894                         }
895                         data = (unsigned short *)(mbuf->data);
896                         spin_lock_irqsave(&lock, flags);
897                         for (i = 0; i < mbuf->len; i++) {
898                                 if (!pss_put_dspword(devc, *data++)) {
899                                         spin_unlock_irqrestore(&lock,flags);
900                                         mbuf->len = i;  /* feed back number of WORDs sent */
901                                         err = copy_to_user(arg, mbuf, sizeof(copr_msg));
902                                         vfree(mbuf);
903                                         return err ? -EFAULT : -EIO;
904                                 }
905                         }
906                         spin_unlock_irqrestore(&lock,flags);
907                         vfree(mbuf);
908                         return 0;
909
910                 case SNDCTL_COPR_RCVMSG:
911                         err = 0;
912                         mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
913                         if (mbuf == NULL)
914                                 return -ENOSPC;
915                         data = (unsigned short *)mbuf->data;
916                         spin_lock_irqsave(&lock, flags);
917                         for (i = 0; i < sizeof(mbuf->data)/sizeof(unsigned short); i++) {
918                                 mbuf->len = i;  /* feed back number of WORDs read */
919                                 if (!pss_get_dspword(devc, data++)) {
920                                         if (i == 0)
921                                                 err = -EIO;
922                                         break;
923                                 }
924                         }
925                         spin_unlock_irqrestore(&lock,flags);
926                         if (copy_to_user(arg, mbuf, sizeof(copr_msg)))
927                                 err = -EFAULT;
928                         vfree(mbuf);
929                         return err;
930                 
931                 case SNDCTL_COPR_RDATA:
932                         if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
933                                 return -EFAULT;
934                         spin_lock_irqsave(&lock, flags);
935                         if (!pss_put_dspword(devc, 0x00d0)) {
936                                 spin_unlock_irqrestore(&lock,flags);
937                                 return -EIO;
938                         }
939                         if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
940                                 spin_unlock_irqrestore(&lock,flags);
941                                 return -EIO;
942                         }
943                         if (!pss_get_dspword(devc, &tmp)) {
944                                 spin_unlock_irqrestore(&lock,flags);
945                                 return -EIO;
946                         }
947                         dbuf.parm1 = tmp;
948                         spin_unlock_irqrestore(&lock,flags);
949                         if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
950                                 return -EFAULT;
951                         return 0;
952                 
953                 case SNDCTL_COPR_WDATA:
954                         if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
955                                 return -EFAULT;
956                         spin_lock_irqsave(&lock, flags);
957                         if (!pss_put_dspword(devc, 0x00d1)) {
958                                 spin_unlock_irqrestore(&lock,flags);
959                                 return -EIO;
960                         }
961                         if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
962                                 spin_unlock_irqrestore(&lock,flags);
963                                 return -EIO;
964                         }
965                         tmp = (unsigned int)dbuf.parm2 & 0xffff;
966                         if (!pss_put_dspword(devc, tmp)) {
967                                 spin_unlock_irqrestore(&lock,flags);
968                                 return -EIO;
969                         }
970                         spin_unlock_irqrestore(&lock,flags);
971                         return 0;
972                 
973                 case SNDCTL_COPR_WCODE:
974                         if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
975                                 return -EFAULT;
976                         spin_lock_irqsave(&lock, flags);
977                         if (!pss_put_dspword(devc, 0x00d3)) {
978                                 spin_unlock_irqrestore(&lock,flags);
979                                 return -EIO;
980                         }
981                         if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
982                                 spin_unlock_irqrestore(&lock,flags);
983                                 return -EIO;
984                         }
985                         tmp = (unsigned int)dbuf.parm2 & 0x00ff;
986                         if (!pss_put_dspword(devc, tmp)) {
987                                 spin_unlock_irqrestore(&lock,flags);
988                                 return -EIO;
989                         }
990                         tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
991                         if (!pss_put_dspword(devc, tmp)) {
992                                 spin_unlock_irqrestore(&lock,flags);
993                                 return -EIO;
994                         }
995                         spin_unlock_irqrestore(&lock,flags);
996                         return 0;
997                 
998                 case SNDCTL_COPR_RCODE:
999                         if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
1000                                 return -EFAULT;
1001                         spin_lock_irqsave(&lock, flags);
1002                         if (!pss_put_dspword(devc, 0x00d2)) {
1003                                 spin_unlock_irqrestore(&lock,flags);
1004                                 return -EIO;
1005                         }
1006                         if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
1007                                 spin_unlock_irqrestore(&lock,flags);
1008                                 return -EIO;
1009                         }
1010                         if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
1011                                 spin_unlock_irqrestore(&lock,flags);
1012                                 return -EIO;
1013                         }
1014                         dbuf.parm1 = tmp << 8;
1015                         if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
1016                                 spin_unlock_irqrestore(&lock,flags);
1017                                 return -EIO;
1018                         }
1019                         dbuf.parm1 |= tmp & 0x00ff;
1020                         spin_unlock_irqrestore(&lock,flags);
1021                         if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
1022                                 return -EFAULT;
1023                         return 0;
1024
1025                 default:
1026                         return -EINVAL;
1027         }
1028         return -EINVAL;
1029 }
1030
1031 static coproc_operations pss_coproc_operations =
1032 {
1033         "ADSP-2115",
1034         THIS_MODULE,
1035         pss_coproc_open,
1036         pss_coproc_close,
1037         pss_coproc_ioctl,
1038         pss_coproc_reset,
1039         &pss_data
1040 };
1041
1042 static int __init probe_pss_mss(struct address_info *hw_config)
1043 {
1044         volatile int timeout;
1045         struct resource *ports;
1046         int        my_mix = -999;       /* gcc shut up */
1047
1048         if (!pss_initialized)
1049                 return 0;
1050
1051         if (!request_region(hw_config->io_base, 4, "WSS config")) {
1052                 printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1053                 return 0;
1054         }
1055         ports = request_region(hw_config->io_base + 4, 4, "ad1848");
1056         if (!ports) {
1057                 printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1058                 release_region(hw_config->io_base, 4);
1059                 return 0;
1060         }
1061         if (!set_io_base(devc, CONF_WSS, hw_config->io_base)) {
1062                 printk("PSS: WSS base not settable.\n");
1063                 goto fail;
1064         }
1065         if (!set_irq(devc, CONF_WSS, hw_config->irq)) {
1066                 printk("PSS: WSS IRQ allocation error.\n");
1067                 goto fail;
1068         }
1069         if (!set_dma(devc, CONF_WSS, hw_config->dma)) {
1070                 printk(KERN_ERR "PSS: WSS DMA allocation error\n");
1071                 goto fail;
1072         }
1073         /*
1074          * For some reason the card returns 0xff in the WSS status register
1075          * immediately after boot. Probably MIDI+SB emulation algorithm
1076          * downloaded to the ADSP2115 spends some time initializing the card.
1077          * Let's try to wait until it finishes this task.
1078          */
1079         for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) &
1080           WSS_INITIALIZING); timeout++)
1081                 ;
1082
1083         outb((0x0b), hw_config->io_base + WSS_INDEX);   /* Required by some cards */
1084
1085         for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) &&
1086           (timeout < 100000); timeout++)
1087                 ;
1088
1089         if (!probe_ms_sound(hw_config, ports))
1090                 goto fail;
1091
1092         devc->ad_mixer_dev = NO_WSS_MIXER;
1093         if (pss_mixer) 
1094         {
1095                 if ((my_mix = sound_install_mixer (MIXER_DRIVER_VERSION,
1096                         "PSS-SPEAKERS and AD1848 (through MSS audio codec)",
1097                         &pss_mixer_operations,
1098                         sizeof (struct mixer_operations),
1099                         devc)) < 0) 
1100                 {
1101                         printk(KERN_ERR "Could not install PSS mixer\n");
1102                         goto fail;
1103                 }
1104         }
1105         pss_mixer_reset(devc);
1106         attach_ms_sound(hw_config, ports, THIS_MODULE); /* Slot 0 */
1107
1108         if (hw_config->slots[0] != -1)
1109         {
1110                 /* The MSS driver installed itself */
1111                 audio_devs[hw_config->slots[0]]->coproc = &pss_coproc_operations;
1112                 if (pss_mixer && (num_mixers == (my_mix + 2)))
1113                 {
1114                         /* The MSS mixer installed */
1115                         devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;
1116                 }
1117         }
1118         return 1;
1119 fail:
1120         release_region(hw_config->io_base + 4, 4);
1121         release_region(hw_config->io_base, 4);
1122         return 0;
1123 }
1124
1125 static inline void __exit unload_pss(struct address_info *hw_config)
1126 {
1127         release_region(hw_config->io_base, 0x10);
1128         release_region(hw_config->io_base+0x10, 0x9);
1129 }
1130
1131 static inline void __exit unload_pss_mpu(struct address_info *hw_config)
1132 {
1133         unload_mpu401(hw_config);
1134 }
1135
1136 static inline void __exit unload_pss_mss(struct address_info *hw_config)
1137 {
1138         unload_ms_sound(hw_config);
1139 }
1140
1141
1142 static struct address_info cfg;
1143 static struct address_info cfg2;
1144 static struct address_info cfg_mpu;
1145
1146 static int pss_io __initdata    = -1;
1147 static int mss_io __initdata    = -1;
1148 static int mss_irq __initdata   = -1;
1149 static int mss_dma __initdata   = -1;
1150 static int mpu_io __initdata    = -1;
1151 static int mpu_irq __initdata   = -1;
1152 static int pss_no_sound = 0;    /* Just configure non-sound components */
1153 static int pss_keep_settings  = 1;      /* Keep hardware settings at module exit */
1154 static char *pss_firmware = "/etc/sound/pss_synth";
1155
1156 module_param(pss_io, int, 0);
1157 MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
1158 module_param(mss_io, int, 0);
1159 MODULE_PARM_DESC(mss_io, "Set WSS (audio) i/o base (0x530, 0x604, 0xE80, 0xF40, or other. Address must end in 0 or 4 and must be from 0x100 to 0xFF4)");
1160 module_param(mss_irq, int, 0);
1161 MODULE_PARM_DESC(mss_irq, "Set WSS (audio) IRQ (3, 5, 7, 9, 10, 11, 12)");
1162 module_param(mss_dma, int, 0);
1163 MODULE_PARM_DESC(mss_dma, "Set WSS (audio) DMA (0, 1, 3)");
1164 module_param(mpu_io, int, 0);
1165 MODULE_PARM_DESC(mpu_io, "Set MIDI i/o base (0x330 or other. Address must be on 4 location boundaries and must be from 0x100 to 0xFFC)");
1166 module_param(mpu_irq, int, 0);
1167 MODULE_PARM_DESC(mpu_irq, "Set MIDI IRQ (3, 5, 7, 9, 10, 11, 12)");
1168 module_param(pss_cdrom_port, int, 0);
1169 MODULE_PARM_DESC(pss_cdrom_port, "Set the PSS CDROM port i/o base (0x340 or other)");
1170 module_param(pss_enable_joystick, bool, 0);
1171 MODULE_PARM_DESC(pss_enable_joystick, "Enables the PSS joystick port (1 to enable, 0 to disable)");
1172 module_param(pss_no_sound, bool, 0);
1173 MODULE_PARM_DESC(pss_no_sound, "Configure sound compoents (0 - no, 1 - yes)");
1174 module_param(pss_keep_settings, bool, 0);
1175 MODULE_PARM_DESC(pss_keep_settings, "Keep hardware setting at driver unloading (0 - no, 1 - yes)");
1176 module_param(pss_firmware, charp, 0);
1177 MODULE_PARM_DESC(pss_firmware, "Location of the firmware file (default - /etc/sound/pss_synth)");
1178 module_param(pss_mixer, bool, 0);
1179 MODULE_PARM_DESC(pss_mixer, "Enable (1) or disable (0) PSS mixer (controlling of output volume, bass, treble, synth volume). The mixer is not available on all PSS cards.");
1180 MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
1181 MODULE_DESCRIPTION("Module for PSS sound cards (based on AD1848, ADSP-2115 and ESC614). This module includes control of output amplifier and synth volume of the Beethoven ADSP-16 card (this may work with other PSS cards).");
1182 MODULE_LICENSE("GPL");
1183
1184
1185 static int fw_load = 0;
1186 static int pssmpu = 0, pssmss = 0;
1187
1188 /*
1189  *    Load a PSS sound card module
1190  */
1191
1192 static int __init init_pss(void)
1193 {
1194
1195         if(pss_no_sound)                /* If configuring only nonsound components */
1196         {
1197                 cfg.io_base = pss_io;
1198                 if(!probe_pss(&cfg))
1199                         return -ENODEV;
1200                 printk(KERN_INFO "ECHO-PSS  Rev. %d\n", inw(REG(PSS_ID)) & 0x00ff);
1201                 printk(KERN_INFO "PSS: loading in no sound mode.\n");
1202                 disable_all_emulations();
1203                 configure_nonsound_components();
1204                 release_region(pss_io, 0x10);
1205                 release_region(pss_io + 0x10, 0x9);
1206                 return 0;
1207         }
1208
1209         cfg.io_base = pss_io;
1210
1211         cfg2.io_base = mss_io;
1212         cfg2.irq = mss_irq;
1213         cfg2.dma = mss_dma;
1214
1215         cfg_mpu.io_base = mpu_io;
1216         cfg_mpu.irq = mpu_irq;
1217
1218         if (cfg.io_base == -1 || cfg2.io_base == -1 || cfg2.irq == -1 || cfg.dma == -1) {
1219                 printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
1220                 return -EINVAL;
1221         }
1222
1223         if (!pss_synth) {
1224                 fw_load = 1;
1225                 pss_synthLen = mod_firmware_load(pss_firmware, (void *) &pss_synth);
1226         }
1227         if (!attach_pss(&cfg))
1228                 return -ENODEV;
1229         /*
1230          *    Attach stuff
1231          */
1232         if (probe_pss_mpu(&cfg_mpu))
1233                 pssmpu = 1;
1234
1235         if (probe_pss_mss(&cfg2))
1236                 pssmss = 1;
1237
1238         return 0;
1239 }
1240
1241 static void __exit cleanup_pss(void)
1242 {
1243         if(!pss_no_sound)
1244         {
1245                 if(fw_load && pss_synth)
1246                         vfree(pss_synth);
1247                 if(pssmss)
1248                         unload_pss_mss(&cfg2);
1249                 if(pssmpu)
1250                         unload_pss_mpu(&cfg_mpu);
1251                 unload_pss(&cfg);
1252         }
1253
1254         if(!pss_keep_settings)  /* Keep hardware settings if asked */
1255         {
1256                 disable_all_emulations();
1257                 printk(KERN_INFO "Resetting PSS sound card configurations.\n");
1258         }
1259 }
1260
1261 module_init(init_pss);
1262 module_exit(cleanup_pss);
1263
1264 #ifndef MODULE
1265 static int __init setup_pss(char *str)
1266 {
1267         /* io, mss_io, mss_irq, mss_dma, mpu_io, mpu_irq */
1268         int ints[7];
1269         
1270         str = get_options(str, ARRAY_SIZE(ints), ints);
1271
1272         pss_io  = ints[1];
1273         mss_io  = ints[2];
1274         mss_irq = ints[3];
1275         mss_dma = ints[4];
1276         mpu_io  = ints[5];
1277         mpu_irq = ints[6];
1278
1279         return 1;
1280 }
1281
1282 __setup("pss=", setup_pss);
1283 #endif