diff options
Diffstat (limited to 'sound/isa/gus/interwave.c')
-rw-r--r-- | sound/isa/gus/interwave.c | 242 |
1 files changed, 118 insertions, 124 deletions
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 3e9ad930deae..18a98123e286 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -28,14 +28,8 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_LICENSE("GPL"); #ifndef SNDRV_STB MODULE_DESCRIPTION("AMD InterWave"); -MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Plug & Play}," - "{STB,SoundRage32}," - "{MED,MED3210}," - "{Dynasonix,Dynasonix Pro}," - "{Panasonic,PCA761AW}}"); #else MODULE_DESCRIPTION("AMD InterWave STB with TEA6330T"); -MODULE_SUPPORTED_DEVICE("{{AMD,InterWave STB with TEA6330T}}"); #endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ @@ -58,11 +52,9 @@ static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; static int effect[SNDRV_CARDS]; #ifdef SNDRV_STB -#define PFX "interwave-stb: " #define INTERWAVE_DRIVER "snd_interwave_stb" #define INTERWAVE_PNP_DRIVER "interwave-stb" #else -#define PFX "interwave: " #define INTERWAVE_DRIVER "snd_interwave" #define INTERWAVE_PNP_DRIVER "interwave" #endif @@ -154,7 +146,7 @@ static void snd_interwave_i2c_setlines(struct snd_i2c_bus *bus, int ctrl, int da unsigned long port = bus->private_value; #if 0 - printk(KERN_DEBUG "i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data); + dev_dbg(bus->card->dev, "i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data); #endif outb((data << 1) | ctrl, port); udelay(10); @@ -167,7 +159,7 @@ static int snd_interwave_i2c_getclockline(struct snd_i2c_bus *bus) res = inb(port) & 1; #if 0 - printk(KERN_DEBUG "i2c_getclockline - 0x%lx -> %i\n", port, res); + dev_dbg(bus->card->dev, "i2c_getclockline - 0x%lx -> %i\n", port, res); #endif return res; } @@ -181,7 +173,7 @@ static int snd_interwave_i2c_getdataline(struct snd_i2c_bus *bus, int ack) udelay(10); res = (inb(port) & 2) >> 1; #if 0 - printk(KERN_DEBUG "i2c_getdataline - 0x%lx -> %i\n", port, res); + dev_dbg(bus->card->dev, "i2c_getdataline - 0x%lx -> %i\n", port, res); #endif return res; } @@ -210,24 +202,29 @@ static int snd_interwave_detect_stb(struct snd_interwave *iwcard, port = 0x360; } while (port <= 0x380) { - if ((iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)")) != NULL) + iwcard->i2c_res = devm_request_region(card->dev, port, 1, + "InterWave (I2C bus)"); + if (iwcard->i2c_res) break; port += 0x10; } } else { - iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)"); + iwcard->i2c_res = devm_request_region(card->dev, port, 1, + "InterWave (I2C bus)"); } if (iwcard->i2c_res == NULL) { - snd_printk(KERN_ERR "interwave: can't grab i2c bus port\n"); + dev_err(card->dev, "interwave: can't grab i2c bus port\n"); return -ENODEV; } sprintf(name, "InterWave-%i", card->number); - if ((err = snd_i2c_bus_create(card, name, NULL, &bus)) < 0) + err = snd_i2c_bus_create(card, name, NULL, &bus); + if (err < 0) return err; bus->private_value = port; bus->hw_ops.bit = &snd_interwave_i2c_bit_ops; - if ((err = snd_tea6330t_detect(bus, 0)) < 0) + err = snd_tea6330t_detect(bus, 0); + if (err < 0) return err; *rbus = bus; return 0; @@ -247,15 +244,17 @@ static int snd_interwave_detect(struct snd_interwave *iwcard, int d; snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */ - if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) { - snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d); + d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET); + if ((d & 0x07) != 0) { + dev_dbg(gus->card->dev, "[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d); return -ENODEV; } udelay(160); snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */ udelay(160); - if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) { - snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); + d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET); + if ((d & 0x07) != 1) { + dev_dbg(gus->card->dev, "[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); return -ENODEV; } spin_lock_irqsave(&gus->reg_lock, flags); @@ -264,10 +263,13 @@ static int snd_interwave_detect(struct snd_interwave *iwcard, rev2 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER); snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, rev1); spin_unlock_irqrestore(&gus->reg_lock, flags); - snd_printdd("[0x%lx] InterWave check - rev1=0x%x, rev2=0x%x\n", gus->gf1.port, rev1, rev2); + dev_dbg(gus->card->dev, + "[0x%lx] InterWave check - rev1=0x%x, rev2=0x%x\n", + gus->gf1.port, rev1, rev2); if ((rev1 & 0xf0) == (rev2 & 0xf0) && (rev1 & 0x0f) != (rev2 & 0x0f)) { - snd_printdd("[0x%lx] InterWave check - passed\n", gus->gf1.port); + dev_dbg(gus->card->dev, + "[0x%lx] InterWave check - passed\n", gus->gf1.port); gus->interwave = 1; strcpy(gus->card->shortname, "AMD InterWave"); gus->revision = rev1 >> 4; @@ -277,7 +279,7 @@ static int snd_interwave_detect(struct snd_interwave *iwcard, return snd_interwave_detect_stb(iwcard, gus, dev, rbus); #endif } - snd_printdd("[0x%lx] InterWave check - failed\n", gus->gf1.port); + dev_dbg(gus->card->dev, "[0x%lx] InterWave check - failed\n", gus->gf1.port); return -ENODEV; } @@ -326,7 +328,7 @@ static void snd_interwave_bank_sizes(struct snd_gus_card *gus, int *sizes) snd_gf1_poke(gus, local, d); snd_gf1_poke(gus, local + 1, d + 1); #if 0 - printk(KERN_DEBUG "d = 0x%x, local = 0x%x, " + dev_dbg(gus->card->dev, "d = 0x%x, local = 0x%x, " "local + 1 = 0x%x, idx << 22 = 0x%x\n", d, snd_gf1_peek(gus, local), @@ -341,7 +343,7 @@ static void snd_interwave_bank_sizes(struct snd_gus_card *gus, int *sizes) } } #if 0 - printk(KERN_DEBUG "sizes: %i %i %i %i\n", + dev_dbg(gus->card->dev, "sizes: %i %i %i %i\n", sizes[0], sizes[1], sizes[2], sizes[3]); #endif } @@ -396,12 +398,12 @@ static void snd_interwave_detect_memory(struct snd_gus_card *gus) lmct = (psizes[3] << 24) | (psizes[2] << 16) | (psizes[1] << 8) | psizes[0]; #if 0 - printk(KERN_DEBUG "lmct = 0x%08x\n", lmct); + dev_dbg(gus->card->dev, "lmct = 0x%08x\n", lmct); #endif for (i = 0; i < ARRAY_SIZE(lmc); i++) if (lmct == lmc[i]) { #if 0 - printk(KERN_DEBUG "found !!! %i\n", i); + dev_dbg(gus->card->dev, "found !!! %i\n", i); #endif snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i); snd_interwave_bank_sizes(gus, psizes); @@ -499,16 +501,20 @@ static int snd_interwave_mixer(struct snd_wss *chip) #if 0 /* remove mono microphone controls */ strcpy(id1.name, "Mic Playback Switch"); - if ((err = snd_ctl_remove_id(card, &id1)) < 0) + err = snd_ctl_remove_id(card, &id1); + if (err < 0) return err; strcpy(id1.name, "Mic Playback Volume"); - if ((err = snd_ctl_remove_id(card, &id1)) < 0) + err = snd_ctl_remove_id(card, &id1); + if (err < 0) return err; #endif /* add new master and mic controls */ - for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++) - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0) + for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++) { + err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip)); + if (err < 0) return err; + } snd_wss_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f); snd_wss_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f); snd_wss_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f); @@ -516,20 +522,24 @@ static int snd_interwave_mixer(struct snd_wss *chip) /* reassign AUXA to SYNTHESIZER */ strcpy(id1.name, "Aux Playback Switch"); strcpy(id2.name, "Synth Playback Switch"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + err = snd_ctl_rename_id(card, &id1, &id2); + if (err < 0) return err; strcpy(id1.name, "Aux Playback Volume"); strcpy(id2.name, "Synth Playback Volume"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + err = snd_ctl_rename_id(card, &id1, &id2); + if (err < 0) return err; /* reassign AUXB to CD */ strcpy(id1.name, "Aux Playback Switch"); id1.index = 1; strcpy(id2.name, "CD Playback Switch"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + err = snd_ctl_rename_id(card, &id1, &id2); + if (err < 0) return err; strcpy(id1.name, "Aux Playback Volume"); strcpy(id2.name, "CD Playback Volume"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + err = snd_ctl_rename_id(card, &id1, &id2); + if (err < 0) return err; return 0; } @@ -557,12 +567,12 @@ static int snd_interwave_pnp(int dev, struct snd_interwave *iwcard, err = pnp_activate_dev(pdev); if (err < 0) { - snd_printk(KERN_ERR "InterWave PnP configure failure (out of resources?)\n"); + dev_err(&pdev->dev, "InterWave PnP configure failure (out of resources?)\n"); return err; } if (pnp_port_start(pdev, 0) + 0x100 != pnp_port_start(pdev, 1) || pnp_port_start(pdev, 0) + 0x10c != pnp_port_start(pdev, 2)) { - snd_printk(KERN_ERR "PnP configure failure (wrong ports)\n"); + dev_err(&pdev->dev, "PnP configure failure (wrong ports)\n"); return -ENOENT; } port[dev] = pnp_port_start(pdev, 0); @@ -570,40 +580,31 @@ static int snd_interwave_pnp(int dev, struct snd_interwave *iwcard, if (dma2[dev] >= 0) dma2[dev] = pnp_dma(pdev, 1); irq[dev] = pnp_irq(pdev, 0); - snd_printdd("isapnp IW: sb port=0x%llx, gf1 port=0x%llx, codec port=0x%llx\n", - (unsigned long long)pnp_port_start(pdev, 0), - (unsigned long long)pnp_port_start(pdev, 1), - (unsigned long long)pnp_port_start(pdev, 2)); - snd_printdd("isapnp IW: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]); + dev_dbg(&pdev->dev, + "isapnp IW: sb port=0x%llx, gf1 port=0x%llx, codec port=0x%llx\n", + (unsigned long long)pnp_port_start(pdev, 0), + (unsigned long long)pnp_port_start(pdev, 1), + (unsigned long long)pnp_port_start(pdev, 2)); + dev_dbg(&pdev->dev, + "isapnp IW: dma1=%i, dma2=%i, irq=%i\n", + dma1[dev], dma2[dev], irq[dev]); #ifdef SNDRV_STB /* Tone Control initialization */ pdev = iwcard->devtc; err = pnp_activate_dev(pdev); if (err < 0) { - snd_printk(KERN_ERR "InterWave ToneControl PnP configure failure (out of resources?)\n"); + dev_err(&pdev->dev, + "InterWave ToneControl PnP configure failure (out of resources?)\n"); return err; } port_tc[dev] = pnp_port_start(pdev, 0); - snd_printdd("isapnp IW: tone control port=0x%lx\n", port_tc[dev]); + dev_dbg(&pdev->dev, "isapnp IW: tone control port=0x%lx\n", port_tc[dev]); #endif return 0; } #endif /* CONFIG_PNP */ -static void snd_interwave_free(struct snd_card *card) -{ - struct snd_interwave *iwcard = card->private_data; - - if (iwcard == NULL) - return; -#ifdef SNDRV_STB - release_and_free_resource(iwcard->i2c_res); -#endif - if (iwcard->irq >= 0) - free_irq(iwcard->irq, (void *)iwcard); -} - static int snd_interwave_card_new(struct device *pdev, int dev, struct snd_card **cardp) { @@ -611,24 +612,30 @@ static int snd_interwave_card_new(struct device *pdev, int dev, struct snd_interwave *iwcard; int err; - err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_interwave), &card); + err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_interwave), &card); if (err < 0) return err; iwcard = card->private_data; iwcard->card = card; iwcard->irq = -1; - card->private_free = snd_interwave_free; *cardp = card; return 0; } -static int snd_interwave_probe(struct snd_card *card, int dev) +static int snd_interwave_probe_gus(struct snd_card *card, int dev, + struct snd_gus_card **gusp) +{ + return snd_gus_create(card, port[dev], -irq[dev], dma1[dev], dma2[dev], + 0, 32, pcm_channels[dev], effect[dev], gusp); +} + +static int snd_interwave_probe(struct snd_card *card, int dev, + struct snd_gus_card *gus) { int xirq, xdma1, xdma2; struct snd_interwave *iwcard = card->private_data; struct snd_wss *wss; - struct snd_gus_card *gus; #ifdef SNDRV_STB struct snd_i2c_bus *i2c_bus; #endif @@ -639,18 +646,12 @@ static int snd_interwave_probe(struct snd_card *card, int dev) xdma1 = dma1[dev]; xdma2 = dma2[dev]; - if ((err = snd_gus_create(card, - port[dev], - -xirq, xdma1, xdma2, - 0, 32, - pcm_channels[dev], effect[dev], &gus)) < 0) - return err; - - if ((err = snd_interwave_detect(iwcard, gus, dev + err = snd_interwave_detect(iwcard, gus, dev #ifdef SNDRV_STB - , &i2c_bus + , &i2c_bus #endif - )) < 0) + ); + if (err < 0) return err; iwcard->gus_status_reg = gus->gf1.reg_irqstat; @@ -658,12 +659,13 @@ static int snd_interwave_probe(struct snd_card *card, int dev) snd_interwave_init(dev, gus); snd_interwave_detect_memory(gus); - if ((err = snd_gus_initialize(gus)) < 0) + err = snd_gus_initialize(gus); + if (err < 0) return err; - if (request_irq(xirq, snd_interwave_interrupt, 0, - "InterWave", iwcard)) { - snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); + if (devm_request_irq(card->dev, xirq, snd_interwave_interrupt, 0, + "InterWave", iwcard)) { + dev_err(card->dev, "unable to grab IRQ %d\n", xirq); return -EBUSY; } iwcard->irq = xirq; @@ -714,19 +716,23 @@ static int snd_interwave_probe(struct snd_card *card, int dev) strcpy(id1.name, "Master Playback Switch"); strcpy(id2.name, id1.name); id2.index = 1; - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + err = snd_ctl_rename_id(card, &id1, &id2); + if (err < 0) return err; strcpy(id1.name, "Master Playback Volume"); strcpy(id2.name, id1.name); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + err = snd_ctl_rename_id(card, &id1, &id2); + if (err < 0) return err; - if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0) + err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1); + if (err < 0) return err; } #endif gus->uart_enable = midi[dev]; - if ((err = snd_gf1_rawmidi_new(gus, 0)) < 0) + err = snd_gf1_rawmidi_new(gus, 0); + if (err < 0) return err; #ifndef SNDRV_STB @@ -755,23 +761,6 @@ static int snd_interwave_probe(struct snd_card *card, int dev) return 0; } -static int snd_interwave_isa_probe1(int dev, struct device *devptr) -{ - struct snd_card *card; - int err; - - err = snd_interwave_card_new(devptr, dev, &card); - if (err < 0) - return err; - - if ((err = snd_interwave_probe(card, dev)) < 0) { - snd_card_free(card); - return err; - } - dev_set_drvdata(devptr, card); - return 0; -} - static int snd_interwave_isa_match(struct device *pdev, unsigned int dev) { @@ -787,54 +776,64 @@ static int snd_interwave_isa_match(struct device *pdev, static int snd_interwave_isa_probe(struct device *pdev, unsigned int dev) { + struct snd_card *card; + struct snd_gus_card *gus; int err; static const int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; static const int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1}; if (irq[dev] == SNDRV_AUTO_IRQ) { - if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); + irq[dev] = snd_legacy_find_free_irq(possible_irqs); + if (irq[dev] < 0) { + dev_err(pdev, "unable to find a free IRQ\n"); return -EBUSY; } } if (dma1[dev] == SNDRV_AUTO_DMA) { - if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA1\n"); + dma1[dev] = snd_legacy_find_free_dma(possible_dmas); + if (dma1[dev] < 0) { + dev_err(pdev, "unable to find a free DMA1\n"); return -EBUSY; } } if (dma2[dev] == SNDRV_AUTO_DMA) { - if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA2\n"); + dma2[dev] = snd_legacy_find_free_dma(possible_dmas); + if (dma2[dev] < 0) { + dev_err(pdev, "unable to find a free DMA2\n"); return -EBUSY; } } + err = snd_interwave_card_new(pdev, dev, &card); + if (err < 0) + return err; + if (port[dev] != SNDRV_AUTO_PORT) - return snd_interwave_isa_probe1(dev, pdev); + err = snd_interwave_probe_gus(card, dev, &gus); else { static const long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260}; int i; for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { port[dev] = possible_ports[i]; - err = snd_interwave_isa_probe1(dev, pdev); + err = snd_interwave_probe_gus(card, dev, &gus); if (! err) return 0; } - return err; } -} + if (err < 0) + return err; -static int snd_interwave_isa_remove(struct device *devptr, unsigned int dev) -{ - snd_card_free(dev_get_drvdata(devptr)); + err = snd_interwave_probe(card, dev, gus); + if (err < 0) + return err; + + dev_set_drvdata(pdev, card); return 0; } static struct isa_driver snd_interwave_driver = { .match = snd_interwave_isa_match, .probe = snd_interwave_isa_probe, - .remove = snd_interwave_isa_remove, /* FIXME: suspend,resume */ .driver = { .name = INTERWAVE_DRIVER @@ -847,6 +846,7 @@ static int snd_interwave_pnp_detect(struct pnp_card_link *pcard, { static int dev; struct snd_card *card; + struct snd_gus_card *gus; int res; for ( ; dev < SNDRV_CARDS; dev++) { @@ -860,31 +860,25 @@ static int snd_interwave_pnp_detect(struct pnp_card_link *pcard, if (res < 0) return res; - if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) { - snd_card_free(card); + res = snd_interwave_pnp(dev, card->private_data, pcard, pid); + if (res < 0) return res; - } - if ((res = snd_interwave_probe(card, dev)) < 0) { - snd_card_free(card); + res = snd_interwave_probe_gus(card, dev, &gus); + if (res < 0) + return res; + res = snd_interwave_probe(card, dev, gus); + if (res < 0) return res; - } pnp_set_card_drvdata(pcard, card); dev++; return 0; } -static void snd_interwave_pnp_remove(struct pnp_card_link *pcard) -{ - snd_card_free(pnp_get_card_drvdata(pcard)); - pnp_set_card_drvdata(pcard, NULL); -} - static struct pnp_card_driver interwave_pnpc_driver = { .flags = PNP_DRIVER_RES_DISABLE, .name = INTERWAVE_PNP_DRIVER, .id_table = snd_interwave_pnpids, .probe = snd_interwave_pnp_detect, - .remove = snd_interwave_pnp_remove, /* FIXME: suspend,resume */ }; |