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