Loading Documentation/sound/alsa/ALSA-Configuration.txt +3 −1 Original line number Diff line number Diff line Loading @@ -1570,13 +1570,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-sc6000 ----------------- Module for Gallant SC-6000 soundcard. Module for Gallant SC-6000 soundcard and later models: SC-6600 and SC-7000. port - Port # (0x220 or 0x240) mss_port - MSS Port # (0x530 or 0xe80) irq - IRQ # (5,7,9,10,11) mpu_irq - MPU-401 IRQ # (5,7,9,10) ,0 - no MPU-401 irq dma - DMA # (1,3,0) joystick - Enable gameport - 0 = disable (default), 1 = enable This module supports multiple cards. Loading sound/isa/Kconfig +5 −2 Original line number Diff line number Diff line Loading @@ -177,15 +177,18 @@ config SND_ES18XX will be called snd-es18xx. config SND_SC6000 tristate "Gallant SC-6000, Audio Excel DSP 16" tristate "Gallant SC-6000/6600/7000 and Audio Excel DSP 16" depends on HAS_IOPORT select SND_WSS_LIB select SND_OPL3_LIB select SND_MPU401_UART help Say Y here to include support for Gallant SC-6000 card and clones: Say Y here to include support for Gallant SC-6000, SC-6600, SC-7000 cards and clones: Audio Excel DSP 16 and Zoltrix AV302. These cards are based on CompuMedia ASC-9308 or ASC-9408 chips. To compile this driver as a module, choose M here: the module will be called snd-sc6000. Loading sound/isa/sc6000.c +106 −28 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ * Driver for Gallant SC-6000 soundcard. This card is also known as * Audio Excel DSP 16 or Zoltrix AV302. * These cards use CompuMedia ASC-9308 chip + AD1848 codec. * SC-6600 and SC-7000 cards are also supported. They are based on * CompuMedia ASC-9408 chip and CS4231 codec. * * Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl> * Loading Loading @@ -54,6 +56,7 @@ static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x300, 0x310, 0x320, 0x330 */ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 0 */ static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0, 1, 3 */ static bool joystick[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = false }; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for sc-6000 based soundcard."); Loading @@ -73,6 +76,8 @@ module_param_array(mpu_irq, int, NULL, 0444); MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for sc-6000 driver."); module_param_array(dma, int, NULL, 0444); MODULE_PARM_DESC(dma, "DMA # for sc-6000 driver."); module_param_array(joystick, bool, NULL, 0444); MODULE_PARM_DESC(joystick, "Enable gameport."); /* * Commands of SC6000's DSP (SBPRO+special). Loading Loading @@ -191,7 +196,7 @@ static __devinit unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq) return val; } static __devinit int sc6000_wait_data(char __iomem *vport) static int sc6000_wait_data(char __iomem *vport) { int loop = 1000; unsigned char val = 0; Loading @@ -206,7 +211,7 @@ static __devinit int sc6000_wait_data(char __iomem *vport) return -EAGAIN; } static __devinit int sc6000_read(char __iomem *vport) static int sc6000_read(char __iomem *vport) { if (sc6000_wait_data(vport)) return -EBUSY; Loading @@ -215,7 +220,7 @@ static __devinit int sc6000_read(char __iomem *vport) } static __devinit int sc6000_write(char __iomem *vport, int cmd) static int sc6000_write(char __iomem *vport, int cmd) { unsigned char val; int loop = 500000; Loading Loading @@ -276,8 +281,33 @@ static int __devinit sc6000_dsp_reset(char __iomem *vport) } /* detection and initialization */ static int __devinit sc6000_cfg_write(char __iomem *vport, unsigned char softcfg) static int __devinit sc6000_hw_cfg_write(char __iomem *vport, const int *cfg) { if (sc6000_write(vport, COMMAND_6C) < 0) { snd_printk(KERN_WARNING "CMD 0x%x: failed!\n", COMMAND_6C); return -EIO; } if (sc6000_write(vport, COMMAND_5C) < 0) { snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_5C); return -EIO; } if (sc6000_write(vport, cfg[0]) < 0) { snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[0]); return -EIO; } if (sc6000_write(vport, cfg[1]) < 0) { snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[1]); return -EIO; } if (sc6000_write(vport, COMMAND_C5) < 0) { snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_C5); return -EIO; } return 0; } static int sc6000_cfg_write(char __iomem *vport, unsigned char softcfg) { if (sc6000_write(vport, WRITE_MDIRQ_CFG)) { Loading @@ -291,7 +321,7 @@ static int __devinit sc6000_cfg_write(char __iomem *vport, return 0; } static int __devinit sc6000_setup_board(char __iomem *vport, int config) static int sc6000_setup_board(char __iomem *vport, int config) { int loop = 10; Loading Loading @@ -334,16 +364,39 @@ static int __devinit sc6000_init_mss(char __iomem *vport, int config, return 0; } static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, char __iomem *vmss_port, int mpu_irq) static void __devinit sc6000_hw_cfg_encode(char __iomem *vport, int *cfg, long xport, long xmpu, long xmss_port, int joystick) { cfg[0] = 0; cfg[1] = 0; if (xport == 0x240) cfg[0] |= 1; if (xmpu != SNDRV_AUTO_PORT) { cfg[0] |= (xmpu & 0x30) >> 2; cfg[1] |= 0x20; } if (xmss_port == 0xe80) cfg[0] |= 0x10; cfg[0] |= 0x40; /* always set */ if (!joystick) cfg[0] |= 0x02; cfg[1] |= 0x80; /* enable WSS system */ cfg[1] &= ~0x40; /* disable IDE */ snd_printd("hw cfg %x, %x\n", cfg[0], cfg[1]); } static int __devinit sc6000_init_board(char __iomem *vport, char __iomem *vmss_port, int dev) { char answer[15]; char version[2]; int mss_config = sc6000_irq_to_softcfg(irq) | sc6000_dma_to_softcfg(dma); int mss_config = sc6000_irq_to_softcfg(irq[dev]) | sc6000_dma_to_softcfg(dma[dev]); int config = mss_config | sc6000_mpu_irq_to_softcfg(mpu_irq); sc6000_mpu_irq_to_softcfg(mpu_irq[dev]); int err; int old = 0; err = sc6000_dsp_reset(vport); if (err < 0) { Loading @@ -360,7 +413,6 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, /* * My SC-6000 card return "SC-6000" in DSPCopyright, so * if we have something different, we have to be warned. * Mine returns "SC-6000A " - KH */ if (strncmp("SC-6000", answer, 7)) snd_printk(KERN_WARNING "Warning: non SC-6000 audio card!\n"); Loading @@ -372,13 +424,32 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, printk(KERN_INFO PFX "Detected model: %s, DSP version %d.%d\n", answer, version[0], version[1]); /* * 0x0A == (IRQ 7, DMA 1, MIRQ 0) */ err = sc6000_cfg_write(vport, 0x0a); /* set configuration */ sc6000_write(vport, COMMAND_5C); if (sc6000_read(vport) < 0) old = 1; if (!old) { int cfg[2]; sc6000_hw_cfg_encode(vport, &cfg[0], port[dev], mpu_port[dev], mss_port[dev], joystick[dev]); if (sc6000_hw_cfg_write(vport, cfg) < 0) { snd_printk(KERN_ERR "sc6000_hw_cfg_write: failed!\n"); return -EIO; } } err = sc6000_setup_board(vport, config); if (err < 0) { snd_printk(KERN_ERR "sc6000_cfg_write: failed!\n"); return -EFAULT; snd_printk(KERN_ERR "sc6000_setup_board: failed!\n"); return -ENODEV; } sc6000_dsp_reset(vport); if (!old) { sc6000_write(vport, COMMAND_60); sc6000_write(vport, 0x02); sc6000_dsp_reset(vport); } err = sc6000_setup_board(vport, config); Loading @@ -386,7 +457,6 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, snd_printk(KERN_ERR "sc6000_setup_board: failed!\n"); return -ENODEV; } err = sc6000_init_mss(vport, config, vmss_port, mss_config); if (err < 0) { snd_printk(KERN_ERR "Cannot initialize " Loading Loading @@ -485,14 +555,16 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) struct snd_card *card; struct snd_wss *chip; struct snd_opl3 *opl3; char __iomem *vport; char __iomem **vport; char __iomem *vmss_port; err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); err = snd_card_create(index[dev], id[dev], THIS_MODULE, sizeof(vport), &card); if (err < 0) return err; vport = card->private_data; if (xirq == SNDRV_AUTO_IRQ) { xirq = snd_legacy_find_free_irq(possible_irqs); if (xirq < 0) { Loading @@ -517,8 +589,8 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) err = -EBUSY; goto err_exit; } vport = devm_ioport_map(devptr, port[dev], 0x10); if (!vport) { *vport = devm_ioport_map(devptr, port[dev], 0x10); if (*vport == NULL) { snd_printk(KERN_ERR PFX "I/O port cannot be iomaped.\n"); err = -EBUSY; Loading @@ -533,7 +605,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) goto err_unmap1; } vmss_port = devm_ioport_map(devptr, mss_port[dev], 4); if (!vport) { if (!vmss_port) { snd_printk(KERN_ERR PFX "MSS port I/O cannot be iomaped.\n"); err = -EBUSY; Loading @@ -544,7 +616,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) port[dev], xirq, xdma, mpu_irq[dev] == SNDRV_AUTO_IRQ ? 0 : mpu_irq[dev]); err = sc6000_init_board(vport, xirq, xdma, vmss_port, mpu_irq[dev]); err = sc6000_init_board(*vport, vmss_port, dev); if (err < 0) goto err_unmap2; Loading @@ -552,7 +624,6 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) WSS_HW_DETECT, 0, &chip); if (err < 0) goto err_unmap2; card->private_data = chip; err = snd_wss_pcm(chip, 0, NULL); if (err < 0) { Loading Loading @@ -608,6 +679,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) return 0; err_unmap2: sc6000_setup_board(*vport, 0); release_region(mss_port[dev], 4); err_unmap1: release_region(port[dev], 0x10); Loading @@ -618,11 +690,17 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) static int __devexit snd_sc6000_remove(struct device *devptr, unsigned int dev) { struct snd_card *card = dev_get_drvdata(devptr); char __iomem **vport = card->private_data; if (sc6000_setup_board(*vport, 0) < 0) snd_printk(KERN_WARNING "sc6000_setup_board failed on exit!\n"); release_region(port[dev], 0x10); release_region(mss_port[dev], 4); snd_card_free(dev_get_drvdata(devptr)); dev_set_drvdata(devptr, NULL); snd_card_free(card); return 0; } Loading Loading
Documentation/sound/alsa/ALSA-Configuration.txt +3 −1 Original line number Diff line number Diff line Loading @@ -1570,13 +1570,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-sc6000 ----------------- Module for Gallant SC-6000 soundcard. Module for Gallant SC-6000 soundcard and later models: SC-6600 and SC-7000. port - Port # (0x220 or 0x240) mss_port - MSS Port # (0x530 or 0xe80) irq - IRQ # (5,7,9,10,11) mpu_irq - MPU-401 IRQ # (5,7,9,10) ,0 - no MPU-401 irq dma - DMA # (1,3,0) joystick - Enable gameport - 0 = disable (default), 1 = enable This module supports multiple cards. Loading
sound/isa/Kconfig +5 −2 Original line number Diff line number Diff line Loading @@ -177,15 +177,18 @@ config SND_ES18XX will be called snd-es18xx. config SND_SC6000 tristate "Gallant SC-6000, Audio Excel DSP 16" tristate "Gallant SC-6000/6600/7000 and Audio Excel DSP 16" depends on HAS_IOPORT select SND_WSS_LIB select SND_OPL3_LIB select SND_MPU401_UART help Say Y here to include support for Gallant SC-6000 card and clones: Say Y here to include support for Gallant SC-6000, SC-6600, SC-7000 cards and clones: Audio Excel DSP 16 and Zoltrix AV302. These cards are based on CompuMedia ASC-9308 or ASC-9408 chips. To compile this driver as a module, choose M here: the module will be called snd-sc6000. Loading
sound/isa/sc6000.c +106 −28 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ * Driver for Gallant SC-6000 soundcard. This card is also known as * Audio Excel DSP 16 or Zoltrix AV302. * These cards use CompuMedia ASC-9308 chip + AD1848 codec. * SC-6600 and SC-7000 cards are also supported. They are based on * CompuMedia ASC-9408 chip and CS4231 codec. * * Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl> * Loading Loading @@ -54,6 +56,7 @@ static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x300, 0x310, 0x320, 0x330 */ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 0 */ static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0, 1, 3 */ static bool joystick[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = false }; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for sc-6000 based soundcard."); Loading @@ -73,6 +76,8 @@ module_param_array(mpu_irq, int, NULL, 0444); MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for sc-6000 driver."); module_param_array(dma, int, NULL, 0444); MODULE_PARM_DESC(dma, "DMA # for sc-6000 driver."); module_param_array(joystick, bool, NULL, 0444); MODULE_PARM_DESC(joystick, "Enable gameport."); /* * Commands of SC6000's DSP (SBPRO+special). Loading Loading @@ -191,7 +196,7 @@ static __devinit unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq) return val; } static __devinit int sc6000_wait_data(char __iomem *vport) static int sc6000_wait_data(char __iomem *vport) { int loop = 1000; unsigned char val = 0; Loading @@ -206,7 +211,7 @@ static __devinit int sc6000_wait_data(char __iomem *vport) return -EAGAIN; } static __devinit int sc6000_read(char __iomem *vport) static int sc6000_read(char __iomem *vport) { if (sc6000_wait_data(vport)) return -EBUSY; Loading @@ -215,7 +220,7 @@ static __devinit int sc6000_read(char __iomem *vport) } static __devinit int sc6000_write(char __iomem *vport, int cmd) static int sc6000_write(char __iomem *vport, int cmd) { unsigned char val; int loop = 500000; Loading Loading @@ -276,8 +281,33 @@ static int __devinit sc6000_dsp_reset(char __iomem *vport) } /* detection and initialization */ static int __devinit sc6000_cfg_write(char __iomem *vport, unsigned char softcfg) static int __devinit sc6000_hw_cfg_write(char __iomem *vport, const int *cfg) { if (sc6000_write(vport, COMMAND_6C) < 0) { snd_printk(KERN_WARNING "CMD 0x%x: failed!\n", COMMAND_6C); return -EIO; } if (sc6000_write(vport, COMMAND_5C) < 0) { snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_5C); return -EIO; } if (sc6000_write(vport, cfg[0]) < 0) { snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[0]); return -EIO; } if (sc6000_write(vport, cfg[1]) < 0) { snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[1]); return -EIO; } if (sc6000_write(vport, COMMAND_C5) < 0) { snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_C5); return -EIO; } return 0; } static int sc6000_cfg_write(char __iomem *vport, unsigned char softcfg) { if (sc6000_write(vport, WRITE_MDIRQ_CFG)) { Loading @@ -291,7 +321,7 @@ static int __devinit sc6000_cfg_write(char __iomem *vport, return 0; } static int __devinit sc6000_setup_board(char __iomem *vport, int config) static int sc6000_setup_board(char __iomem *vport, int config) { int loop = 10; Loading Loading @@ -334,16 +364,39 @@ static int __devinit sc6000_init_mss(char __iomem *vport, int config, return 0; } static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, char __iomem *vmss_port, int mpu_irq) static void __devinit sc6000_hw_cfg_encode(char __iomem *vport, int *cfg, long xport, long xmpu, long xmss_port, int joystick) { cfg[0] = 0; cfg[1] = 0; if (xport == 0x240) cfg[0] |= 1; if (xmpu != SNDRV_AUTO_PORT) { cfg[0] |= (xmpu & 0x30) >> 2; cfg[1] |= 0x20; } if (xmss_port == 0xe80) cfg[0] |= 0x10; cfg[0] |= 0x40; /* always set */ if (!joystick) cfg[0] |= 0x02; cfg[1] |= 0x80; /* enable WSS system */ cfg[1] &= ~0x40; /* disable IDE */ snd_printd("hw cfg %x, %x\n", cfg[0], cfg[1]); } static int __devinit sc6000_init_board(char __iomem *vport, char __iomem *vmss_port, int dev) { char answer[15]; char version[2]; int mss_config = sc6000_irq_to_softcfg(irq) | sc6000_dma_to_softcfg(dma); int mss_config = sc6000_irq_to_softcfg(irq[dev]) | sc6000_dma_to_softcfg(dma[dev]); int config = mss_config | sc6000_mpu_irq_to_softcfg(mpu_irq); sc6000_mpu_irq_to_softcfg(mpu_irq[dev]); int err; int old = 0; err = sc6000_dsp_reset(vport); if (err < 0) { Loading @@ -360,7 +413,6 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, /* * My SC-6000 card return "SC-6000" in DSPCopyright, so * if we have something different, we have to be warned. * Mine returns "SC-6000A " - KH */ if (strncmp("SC-6000", answer, 7)) snd_printk(KERN_WARNING "Warning: non SC-6000 audio card!\n"); Loading @@ -372,13 +424,32 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, printk(KERN_INFO PFX "Detected model: %s, DSP version %d.%d\n", answer, version[0], version[1]); /* * 0x0A == (IRQ 7, DMA 1, MIRQ 0) */ err = sc6000_cfg_write(vport, 0x0a); /* set configuration */ sc6000_write(vport, COMMAND_5C); if (sc6000_read(vport) < 0) old = 1; if (!old) { int cfg[2]; sc6000_hw_cfg_encode(vport, &cfg[0], port[dev], mpu_port[dev], mss_port[dev], joystick[dev]); if (sc6000_hw_cfg_write(vport, cfg) < 0) { snd_printk(KERN_ERR "sc6000_hw_cfg_write: failed!\n"); return -EIO; } } err = sc6000_setup_board(vport, config); if (err < 0) { snd_printk(KERN_ERR "sc6000_cfg_write: failed!\n"); return -EFAULT; snd_printk(KERN_ERR "sc6000_setup_board: failed!\n"); return -ENODEV; } sc6000_dsp_reset(vport); if (!old) { sc6000_write(vport, COMMAND_60); sc6000_write(vport, 0x02); sc6000_dsp_reset(vport); } err = sc6000_setup_board(vport, config); Loading @@ -386,7 +457,6 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, snd_printk(KERN_ERR "sc6000_setup_board: failed!\n"); return -ENODEV; } err = sc6000_init_mss(vport, config, vmss_port, mss_config); if (err < 0) { snd_printk(KERN_ERR "Cannot initialize " Loading Loading @@ -485,14 +555,16 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) struct snd_card *card; struct snd_wss *chip; struct snd_opl3 *opl3; char __iomem *vport; char __iomem **vport; char __iomem *vmss_port; err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); err = snd_card_create(index[dev], id[dev], THIS_MODULE, sizeof(vport), &card); if (err < 0) return err; vport = card->private_data; if (xirq == SNDRV_AUTO_IRQ) { xirq = snd_legacy_find_free_irq(possible_irqs); if (xirq < 0) { Loading @@ -517,8 +589,8 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) err = -EBUSY; goto err_exit; } vport = devm_ioport_map(devptr, port[dev], 0x10); if (!vport) { *vport = devm_ioport_map(devptr, port[dev], 0x10); if (*vport == NULL) { snd_printk(KERN_ERR PFX "I/O port cannot be iomaped.\n"); err = -EBUSY; Loading @@ -533,7 +605,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) goto err_unmap1; } vmss_port = devm_ioport_map(devptr, mss_port[dev], 4); if (!vport) { if (!vmss_port) { snd_printk(KERN_ERR PFX "MSS port I/O cannot be iomaped.\n"); err = -EBUSY; Loading @@ -544,7 +616,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) port[dev], xirq, xdma, mpu_irq[dev] == SNDRV_AUTO_IRQ ? 0 : mpu_irq[dev]); err = sc6000_init_board(vport, xirq, xdma, vmss_port, mpu_irq[dev]); err = sc6000_init_board(*vport, vmss_port, dev); if (err < 0) goto err_unmap2; Loading @@ -552,7 +624,6 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) WSS_HW_DETECT, 0, &chip); if (err < 0) goto err_unmap2; card->private_data = chip; err = snd_wss_pcm(chip, 0, NULL); if (err < 0) { Loading Loading @@ -608,6 +679,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) return 0; err_unmap2: sc6000_setup_board(*vport, 0); release_region(mss_port[dev], 4); err_unmap1: release_region(port[dev], 0x10); Loading @@ -618,11 +690,17 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) static int __devexit snd_sc6000_remove(struct device *devptr, unsigned int dev) { struct snd_card *card = dev_get_drvdata(devptr); char __iomem **vport = card->private_data; if (sc6000_setup_board(*vport, 0) < 0) snd_printk(KERN_WARNING "sc6000_setup_board failed on exit!\n"); release_region(port[dev], 0x10); release_region(mss_port[dev], 4); snd_card_free(dev_get_drvdata(devptr)); dev_set_drvdata(devptr, NULL); snd_card_free(card); return 0; } Loading