0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/init.h>
0015 #include <linux/module.h>
0016 #include <linux/io.h>
0017 #include <linux/delay.h>
0018 #include <asm/dma.h>
0019 #include <linux/isa.h>
0020 #include <sound/core.h>
0021 #include <sound/mpu401.h>
0022 #include <sound/opl3.h>
0023 #include <sound/sb.h>
0024 #define SNDRV_LEGACY_FIND_FREE_IRQ
0025 #define SNDRV_LEGACY_FIND_FREE_DMA
0026 #include <sound/initval.h>
0027
0028 #define PFX "jazz16: "
0029
0030 MODULE_DESCRIPTION("Media Vision Jazz16");
0031 MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
0032 MODULE_LICENSE("GPL");
0033
0034 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
0035 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
0036 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
0037 static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0038 static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0039 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
0040 static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
0041 static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
0042 static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
0043
0044 module_param_array(index, int, NULL, 0444);
0045 MODULE_PARM_DESC(index, "Index value for Media Vision Jazz16 based soundcard.");
0046 module_param_array(id, charp, NULL, 0444);
0047 MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard.");
0048 module_param_array(enable, bool, NULL, 0444);
0049 MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard.");
0050 module_param_hw_array(port, long, ioport, NULL, 0444);
0051 MODULE_PARM_DESC(port, "Port # for jazz16 driver.");
0052 module_param_hw_array(mpu_port, long, ioport, NULL, 0444);
0053 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver.");
0054 module_param_hw_array(irq, int, irq, NULL, 0444);
0055 MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver.");
0056 module_param_hw_array(mpu_irq, int, irq, NULL, 0444);
0057 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver.");
0058 module_param_hw_array(dma8, int, dma, NULL, 0444);
0059 MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver.");
0060 module_param_hw_array(dma16, int, dma, NULL, 0444);
0061 MODULE_PARM_DESC(dma16, "DMA16 # for jazz16 driver.");
0062
0063 #define SB_JAZZ16_WAKEUP 0xaf
0064 #define SB_JAZZ16_SET_PORTS 0x50
0065 #define SB_DSP_GET_JAZZ_BRD_REV 0xfa
0066 #define SB_JAZZ16_SET_DMAINTR 0xfb
0067 #define SB_DSP_GET_JAZZ_MODEL 0xfe
0068
0069 struct snd_card_jazz16 {
0070 struct snd_sb *chip;
0071 };
0072
0073 static irqreturn_t jazz16_interrupt(int irq, void *chip)
0074 {
0075 return snd_sb8dsp_interrupt(chip);
0076 }
0077
0078 static int jazz16_configure_ports(unsigned long port,
0079 unsigned long mpu_port, int idx)
0080 {
0081 unsigned char val;
0082
0083 if (!request_region(0x201, 1, "jazz16 config")) {
0084 snd_printk(KERN_ERR "config port region is already in use.\n");
0085 return -EBUSY;
0086 }
0087 outb(SB_JAZZ16_WAKEUP - idx, 0x201);
0088 udelay(100);
0089 outb(SB_JAZZ16_SET_PORTS + idx, 0x201);
0090 udelay(100);
0091 val = port & 0x70;
0092 val |= (mpu_port & 0x30) >> 4;
0093 outb(val, 0x201);
0094
0095 release_region(0x201, 1);
0096 return 0;
0097 }
0098
0099 static int jazz16_detect_board(unsigned long port,
0100 unsigned long mpu_port)
0101 {
0102 int err;
0103 int val;
0104 struct snd_sb chip;
0105
0106 if (!request_region(port, 0x10, "jazz16")) {
0107 snd_printk(KERN_ERR "I/O port region is already in use.\n");
0108 return -EBUSY;
0109 }
0110
0111 chip.port = port;
0112
0113 err = snd_sbdsp_reset(&chip);
0114 if (err < 0)
0115 for (val = 0; val < 4; val++) {
0116 err = jazz16_configure_ports(port, mpu_port, val);
0117 if (err < 0)
0118 break;
0119
0120 err = snd_sbdsp_reset(&chip);
0121 if (!err)
0122 break;
0123 }
0124 if (err < 0) {
0125 err = -ENODEV;
0126 goto err_unmap;
0127 }
0128 if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_BRD_REV)) {
0129 err = -EBUSY;
0130 goto err_unmap;
0131 }
0132 val = snd_sbdsp_get_byte(&chip);
0133 if (val >= 0x30)
0134 snd_sbdsp_get_byte(&chip);
0135
0136 if ((val & 0xf0) != 0x10) {
0137 err = -ENODEV;
0138 goto err_unmap;
0139 }
0140 if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_MODEL)) {
0141 err = -EBUSY;
0142 goto err_unmap;
0143 }
0144 snd_sbdsp_get_byte(&chip);
0145 err = snd_sbdsp_get_byte(&chip);
0146 snd_printd("Media Vision Jazz16 board detected: rev 0x%x, model 0x%x\n",
0147 val, err);
0148
0149 err = 0;
0150
0151 err_unmap:
0152 release_region(port, 0x10);
0153 return err;
0154 }
0155
0156 static int jazz16_configure_board(struct snd_sb *chip, int mpu_irq)
0157 {
0158 static const unsigned char jazz_irq_bits[] = { 0, 0, 2, 3, 0, 1, 0, 4,
0159 0, 2, 5, 0, 0, 0, 0, 6 };
0160 static const unsigned char jazz_dma_bits[] = { 0, 1, 0, 2, 0, 3, 0, 4 };
0161
0162 if (jazz_dma_bits[chip->dma8] == 0 ||
0163 jazz_dma_bits[chip->dma16] == 0 ||
0164 jazz_irq_bits[chip->irq] == 0)
0165 return -EINVAL;
0166
0167 if (!snd_sbdsp_command(chip, SB_JAZZ16_SET_DMAINTR))
0168 return -EBUSY;
0169
0170 if (!snd_sbdsp_command(chip,
0171 jazz_dma_bits[chip->dma8] |
0172 (jazz_dma_bits[chip->dma16] << 4)))
0173 return -EBUSY;
0174
0175 if (!snd_sbdsp_command(chip,
0176 jazz_irq_bits[chip->irq] |
0177 (jazz_irq_bits[mpu_irq] << 4)))
0178 return -EBUSY;
0179
0180 return 0;
0181 }
0182
0183 static int snd_jazz16_match(struct device *devptr, unsigned int dev)
0184 {
0185 if (!enable[dev])
0186 return 0;
0187 if (port[dev] == SNDRV_AUTO_PORT) {
0188 snd_printk(KERN_ERR "please specify port\n");
0189 return 0;
0190 } else if (port[dev] == 0x200 || (port[dev] & ~0x270)) {
0191 snd_printk(KERN_ERR "incorrect port specified\n");
0192 return 0;
0193 }
0194 if (dma8[dev] != SNDRV_AUTO_DMA &&
0195 dma8[dev] != 1 && dma8[dev] != 3) {
0196 snd_printk(KERN_ERR "dma8 must be 1 or 3\n");
0197 return 0;
0198 }
0199 if (dma16[dev] != SNDRV_AUTO_DMA &&
0200 dma16[dev] != 5 && dma16[dev] != 7) {
0201 snd_printk(KERN_ERR "dma16 must be 5 or 7\n");
0202 return 0;
0203 }
0204 if (mpu_port[dev] != SNDRV_AUTO_PORT &&
0205 (mpu_port[dev] & ~0x030) != 0x300) {
0206 snd_printk(KERN_ERR "incorrect mpu_port specified\n");
0207 return 0;
0208 }
0209 if (mpu_irq[dev] != SNDRV_AUTO_DMA &&
0210 mpu_irq[dev] != 2 && mpu_irq[dev] != 3 &&
0211 mpu_irq[dev] != 5 && mpu_irq[dev] != 7) {
0212 snd_printk(KERN_ERR "mpu_irq must be 2, 3, 5 or 7\n");
0213 return 0;
0214 }
0215 return 1;
0216 }
0217
0218 static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
0219 {
0220 struct snd_card *card;
0221 struct snd_card_jazz16 *jazz16;
0222 struct snd_sb *chip;
0223 struct snd_opl3 *opl3;
0224 static const int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1};
0225 static const int possible_dmas8[] = {1, 3, -1};
0226 static const int possible_dmas16[] = {5, 7, -1};
0227 int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq;
0228
0229 err = snd_devm_card_new(devptr, index[dev], id[dev], THIS_MODULE,
0230 sizeof(struct snd_card_jazz16), &card);
0231 if (err < 0)
0232 return err;
0233
0234 jazz16 = card->private_data;
0235
0236 xirq = irq[dev];
0237 if (xirq == SNDRV_AUTO_IRQ) {
0238 xirq = snd_legacy_find_free_irq(possible_irqs);
0239 if (xirq < 0) {
0240 snd_printk(KERN_ERR "unable to find a free IRQ\n");
0241 return -EBUSY;
0242 }
0243 }
0244 xdma8 = dma8[dev];
0245 if (xdma8 == SNDRV_AUTO_DMA) {
0246 xdma8 = snd_legacy_find_free_dma(possible_dmas8);
0247 if (xdma8 < 0) {
0248 snd_printk(KERN_ERR "unable to find a free DMA8\n");
0249 return -EBUSY;
0250 }
0251 }
0252 xdma16 = dma16[dev];
0253 if (xdma16 == SNDRV_AUTO_DMA) {
0254 xdma16 = snd_legacy_find_free_dma(possible_dmas16);
0255 if (xdma16 < 0) {
0256 snd_printk(KERN_ERR "unable to find a free DMA16\n");
0257 return -EBUSY;
0258 }
0259 }
0260
0261 xmpu_port = mpu_port[dev];
0262 if (xmpu_port == SNDRV_AUTO_PORT)
0263 xmpu_port = 0;
0264 err = jazz16_detect_board(port[dev], xmpu_port);
0265 if (err < 0) {
0266 printk(KERN_ERR "Media Vision Jazz16 board not detected\n");
0267 return err;
0268 }
0269 err = snd_sbdsp_create(card, port[dev], irq[dev],
0270 jazz16_interrupt,
0271 dma8[dev], dma16[dev],
0272 SB_HW_JAZZ16,
0273 &chip);
0274 if (err < 0)
0275 return err;
0276
0277 xmpu_irq = mpu_irq[dev];
0278 if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT)
0279 xmpu_irq = 0;
0280 err = jazz16_configure_board(chip, xmpu_irq);
0281 if (err < 0) {
0282 printk(KERN_ERR "Media Vision Jazz16 configuration failed\n");
0283 return err;
0284 }
0285
0286 jazz16->chip = chip;
0287
0288 strcpy(card->driver, "jazz16");
0289 strcpy(card->shortname, "Media Vision Jazz16");
0290 sprintf(card->longname,
0291 "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d",
0292 port[dev], xirq, xdma8, xdma16);
0293
0294 err = snd_sb8dsp_pcm(chip, 0);
0295 if (err < 0)
0296 return err;
0297 err = snd_sbmixer_new(chip);
0298 if (err < 0)
0299 return err;
0300
0301 err = snd_opl3_create(card, chip->port, chip->port + 2,
0302 OPL3_HW_AUTO, 1, &opl3);
0303 if (err < 0)
0304 snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
0305 chip->port, chip->port + 2);
0306 else {
0307 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
0308 if (err < 0)
0309 return err;
0310 }
0311 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
0312 if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
0313 mpu_irq[dev] = -1;
0314
0315 if (snd_mpu401_uart_new(card, 0,
0316 MPU401_HW_MPU401,
0317 mpu_port[dev], 0,
0318 mpu_irq[dev],
0319 NULL) < 0)
0320 snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n",
0321 mpu_port[dev]);
0322 }
0323
0324 err = snd_card_register(card);
0325 if (err < 0)
0326 return err;
0327
0328 dev_set_drvdata(devptr, card);
0329 return 0;
0330 }
0331
0332 #ifdef CONFIG_PM
0333 static int snd_jazz16_suspend(struct device *pdev, unsigned int n,
0334 pm_message_t state)
0335 {
0336 struct snd_card *card = dev_get_drvdata(pdev);
0337 struct snd_card_jazz16 *acard = card->private_data;
0338 struct snd_sb *chip = acard->chip;
0339
0340 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
0341 snd_sbmixer_suspend(chip);
0342 return 0;
0343 }
0344
0345 static int snd_jazz16_resume(struct device *pdev, unsigned int n)
0346 {
0347 struct snd_card *card = dev_get_drvdata(pdev);
0348 struct snd_card_jazz16 *acard = card->private_data;
0349 struct snd_sb *chip = acard->chip;
0350
0351 snd_sbdsp_reset(chip);
0352 snd_sbmixer_resume(chip);
0353 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
0354 return 0;
0355 }
0356 #endif
0357
0358 static struct isa_driver snd_jazz16_driver = {
0359 .match = snd_jazz16_match,
0360 .probe = snd_jazz16_probe,
0361 #ifdef CONFIG_PM
0362 .suspend = snd_jazz16_suspend,
0363 .resume = snd_jazz16_resume,
0364 #endif
0365 .driver = {
0366 .name = "jazz16"
0367 },
0368 };
0369
0370 module_isa_driver(snd_jazz16_driver, SNDRV_CARDS);