linux/sound/oss/pss.c
<<
>>
Prefs
   1/*
   2 * sound/oss/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 firmware 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
 120static bool pss_mixer = 1;
 121#else
 122static bool pss_mixer;
 123#endif
 124
 125
 126struct 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};
 133
 134struct pss_confdata {
 135        int             base;
 136        int             irq;
 137        int             dma;
 138        int            *osp;
 139        struct pss_mixerdata mixer;
 140        int             ad_mixer_dev;
 141};
 142  
 143static struct pss_confdata pss_data;
 144static struct pss_confdata *devc = &pss_data;
 145static DEFINE_SPINLOCK(lock);
 146
 147static int      pss_initialized;
 148static int      nonstandard_microcode;
 149static int      pss_cdrom_port = -1;    /* Parameter for the PSS cdrom port */
 150static bool     pss_enable_joystick;    /* Parameter for enabling the joystick */
 151static coproc_operations pss_coproc_operations;
 152
 153static void pss_write(struct 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
 177static 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
 209static int set_irq(struct 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
 235static void set_io_base(struct 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
 243static int set_dma(struct pss_confdata *devc, int dev, int dma)
 244{
 245        static unsigned short dma_bits[8] =
 246        {
 247                0x0001, 0x0002, 0x0000, 0x0003,
 248                0x0000, 0x0005, 0x0006, 0x0007
 249        };
 250
 251        unsigned short  tmp, bits;
 252
 253        if (dma < 0 || dma > 7)
 254                return 0;
 255
 256        tmp = inw(REG(dev)) & ~0x07;    /* Load confreg, mask DMA bits out */
 257
 258        if ((bits = dma_bits[dma]) == 0 && dma != 4)
 259        {
 260                  printk(KERN_ERR "PSS: Invalid DMA %d\n", dma);
 261                  return 0;
 262        }
 263        outw(tmp | bits, REG(dev));
 264        return 1;
 265}
 266
 267static int pss_reset_dsp(struct pss_confdata *devc)
 268{
 269        unsigned long   i, limit = jiffies + HZ/10;
 270
 271        outw(0x2000, REG(PSS_CONTROL));
 272        for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
 273                inw(REG(PSS_CONTROL));
 274        outw(0x0000, REG(PSS_CONTROL));
 275        return 1;
 276}
 277
 278static int pss_put_dspword(struct pss_confdata *devc, unsigned short word)
 279{
 280        int i, val;
 281
 282        for (i = 0; i < 327680; i++)
 283        {
 284                val = inw(REG(PSS_STATUS));
 285                if (val & PSS_WRITE_EMPTY)
 286                {
 287                        outw(word, REG(PSS_DATA));
 288                        return 1;
 289                }
 290        }
 291        return 0;
 292}
 293
 294static int pss_get_dspword(struct pss_confdata *devc, unsigned short *word)
 295{
 296        int i, val;
 297
 298        for (i = 0; i < 327680; i++)
 299        {
 300                val = inw(REG(PSS_STATUS));
 301                if (val & PSS_READ_FULL)
 302                {
 303                        *word = inw(REG(PSS_DATA));
 304                        return 1;
 305                }
 306        }
 307        return 0;
 308}
 309
 310static int pss_download_boot(struct pss_confdata *devc, unsigned char *block,
 311                             int size, int flags)
 312{
 313        int i, val, count;
 314        unsigned long limit;
 315
 316        if (flags & CPF_FIRST)
 317        {
 318/*_____ Warn DSP software that a boot is coming */
 319                outw(0x00fe, REG(PSS_DATA));
 320
 321                limit = jiffies + HZ/10;
 322                for (i = 0; i < 32768 && time_before(jiffies, limit); i++)
 323                        if (inw(REG(PSS_DATA)) == 0x5500)
 324                                break;
 325
 326                outw(*block++, REG(PSS_DATA));
 327                pss_reset_dsp(devc);
 328        }
 329        count = 1;
 330        while ((flags&CPF_LAST) || count<size )
 331        {
 332                int j;
 333
 334                for (j = 0; j < 327670; j++)
 335                {
 336/*_____ Wait for BG to appear */
 337                        if (inw(REG(PSS_STATUS)) & PSS_FLAG3)
 338                                break;
 339                }
 340
 341                if (j == 327670)
 342                {
 343                        /* It's ok we timed out when the file was empty */
 344                        if (count >= size && flags & CPF_LAST)
 345                                break;
 346                        else
 347                        {
 348                                printk("\n");
 349                                printk(KERN_ERR "PSS: Download timeout problems, byte %d=%d\n", count, size);
 350                                return 0;
 351                        }
 352                }
 353/*_____ Send the next byte */
 354                if (count >= size) 
 355                {
 356                        /* If not data in block send 0xffff */
 357                        outw (0xffff, REG (PSS_DATA));
 358                }
 359                else
 360                {
 361                        /*_____ Send the next byte */
 362                        outw (*block++, REG (PSS_DATA));
 363                }
 364                count++;
 365        }
 366
 367        if (flags & CPF_LAST)
 368        {
 369/*_____ Why */
 370                outw(0, REG(PSS_DATA));
 371
 372                limit = jiffies + HZ/10;
 373                for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
 374                        val = inw(REG(PSS_STATUS));
 375
 376                limit = jiffies + HZ/10;
 377                for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
 378                {
 379                        val = inw(REG(PSS_STATUS));
 380                        if (val & 0x4000)
 381                                break;
 382                }
 383
 384                /* now read the version */
 385                for (i = 0; i < 32000; i++)
 386                {
 387                        val = inw(REG(PSS_STATUS));
 388                        if (val & PSS_READ_FULL)
 389                                break;
 390                }
 391                if (i == 32000)
 392                        return 0;
 393
 394                val = inw(REG(PSS_DATA));
 395                /* printk( "<PSS: microcode version %d.%d loaded>",  val/16,  val % 16); */
 396        }
 397        return 1;
 398}
 399
 400/* Mixer */
 401static void set_master_volume(struct pss_confdata *devc, int left, int right)
 402{
 403        static unsigned char log_scale[101] =  {
 404                0xdb, 0xe0, 0xe3, 0xe5, 0xe7, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee,
 405                0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3,
 406                0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7,
 407                0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9,
 408                0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb,
 409                0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
 410                0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
 411                0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
 412                0xfe, 0xfe, 0xff, 0xff, 0xff
 413        };
 414        pss_write(devc, 0x0010);
 415        pss_write(devc, log_scale[left] | 0x0000);
 416        pss_write(devc, 0x0010);
 417        pss_write(devc, log_scale[right] | 0x0100);
 418}
 419
 420static void set_synth_volume(struct pss_confdata *devc, int volume)
 421{
 422        int vol = ((0x8000*volume)/100L);
 423        pss_write(devc, 0x0080);
 424        pss_write(devc, vol);
 425        pss_write(devc, 0x0081);
 426        pss_write(devc, vol);
 427}
 428
 429static void set_bass(struct pss_confdata *devc, int level)
 430{
 431        int vol = (int)(((0xfd - 0xf0) * level)/100L) + 0xf0;
 432        pss_write(devc, 0x0010);
 433        pss_write(devc, vol | 0x0200);
 434};
 435
 436static void set_treble(struct pss_confdata *devc, int level)
 437{       
 438        int vol = (((0xfd - 0xf0) * level)/100L) + 0xf0;
 439        pss_write(devc, 0x0010);
 440        pss_write(devc, vol | 0x0300);
 441};
 442
 443static void pss_mixer_reset(struct pss_confdata *devc)
 444{
 445        set_master_volume(devc, 33, 33);
 446        set_bass(devc, 50);
 447        set_treble(devc, 50);
 448        set_synth_volume(devc, 30);
 449        pss_write (devc, 0x0010);
 450        pss_write (devc, 0x0800 | 0xce);        /* Stereo */
 451        
 452        if(pss_mixer)
 453        {
 454                devc->mixer.volume_l = devc->mixer.volume_r = 33;
 455                devc->mixer.bass = 50;
 456                devc->mixer.treble = 50;
 457                devc->mixer.synth = 30;
 458        }
 459}
 460
 461static int set_volume_mono(unsigned __user *p, unsigned int *aleft)
 462{
 463        unsigned int left, volume;
 464        if (get_user(volume, p))
 465                return -EFAULT;
 466        
 467        left = volume & 0xff;
 468        if (left > 100)
 469                left = 100;
 470        *aleft = left;
 471        return 0;
 472}
 473
 474static int set_volume_stereo(unsigned __user *p,
 475                             unsigned int *aleft,
 476                             unsigned int *aright)
 477{
 478        unsigned int left, right, volume;
 479        if (get_user(volume, p))
 480                return -EFAULT;
 481
 482        left = volume & 0xff;
 483        if (left > 100)
 484                left = 100;
 485        right = (volume >> 8) & 0xff;
 486        if (right > 100)
 487                right = 100;
 488        *aleft = left;
 489        *aright = right;
 490        return 0;
 491}
 492
 493static int ret_vol_mono(int left)
 494{
 495        return ((left << 8) | left);
 496}
 497
 498static int ret_vol_stereo(int left, int right)
 499{
 500        return ((right << 8) | left);
 501}
 502
 503static int call_ad_mixer(struct pss_confdata *devc, unsigned int cmd,
 504                         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
 512static int pss_mixer_ioctl (int dev, unsigned int cmd, void __user *arg)
 513{
 514        struct 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
 643static 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
 651static 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
 660static 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                printk(KERN_INFO "PSS: CDROM port not enabled.\n");
 678        } else if (!request_region(pss_cdrom_port, 2, "PSS CDROM")) {
 679                pss_cdrom_port = -1;
 680                printk(KERN_ERR "PSS: CDROM I/O port conflict.\n");
 681        } else {
 682                set_io_base(devc, CONF_CDROM, pss_cdrom_port);
 683                printk(KERN_INFO "PSS: CDROM I/O port set to 0x%x.\n", pss_cdrom_port);
 684        }
 685}
 686
 687static int __init attach_pss(struct address_info *hw_config)
 688{
 689        unsigned short  id;
 690        char tmp[100];
 691
 692        devc->base = hw_config->io_base;
 693        devc->irq = hw_config->irq;
 694        devc->dma = hw_config->dma;
 695        devc->osp = hw_config->osp;
 696        devc->ad_mixer_dev = NO_WSS_MIXER;
 697
 698        if (!probe_pss(hw_config))
 699                return 0;
 700
 701        id = inw(REG(PSS_ID)) & 0x00ff;
 702
 703        /*
 704         * Disable all emulations. Will be enabled later (if required).
 705         */
 706         
 707        disable_all_emulations();
 708
 709#ifdef YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
 710        if (sound_alloc_dma(hw_config->dma, "PSS"))
 711        {
 712                printk("pss.c: Can't allocate DMA channel.\n");
 713                release_region(hw_config->io_base, 0x10);
 714                release_region(hw_config->io_base+0x10, 0x9);
 715                return 0;
 716        }
 717        if (!set_irq(devc, CONF_PSS, devc->irq))
 718        {
 719                printk("PSS: IRQ allocation error.\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_dma(devc, CONF_PSS, devc->dma))
 725        {
 726                printk(KERN_ERR "PSS: DMA 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#endif
 732
 733        configure_nonsound_components();
 734        pss_initialized = 1;
 735        sprintf(tmp, "ECHO-PSS  Rev. %d", id);
 736        conf_printf(tmp, hw_config);
 737        return 1;
 738}
 739
 740static int __init probe_pss_mpu(struct address_info *hw_config)
 741{
 742        struct resource *ports;
 743        int timeout;
 744
 745        if (!pss_initialized)
 746                return 0;
 747
 748        ports = request_region(hw_config->io_base, 2, "mpu401");
 749
 750        if (!ports) {
 751                printk(KERN_ERR "PSS: MPU I/O port conflict\n");
 752                return 0;
 753        }
 754        set_io_base(devc, CONF_MIDI, hw_config->io_base);
 755        if (!set_irq(devc, CONF_MIDI, hw_config->irq)) {
 756                printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n");
 757                goto fail;
 758        }
 759        if (!pss_synthLen) {
 760                printk(KERN_ERR "PSS: Can't enable MPU. MIDI synth microcode not available.\n");
 761                goto fail;
 762        }
 763        if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
 764                printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
 765                goto fail;
 766        }
 767
 768        /*
 769         * Finally wait until the DSP algorithm has initialized itself and
 770         * deactivates receive interrupt.
 771         */
 772
 773        for (timeout = 900000; timeout > 0; timeout--)
 774        {
 775                if ((inb(hw_config->io_base + 1) & 0x80) == 0)  /* Input data avail */
 776                        inb(hw_config->io_base);        /* Discard it */
 777                else
 778                        break;  /* No more input */
 779        }
 780
 781        if (!probe_mpu401(hw_config, ports))
 782                goto fail;
 783
 784        attach_mpu401(hw_config, THIS_MODULE);  /* Slot 1 */
 785        if (hw_config->slots[1] != -1)  /* The MPU driver installed itself */
 786                midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
 787        return 1;
 788fail:
 789        release_region(hw_config->io_base, 2);
 790        return 0;
 791}
 792
 793static int pss_coproc_open(void *dev_info, int sub_device)
 794{
 795        switch (sub_device)
 796        {
 797                case COPR_MIDI:
 798                        if (pss_synthLen == 0)
 799                        {
 800                                printk(KERN_ERR "PSS: MIDI synth microcode not available.\n");
 801                                return -EIO;
 802                        }
 803                        if (nonstandard_microcode)
 804                                if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
 805                        {
 806                                printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
 807                                return -EIO;
 808                        }
 809                        nonstandard_microcode = 0;
 810                        break;
 811
 812                default:
 813                        break;
 814        }
 815        return 0;
 816}
 817
 818static void pss_coproc_close(void *dev_info, int sub_device)
 819{
 820        return;
 821}
 822
 823static void pss_coproc_reset(void *dev_info)
 824{
 825        if (pss_synthLen)
 826                if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
 827                {
 828                        printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
 829                }
 830        nonstandard_microcode = 0;
 831}
 832
 833static int download_boot_block(void *dev_info, copr_buffer * buf)
 834{
 835        if (buf->len <= 0 || buf->len > sizeof(buf->data))
 836                return -EINVAL;
 837
 838        if (!pss_download_boot(devc, buf->data, buf->len, buf->flags))
 839        {
 840                printk(KERN_ERR "PSS: Unable to load microcode block to DSP.\n");
 841                return -EIO;
 842        }
 843        nonstandard_microcode = 1;      /* The MIDI microcode has been overwritten */
 844        return 0;
 845}
 846
 847static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
 848{
 849        copr_buffer *buf;
 850        copr_msg *mbuf;
 851        copr_debug_buf dbuf;
 852        unsigned short tmp;
 853        unsigned long flags;
 854        unsigned short *data;
 855        int i, err;
 856        /* printk( "PSS coproc ioctl %x %x %d\n",  cmd,  arg,  local); */
 857        
 858        switch (cmd) 
 859        {
 860                case SNDCTL_COPR_RESET:
 861                        pss_coproc_reset(dev_info);
 862                        return 0;
 863
 864                case SNDCTL_COPR_LOAD:
 865                        buf = vmalloc(sizeof(copr_buffer));
 866                        if (buf == NULL)
 867                                return -ENOSPC;
 868                        if (copy_from_user(buf, arg, sizeof(copr_buffer))) {
 869                                vfree(buf);
 870                                return -EFAULT;
 871                        }
 872                        err = download_boot_block(dev_info, buf);
 873                        vfree(buf);
 874                        return err;
 875                
 876                case SNDCTL_COPR_SENDMSG:
 877                        mbuf = vmalloc(sizeof(copr_msg));
 878                        if (mbuf == NULL)
 879                                return -ENOSPC;
 880                        if (copy_from_user(mbuf, arg, sizeof(copr_msg))) {
 881                                vfree(mbuf);
 882                                return -EFAULT;
 883                        }
 884                        data = (unsigned short *)(mbuf->data);
 885                        spin_lock_irqsave(&lock, flags);
 886                        for (i = 0; i < mbuf->len; i++) {
 887                                if (!pss_put_dspword(devc, *data++)) {
 888                                        spin_unlock_irqrestore(&lock,flags);
 889                                        mbuf->len = i;  /* feed back number of WORDs sent */
 890                                        err = copy_to_user(arg, mbuf, sizeof(copr_msg));
 891                                        vfree(mbuf);
 892                                        return err ? -EFAULT : -EIO;
 893                                }
 894                        }
 895                        spin_unlock_irqrestore(&lock,flags);
 896                        vfree(mbuf);
 897                        return 0;
 898
 899                case SNDCTL_COPR_RCVMSG:
 900                        err = 0;
 901                        mbuf = vmalloc(sizeof(copr_msg));
 902                        if (mbuf == NULL)
 903                                return -ENOSPC;
 904                        data = (unsigned short *)mbuf->data;
 905                        spin_lock_irqsave(&lock, flags);
 906                        for (i = 0; i < sizeof(mbuf->data)/sizeof(unsigned short); i++) {
 907                                mbuf->len = i;  /* feed back number of WORDs read */
 908                                if (!pss_get_dspword(devc, data++)) {
 909                                        if (i == 0)
 910                                                err = -EIO;
 911                                        break;
 912                                }
 913                        }
 914                        spin_unlock_irqrestore(&lock,flags);
 915                        if (copy_to_user(arg, mbuf, sizeof(copr_msg)))
 916                                err = -EFAULT;
 917                        vfree(mbuf);
 918                        return err;
 919                
 920                case SNDCTL_COPR_RDATA:
 921                        if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
 922                                return -EFAULT;
 923                        spin_lock_irqsave(&lock, flags);
 924                        if (!pss_put_dspword(devc, 0x00d0)) {
 925                                spin_unlock_irqrestore(&lock,flags);
 926                                return -EIO;
 927                        }
 928                        if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
 929                                spin_unlock_irqrestore(&lock,flags);
 930                                return -EIO;
 931                        }
 932                        if (!pss_get_dspword(devc, &tmp)) {
 933                                spin_unlock_irqrestore(&lock,flags);
 934                                return -EIO;
 935                        }
 936                        dbuf.parm1 = tmp;
 937                        spin_unlock_irqrestore(&lock,flags);
 938                        if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
 939                                return -EFAULT;
 940                        return 0;
 941                
 942                case SNDCTL_COPR_WDATA:
 943                        if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
 944                                return -EFAULT;
 945                        spin_lock_irqsave(&lock, flags);
 946                        if (!pss_put_dspword(devc, 0x00d1)) {
 947                                spin_unlock_irqrestore(&lock,flags);
 948                                return -EIO;
 949                        }
 950                        if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
 951                                spin_unlock_irqrestore(&lock,flags);
 952                                return -EIO;
 953                        }
 954                        tmp = (unsigned int)dbuf.parm2 & 0xffff;
 955                        if (!pss_put_dspword(devc, tmp)) {
 956                                spin_unlock_irqrestore(&lock,flags);
 957                                return -EIO;
 958                        }
 959                        spin_unlock_irqrestore(&lock,flags);
 960                        return 0;
 961                
 962                case SNDCTL_COPR_WCODE:
 963                        if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
 964                                return -EFAULT;
 965                        spin_lock_irqsave(&lock, flags);
 966                        if (!pss_put_dspword(devc, 0x00d3)) {
 967                                spin_unlock_irqrestore(&lock,flags);
 968                                return -EIO;
 969                        }
 970                        if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
 971                                spin_unlock_irqrestore(&lock,flags);
 972                                return -EIO;
 973                        }
 974                        tmp = (unsigned int)dbuf.parm2 & 0x00ff;
 975                        if (!pss_put_dspword(devc, tmp)) {
 976                                spin_unlock_irqrestore(&lock,flags);
 977                                return -EIO;
 978                        }
 979                        tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
 980                        if (!pss_put_dspword(devc, tmp)) {
 981                                spin_unlock_irqrestore(&lock,flags);
 982                                return -EIO;
 983                        }
 984                        spin_unlock_irqrestore(&lock,flags);
 985                        return 0;
 986                
 987                case SNDCTL_COPR_RCODE:
 988                        if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
 989                                return -EFAULT;
 990                        spin_lock_irqsave(&lock, flags);
 991                        if (!pss_put_dspword(devc, 0x00d2)) {
 992                                spin_unlock_irqrestore(&lock,flags);
 993                                return -EIO;
 994                        }
 995                        if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
 996                                spin_unlock_irqrestore(&lock,flags);
 997                                return -EIO;
 998                        }
 999                        if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
1000                                spin_unlock_irqrestore(&lock,flags);
1001                                return -EIO;
1002                        }
1003                        dbuf.parm1 = tmp << 8;
1004                        if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
1005                                spin_unlock_irqrestore(&lock,flags);
1006                                return -EIO;
1007                        }
1008                        dbuf.parm1 |= tmp & 0x00ff;
1009                        spin_unlock_irqrestore(&lock,flags);
1010                        if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
1011                                return -EFAULT;
1012                        return 0;
1013
1014                default:
1015                        return -EINVAL;
1016        }
1017        return -EINVAL;
1018}
1019
1020static coproc_operations pss_coproc_operations =
1021{
1022        "ADSP-2115",
1023        THIS_MODULE,
1024        pss_coproc_open,
1025        pss_coproc_close,
1026        pss_coproc_ioctl,
1027        pss_coproc_reset,
1028        &pss_data
1029};
1030
1031static int __init probe_pss_mss(struct address_info *hw_config)
1032{
1033        volatile int timeout;
1034        struct resource *ports;
1035        int        my_mix = -999;       /* gcc shut up */
1036
1037        if (!pss_initialized)
1038                return 0;
1039
1040        if (!request_region(hw_config->io_base, 4, "WSS config")) {
1041                printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1042                return 0;
1043        }
1044        ports = request_region(hw_config->io_base + 4, 4, "ad1848");
1045        if (!ports) {
1046                printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
1047                release_region(hw_config->io_base, 4);
1048                return 0;
1049        }
1050        set_io_base(devc, CONF_WSS, hw_config->io_base);
1051        if (!set_irq(devc, CONF_WSS, hw_config->irq)) {
1052                printk("PSS: WSS IRQ allocation error.\n");
1053                goto fail;
1054        }
1055        if (!set_dma(devc, CONF_WSS, hw_config->dma)) {
1056                printk(KERN_ERR "PSS: WSS DMA allocation error\n");
1057                goto fail;
1058        }
1059        /*
1060         * For some reason the card returns 0xff in the WSS status register
1061         * immediately after boot. Probably MIDI+SB emulation algorithm
1062         * downloaded to the ADSP2115 spends some time initializing the card.
1063         * Let's try to wait until it finishes this task.
1064         */
1065        for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) &
1066          WSS_INITIALIZING); timeout++)
1067                ;
1068
1069        outb((0x0b), hw_config->io_base + WSS_INDEX);   /* Required by some cards */
1070
1071        for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) &&
1072          (timeout < 100000); timeout++)
1073                ;
1074
1075        if (!probe_ms_sound(hw_config, ports))
1076                goto fail;
1077
1078        devc->ad_mixer_dev = NO_WSS_MIXER;
1079        if (pss_mixer) 
1080        {
1081                if ((my_mix = sound_install_mixer (MIXER_DRIVER_VERSION,
1082                        "PSS-SPEAKERS and AD1848 (through MSS audio codec)",
1083                        &pss_mixer_operations,
1084                        sizeof (struct mixer_operations),
1085                        devc)) < 0) 
1086                {
1087                        printk(KERN_ERR "Could not install PSS mixer\n");
1088                        goto fail;
1089                }
1090        }
1091        pss_mixer_reset(devc);
1092        attach_ms_sound(hw_config, ports, THIS_MODULE); /* Slot 0 */
1093
1094        if (hw_config->slots[0] != -1)
1095        {
1096                /* The MSS driver installed itself */
1097                audio_devs[hw_config->slots[0]]->coproc = &pss_coproc_operations;
1098                if (pss_mixer && (num_mixers == (my_mix + 2)))
1099                {
1100                        /* The MSS mixer installed */
1101                        devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;
1102                }
1103        }
1104        return 1;
1105fail:
1106        release_region(hw_config->io_base + 4, 4);
1107        release_region(hw_config->io_base, 4);
1108        return 0;
1109}
1110
1111static inline void __exit unload_pss(struct address_info *hw_config)
1112{
1113        release_region(hw_config->io_base, 0x10);
1114        release_region(hw_config->io_base+0x10, 0x9);
1115}
1116
1117static inline void __exit unload_pss_mpu(struct address_info *hw_config)
1118{
1119        unload_mpu401(hw_config);
1120}
1121
1122static inline void __exit unload_pss_mss(struct address_info *hw_config)
1123{
1124        unload_ms_sound(hw_config);
1125}
1126
1127
1128static struct address_info cfg;
1129static struct address_info cfg2;
1130static struct address_info cfg_mpu;
1131
1132static int pss_io __initdata    = -1;
1133static int mss_io __initdata    = -1;
1134static int mss_irq __initdata   = -1;
1135static int mss_dma __initdata   = -1;
1136static int mpu_io __initdata    = -1;
1137static int mpu_irq __initdata   = -1;
1138static bool pss_no_sound = 0;   /* Just configure non-sound components */
1139static bool pss_keep_settings  = 1;     /* Keep hardware settings at module exit */
1140static char *pss_firmware = "/etc/sound/pss_synth";
1141
1142module_param_hw(pss_io, int, ioport, 0);
1143MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
1144module_param_hw(mss_io, int, ioport, 0);
1145MODULE_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)");
1146module_param_hw(mss_irq, int, irq, 0);
1147MODULE_PARM_DESC(mss_irq, "Set WSS (audio) IRQ (3, 5, 7, 9, 10, 11, 12)");
1148module_param_hw(mss_dma, int, dma, 0);
1149MODULE_PARM_DESC(mss_dma, "Set WSS (audio) DMA (0, 1, 3)");
1150module_param_hw(mpu_io, int, ioport, 0);
1151MODULE_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)");
1152module_param_hw(mpu_irq, int, irq, 0);
1153MODULE_PARM_DESC(mpu_irq, "Set MIDI IRQ (3, 5, 7, 9, 10, 11, 12)");
1154module_param_hw(pss_cdrom_port, int, ioport, 0);
1155MODULE_PARM_DESC(pss_cdrom_port, "Set the PSS CDROM port i/o base (0x340 or other)");
1156module_param(pss_enable_joystick, bool, 0);
1157MODULE_PARM_DESC(pss_enable_joystick, "Enables the PSS joystick port (1 to enable, 0 to disable)");
1158module_param(pss_no_sound, bool, 0);
1159MODULE_PARM_DESC(pss_no_sound, "Configure sound compoents (0 - no, 1 - yes)");
1160module_param(pss_keep_settings, bool, 0);
1161MODULE_PARM_DESC(pss_keep_settings, "Keep hardware setting at driver unloading (0 - no, 1 - yes)");
1162module_param(pss_firmware, charp, 0);
1163MODULE_PARM_DESC(pss_firmware, "Location of the firmware file (default - /etc/sound/pss_synth)");
1164module_param(pss_mixer, bool, 0);
1165MODULE_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.");
1166MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
1167MODULE_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).");
1168MODULE_LICENSE("GPL");
1169
1170
1171static int fw_load = 0;
1172static int pssmpu = 0, pssmss = 0;
1173
1174/*
1175 *    Load a PSS sound card module
1176 */
1177
1178static int __init init_pss(void)
1179{
1180
1181        if(pss_no_sound)                /* If configuring only nonsound components */
1182        {
1183                cfg.io_base = pss_io;
1184                if(!probe_pss(&cfg))
1185                        return -ENODEV;
1186                printk(KERN_INFO "ECHO-PSS  Rev. %d\n", inw(REG(PSS_ID)) & 0x00ff);
1187                printk(KERN_INFO "PSS: loading in no sound mode.\n");
1188                disable_all_emulations();
1189                configure_nonsound_components();
1190                release_region(pss_io, 0x10);
1191                release_region(pss_io + 0x10, 0x9);
1192                return 0;
1193        }
1194
1195        cfg.io_base = pss_io;
1196
1197        cfg2.io_base = mss_io;
1198        cfg2.irq = mss_irq;
1199        cfg2.dma = mss_dma;
1200
1201        cfg_mpu.io_base = mpu_io;
1202        cfg_mpu.irq = mpu_irq;
1203
1204        if (cfg.io_base == -1 || cfg2.io_base == -1 || cfg2.irq == -1 || cfg.dma == -1) {
1205                printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
1206                return -EINVAL;
1207        }
1208
1209        if (!pss_synth) {
1210                fw_load = 1;
1211                pss_synthLen = mod_firmware_load(pss_firmware, (void *) &pss_synth);
1212        }
1213        if (!attach_pss(&cfg))
1214                return -ENODEV;
1215        /*
1216         *    Attach stuff
1217         */
1218        if (probe_pss_mpu(&cfg_mpu))
1219                pssmpu = 1;
1220
1221        if (probe_pss_mss(&cfg2))
1222                pssmss = 1;
1223
1224        return 0;
1225}
1226
1227static void __exit cleanup_pss(void)
1228{
1229        if(!pss_no_sound)
1230        {
1231                if (fw_load)
1232                        vfree(pss_synth);
1233                if(pssmss)
1234                        unload_pss_mss(&cfg2);
1235                if(pssmpu)
1236                        unload_pss_mpu(&cfg_mpu);
1237                unload_pss(&cfg);
1238        } else if (pss_cdrom_port != -1)
1239                release_region(pss_cdrom_port, 2);
1240
1241        if(!pss_keep_settings)  /* Keep hardware settings if asked */
1242        {
1243                disable_all_emulations();
1244                printk(KERN_INFO "Resetting PSS sound card configurations.\n");
1245        }
1246}
1247
1248module_init(init_pss);
1249module_exit(cleanup_pss);
1250
1251#ifndef MODULE
1252static int __init setup_pss(char *str)
1253{
1254        /* io, mss_io, mss_irq, mss_dma, mpu_io, mpu_irq */
1255        int ints[7];
1256        
1257        str = get_options(str, ARRAY_SIZE(ints), ints);
1258
1259        pss_io  = ints[1];
1260        mss_io  = ints[2];
1261        mss_irq = ints[3];
1262        mss_dma = ints[4];
1263        mpu_io  = ints[5];
1264        mpu_irq = ints[6];
1265
1266        return 1;
1267}
1268
1269__setup("pss=", setup_pss);
1270#endif
1271