X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fpci%2Fmaestro3.c;h=87fae627b80168c0cc938d94826042096ec55c5e;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=26a5de08d9622558977c8fade864d74a75302f88;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 26a5de08d..87fae627b 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -39,20 +39,19 @@ #include #include #include +#include #include #include #include #include #include #include -#define SNDRV_GET_ID #include MODULE_AUTHOR("Zach Brown , Takashi Iwai "); MODULE_DESCRIPTION("ESS Maestro3 PCI"); MODULE_LICENSE("GPL"); -MODULE_CLASSES("{sound}"); -MODULE_DEVICES("{{ESS,Maestro3 PCI}," +MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI}," "{ESS,ES1988}," "{ESS,Allegro PCI}," "{ESS,Allegro-1 PCI}," @@ -64,21 +63,16 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* all enabled */ static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; static int amp_gpio[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; -MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); -MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC); -MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s"); +module_param_array(id, charp, NULL, 0444); MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); -MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC); -MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable this soundcard."); -MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); -MODULE_PARM(external_amp, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(external_amp, bool, NULL, 0444); MODULE_PARM_DESC(external_amp, "Enable external amp for " CARD_NAME " soundcard."); -MODULE_PARM_SYNTAX(external_amp, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC); -MODULE_PARM(amp_gpio, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(amp_gpio, int, NULL, 0444); MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)"); -MODULE_PARM_SYNTAX(amp_gpio, SNDRV_ENABLED); #define MAX_PLAYBACKS 2 #define MAX_CAPTURES 1 @@ -775,8 +769,6 @@ MODULE_PARM_SYNTAX(amp_gpio, SNDRV_ENABLED); typedef struct snd_m3_dma m3_dma_t; typedef struct snd_m3 m3_t; -#define chip_t m3_t - /* quirk lists */ struct m3_quirk { @@ -826,7 +818,6 @@ struct snd_m3 { snd_card_t *card; unsigned long iobase; - struct resource *iobase_res; int irq; int allegro_flag : 1; @@ -967,7 +958,7 @@ static struct m3_quirk m3_quirk_list[] = { .amp_gpio = 0x03, }, /* END */ - { 0 } + { NULL } }; @@ -1164,12 +1155,11 @@ snd_m3_pcm_trigger(snd_pcm_substream_t *subs, int cmd) { m3_t *chip = snd_pcm_substream_chip(subs); m3_dma_t *s = (m3_dma_t*)subs->runtime->private_data; - unsigned long flags; int err = -EINVAL; snd_assert(s != NULL, return -ENXIO); - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: @@ -1190,7 +1180,7 @@ snd_m3_pcm_trigger(snd_pcm_substream_t *subs, int cmd) } break; } - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock(&chip->reg_lock); return err; } @@ -1476,7 +1466,6 @@ snd_m3_pcm_prepare(snd_pcm_substream_t *subs) m3_t *chip = snd_pcm_substream_chip(subs); snd_pcm_runtime_t *runtime = subs->runtime; m3_dma_t *s = (m3_dma_t*)runtime->private_data; - unsigned long flags; snd_assert(s != NULL, return -ENXIO); @@ -1487,7 +1476,7 @@ snd_m3_pcm_prepare(snd_pcm_substream_t *subs) runtime->rate < 8000) return -EINVAL; - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irq(&chip->reg_lock); snd_m3_pcm_setup1(chip, s, subs); @@ -1498,7 +1487,7 @@ snd_m3_pcm_prepare(snd_pcm_substream_t *subs) snd_m3_pcm_setup2(chip, s, runtime); - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irq(&chip->reg_lock); return 0; } @@ -1572,7 +1561,7 @@ static void snd_m3_update_ptr(m3_t *chip, m3_dma_t *s) static irqreturn_t snd_m3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - m3_t *chip = snd_magic_cast(m3_t, dev_id, ); + m3_t *chip = dev_id; u8 status; int i; @@ -1669,20 +1658,19 @@ snd_m3_substream_open(m3_t *chip, snd_pcm_substream_t *subs) { int i; m3_dma_t *s; - unsigned long flags; - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irq(&chip->reg_lock); for (i = 0; i < chip->num_substreams; i++) { s = &chip->substreams[i]; if (! s->opened) goto __found; } - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irq(&chip->reg_lock); return -ENOMEM; __found: s->opened = 1; s->running = 0; - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irq(&chip->reg_lock); subs->runtime->private_data = s; s->substream = subs; @@ -1702,12 +1690,11 @@ static void snd_m3_substream_close(m3_t *chip, snd_pcm_substream_t *subs) { m3_dma_t *s = (m3_dma_t*) subs->runtime->private_data; - unsigned long flags; if (s == NULL) return; /* not opened properly */ - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irq(&chip->reg_lock); if (s->substream && s->running) snd_m3_pcm_stop(chip, s, s->substream); /* does this happen? */ if (s->in_lists) { @@ -1718,7 +1705,7 @@ snd_m3_substream_close(m3_t *chip, snd_pcm_substream_t *subs) } s->running = 0; s->opened = 0; - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irq(&chip->reg_lock); } static int @@ -1847,35 +1834,25 @@ static int snd_m3_ac97_wait(m3_t *chip) static unsigned short snd_m3_ac97_read(ac97_t *ac97, unsigned short reg) { - m3_t *chip = snd_magic_cast(m3_t, ac97->private_data, return -ENXIO); - unsigned short ret = 0; - unsigned long flags; + m3_t *chip = ac97->private_data; - spin_lock_irqsave(&chip->reg_lock, flags); if (snd_m3_ac97_wait(chip)) - goto __error; - snd_m3_outb(chip, 0x80 | (reg & 0x7f), 0x30); + return 0xffff; + snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); if (snd_m3_ac97_wait(chip)) - goto __error; - ret = snd_m3_inw(chip, 0x32); -__error: - spin_unlock_irqrestore(&chip->reg_lock, flags); - return ret; + return 0xffff; + return snd_m3_inw(chip, CODEC_DATA); } static void snd_m3_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val) { - m3_t *chip = snd_magic_cast(m3_t, ac97->private_data, return); - unsigned long flags; + m3_t *chip = ac97->private_data; - spin_lock_irqsave(&chip->reg_lock, flags); if (snd_m3_ac97_wait(chip)) - goto __error; - snd_m3_outw(chip, val, 0x32); - snd_m3_outb(chip, reg & 0x7f, 0x30); -__error: - spin_unlock_irqrestore(&chip->reg_lock, flags); + return; + snd_m3_outw(chip, val, CODEC_DATA); + snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); } @@ -1982,14 +1959,15 @@ static void snd_m3_ac97_reset(m3_t *chip) static int __devinit snd_m3_mixer(m3_t *chip) { - ac97_bus_t bus, *pbus; - ac97_t ac97; + ac97_bus_t *pbus; + ac97_template_t ac97; int err; + static ac97_bus_ops_t ops = { + .write = snd_m3_ac97_write, + .read = snd_m3_ac97_read, + }; - memset(&bus, 0, sizeof(bus)); - bus.write = snd_m3_ac97_write; - bus.read = snd_m3_ac97_read; - if ((err = snd_ac97_bus(chip->card, &bus, &pbus)) < 0) + if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0) return err; memset(&ac97, 0, sizeof(ac97)); @@ -2166,7 +2144,7 @@ static void __devinit snd_m3_assp_init(m3_t *chip) KDATA_DMA_XFER0); /* write kernel into code memory.. */ - for (i = 0 ; i < sizeof(assp_kernel_image) / 2; i++) { + for (i = 0 ; i < ARRAY_SIZE(assp_kernel_image); i++) { snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, REV_B_CODE_MEMORY_BEGIN + i, assp_kernel_image[i]); @@ -2178,7 +2156,7 @@ static void __devinit snd_m3_assp_init(m3_t *chip) * drop it there. It seems that the minisrc doesn't * need vectors, so we won't bother with them.. */ - for (i = 0; i < sizeof(assp_minisrc_image) / 2; i++) { + for (i = 0; i < ARRAY_SIZE(assp_minisrc_image); i++) { snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, 0x400 + i, assp_minisrc_image[i]); @@ -2367,41 +2345,38 @@ snd_m3_enable_ints(m3_t *chip) static int snd_m3_free(m3_t *chip) { - unsigned long flags; m3_dma_t *s; int i; if (chip->substreams) { - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irq(&chip->reg_lock); for (i = 0; i < chip->num_substreams; i++) { s = &chip->substreams[i]; /* check surviving pcms; this should not happen though.. */ if (s->substream && s->running) snd_m3_pcm_stop(chip, s, s->substream); } - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irq(&chip->reg_lock); kfree(chip->substreams); } - if (chip->iobase_res) { + if (chip->iobase) { snd_m3_outw(chip, HOST_INT_CTRL, 0); /* disable ints */ } #ifdef CONFIG_PM - if (chip->suspend_mem) - vfree(chip->suspend_mem); + vfree(chip->suspend_mem); #endif - if (chip->irq >= 0) + if (chip->irq >= 0) { synchronize_irq(chip->irq); - - if (chip->iobase_res) { - release_resource(chip->iobase_res); - kfree_nocheck(chip->iobase_res); - } - if (chip->irq >= 0) free_irq(chip->irq, (void *)chip); + } - snd_magic_kfree(chip); + if (chip->iobase) + pci_release_regions(chip->pci); + + pci_disable_device(chip->pci); + kfree(chip); return 0; } @@ -2410,18 +2385,16 @@ static int snd_m3_free(m3_t *chip) * APM support */ #ifdef CONFIG_PM - -static void m3_suspend(m3_t *chip) +static int m3_suspend(snd_card_t *card, unsigned int state) { - snd_card_t *card = chip->card; + m3_t *chip = card->pm_private_data; int i, index; if (chip->suspend_mem == NULL) - return; - if (card->power_state == SNDRV_CTL_POWER_D3hot) - return; + return 0; snd_pcm_suspend_all(chip->pcm); + snd_ac97_suspend(chip->ac97); big_mdelay(10); /* give the assp a chance to idle.. */ @@ -2439,18 +2412,21 @@ static void m3_suspend(m3_t *chip) /* power down apci registers */ snd_m3_outw(chip, 0xffff, 0x54); snd_m3_outw(chip, 0xffff, 0x56); - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + + pci_disable_device(chip->pci); + return 0; } -static void m3_resume(m3_t *chip) +static int m3_resume(snd_card_t *card, unsigned int state) { - snd_card_t *card = chip->card; + m3_t *chip = card->pm_private_data; int i, index; if (chip->suspend_mem == NULL) - return; - if (card->power_state == SNDRV_CTL_POWER_D0) - return; + return 0; + + pci_enable_device(chip->pci); + pci_set_master(chip->pci); /* first lets just bring everything back. .*/ snd_m3_outw(chip, 0, 0x54); @@ -2480,42 +2456,8 @@ static void m3_resume(m3_t *chip) snd_m3_enable_ints(chip); snd_m3_amp_enable(chip, 1); - snd_power_change_state(card, SNDRV_CTL_POWER_D0); -} - -static int snd_m3_suspend(struct pci_dev *pci, u32 state) -{ - m3_t *chip = snd_magic_cast(m3_t, pci_get_drvdata(pci), return -ENXIO); - m3_suspend(chip); - return 0; -} -static int snd_m3_resume(struct pci_dev *pci) -{ - m3_t *chip = snd_magic_cast(m3_t, pci_get_drvdata(pci), return -ENXIO); - m3_resume(chip); return 0; } - -/* callback */ -static int snd_m3_set_power_state(snd_card_t *card, unsigned int power_state) -{ - m3_t *chip = snd_magic_cast(m3_t, card->power_state_private_data, return -ENXIO); - switch (power_state) { - case SNDRV_CTL_POWER_D0: - case SNDRV_CTL_POWER_D1: - case SNDRV_CTL_POWER_D2: - m3_resume(chip); - break; - case SNDRV_CTL_POWER_D3hot: - case SNDRV_CTL_POWER_D3cold: - m3_suspend(chip); - break; - default: - return -EINVAL; - } - return 0; -} - #endif /* CONFIG_PM */ @@ -2524,7 +2466,7 @@ static int snd_m3_set_power_state(snd_card_t *card, unsigned int power_state) static int snd_m3_dev_free(snd_device_t *device) { - m3_t *chip = snd_magic_cast(m3_t, device->device_data, return -ENXIO); + m3_t *chip = device->device_data; return snd_m3_free(chip); } @@ -2551,12 +2493,15 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { snd_printk("architecture does not support 28bit PCI busmaster DMA\n"); + pci_disable_device(pci); return -ENXIO; } - chip = snd_magic_kcalloc(m3_t, 0, GFP_KERNEL); - if (chip == NULL) + chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + if (chip == NULL) { + pci_disable_device(pci); return -ENOMEM; + } spin_lock_init(&chip->reg_lock); switch (pci->device) { @@ -2597,18 +2542,17 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, chip->num_substreams = NR_DSPS; chip->substreams = kmalloc(sizeof(m3_dma_t) * chip->num_substreams, GFP_KERNEL); if (chip->substreams == NULL) { - snd_magic_kfree(chip); + kfree(chip); + pci_disable_device(pci); return -ENOMEM; } memset(chip->substreams, 0, sizeof(m3_dma_t) * chip->num_substreams); - chip->iobase = pci_resource_start(pci, 0); - if ((chip->iobase_res = request_region(chip->iobase, 256, - card->driver)) == NULL) { - snd_printk("unable to grab i/o ports %ld\n", chip->iobase); + if ((err = pci_request_regions(pci, card->driver)) < 0) { snd_m3_free(chip); - return -EBUSY; + return err; } + chip->iobase = pci_resource_start(pci, 0); /* just to be sure */ pci_set_master(pci); @@ -2620,26 +2564,7 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, snd_m3_assp_init(chip); snd_m3_amp_enable(chip, 1); - - if ((err = snd_m3_mixer(chip)) < 0) { - snd_m3_free(chip); - return err; - } - for (i = 0; i < chip->num_substreams; i++) { - m3_dma_t *s = &chip->substreams[i]; - s->chip = chip; - if ((err = snd_m3_assp_client_init(chip, s, i)) < 0) { - snd_m3_free(chip); - return err; - } - } - - if ((err = snd_m3_pcm(chip, 0)) < 0) { - snd_m3_free(chip); - return err; - } - if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)chip)) { snd_printk("unable to grab IRQ %d\n", pci->irq); @@ -2651,11 +2576,9 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, #ifdef CONFIG_PM chip->suspend_mem = vmalloc(sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH)); if (chip->suspend_mem == NULL) - snd_printk("can't allocate apm buffer\n"); - else { - card->set_power_state = snd_m3_set_power_state; - card->power_state_private_data = chip; - } + snd_printk(KERN_WARNING "can't allocate apm buffer\n"); + else + snd_card_set_pm_callback(card, m3_suspend, m3_resume, chip); #endif if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { @@ -2663,6 +2586,19 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, return err; } + if ((err = snd_m3_mixer(chip)) < 0) + return err; + + for (i = 0; i < chip->num_substreams; i++) { + m3_dma_t *s = &chip->substreams[i]; + s->chip = chip; + if ((err = snd_m3_assp_client_init(chip, s, i)) < 0) + return err; + } + + if ((err = snd_m3_pcm(chip, 0)) < 0) + return err; + snd_m3_enable_ints(chip); snd_m3_assp_continue(chip); @@ -2738,16 +2674,14 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) printk(KERN_WARNING "maestro3: no midi support.\n"); #endif - pci_set_drvdata(pci, chip); + pci_set_drvdata(pci, card); dev++; return 0; } static void __devexit snd_m3_remove(struct pci_dev *pci) { - m3_t *chip = snd_magic_cast(m3_t, pci_get_drvdata(pci), return); - if (chip) - snd_card_free(chip->card); + snd_card_free(pci_get_drvdata(pci)); pci_set_drvdata(pci, NULL); } @@ -2756,23 +2690,12 @@ static struct pci_driver driver = { .id_table = snd_m3_ids, .probe = snd_m3_probe, .remove = __devexit_p(snd_m3_remove), -#ifdef CONFIG_PM - .suspend = snd_m3_suspend, - .resume = snd_m3_resume, -#endif + SND_PCI_PM_CALLBACKS }; static int __init alsa_card_m3_init(void) { - int err; - - if ((err = pci_module_init(&driver)) < 0) { -#ifdef MODULE - printk(KERN_ERR "Maestro3/Allegro soundcard not found or device busy\n"); -#endif - return err; - } - return 0; + return pci_module_init(&driver); } static void __exit alsa_card_m3_exit(void) @@ -2782,26 +2705,3 @@ static void __exit alsa_card_m3_exit(void) module_init(alsa_card_m3_init) module_exit(alsa_card_m3_exit) - -#ifndef MODULE - -/* format is: snd-maestro3=enable,index,id,external_amp,amp_gpio */ - -static int __init alsa_card_maestro3_setup(char *str) -{ - static unsigned __initdata nr_dev = 0; - - if (nr_dev >= SNDRV_CARDS) - return 0; - (void)(get_option(&str,&enable[nr_dev]) == 2 && - get_option(&str,&index[nr_dev]) == 2 && - get_id(&str,&id[nr_dev]) == 2 && - get_option(&str,&external_amp[nr_dev]) == 2 && - get_option(&str,&_gpio[nr_dev]) == 2); - nr_dev++; - return 1; -} - -__setup("snd-maestro3=", alsa_card_maestro3_setup); - -#endif /* ifndef MODULE */