Commit 743e83a4 authored by Adam Belay's avatar Adam Belay

ALSA SB16 PnP Update

Updates the driver to the new pnp apis.  Although it has only been tested
for compiliation, it is an improvement over the existing broken code. 
These changes are based on a update by Shaheed Haque <srhaque@iee.org>.
parent d04b51de
...@@ -23,11 +23,7 @@ ...@@ -23,11 +23,7 @@
#include <asm/dma.h> #include <asm/dma.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#ifndef LINUX_ISAPNP_H #include <linux/pnp.h>
#include <linux/isapnp.h>
#define isapnp_card pci_bus
#define isapnp_dev pci_dev
#endif
#include <sound/core.h> #include <sound/core.h>
#include <sound/sb.h> #include <sound/sb.h>
#include <sound/sb16_csp.h> #include <sound/sb16_csp.h>
...@@ -77,7 +73,7 @@ MODULE_DEVICES("{{Creative Labs,SB AWE 32}," ...@@ -77,7 +73,7 @@ MODULE_DEVICES("{{Creative Labs,SB AWE 32},"
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif #endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
...@@ -106,10 +102,10 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC); ...@@ -106,10 +102,10 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable, "Enable SoundBlaster 16 soundcard."); MODULE_PARM_DESC(enable, "Enable SoundBlaster 16 soundcard.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
MODULE_PARM(isapnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(pnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard."); MODULE_PARM_DESC(pnp, "PnP detection for specified soundcard.");
MODULE_PARM_SYNTAX(isapnp, SNDRV_ISAPNP_DESC); MODULE_PARM_SYNTAX(pnp, SNDRV_ISAPNP_DESC);
#endif #endif
MODULE_PARM(port, "1-" __MODULE_STRING(SNDRV_CARDS) "l"); MODULE_PARM(port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
MODULE_PARM_DESC(port, "Port # for SB16 driver."); MODULE_PARM_DESC(port, "Port # for SB16 driver.");
...@@ -148,231 +144,211 @@ MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth."); ...@@ -148,231 +144,211 @@ MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
MODULE_PARM_SYNTAX(seq_ports, SNDRV_ENABLED ",allows:{{0,8}},skill:advanced"); MODULE_PARM_SYNTAX(seq_ports, SNDRV_ENABLED ",allows:{{0,8}},skill:advanced");
#endif #endif
struct snd_sb16 { struct snd_card_sb16 {
struct resource *fm_res; /* used to block FM i/o region for legacy cards */ struct resource *fm_res; /* used to block FM i/o region for legacy cards */
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
struct isapnp_dev *dev; int dev_no;
struct pnp_dev *dev;
#ifdef SNDRV_SBAWE_EMU8000 #ifdef SNDRV_SBAWE_EMU8000
struct isapnp_dev *devwt; struct pnp_dev *devwt;
#endif #endif
#endif #endif
}; };
static snd_card_t *snd_sb16_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; static snd_card_t *snd_sb16_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
#ifdef __ISAPNP__
static struct isapnp_card *snd_sb16_isapnp_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; static struct pnp_card_device_id snd_sb16_pnpids[] __devinitdata = {
static const struct isapnp_card_id *snd_sb16_isapnp_id[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
#define ISAPNP_SB16(_va, _vb, _vc, _device, _audio) \
{ \
ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), } \
}
#define ISAPNP_SBAWE(_va, _vb, _vc, _device, _audio, _awe) \
{ \
ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
ISAPNP_DEVICE_ID(_va, _vb, _vc, _awe), } \
}
static struct isapnp_card_id snd_sb16_pnpids[] __devinitdata = {
#ifndef SNDRV_SBAWE #ifndef SNDRV_SBAWE
/* Sound Blaster 16 PnP */ /* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0024,0x0031), { .id = "CTL0024", .devs = { { "CTL0031" } } },
/* Sound Blaster 16 PnP */ /* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0025,0x0031), { .id = "CTL0025", .devs = { { "CTL0031" } } },
/* Sound Blaster 16 PnP */ /* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0026,0x0031), { .id = "CTL0026", .devs = { { "CTL0031" } } },
/* Sound Blaster 16 PnP */ /* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0027,0x0031), { .id = "CTL0027", .devs = { { "CTL0031" } } },
/* Sound Blaster 16 PnP */ /* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0028,0x0031), { .id = "CTL0028", .devs = { { "CTL0031" } } },
/* Sound Blaster 16 PnP */ /* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x0029,0x0031), { .id = "CTL0029", .devs = { { "CTL0031" } } },
/* Sound Blaster 16 PnP */ /* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x002a,0x0031), { .id = "CTL002a", .devs = { { "CTL0031" } } },
/* Sound Blaster 16 PnP */ /* Sound Blaster 16 PnP */
/* Note: This card has also a CTL0051:StereoEnhance device!!! */ /* Note: This card has also a CTL0051:StereoEnhance device!!! */
ISAPNP_SB16('C','T','L',0x002b,0x0031), { .id = "CTL002b", .devs = { { "CTL0031" } } },
/* Sound Blaster 16 PnP */ /* Sound Blaster 16 PnP */
ISAPNP_SB16('C','T','L',0x002c,0x0031), { .id = "CTL002c", .devs = { { "CTL0031" } } },
/* Sound Blaster Vibra16S */ /* Sound Blaster Vibra16S */
ISAPNP_SB16('C','T','L',0x0051,0x0001), { .id = "CTL0051", .devs = { { "CTL0001" } } },
/* Sound Blaster Vibra16C */ /* Sound Blaster Vibra16C */
ISAPNP_SB16('C','T','L',0x0070,0x0001), { .id = "CTL0070", .devs = { { "CTL0001" } } },
/* Sound Blaster Vibra16CL - added by ctm@ardi.com */ /* Sound Blaster Vibra16CL - added by ctm@ardi.com */
ISAPNP_SB16('C','T','L',0x0080,0x0041), { .id = "CTL0080", .devs = { { "CTL0041" } } },
/* Sound Blaster 16 'value' PnP. It says model ct4130 on the pcb, */ /* Sound Blaster 16 'value' PnP. It says model ct4130 on the pcb, */
/* but ct4131 on a sticker on the board.. */ /* but ct4131 on a sticker on the board.. */
ISAPNP_SB16('C','T','L',0x0086,0x0041), { .id = "CTL0086", .devs = { { "CTL0041" } } },
/* Sound Blaster Vibra16X */ /* Sound Blaster Vibra16X */
ISAPNP_SB16('C','T','L',0x00f0,0x0043), { .id = "CTL00f0", .devs = { { "CTL0043" } } },
#else /* SNDRV_SBAWE defined */ #else /* SNDRV_SBAWE defined */
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x0035,0x0031,0x0021), { .id = "CTL0035", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x0039,0x0031,0x0021), { .id = "CTL0039", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x0042,0x0031,0x0021), { .id = "CTL0042", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x0043,0x0031,0x0021), { .id = "CTL0043", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
/* Note: This card has also a CTL0051:StereoEnhance device!!! */ /* Note: This card has also a CTL0051:StereoEnhance device!!! */
ISAPNP_SBAWE('C','T','L',0x0044,0x0031,0x0021), { .id = "CTL0044", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
/* Note: This card has also a CTL0051:StereoEnhance device!!! */ /* Note: This card has also a CTL0051:StereoEnhance device!!! */
ISAPNP_SBAWE('C','T','L',0x0045,0x0031,0x0021), { .id = "CTL0045", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x0046,0x0031,0x0021), { .id = "CTL0046", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x0047,0x0031,0x0021), { .id = "CTL0047", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x0048,0x0031,0x0021), { .id = "CTL0048", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x0054,0x0031,0x0021), { .id = "CTL0054", .devs = { { "CTL0031" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x009a,0x0041,0x0021), { .id = "CTL009a", .devs = { { "CTL0041" }, { "CTL0021" } } },
/* Sound Blaster AWE 32 PnP */ /* Sound Blaster AWE 32 PnP */
ISAPNP_SBAWE('C','T','L',0x009c,0x0041,0x0021), { .id = "CTL009c", .devs = { { "CTL0041" }, { "CTL0021" } } },
/* Sound Blaster 32 PnP */ /* Sound Blaster 32 PnP */
ISAPNP_SBAWE('C','T','L',0x009f,0x0041,0x0021), { .id = "CTL009f", .devs = { { "CTL0041" }, { "CTL0021" } } },
/* Sound Blaster AWE 64 PnP */ /* Sound Blaster AWE 64 PnP */
ISAPNP_SBAWE('C','T','L',0x009d,0x0042,0x0022), { .id = "CTL009d", .devs = { { "CTL0042" }, { "CTL0022" } } },
/* Sound Blaster AWE 64 PnP Gold */ /* Sound Blaster AWE 64 PnP Gold */
ISAPNP_SBAWE('C','T','L',0x009e,0x0044,0x0023), { .id = "CTL009e", .devs = { { "CTL0044" }, { "CTL0023" } } },
/* Sound Blaster AWE 64 PnP Gold */ /* Sound Blaster AWE 64 PnP Gold */
ISAPNP_SBAWE('C','T','L',0x00b2,0x0044,0x0023), { .id = "CTL00b2", .devs = { { "CTL0044" }, { "CTL0023" } } },
/* Sound Blaster AWE 64 PnP */ /* Sound Blaster AWE 64 PnP */
ISAPNP_SBAWE('C','T','L',0x00c1,0x0042,0x0022), { .id = "CTL00c1", .devs = { { "CTL0042" }, { "CTL0022" } } },
/* Sound Blaster AWE 64 PnP */ /* Sound Blaster AWE 64 PnP */
ISAPNP_SBAWE('C','T','L',0x00c3,0x0045,0x0022), { .id = "CTL00c3", .devs = { { "CTL0045" }, { "CTL0022" } } },
/* Sound Blaster AWE 64 PnP */ /* Sound Blaster AWE 64 PnP */
ISAPNP_SBAWE('C','T','L',0x00c5,0x0045,0x0022), { .id = "CTL00c5", .devs = { { "CTL0045" }, { "CTL0022" } } },
/* Sound Blaster AWE 64 PnP */ /* Sound Blaster AWE 64 PnP */
ISAPNP_SBAWE('C','T','L',0x00c7,0x0045,0x0022), { .id = "CTL00c7", .devs = { { "CTL0045" }, { "CTL0022" } } },
/* Sound Blaster AWE 64 PnP */ /* Sound Blaster AWE 64 PnP */
ISAPNP_SBAWE('C','T','L',0x00e4,0x0045,0x0022), { .id = "CTL00e4", .devs = { { "CTL0045" }, { "CTL0022" } } },
/* Sound Blaster AWE 64 PnP */ /* Sound Blaster AWE 64 PnP */
ISAPNP_SBAWE('C','T','L',0x00e9,0x0045,0x0022), { .id = "CTL00e9", .devs = { { "CTL0045" }, { "CTL0022" } } },
/* Sound Blaster 16 PnP (AWE) */ /* Sound Blaster 16 PnP (AWE) */
ISAPNP_SBAWE('C','T','L',0x00ed,0x0041,0x0070), { .id = "CTL00ed", .devs = { { "CTL0041" }, { "CTL0070" } } },
/* Generic entries */ /* Generic entries */
ISAPNP_SBAWE('C','T','L',ISAPNP_ANY_ID,0x0031,0x0021), { .id = "CTLXXXX" , .devs = { { "CTL0031" }, { "CTL0021" } } },
ISAPNP_SBAWE('C','T','L',ISAPNP_ANY_ID,0x0041,0x0021), { .id = "CTLXXXX" , .devs = { { "CTL0041" }, { "CTL0021" } } },
ISAPNP_SBAWE('C','T','L',ISAPNP_ANY_ID,0x0042,0x0022), { .id = "CTLXXXX" , .devs = { { "CTL0042" }, { "CTL0022" } } },
ISAPNP_SBAWE('C','T','L',ISAPNP_ANY_ID,0x0044,0x0023), { .id = "CTLXXXX" , .devs = { { "CTL0044" }, { "CTL0023" } } },
ISAPNP_SBAWE('C','T','L',ISAPNP_ANY_ID,0x0045,0x0022), { .id = "CTLXXXX" , .devs = { { "CTL0045" }, { "CTL0022" } } },
#endif /* SNDRV_SBAWE */ #endif /* SNDRV_SBAWE */
{ ISAPNP_CARD_END, } { .id = "", }
}; };
ISAPNP_CARD_TABLE(snd_sb16_pnpids); MODULE_DEVICE_TABLE(pnp_card, snd_sb16_pnpids);
static int __init snd_sb16_isapnp(int dev, struct snd_sb16 *acard) #ifdef SNDRV_SBAWE_EMU8000
#define DRIVER_NAME "snd-card-sbawe"
#else
#define DRIVER_NAME "snd-card-sb16"
#endif
static int __devinit snd_card_sb16_pnp(int dev, struct snd_card_sb16 *acard,
struct pnp_card_link *card,
const struct pnp_card_device_id *id)
{ {
const struct isapnp_card_id *id = snd_sb16_isapnp_id[dev]; struct pnp_dev *pdev;
struct isapnp_card *card = snd_sb16_isapnp_cards[dev]; struct pnp_resource_table * cfg = kmalloc(GFP_ATOMIC, sizeof(struct pnp_resource_table));
struct isapnp_dev *pdev; int err;
acard->dev = isapnp_find_dev(card, id->devs[0].vendor, id->devs[0].function, NULL); if (!cfg)
if (acard->dev->active) { return -ENOMEM;
acard->dev = NULL; acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
return -EBUSY; if (acard->dev == NULL) {
} kfree(cfg);
return -ENODEV;
}
#ifdef SNDRV_SBAWE_EMU8000 #ifdef SNDRV_SBAWE_EMU8000
acard->devwt = isapnp_find_dev(card, id->devs[1].vendor, id->devs[1].function, NULL); acard->devwt = pnp_request_card_device(card, id->devs[1].id, acard->dev);
if (acard->devwt->active) { #endif
acard->dev = acard->devwt = NULL;
return -EBUSY;
}
#endif
/* Audio initialization */ /* Audio initialization */
pdev = acard->dev; pdev = acard->dev;
if (pdev->prepare(pdev) < 0)
return -EAGAIN; pnp_init_resource_table(cfg);
/* override resources */
if (port[dev] != SNDRV_AUTO_PORT) if (port[dev] != SNDRV_AUTO_PORT)
isapnp_resource_change(&pdev->resource[0], port[dev], 16); pnp_resource_change(&cfg->port_resource[0], port[dev], 16);
if (mpu_port[dev] != SNDRV_AUTO_PORT) if (mpu_port[dev] != SNDRV_AUTO_PORT)
isapnp_resource_change(&pdev->resource[1], mpu_port[dev], 2); pnp_resource_change(&cfg->port_resource[1], mpu_port[dev], 2);
if (fm_port[dev] != SNDRV_AUTO_PORT) if (fm_port[dev] != SNDRV_AUTO_PORT)
isapnp_resource_change(&pdev->resource[2], fm_port[dev], 4); pnp_resource_change(&cfg->port_resource[2], fm_port[dev], 4);
if (dma8[dev] != SNDRV_AUTO_DMA) if (dma8[dev] != SNDRV_AUTO_DMA)
isapnp_resource_change(&pdev->dma_resource[0], dma8[dev], 1); pnp_resource_change(&cfg->dma_resource[0], dma8[dev], 1);
if (dma16[dev] != SNDRV_AUTO_DMA) if (dma16[dev] != SNDRV_AUTO_DMA)
isapnp_resource_change(&pdev->dma_resource[1], dma16[dev], 1); pnp_resource_change(&cfg->dma_resource[1], dma16[dev], 1);
if (irq[dev] != SNDRV_AUTO_IRQ) if (irq[dev] != SNDRV_AUTO_IRQ)
isapnp_resource_change(&pdev->irq_resource[0], irq[dev], 1); pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1);
if (pdev->activate(pdev) < 0) { if ((pnp_manual_config_dev(pdev, cfg, 0)) < 0)
printk(KERN_ERR PFX "isapnp configure failure (out of resources?)\n"); printk(KERN_ERR PFX "AUDIO the requested resources are invalid, using auto config\n");
return -EBUSY; err = pnp_activate_dev(pdev);
} if (err < 0) {
port[dev] = pdev->resource[0].start; printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
mpu_port[dev] = pdev->resource[1].start; kfree(cfg);
fm_port[dev] = pdev->resource[2].start; return err;
dma8[dev] = pdev->dma_resource[0].start; }
dma16[dev] = pdev->dma_resource[1].start; port[dev] = pnp_port_start(pdev, 0);
irq[dev] = pdev->irq_resource[0].start; mpu_port[dev] = pnp_port_start(pdev, 1);
snd_printdd("isapnp SB16: port=0x%lx, mpu port=0x%lx, fm port=0x%lx\n", fm_port[dev] = pnp_port_start(pdev, 2);
dma8[dev] = pnp_dma(pdev, 0);
dma16[dev] = pnp_dma(pdev, 1);
irq[dev] = pnp_irq(pdev, 0);
snd_printdd("pnp SB16: port=0x%lx, mpu port=0x%lx, fm port=0x%lx\n",
port[dev], mpu_port[dev], fm_port[dev]); port[dev], mpu_port[dev], fm_port[dev]);
snd_printdd("isapnp SB16: dma1=%i, dma2=%i, irq=%i\n", snd_printdd("pnp SB16: dma1=%i, dma2=%i, irq=%i\n",
dma8[dev], dma16[dev], irq[dev]); dma8[dev], dma16[dev], irq[dev]);
#ifdef SNDRV_SBAWE_EMU8000 #ifdef SNDRV_SBAWE_EMU8000
/* WaveTable initialization */ /* WaveTable initialization */
pdev = acard->devwt; pdev = acard->devwt;
if (pdev->prepare(pdev)<0) { if (pdev != NULL) {
acard->dev->deactivate(acard->dev); pnp_init_resource_table(cfg);
return -EAGAIN;
} /* override resources */
if (awe_port[dev] != SNDRV_AUTO_PORT) {
isapnp_resource_change(&pdev->resource[0], awe_port[dev], 4); if (awe_port[dev] != SNDRV_AUTO_PORT) {
isapnp_resource_change(&pdev->resource[1], awe_port[dev] + 0x400, 4); pnp_resource_change(&cfg->port_resource[0], awe_port[dev], 4);
isapnp_resource_change(&pdev->resource[2], awe_port[dev] + 0x800, 4); pnp_resource_change(&cfg->port_resource[1], awe_port[dev] + 0x400, 4);
} pnp_resource_change(&cfg->port_resource[2], awe_port[dev] + 0x800, 4);
if (pdev->activate(pdev)<0) { }
printk(KERN_ERR PFX "WaveTable isapnp configure failure (out of resources?)\n"); if ((pnp_manual_config_dev(pdev, cfg, 0)) < 0)
acard->dev->deactivate(acard->dev); printk(KERN_ERR PFX "WaveTable the requested resources are invalid, using auto config\n");
return -EBUSY; err = pnp_activate_dev(pdev);
} if (err < 0) {
awe_port[dev] = pdev->resource[0].start; goto __wt_error;
snd_printdd("isapnp SB16: wavetable port=0x%lx\n", pdev->resource[0].start); }
#endif awe_port[dev] = pnp_port_start(pdev, 0);
return 0; snd_printdd("pnp SB16: wavetable port=0x%lx\n", pdev->resource[0].start);
} } else {
__wt_error:
static void snd_sb16_deactivate(struct snd_sb16 *acard) if (pdev) {
{ pnp_release_card_device(pdev);
if (acard->dev) { printk(KERN_ERR PFX "WaveTable pnp configure failure\n");
acard->dev->deactivate(acard->dev); }
acard->dev = NULL;
}
#ifdef SNDRV_SBAWE_EMU8000
if (acard->devwt) {
acard->devwt->deactivate(acard->devwt);
acard->devwt = NULL; acard->devwt = NULL;
awe_port[dev] = -1;
} }
#endif #endif
kfree(cfg);
return 0;
} }
#endif /* __ISAPNP__ */ static int __init snd_sb16_probe(int dev,
struct pnp_card_link *pcard,
static void snd_sb16_free(snd_card_t *card) const struct pnp_card_device_id *pid)
{
struct snd_sb16 *acard = (struct snd_sb16 *)card->private_data;
if (acard == NULL)
return;
if (acard->fm_res) {
release_resource(acard->fm_res);
kfree_nocheck(acard->fm_res);
}
#ifdef __ISAPNP__
snd_sb16_deactivate(acard);
#endif
}
static int __init snd_sb16_probe(int dev)
{ {
static int possible_irqs[] = {5, 9, 10, 7, -1}; static int possible_irqs[] = {5, 9, 10, 7, -1};
static int possible_dmas8[] = {1, 3, 0, -1}; static int possible_dmas8[] = {1, 3, 0, -1};
...@@ -380,7 +356,7 @@ static int __init snd_sb16_probe(int dev) ...@@ -380,7 +356,7 @@ static int __init snd_sb16_probe(int dev)
int xirq, xdma8, xdma16; int xirq, xdma8, xdma16;
sb_t *chip; sb_t *chip;
snd_card_t *card; snd_card_t *card;
struct snd_sb16 *acard; struct snd_card_sb16 *acard;
opl3_t *opl3; opl3_t *opl3;
snd_hwdep_t *synth = NULL; snd_hwdep_t *synth = NULL;
#ifdef CONFIG_SND_SB16_CSP #ifdef CONFIG_SND_SB16_CSP
...@@ -390,22 +366,21 @@ static int __init snd_sb16_probe(int dev) ...@@ -390,22 +366,21 @@ static int __init snd_sb16_probe(int dev)
int err; int err;
card = snd_card_new(index[dev], id[dev], THIS_MODULE, card = snd_card_new(index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_sb16)); sizeof(struct snd_card_sb16));
if (card == NULL) if (card == NULL)
return -ENOMEM; return -ENOMEM;
acard = (struct snd_sb16 *) card->private_data; acard = (struct snd_card_sb16 *) card->private_data;
card->private_free = snd_sb16_free; if (isapnp[dev]) {
#ifdef __ISAPNP__ if ((err = snd_card_sb16_pnp(dev, acard, pcard, pid))) {
if (isapnp[dev] && snd_sb16_isapnp(dev, acard) < 0) { snd_card_free(card);
snd_card_free(card); return err;
return -EBUSY; }
} }
#endif
xirq = irq[dev]; xirq = irq[dev];
xdma8 = dma8[dev]; xdma8 = dma8[dev];
xdma16 = dma16[dev]; xdma16 = dma16[dev];
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
if (!isapnp[dev]) { if (!isapnp[dev]) {
#endif #endif
if (xirq == SNDRV_AUTO_IRQ) { if (xirq == SNDRV_AUTO_IRQ) {
...@@ -437,7 +412,7 @@ static int __init snd_sb16_probe(int dev) ...@@ -437,7 +412,7 @@ static int __init snd_sb16_probe(int dev)
/* non-PnP AWE port address is hardwired with base port address */ /* non-PnP AWE port address is hardwired with base port address */
awe_port[dev] = port[dev] + 0x400; awe_port[dev] = port[dev] + 0x400;
#endif #endif
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
} }
#endif #endif
...@@ -458,7 +433,7 @@ static int __init snd_sb16_probe(int dev) ...@@ -458,7 +433,7 @@ static int __init snd_sb16_probe(int dev)
return -ENODEV; return -ENODEV;
} }
chip->mpu_port = mpu_port[dev]; chip->mpu_port = mpu_port[dev];
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
if (!isapnp[dev] && (err = snd_sb16dsp_configure(chip)) < 0) { if (!isapnp[dev] && (err = snd_sb16dsp_configure(chip)) < 0) {
#else #else
if ((err = snd_sb16dsp_configure(chip)) < 0) { if ((err = snd_sb16dsp_configure(chip)) < 0) {
...@@ -554,7 +529,10 @@ static int __init snd_sb16_probe(int dev) ...@@ -554,7 +529,10 @@ static int __init snd_sb16_probe(int dev)
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
snd_sb16_cards[dev] = card; if (pcard)
pnp_set_card_drvdata(pcard, card);
else
snd_sb16_legacy[dev] = card;
return 0; return 0;
} }
...@@ -566,12 +544,12 @@ static int __init snd_sb16_probe_legacy_port(unsigned long xport) ...@@ -566,12 +544,12 @@ static int __init snd_sb16_probe_legacy_port(unsigned long xport)
for ( ; dev < SNDRV_CARDS; dev++) { for ( ; dev < SNDRV_CARDS; dev++) {
if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT) if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
continue; continue;
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
if (isapnp[dev]) if (isapnp[dev])
continue; continue;
#endif #endif
port[dev] = xport; port[dev] = xport;
res = snd_sb16_probe(dev); res = snd_sb16_probe(dev, NULL, NULL);
if (res < 0) if (res < 0)
port[dev] = SNDRV_AUTO_PORT; port[dev] = SNDRV_AUTO_PORT;
return res; return res;
...@@ -579,10 +557,10 @@ static int __init snd_sb16_probe_legacy_port(unsigned long xport) ...@@ -579,10 +557,10 @@ static int __init snd_sb16_probe_legacy_port(unsigned long xport)
return -ENODEV; return -ENODEV;
} }
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
static int __init snd_sb16_isapnp_detect(struct isapnp_card *card, static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *card,
const struct isapnp_card_id *id) const struct pnp_card_device_id *id)
{ {
static int dev; static int dev;
int res; int res;
...@@ -590,9 +568,7 @@ static int __init snd_sb16_isapnp_detect(struct isapnp_card *card, ...@@ -590,9 +568,7 @@ static int __init snd_sb16_isapnp_detect(struct isapnp_card *card,
for ( ; dev < SNDRV_CARDS; dev++) { for ( ; dev < SNDRV_CARDS; dev++) {
if (!enable[dev] || !isapnp[dev]) if (!enable[dev] || !isapnp[dev])
continue; continue;
snd_sb16_isapnp_cards[dev] = card; res = snd_sb16_probe(dev, card, id);
snd_sb16_isapnp_id[dev] = id;
res = snd_sb16_probe(dev);
if (res < 0) if (res < 0)
return res; return res;
dev++; dev++;
...@@ -602,7 +578,23 @@ static int __init snd_sb16_isapnp_detect(struct isapnp_card *card, ...@@ -602,7 +578,23 @@ static int __init snd_sb16_isapnp_detect(struct isapnp_card *card,
return -ENODEV; return -ENODEV;
} }
#endif /* __ISAPNP__ */ #endif
static void __devexit snd_sb16_pnp_remove(struct pnp_card_link * pcard)
{
snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
snd_card_disconnect(card);
snd_card_free_in_thread(card);
}
static struct pnp_card_driver sb16_pnpc_driver = {
.flags = PNP_DRIVER_RES_DISABLE,
.name = "sb16",
.id_table = snd_sb16_pnpids,
.probe = snd_sb16_pnp_detect,
.remove = __devexit_p(snd_sb16_pnp_remove),
};
static int __init alsa_card_sb16_init(void) static int __init alsa_card_sb16_init(void)
{ {
...@@ -613,23 +605,23 @@ static int __init alsa_card_sb16_init(void) ...@@ -613,23 +605,23 @@ static int __init alsa_card_sb16_init(void)
for (dev = 0; dev < SNDRV_CARDS; dev++) { for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT) if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT)
continue; continue;
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
if (isapnp[dev]) if (isapnp[dev])
continue; continue;
#endif #endif
if (!snd_sb16_probe(dev)) { if (!snd_sb16_probe(dev, NULL, NULL)) {
cards++; cards++;
continue; continue;
} }
#ifdef MODULE #ifdef MODULE
printk(KERN_ERR "Sound Blaster 16+ soundcard #%i not found at 0x%lx or device busy\n", dev, port[dev]); printk(KERN_ERR "Sound Blaster 16+ soundcard #%i not found at 0x%lx or device busy\n", dev, port[dev]);
#endif #endif
} }
/* legacy auto configured cards */ /* legacy auto configured cards */
cards += snd_legacy_auto_probe(possible_ports, snd_sb16_probe_legacy_port); cards += snd_legacy_auto_probe(possible_ports, snd_sb16_probe_legacy_port);
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
/* ISA PnP cards at last */ /* PnP cards at last */
cards += isapnp_probe_cards(snd_sb16_pnpids, snd_sb16_isapnp_detect); cards += pnp_register_card_driver(&sb16_pnpc_driver);
#endif #endif
if (!cards) { if (!cards) {
...@@ -650,8 +642,12 @@ static void __exit alsa_card_sb16_exit(void) ...@@ -650,8 +642,12 @@ static void __exit alsa_card_sb16_exit(void)
{ {
int dev; int dev;
#ifdef CONFIG_PNP
/* PnP cards first */
pnp_unregister_card_driver(&sb16_pnpc_driver);
#endif
for (dev = 0; dev < SNDRV_CARDS; dev++) for (dev = 0; dev < SNDRV_CARDS; dev++)
snd_card_free(snd_sb16_cards[dev]); snd_card_free(snd_sb16_legacy[dev]);
} }
module_init(alsa_card_sb16_init) module_init(alsa_card_sb16_init)
...@@ -659,7 +655,7 @@ module_exit(alsa_card_sb16_exit) ...@@ -659,7 +655,7 @@ module_exit(alsa_card_sb16_exit)
#ifndef MODULE #ifndef MODULE
/* format is: snd-sb16=enable,index,id,isapnp, /* format is: snd-sb16=enable,index,id,pnp,
port,mpu_port,fm_port, port,mpu_port,fm_port,
irq,dma8,dma16, irq,dma8,dma16,
mic_agc,csp, mic_agc,csp,
...@@ -694,7 +690,7 @@ static int __init alsa_card_sb16_setup(char *str) ...@@ -694,7 +690,7 @@ static int __init alsa_card_sb16_setup(char *str)
get_option(&str,&seq_ports[nr_dev]) == 2 get_option(&str,&seq_ports[nr_dev]) == 2
#endif #endif
); );
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
if (pnp != INT_MAX) if (pnp != INT_MAX)
isapnp[nr_dev] = pnp; isapnp[nr_dev] = pnp;
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment