X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fpci%2Fnm256%2Fnm256.c;h=8a2fa86aa2caca01ae35df743c75f2b420dd6a9e;hb=720b94a4e7548e78be55ab8fd3be4686c57dc808;hp=a6afea5e3b65280a0eed369fa79a93cbd18d7eed;hpb=86090fcac5e27b630656fe3d963a6b80e26dac44;p=linux-2.6.git diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index a6afea5e3..8a2fa86aa 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -31,12 +31,12 @@ #include #include #include +#include #include #include #include #include #include -#define SNDRV_GET_ID #include #define CARD_NAME "NeoMagic 256AV/ZX" @@ -62,32 +62,33 @@ static int force_ac97[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disable static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not specified */ static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */ static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */ +static int boot_devs; -MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(index, int, boot_devs, 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, boot_devs, 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, boot_devs, 0444); MODULE_PARM_DESC(enable, "Enable this soundcard."); MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); -MODULE_PARM(playback_bufsize, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(playback_bufsize, int, boot_devs, 0444); MODULE_PARM_DESC(playback_bufsize, "DAC frame size in kB for " CARD_NAME " soundcard."); MODULE_PARM_SYNTAX(playback_bufsize, SNDRV_ENABLED); -MODULE_PARM(capture_bufsize, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(capture_bufsize, int, boot_devs, 0444); MODULE_PARM_DESC(capture_bufsize, "ADC frame size in kB for " CARD_NAME " soundcard."); MODULE_PARM_SYNTAX(capture_bufsize, SNDRV_ENABLED); -MODULE_PARM(force_ac97, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(force_ac97, bool, boot_devs, 0444); MODULE_PARM_DESC(force_ac97, "Force to use AC97 codec for " CARD_NAME " soundcard."); MODULE_PARM_SYNTAX(force_ac97, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); -MODULE_PARM(buffer_top, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(buffer_top, int, boot_devs, 0444); MODULE_PARM_DESC(buffer_top, "Set the top address of audio buffer for " CARD_NAME " soundcard."); MODULE_PARM_SYNTAX(buffer_top, SNDRV_ENABLED); -MODULE_PARM(use_cache, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(use_cache, bool, boot_devs, 0444); MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access."); MODULE_PARM_SYNTAX(use_cache, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); -MODULE_PARM(vaio_hack, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +module_param_array(vaio_hack, bool, boot_devs, 0444); MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks."); MODULE_PARM_SYNTAX(vaio_hack, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); @@ -274,11 +275,15 @@ struct snd_nm256 { #ifndef PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO #define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006 #endif +#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO +#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016 +#endif static struct pci_device_id snd_nm256_ids[] = { {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0,}, }; @@ -1283,24 +1288,20 @@ snd_nm256_peek_for_sig(nm256_t *chip) * APM event handler, so the card is properly reinitialized after a power * event. */ -static void nm256_suspend(nm256_t *chip) +static int nm256_suspend(snd_card_t *card, unsigned int state) { - snd_card_t *card = chip->card; - - if (card->power_state == SNDRV_CTL_POWER_D3hot) - return; + nm256_t *chip = snd_magic_cast(nm256_t, card->pm_private_data, return -EINVAL); snd_pcm_suspend_all(chip->pcm); + snd_ac97_suspend(chip->ac97); chip->coeffs_current = 0; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + return 0; } -static void nm256_resume(nm256_t *chip) +static int nm256_resume(snd_card_t *card, unsigned int state) { - snd_card_t *card = chip->card; - - if (card->power_state == SNDRV_CTL_POWER_D0) - return; + nm256_t *chip = snd_magic_cast(nm256_t, card->pm_private_data, return -EINVAL); /* Perform a full reset on the hardware */ pci_enable_device(chip->pci); @@ -1310,41 +1311,8 @@ static void nm256_resume(nm256_t *chip) snd_ac97_resume(chip->ac97); snd_power_change_state(card, SNDRV_CTL_POWER_D0); -} - -static int snd_nm256_suspend(struct pci_dev *dev, u32 state) -{ - nm256_t *chip = snd_magic_cast(nm256_t, pci_get_drvdata(dev), return -ENXIO); - nm256_suspend(chip); - return 0; -} -static int snd_nm256_resume(struct pci_dev *dev) -{ - nm256_t *chip = snd_magic_cast(nm256_t, pci_get_drvdata(dev), return -ENXIO); - nm256_resume(chip); - return 0; -} - -/* callback */ -static int snd_nm256_set_power_state(snd_card_t *card, unsigned int power_state) -{ - nm256_t *chip = snd_magic_cast(nm256_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: - nm256_resume(chip); - break; - case SNDRV_CTL_POWER_D3hot: - case SNDRV_CTL_POWER_D3cold: - nm256_suspend(chip); - break; - default: - return -EINVAL; - } return 0; } - #endif /* CONFIG_PM */ static int snd_nm256_free(nm256_t *chip) @@ -1552,10 +1520,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, // pci_set_master(pci); /* needed? */ -#ifdef CONFIG_PM - card->set_power_state = snd_nm256_set_power_state; - card->power_state_private_data = chip; -#endif + snd_card_set_pm_callback(card, nm256_suspend, nm256_resume, chip); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) goto __error; @@ -1571,6 +1536,21 @@ __error: } +struct nm256_quirk { + unsigned short vendor; + unsigned short device; + int type; +}; + +#define NM_BLACKLISTED 1 + +static struct nm256_quirk nm256_quirks[] __devinitdata = { + /* HP omnibook 4150 has cs4232 codec internally */ + { .vendor = 0x103c, .device = 0x0007, .type = NM_BLACKLISTED }, + { } /* terminator */ +}; + + static int __devinit snd_nm256_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { @@ -1579,6 +1559,8 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, nm256_t *chip; int err; unsigned int xbuffer_top; + struct nm256_quirk *q; + u16 subsystem_vendor, subsystem_device; if ((err = pci_enable_device(pci)) < 0) return err; @@ -1590,6 +1572,18 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, return -ENOENT; } + pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); + pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device); + + for (q = nm256_quirks; q->vendor; q++) { + if (q->vendor == subsystem_vendor && q->device == subsystem_device) { + if (q->type == NM_BLACKLISTED) { + printk(KERN_INFO "nm256: The device is blacklisted. Loading stopped\n"); + return -ENODEV; + } + } + } + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); if (card == NULL) return -ENOMEM; @@ -1601,6 +1595,9 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, case PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO: strcpy(card->driver, "NM256ZX"); break; + case PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO: + strcpy(card->driver, "NM256XL+"); + break; default: snd_printk("invalid device id 0x%x\n", pci->device); snd_card_free(card); @@ -1641,16 +1638,14 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, return err; } - pci_set_drvdata(pci, chip); + pci_set_drvdata(pci, card); dev++; return 0; } static void __devexit snd_nm256_remove(struct pci_dev *pci) { - nm256_t *chip = snd_magic_cast(nm256_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); } @@ -1660,23 +1655,13 @@ static struct pci_driver driver = { .id_table = snd_nm256_ids, .probe = snd_nm256_probe, .remove = __devexit_p(snd_nm256_remove), -#ifdef CONFIG_PM - .suspend = snd_nm256_suspend, - .resume = snd_nm256_resume, -#endif + SND_PCI_PM_CALLBACKS }; static int __init alsa_card_nm256_init(void) { - int err; - if ((err = pci_module_init(&driver)) < 0) { -#ifdef MODULE - printk(KERN_ERR "NeoMagic 256 audio soundchip not found or device busy\n"); -#endif - return err; - } - return 0; + return pci_module_init(&driver); } static void __exit alsa_card_nm256_exit(void) @@ -1686,31 +1671,3 @@ static void __exit alsa_card_nm256_exit(void) module_init(alsa_card_nm256_init) module_exit(alsa_card_nm256_exit) - -#ifndef MODULE - -/* format is: snd-nm256=enable,index,id, - playback_bufsize,capture_bufsize, - force_ac97,buffer_top,use_cache */ - -static int __init alsa_card_nm256_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,&playback_bufsize[nr_dev]) == 2 && - get_option(&str,&capture_bufsize[nr_dev]) == 2 && - get_option(&str,&force_ac97[nr_dev]) == 2 && - get_option(&str,&buffer_top[nr_dev]) == 2 && - get_option(&str,&use_cache[nr_dev]) == 2); - nr_dev++; - return 1; -} - -__setup("snd-nm256=", alsa_card_nm256_setup); - -#endif /* ifndef MODULE */