Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     card-opti92x-ad1848.c - driver for OPTi 82c92x based soundcards.
0004     Copyright (C) 1998-2000 by Massimo Piccioni <dafastidio@libero.it>
0005 
0006     Part of this code was developed at the Italian Ministry of Air Defence,
0007     Sixth Division (oh, che pace ...), Rome.
0008 
0009     Thanks to Maria Grazia Pollarini, Salvatore Vassallo.
0010 
0011 */
0012 
0013 
0014 #include <linux/init.h>
0015 #include <linux/err.h>
0016 #include <linux/isa.h>
0017 #include <linux/delay.h>
0018 #include <linux/pnp.h>
0019 #include <linux/module.h>
0020 #include <linux/io.h>
0021 #include <asm/dma.h>
0022 #include <sound/core.h>
0023 #include <sound/tlv.h>
0024 #include <sound/wss.h>
0025 #include <sound/mpu401.h>
0026 #include <sound/opl3.h>
0027 #ifndef OPTi93X
0028 #include <sound/opl4.h>
0029 #endif
0030 #define SNDRV_LEGACY_FIND_FREE_IOPORT
0031 #define SNDRV_LEGACY_FIND_FREE_IRQ
0032 #define SNDRV_LEGACY_FIND_FREE_DMA
0033 #include <sound/initval.h>
0034 
0035 MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
0036 MODULE_LICENSE("GPL");
0037 #ifdef OPTi93X
0038 MODULE_DESCRIPTION("OPTi93X");
0039 #else   /* OPTi93X */
0040 #ifdef CS4231
0041 MODULE_DESCRIPTION("OPTi92X - CS4231");
0042 #else   /* CS4231 */
0043 MODULE_DESCRIPTION("OPTi92X - AD1848");
0044 #endif  /* CS4231 */
0045 #endif  /* OPTi93X */
0046 
0047 static int index = SNDRV_DEFAULT_IDX1;  /* Index 0-MAX */
0048 static char *id = SNDRV_DEFAULT_STR1;       /* ID for this card */
0049 //static bool enable = SNDRV_DEFAULT_ENABLE1;   /* Enable this card */
0050 #ifdef CONFIG_PNP
0051 static bool isapnp = true;          /* Enable ISA PnP detection */
0052 #endif
0053 static long port = SNDRV_DEFAULT_PORT1;     /* 0x530,0xe80,0xf40,0x604 */
0054 static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */
0055 static long fm_port = SNDRV_DEFAULT_PORT1;  /* 0x388 */
0056 static int irq = SNDRV_DEFAULT_IRQ1;        /* 5,7,9,10,11 */
0057 static int mpu_irq = SNDRV_DEFAULT_IRQ1;    /* 5,7,9,10 */
0058 static int dma1 = SNDRV_DEFAULT_DMA1;       /* 0,1,3 */
0059 #if defined(CS4231) || defined(OPTi93X)
0060 static int dma2 = SNDRV_DEFAULT_DMA1;       /* 0,1,3 */
0061 #endif  /* CS4231 || OPTi93X */
0062 
0063 module_param(index, int, 0444);
0064 MODULE_PARM_DESC(index, "Index value for opti9xx based soundcard.");
0065 module_param(id, charp, 0444);
0066 MODULE_PARM_DESC(id, "ID string for opti9xx based soundcard.");
0067 //module_param(enable, bool, 0444);
0068 //MODULE_PARM_DESC(enable, "Enable opti9xx soundcard.");
0069 #ifdef CONFIG_PNP
0070 module_param(isapnp, bool, 0444);
0071 MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
0072 #endif
0073 module_param_hw(port, long, ioport, 0444);
0074 MODULE_PARM_DESC(port, "WSS port # for opti9xx driver.");
0075 module_param_hw(mpu_port, long, ioport, 0444);
0076 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for opti9xx driver.");
0077 module_param_hw(fm_port, long, ioport, 0444);
0078 MODULE_PARM_DESC(fm_port, "FM port # for opti9xx driver.");
0079 module_param_hw(irq, int, irq, 0444);
0080 MODULE_PARM_DESC(irq, "WSS irq # for opti9xx driver.");
0081 module_param_hw(mpu_irq, int, irq, 0444);
0082 MODULE_PARM_DESC(mpu_irq, "MPU-401 irq # for opti9xx driver.");
0083 module_param_hw(dma1, int, dma, 0444);
0084 MODULE_PARM_DESC(dma1, "1st dma # for opti9xx driver.");
0085 #if defined(CS4231) || defined(OPTi93X)
0086 module_param_hw(dma2, int, dma, 0444);
0087 MODULE_PARM_DESC(dma2, "2nd dma # for opti9xx driver.");
0088 #endif  /* CS4231 || OPTi93X */
0089 
0090 #define OPTi9XX_HW_82C928   1
0091 #define OPTi9XX_HW_82C929   2
0092 #define OPTi9XX_HW_82C924   3
0093 #define OPTi9XX_HW_82C925   4
0094 #define OPTi9XX_HW_82C930   5
0095 #define OPTi9XX_HW_82C931   6
0096 #define OPTi9XX_HW_82C933   7
0097 #define OPTi9XX_HW_LAST     OPTi9XX_HW_82C933
0098 
0099 #define OPTi9XX_MC_REG(n)   n
0100 
0101 #ifdef OPTi93X
0102 
0103 #define OPTi93X_STATUS          0x02
0104 #define OPTi93X_PORT(chip, r)       ((chip)->port + OPTi93X_##r)
0105 
0106 #define OPTi93X_IRQ_PLAYBACK        0x04
0107 #define OPTi93X_IRQ_CAPTURE     0x08
0108 
0109 #endif /* OPTi93X */
0110 
0111 struct snd_opti9xx {
0112     unsigned short hardware;
0113     unsigned char password;
0114     char name[7];
0115 
0116     unsigned long mc_base;
0117     struct resource *res_mc_base;
0118     unsigned long mc_base_size;
0119 #ifdef OPTi93X
0120     unsigned long mc_indir_index;
0121     struct resource *res_mc_indir;
0122 #endif  /* OPTi93X */
0123     struct snd_wss *codec;
0124     unsigned long pwd_reg;
0125 
0126     spinlock_t lock;
0127 
0128     long wss_base;
0129     int irq;
0130 };
0131 
0132 static int snd_opti9xx_pnp_is_probed;
0133 
0134 #ifdef CONFIG_PNP
0135 
0136 static const struct pnp_card_device_id snd_opti9xx_pnpids[] = {
0137 #ifndef OPTi93X
0138     /* OPTi 82C924 */
0139     { .id = "OPT0924",
0140       .devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } },
0141       .driver_data = 0x0924 },
0142     /* OPTi 82C925 */
0143     { .id = "OPT0925",
0144       .devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } },
0145       .driver_data = 0x0925 },
0146 #else
0147     /* OPTi 82C931/3 */
0148     { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } },
0149       .driver_data = 0x0931 },
0150 #endif  /* OPTi93X */
0151     { .id = "" }
0152 };
0153 
0154 MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
0155 
0156 #endif  /* CONFIG_PNP */
0157 
0158 #define DEV_NAME KBUILD_MODNAME
0159 
0160 static const char * const snd_opti9xx_names[] = {
0161     "unknown",
0162     "82C928",   "82C929",
0163     "82C924",   "82C925",
0164     "82C930",   "82C931",   "82C933"
0165 };
0166 
0167 static int snd_opti9xx_init(struct snd_opti9xx *chip,
0168                 unsigned short hardware)
0169 {
0170     static const int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
0171 
0172     chip->hardware = hardware;
0173     strcpy(chip->name, snd_opti9xx_names[hardware]);
0174 
0175     spin_lock_init(&chip->lock);
0176 
0177     chip->irq = -1;
0178 
0179 #ifndef OPTi93X
0180 #ifdef CONFIG_PNP
0181     if (isapnp && chip->mc_base)
0182         /* PnP resource gives the least 10 bits */
0183         chip->mc_base |= 0xc00;
0184     else
0185 #endif  /* CONFIG_PNP */
0186     {
0187         chip->mc_base = 0xf8c;
0188         chip->mc_base_size = opti9xx_mc_size[hardware];
0189     }
0190 #else
0191         chip->mc_base_size = opti9xx_mc_size[hardware];
0192 #endif
0193 
0194     switch (hardware) {
0195 #ifndef OPTi93X
0196     case OPTi9XX_HW_82C928:
0197     case OPTi9XX_HW_82C929:
0198         chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3;
0199         chip->pwd_reg = 3;
0200         break;
0201 
0202     case OPTi9XX_HW_82C924:
0203     case OPTi9XX_HW_82C925:
0204         chip->password = 0xe5;
0205         chip->pwd_reg = 3;
0206         break;
0207 #else   /* OPTi93X */
0208 
0209     case OPTi9XX_HW_82C930:
0210     case OPTi9XX_HW_82C931:
0211     case OPTi9XX_HW_82C933:
0212         chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
0213         if (!chip->mc_indir_index)
0214             chip->mc_indir_index = 0xe0e;
0215         chip->password = 0xe4;
0216         chip->pwd_reg = 0;
0217         break;
0218 #endif  /* OPTi93X */
0219 
0220     default:
0221         snd_printk(KERN_ERR "chip %d not supported\n", hardware);
0222         return -ENODEV;
0223     }
0224     return 0;
0225 }
0226 
0227 static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
0228                       unsigned char reg)
0229 {
0230     unsigned long flags;
0231     unsigned char retval = 0xff;
0232 
0233     spin_lock_irqsave(&chip->lock, flags);
0234     outb(chip->password, chip->mc_base + chip->pwd_reg);
0235 
0236     switch (chip->hardware) {
0237 #ifndef OPTi93X
0238     case OPTi9XX_HW_82C924:
0239     case OPTi9XX_HW_82C925:
0240         if (reg > 7) {
0241             outb(reg, chip->mc_base + 8);
0242             outb(chip->password, chip->mc_base + chip->pwd_reg);
0243             retval = inb(chip->mc_base + 9);
0244             break;
0245         }
0246         fallthrough;
0247 
0248     case OPTi9XX_HW_82C928:
0249     case OPTi9XX_HW_82C929:
0250         retval = inb(chip->mc_base + reg);
0251         break;
0252 #else   /* OPTi93X */
0253 
0254     case OPTi9XX_HW_82C930:
0255     case OPTi9XX_HW_82C931:
0256     case OPTi9XX_HW_82C933:
0257         outb(reg, chip->mc_indir_index);
0258         outb(chip->password, chip->mc_base + chip->pwd_reg);
0259         retval = inb(chip->mc_indir_index + 1);
0260         break;
0261 #endif  /* OPTi93X */
0262 
0263     default:
0264         snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
0265     }
0266 
0267     spin_unlock_irqrestore(&chip->lock, flags);
0268     return retval;
0269 }
0270 
0271 static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
0272                   unsigned char value)
0273 {
0274     unsigned long flags;
0275 
0276     spin_lock_irqsave(&chip->lock, flags);
0277     outb(chip->password, chip->mc_base + chip->pwd_reg);
0278 
0279     switch (chip->hardware) {
0280 #ifndef OPTi93X
0281     case OPTi9XX_HW_82C924:
0282     case OPTi9XX_HW_82C925:
0283         if (reg > 7) {
0284             outb(reg, chip->mc_base + 8);
0285             outb(chip->password, chip->mc_base + chip->pwd_reg);
0286             outb(value, chip->mc_base + 9);
0287             break;
0288         }
0289         fallthrough;
0290 
0291     case OPTi9XX_HW_82C928:
0292     case OPTi9XX_HW_82C929:
0293         outb(value, chip->mc_base + reg);
0294         break;
0295 #else   /* OPTi93X */
0296 
0297     case OPTi9XX_HW_82C930:
0298     case OPTi9XX_HW_82C931:
0299     case OPTi9XX_HW_82C933:
0300         outb(reg, chip->mc_indir_index);
0301         outb(chip->password, chip->mc_base + chip->pwd_reg);
0302         outb(value, chip->mc_indir_index + 1);
0303         break;
0304 #endif  /* OPTi93X */
0305 
0306     default:
0307         snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
0308     }
0309 
0310     spin_unlock_irqrestore(&chip->lock, flags);
0311 }
0312 
0313 
0314 static inline void snd_opti9xx_write_mask(struct snd_opti9xx *chip,
0315         unsigned char reg, unsigned char value, unsigned char mask)
0316 {
0317     unsigned char oldval = snd_opti9xx_read(chip, reg);
0318 
0319     snd_opti9xx_write(chip, reg, (oldval & ~mask) | (value & mask));
0320 }
0321 
0322 static int snd_opti9xx_configure(struct snd_opti9xx *chip,
0323                        long port,
0324                        int irq, int dma1, int dma2,
0325                        long mpu_port, int mpu_irq)
0326 {
0327     unsigned char wss_base_bits;
0328     unsigned char irq_bits;
0329     unsigned char dma_bits;
0330     unsigned char mpu_port_bits = 0;
0331     unsigned char mpu_irq_bits;
0332 
0333     switch (chip->hardware) {
0334 #ifndef OPTi93X
0335     case OPTi9XX_HW_82C924:
0336         /* opti 929 mode (?), OPL3 clock output, audio enable */
0337         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
0338         /* enable wave audio */
0339         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
0340         fallthrough;
0341 
0342     case OPTi9XX_HW_82C925:
0343         /* enable WSS mode */
0344         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
0345         /* OPL3 FM synthesis */
0346         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
0347         /* disable Sound Blaster IRQ and DMA */
0348         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
0349 #ifdef CS4231
0350         /* cs4231/4248 fix enabled */
0351         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
0352 #else
0353         /* cs4231/4248 fix disabled */
0354         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
0355 #endif  /* CS4231 */
0356         break;
0357 
0358     case OPTi9XX_HW_82C928:
0359     case OPTi9XX_HW_82C929:
0360         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
0361         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
0362         /*
0363         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xa2, 0xae);
0364         */
0365         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);
0366 #ifdef CS4231
0367         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
0368 #else
0369         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
0370 #endif  /* CS4231 */
0371         break;
0372 
0373 #else   /* OPTi93X */
0374     case OPTi9XX_HW_82C931:
0375         /* disable 3D sound (set GPIO1 as output, low) */
0376         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(20), 0x04, 0x0c);
0377         fallthrough;
0378 
0379     case OPTi9XX_HW_82C933:
0380         /*
0381          * The BTC 1817DW has QS1000 wavetable which is connected
0382          * to the serial digital input of the OPTI931.
0383          */
0384         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(21), 0x82, 0xff);
0385         /* 
0386          * This bit sets OPTI931 to automaticaly select FM
0387          * or digital input signal.
0388          */
0389         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(26), 0x01, 0x01);
0390         fallthrough;
0391 
0392     case OPTi9XX_HW_82C930:
0393         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x03);
0394         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0x00, 0xff);
0395         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x10 |
0396             (chip->hardware == OPTi9XX_HW_82C930 ? 0x00 : 0x04),
0397             0x34);
0398         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x20, 0xbf);
0399         break;
0400 #endif  /* OPTi93X */
0401 
0402     default:
0403         snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
0404         return -EINVAL;
0405     }
0406 
0407     /* PnP resource says it decodes only 10 bits of address */
0408     switch (port & 0x3ff) {
0409     case 0x130:
0410         chip->wss_base = 0x530;
0411         wss_base_bits = 0x00;
0412         break;
0413     case 0x204:
0414         chip->wss_base = 0x604;
0415         wss_base_bits = 0x03;
0416         break;
0417     case 0x280:
0418         chip->wss_base = 0xe80;
0419         wss_base_bits = 0x01;
0420         break;
0421     case 0x340:
0422         chip->wss_base = 0xf40;
0423         wss_base_bits = 0x02;
0424         break;
0425     default:
0426         snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port);
0427         goto __skip_base;
0428     }
0429     snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
0430 
0431 __skip_base:
0432     switch (irq) {
0433 //#ifdef OPTi93X
0434     case 5:
0435         irq_bits = 0x05;
0436         break;
0437 //#endif    /* OPTi93X */
0438     case 7:
0439         irq_bits = 0x01;
0440         break;
0441     case 9:
0442         irq_bits = 0x02;
0443         break;
0444     case 10:
0445         irq_bits = 0x03;
0446         break;
0447     case 11:
0448         irq_bits = 0x04;
0449         break;
0450     default:
0451         snd_printk(KERN_WARNING "WSS irq # %d not valid\n", irq);
0452         goto __skip_resources;
0453     }
0454 
0455     switch (dma1) {
0456     case 0:
0457         dma_bits = 0x01;
0458         break;
0459     case 1:
0460         dma_bits = 0x02;
0461         break;
0462     case 3:
0463         dma_bits = 0x03;
0464         break;
0465     default:
0466         snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", dma1);
0467         goto __skip_resources;
0468     }
0469 
0470 #if defined(CS4231) || defined(OPTi93X)
0471     if (dma1 == dma2) {
0472         snd_printk(KERN_ERR "don't want to share dmas\n");
0473         return -EBUSY;
0474     }
0475 
0476     switch (dma2) {
0477     case 0:
0478     case 1:
0479         break;
0480     default:
0481         snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", dma2);
0482         goto __skip_resources;
0483     }
0484     dma_bits |= 0x04;
0485 #endif  /* CS4231 || OPTi93X */
0486 
0487 #ifndef OPTi93X
0488      outb(irq_bits << 3 | dma_bits, chip->wss_base);
0489 #else /* OPTi93X */
0490     snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
0491 #endif /* OPTi93X */
0492 
0493 __skip_resources:
0494     if (chip->hardware > OPTi9XX_HW_82C928) {
0495         switch (mpu_port) {
0496         case 0:
0497         case -1:
0498             break;
0499         case 0x300:
0500             mpu_port_bits = 0x03;
0501             break;
0502         case 0x310:
0503             mpu_port_bits = 0x02;
0504             break;
0505         case 0x320:
0506             mpu_port_bits = 0x01;
0507             break;
0508         case 0x330:
0509             mpu_port_bits = 0x00;
0510             break;
0511         default:
0512             snd_printk(KERN_WARNING
0513                    "MPU-401 port 0x%lx not valid\n", mpu_port);
0514             goto __skip_mpu;
0515         }
0516 
0517         switch (mpu_irq) {
0518         case 5:
0519             mpu_irq_bits = 0x02;
0520             break;
0521         case 7:
0522             mpu_irq_bits = 0x03;
0523             break;
0524         case 9:
0525             mpu_irq_bits = 0x00;
0526             break;
0527         case 10:
0528             mpu_irq_bits = 0x01;
0529             break;
0530         default:
0531             snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n",
0532                 mpu_irq);
0533             goto __skip_mpu;
0534         }
0535 
0536         snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6),
0537             (mpu_port <= 0) ? 0x00 :
0538                 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
0539             0xf8);
0540     }
0541 __skip_mpu:
0542 
0543     return 0;
0544 }
0545 
0546 #ifdef OPTi93X
0547 
0548 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0);
0549 static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
0550 static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0);
0551 
0552 static const struct snd_kcontrol_new snd_opti93x_controls[] = {
0553 WSS_DOUBLE("Master Playback Switch", 0,
0554         OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
0555 WSS_DOUBLE_TLV("Master Playback Volume", 0,
0556         OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
0557         db_scale_5bit_3db_step),
0558 WSS_DOUBLE_TLV("PCM Playback Volume", 0,
0559         CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1,
0560         db_scale_5bit),
0561 WSS_DOUBLE_TLV("FM Playback Volume", 0,
0562         CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1,
0563         db_scale_4bit_12db_max),
0564 WSS_DOUBLE("Line Playback Switch", 0,
0565         CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
0566 WSS_DOUBLE_TLV("Line Playback Volume", 0,
0567         CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1,
0568         db_scale_4bit_12db_max),
0569 WSS_DOUBLE("Mic Playback Switch", 0,
0570         OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
0571 WSS_DOUBLE_TLV("Mic Playback Volume", 0,
0572         OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1,
0573         db_scale_4bit_12db_max),
0574 WSS_DOUBLE_TLV("CD Playback Volume", 0,
0575         CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1,
0576         db_scale_4bit_12db_max),
0577 WSS_DOUBLE("Aux Playback Switch", 0,
0578         OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
0579 WSS_DOUBLE_TLV("Aux Playback Volume", 0,
0580         OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1,
0581         db_scale_4bit_12db_max),
0582 };
0583 
0584 static int snd_opti93x_mixer(struct snd_wss *chip)
0585 {
0586     struct snd_card *card;
0587     unsigned int idx;
0588     struct snd_ctl_elem_id id1, id2;
0589     int err;
0590 
0591     if (snd_BUG_ON(!chip || !chip->pcm))
0592         return -EINVAL;
0593 
0594     card = chip->card;
0595 
0596     strcpy(card->mixername, chip->pcm->name);
0597 
0598     memset(&id1, 0, sizeof(id1));
0599     memset(&id2, 0, sizeof(id2));
0600     id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0601     /* reassign AUX0 switch to CD */
0602     strcpy(id1.name, "Aux Playback Switch");
0603     strcpy(id2.name, "CD Playback Switch");
0604     err = snd_ctl_rename_id(card, &id1, &id2);
0605     if (err < 0) {
0606         snd_printk(KERN_ERR "Cannot rename opti93x control\n");
0607         return err;
0608     }
0609     /* reassign AUX1 switch to FM */
0610     strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
0611     strcpy(id2.name, "FM Playback Switch");
0612     err = snd_ctl_rename_id(card, &id1, &id2);
0613     if (err < 0) {
0614         snd_printk(KERN_ERR "Cannot rename opti93x control\n");
0615         return err;
0616     }
0617     /* remove AUX1 volume */
0618     strcpy(id1.name, "Aux Playback Volume"); id1.index = 1;
0619     snd_ctl_remove_id(card, &id1);
0620 
0621     /* Replace WSS volume controls with OPTi93x volume controls */
0622     id1.index = 0;
0623     for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
0624         strcpy(id1.name, snd_opti93x_controls[idx].name);
0625         snd_ctl_remove_id(card, &id1);
0626 
0627         err = snd_ctl_add(card,
0628                 snd_ctl_new1(&snd_opti93x_controls[idx], chip));
0629         if (err < 0)
0630             return err;
0631     }
0632     return 0;
0633 }
0634 
0635 static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
0636 {
0637     struct snd_opti9xx *chip = dev_id;
0638     struct snd_wss *codec = chip->codec;
0639     unsigned char status;
0640 
0641     if (!codec)
0642         return IRQ_HANDLED;
0643 
0644     status = snd_opti9xx_read(chip, OPTi9XX_MC_REG(11));
0645     if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream)
0646         snd_pcm_period_elapsed(codec->playback_substream);
0647     if ((status & OPTi93X_IRQ_CAPTURE) && codec->capture_substream) {
0648         snd_wss_overrange(codec);
0649         snd_pcm_period_elapsed(codec->capture_substream);
0650     }
0651     outb(0x00, OPTi93X_PORT(codec, STATUS));
0652     return IRQ_HANDLED;
0653 }
0654 
0655 #endif /* OPTi93X */
0656 
0657 static int snd_opti9xx_read_check(struct snd_card *card,
0658                   struct snd_opti9xx *chip)
0659 {
0660     unsigned char value;
0661 #ifdef OPTi93X
0662     unsigned long flags;
0663 #endif
0664 
0665     chip->res_mc_base =
0666         devm_request_region(card->dev, chip->mc_base,
0667                     chip->mc_base_size, "OPTi9xx MC");
0668     if (!chip->res_mc_base)
0669         return -EBUSY;
0670 #ifndef OPTi93X
0671     value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
0672     if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
0673         if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
0674             return 0;
0675 #else   /* OPTi93X */
0676     chip->res_mc_indir =
0677         devm_request_region(card->dev, chip->mc_indir_index, 2,
0678                     "OPTi93x MC");
0679     if (!chip->res_mc_indir)
0680         return -EBUSY;
0681 
0682     spin_lock_irqsave(&chip->lock, flags);
0683     outb(chip->password, chip->mc_base + chip->pwd_reg);
0684     outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
0685     spin_unlock_irqrestore(&chip->lock, flags);
0686 
0687     value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
0688     snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
0689     if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
0690         return 0;
0691 
0692     devm_release_resource(card->dev, chip->res_mc_indir);
0693     chip->res_mc_indir = NULL;
0694 #endif  /* OPTi93X */
0695     devm_release_resource(card->dev, chip->res_mc_base);
0696     chip->res_mc_base = NULL;
0697 
0698     return -ENODEV;
0699 }
0700 
0701 static int snd_card_opti9xx_detect(struct snd_card *card,
0702                    struct snd_opti9xx *chip)
0703 {
0704     int i, err;
0705 
0706 #ifndef OPTi93X
0707     for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
0708 #else
0709     for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
0710 #endif
0711         err = snd_opti9xx_init(chip, i);
0712         if (err < 0)
0713             return err;
0714 
0715         err = snd_opti9xx_read_check(card, chip);
0716         if (err == 0)
0717             return 1;
0718 #ifdef OPTi93X
0719         chip->mc_indir_index = 0;
0720 #endif
0721     }
0722     return -ENODEV;
0723 }
0724 
0725 #ifdef CONFIG_PNP
0726 static int snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
0727                 struct pnp_card_link *card,
0728                 const struct pnp_card_device_id *pid)
0729 {
0730     struct pnp_dev *pdev;
0731     int err;
0732     struct pnp_dev *devmpu;
0733 #ifndef OPTi93X
0734     struct pnp_dev *devmc;
0735 #endif
0736 
0737     pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
0738     if (pdev == NULL)
0739         return -EBUSY;
0740 
0741     err = pnp_activate_dev(pdev);
0742     if (err < 0) {
0743         snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
0744         return err;
0745     }
0746 
0747 #ifdef OPTi93X
0748     port = pnp_port_start(pdev, 0) - 4;
0749     fm_port = pnp_port_start(pdev, 1) + 8;
0750     /* adjust mc_indir_index - some cards report it at 0xe?d,
0751        other at 0xe?c but it really is always at 0xe?e */
0752     chip->mc_indir_index = (pnp_port_start(pdev, 3) & ~0xf) | 0xe;
0753 #else
0754     devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
0755     if (devmc == NULL)
0756         return -EBUSY;
0757 
0758     err = pnp_activate_dev(devmc);
0759     if (err < 0) {
0760         snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err);
0761         return err;
0762     }
0763 
0764     port = pnp_port_start(pdev, 1);
0765     fm_port = pnp_port_start(pdev, 2) + 8;
0766     /*
0767      * The MC(0) is never accessed and card does not
0768      * include it in the PnP resource range. OPTI93x include it.
0769      */
0770     chip->mc_base = pnp_port_start(devmc, 0) - 1;
0771     chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
0772 #endif  /* OPTi93X */
0773     irq = pnp_irq(pdev, 0);
0774     dma1 = pnp_dma(pdev, 0);
0775 #if defined(CS4231) || defined(OPTi93X)
0776     dma2 = pnp_dma(pdev, 1);
0777 #endif  /* CS4231 || OPTi93X */
0778 
0779     devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
0780 
0781     if (devmpu && mpu_port > 0) {
0782         err = pnp_activate_dev(devmpu);
0783         if (err < 0) {
0784             snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
0785             mpu_port = -1;
0786         } else {
0787             mpu_port = pnp_port_start(devmpu, 0);
0788             mpu_irq = pnp_irq(devmpu, 0);
0789         }
0790     }
0791     return pid->driver_data;
0792 }
0793 #endif  /* CONFIG_PNP */
0794 
0795 static int snd_opti9xx_probe(struct snd_card *card)
0796 {
0797     static const long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
0798     int error;
0799     int xdma2;
0800     struct snd_opti9xx *chip = card->private_data;
0801     struct snd_wss *codec;
0802     struct snd_rawmidi *rmidi;
0803     struct snd_hwdep *synth;
0804 
0805 #if defined(CS4231) || defined(OPTi93X)
0806     xdma2 = dma2;
0807 #else
0808     xdma2 = -1;
0809 #endif
0810 
0811     if (port == SNDRV_AUTO_PORT) {
0812         port = snd_legacy_find_free_ioport(possible_ports, 4);
0813         if (port < 0) {
0814             snd_printk(KERN_ERR "unable to find a free WSS port\n");
0815             return -EBUSY;
0816         }
0817     }
0818     error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
0819                       mpu_port, mpu_irq);
0820     if (error)
0821         return error;
0822 
0823     error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2,
0824 #ifdef OPTi93X
0825                    WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
0826 #else
0827                    WSS_HW_DETECT, 0,
0828 #endif
0829                    &codec);
0830     if (error < 0)
0831         return error;
0832     chip->codec = codec;
0833     error = snd_wss_pcm(codec, 0);
0834     if (error < 0)
0835         return error;
0836     error = snd_wss_mixer(codec);
0837     if (error < 0)
0838         return error;
0839 #ifdef OPTi93X
0840     error = snd_opti93x_mixer(codec);
0841     if (error < 0)
0842         return error;
0843 #endif
0844 #ifdef CS4231
0845     error = snd_wss_timer(codec, 0);
0846     if (error < 0)
0847         return error;
0848 #endif
0849 #ifdef OPTi93X
0850     error = devm_request_irq(card->dev, irq, snd_opti93x_interrupt,
0851                  0, DEV_NAME" - WSS", chip);
0852     if (error < 0) {
0853         snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq);
0854         return error;
0855     }
0856 #endif
0857     chip->irq = irq;
0858     card->sync_irq = chip->irq;
0859     strcpy(card->driver, chip->name);
0860     sprintf(card->shortname, "OPTi %s", card->driver);
0861 #if defined(CS4231) || defined(OPTi93X)
0862     snprintf(card->longname, sizeof(card->longname),
0863          "%s, %s at 0x%lx, irq %d, dma %d&%d",
0864          card->shortname, codec->pcm->name,
0865          chip->wss_base + 4, irq, dma1, xdma2);
0866 #else
0867     snprintf(card->longname, sizeof(card->longname),
0868          "%s, %s at 0x%lx, irq %d, dma %d",
0869          card->shortname, codec->pcm->name, chip->wss_base + 4, irq,
0870          dma1);
0871 #endif  /* CS4231 || OPTi93X */
0872 
0873     if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
0874         rmidi = NULL;
0875     else {
0876         error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
0877                 mpu_port, 0, mpu_irq, &rmidi);
0878         if (error)
0879             snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
0880                    mpu_port);
0881     }
0882 
0883     if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
0884         struct snd_opl3 *opl3 = NULL;
0885 #ifndef OPTi93X
0886         if (chip->hardware == OPTi9XX_HW_82C928 ||
0887             chip->hardware == OPTi9XX_HW_82C929 ||
0888             chip->hardware == OPTi9XX_HW_82C924) {
0889             struct snd_opl4 *opl4;
0890             /* assume we have an OPL4 */
0891             snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
0892                            0x20, 0x20);
0893             if (snd_opl4_create(card, fm_port, fm_port - 8,
0894                         2, &opl3, &opl4) < 0) {
0895                 /* no luck, use OPL3 instead */
0896                 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
0897                                0x00, 0x20);
0898             }
0899         }
0900 #endif  /* !OPTi93X */
0901         if (!opl3 && snd_opl3_create(card, fm_port, fm_port + 2,
0902                          OPL3_HW_AUTO, 0, &opl3) < 0) {
0903             snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
0904                    fm_port, fm_port + 4 - 1);
0905         }
0906         if (opl3) {
0907             error = snd_opl3_hwdep_new(opl3, 0, 1, &synth);
0908             if (error < 0)
0909                 return error;
0910         }
0911     }
0912 
0913     return snd_card_register(card);
0914 }
0915 
0916 static int snd_opti9xx_card_new(struct device *pdev, struct snd_card **cardp)
0917 {
0918     struct snd_card *card;
0919     int err;
0920 
0921     err = snd_devm_card_new(pdev, index, id, THIS_MODULE,
0922                 sizeof(struct snd_opti9xx), &card);
0923     if (err < 0)
0924         return err;
0925     *cardp = card;
0926     return 0;
0927 }
0928 
0929 static int snd_opti9xx_isa_match(struct device *devptr,
0930                  unsigned int dev)
0931 {
0932 #ifdef CONFIG_PNP
0933     if (snd_opti9xx_pnp_is_probed)
0934         return 0;
0935     if (isapnp)
0936         return 0;
0937 #endif
0938     return 1;
0939 }
0940 
0941 static int snd_opti9xx_isa_probe(struct device *devptr,
0942                  unsigned int dev)
0943 {
0944     struct snd_card *card;
0945     int error;
0946     static const long possible_mpu_ports[] = {0x300, 0x310, 0x320, 0x330, -1};
0947 #ifdef OPTi93X
0948     static const int possible_irqs[] = {5, 9, 10, 11, 7, -1};
0949 #else
0950     static const int possible_irqs[] = {9, 10, 11, 7, -1};
0951 #endif  /* OPTi93X */
0952     static const int possible_mpu_irqs[] = {5, 9, 10, 7, -1};
0953     static const int possible_dma1s[] = {3, 1, 0, -1};
0954 #if defined(CS4231) || defined(OPTi93X)
0955     static const int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
0956 #endif  /* CS4231 || OPTi93X */
0957 
0958     if (mpu_port == SNDRV_AUTO_PORT) {
0959         mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
0960         if (mpu_port < 0) {
0961             snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
0962             return -EBUSY;
0963         }
0964     }
0965     if (irq == SNDRV_AUTO_IRQ) {
0966         irq = snd_legacy_find_free_irq(possible_irqs);
0967         if (irq < 0) {
0968             snd_printk(KERN_ERR "unable to find a free IRQ\n");
0969             return -EBUSY;
0970         }
0971     }
0972     if (mpu_irq == SNDRV_AUTO_IRQ) {
0973         mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs);
0974         if (mpu_irq < 0) {
0975             snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
0976             return -EBUSY;
0977         }
0978     }
0979     if (dma1 == SNDRV_AUTO_DMA) {
0980         dma1 = snd_legacy_find_free_dma(possible_dma1s);
0981         if (dma1 < 0) {
0982             snd_printk(KERN_ERR "unable to find a free DMA1\n");
0983             return -EBUSY;
0984         }
0985     }
0986 #if defined(CS4231) || defined(OPTi93X)
0987     if (dma2 == SNDRV_AUTO_DMA) {
0988         dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4]);
0989         if (dma2 < 0) {
0990             snd_printk(KERN_ERR "unable to find a free DMA2\n");
0991             return -EBUSY;
0992         }
0993     }
0994 #endif
0995 
0996     error = snd_opti9xx_card_new(devptr, &card);
0997     if (error < 0)
0998         return error;
0999 
1000     error = snd_card_opti9xx_detect(card, card->private_data);
1001     if (error < 0)
1002         return error;
1003     error = snd_opti9xx_probe(card);
1004     if (error < 0)
1005         return error;
1006     dev_set_drvdata(devptr, card);
1007     return 0;
1008 }
1009 
1010 #ifdef CONFIG_PM
1011 static int snd_opti9xx_suspend(struct snd_card *card)
1012 {
1013     struct snd_opti9xx *chip = card->private_data;
1014 
1015     snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1016     chip->codec->suspend(chip->codec);
1017     return 0;
1018 }
1019 
1020 static int snd_opti9xx_resume(struct snd_card *card)
1021 {
1022     struct snd_opti9xx *chip = card->private_data;
1023     int error, xdma2;
1024 #if defined(CS4231) || defined(OPTi93X)
1025     xdma2 = dma2;
1026 #else
1027     xdma2 = -1;
1028 #endif
1029 
1030     error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
1031                       mpu_port, mpu_irq);
1032     if (error)
1033         return error;
1034     chip->codec->resume(chip->codec);
1035     snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1036     return 0;
1037 }
1038 
1039 static int snd_opti9xx_isa_suspend(struct device *dev, unsigned int n,
1040                    pm_message_t state)
1041 {
1042     return snd_opti9xx_suspend(dev_get_drvdata(dev));
1043 }
1044 
1045 static int snd_opti9xx_isa_resume(struct device *dev, unsigned int n)
1046 {
1047     return snd_opti9xx_resume(dev_get_drvdata(dev));
1048 }
1049 #endif
1050 
1051 static struct isa_driver snd_opti9xx_driver = {
1052     .match      = snd_opti9xx_isa_match,
1053     .probe      = snd_opti9xx_isa_probe,
1054 #ifdef CONFIG_PM
1055     .suspend    = snd_opti9xx_isa_suspend,
1056     .resume     = snd_opti9xx_isa_resume,
1057 #endif
1058     .driver     = {
1059         .name   = DEV_NAME
1060     },
1061 };
1062 
1063 #ifdef CONFIG_PNP
1064 static int snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
1065                  const struct pnp_card_device_id *pid)
1066 {
1067     struct snd_card *card;
1068     int error, hw;
1069     struct snd_opti9xx *chip;
1070 
1071     if (snd_opti9xx_pnp_is_probed)
1072         return -EBUSY;
1073     if (! isapnp)
1074         return -ENODEV;
1075     error = snd_opti9xx_card_new(&pcard->card->dev, &card);
1076     if (error < 0)
1077         return error;
1078     chip = card->private_data;
1079 
1080     hw = snd_card_opti9xx_pnp(chip, pcard, pid);
1081     switch (hw) {
1082     case 0x0924:
1083         hw = OPTi9XX_HW_82C924;
1084         break;
1085     case 0x0925:
1086         hw = OPTi9XX_HW_82C925;
1087         break;
1088     case 0x0931:
1089         hw = OPTi9XX_HW_82C931;
1090         break;
1091     default:
1092         return -ENODEV;
1093     }
1094 
1095     error = snd_opti9xx_init(chip, hw);
1096     if (error)
1097         return error;
1098     error = snd_opti9xx_read_check(card, chip);
1099     if (error) {
1100         snd_printk(KERN_ERR "OPTI chip not found\n");
1101         return error;
1102     }
1103     error = snd_opti9xx_probe(card);
1104     if (error < 0)
1105         return error;
1106     pnp_set_card_drvdata(pcard, card);
1107     snd_opti9xx_pnp_is_probed = 1;
1108     return 0;
1109 }
1110 
1111 static void snd_opti9xx_pnp_remove(struct pnp_card_link *pcard)
1112 {
1113     snd_opti9xx_pnp_is_probed = 0;
1114 }
1115 
1116 #ifdef CONFIG_PM
1117 static int snd_opti9xx_pnp_suspend(struct pnp_card_link *pcard,
1118                    pm_message_t state)
1119 {
1120     return snd_opti9xx_suspend(pnp_get_card_drvdata(pcard));
1121 }
1122 
1123 static int snd_opti9xx_pnp_resume(struct pnp_card_link *pcard)
1124 {
1125     return snd_opti9xx_resume(pnp_get_card_drvdata(pcard));
1126 }
1127 #endif
1128 
1129 static struct pnp_card_driver opti9xx_pnpc_driver = {
1130     .flags      = PNP_DRIVER_RES_DISABLE,
1131     .name       = DEV_NAME,
1132     .id_table   = snd_opti9xx_pnpids,
1133     .probe      = snd_opti9xx_pnp_probe,
1134     .remove     = snd_opti9xx_pnp_remove,
1135 #ifdef CONFIG_PM
1136     .suspend    = snd_opti9xx_pnp_suspend,
1137     .resume     = snd_opti9xx_pnp_resume,
1138 #endif
1139 };
1140 #endif
1141 
1142 #ifdef OPTi93X
1143 #define CHIP_NAME   "82C93x"
1144 #else
1145 #define CHIP_NAME   "82C92x"
1146 #endif
1147 
1148 static int __init alsa_card_opti9xx_init(void)
1149 {
1150 #ifdef CONFIG_PNP
1151     pnp_register_card_driver(&opti9xx_pnpc_driver);
1152     if (snd_opti9xx_pnp_is_probed)
1153         return 0;
1154     pnp_unregister_card_driver(&opti9xx_pnpc_driver);
1155 #endif
1156     return isa_register_driver(&snd_opti9xx_driver, 1);
1157 }
1158 
1159 static void __exit alsa_card_opti9xx_exit(void)
1160 {
1161     if (!snd_opti9xx_pnp_is_probed) {
1162         isa_unregister_driver(&snd_opti9xx_driver);
1163         return;
1164     }
1165 #ifdef CONFIG_PNP
1166     pnp_unregister_card_driver(&opti9xx_pnpc_driver);
1167 #endif
1168 }
1169 
1170 module_init(alsa_card_opti9xx_init)
1171 module_exit(alsa_card_opti9xx_exit)