Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: Merge es1688 and es968 drivers

The ESS ES968 chip is nothing more then a PnP companion
for a non-PnP audio chip. It was paired with non-PnP ESS' chips:
ES688 and ES1688. The ESS' audio chips are handled by the es1688
driver in native mode. The PnP cards are handled by the ES968
driver in SB compatible mode.

Move the ES968 chip handling to the es1688 driver so the driver
can handle both PnP and non-PnP cards. The es968 is removed.

Also, a new PnP id is added for the card I acquired (the change
was tested on this card).

Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Krzysztof Helt and committed by
Takashi Iwai
a20971b2 396fa827

+190 -306
+8 -13
Documentation/sound/alsa/ALSA-Configuration.txt
··· 632 632 633 633 The power-management is supported. 634 634 635 - Module snd-es968 636 - ---------------- 637 - 638 - Module for sound cards based on ESS ES968 chip (PnP only). 639 - 640 - This module supports multiple cards, PnP and autoprobe. 641 - 642 - The power-management is supported. 643 - 644 635 Module snd-es1688 645 636 ----------------- 646 637 647 638 Module for ESS AudioDrive ES-1688 and ES-688 sound cards. 648 639 649 - port - port # for ES-1688 chip (0x220,0x240,0x260) 650 - fm_port - port # for OPL3 (option; share the same port as default) 640 + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) 651 641 mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default) 652 - irq - IRQ # for ES-1688 chip (5,7,9,10) 653 642 mpu_irq - IRQ # for MPU-401 port (5,7,9,10) 643 + fm_port - port # for OPL3 (option; share the same port as default) 644 + 645 + with isapnp=0, the following additional options are available: 646 + port - port # for ES-1688 chip (0x220,0x240,0x260) 647 + irq - IRQ # for ES-1688 chip (5,7,9,10) 654 648 dma8 - DMA # for ES-1688 chip (0,1,3) 655 649 656 - This module supports multiple cards and autoprobe (without MPU-401 port). 650 + This module supports multiple cards and autoprobe (without MPU-401 port) 651 + and PnP with the ES968 chip. 657 652 658 653 Module snd-es18xx 659 654 -----------------
+1
include/sound/es1688.h
··· 117 117 int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device, 118 118 struct snd_pcm **rpcm); 119 119 int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip); 120 + int snd_es1688_reset(struct snd_es1688 *chip); 120 121 121 122 #endif /* __SOUND_ES1688_H */
+2 -14
sound/isa/Kconfig
··· 128 128 To compile this driver as a module, choose M here: the module 129 129 will be called snd-cs4236. 130 130 131 - config SND_ES968 132 - tristate "Generic ESS ES968 driver" 133 - depends on PNP 134 - select ISAPNP 135 - select SND_MPU401_UART 136 - select SND_SB8_DSP 137 - help 138 - Say Y here to include support for ESS AudioDrive ES968 chips. 139 - 140 - To compile this driver as a module, choose M here: the module 141 - will be called snd-es968. 142 - 143 131 config SND_ES1688 144 - tristate "Generic ESS ES688/ES1688 driver" 132 + tristate "Generic ESS ES688/ES1688 and ES968 PnP driver" 145 133 select SND_OPL3_LIB 146 134 select SND_MPU401_UART 147 135 select SND_PCM 148 136 help 149 137 Say Y here to include support for ESS AudioDrive ES688 or 150 - ES1688 chips. 138 + ES1688 chips. Also, this module support cards with ES968 PnP chip. 151 139 152 140 To compile this driver as a module, choose M here: the module 153 141 will be called snd-es1688.
+177 -28
sound/isa/es1688/es1688.c
··· 22 22 #include <linux/init.h> 23 23 #include <linux/err.h> 24 24 #include <linux/isa.h> 25 + #include <linux/isapnp.h> 25 26 #include <linux/time.h> 26 27 #include <linux/wait.h> 27 28 #include <linux/moduleparam.h> ··· 46 45 "{ESS,ES688 AudioDrive,pnp:ESS6881}," 47 46 "{ESS,ES1688 AudioDrive,pnp:ESS1681}}"); 48 47 48 + MODULE_ALIAS("snd_es968"); 49 + 49 50 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 50 51 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 52 + #ifdef CONFIG_PNP 53 + static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; 54 + #endif 51 55 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ 52 56 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ 53 57 static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ ··· 66 60 module_param_array(id, charp, NULL, 0444); 67 61 MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); 68 62 module_param_array(enable, bool, NULL, 0444); 63 + #ifdef CONFIG_PNP 64 + module_param_array(isapnp, bool, NULL, 0444); 65 + MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard."); 66 + #endif 69 67 MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); 70 68 module_param_array(port, long, NULL, 0444); 71 69 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); ··· 84 74 module_param_array(dma8, int, NULL, 0444); 85 75 MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); 86 76 77 + #ifdef CONFIG_PNP 78 + #define is_isapnp_selected(dev) isapnp[dev] 79 + #else 80 + #define is_isapnp_selected(dev) 0 81 + #endif 82 + 87 83 static int __devinit snd_es1688_match(struct device *dev, unsigned int n) 88 84 { 89 - return enable[n]; 85 + return enable[n] && !is_isapnp_selected(n); 90 86 } 91 87 92 88 static int __devinit snd_es1688_legacy_create(struct snd_card *card, 93 - struct snd_es1688 *chip, struct device *dev, unsigned int n) 89 + struct device *dev, unsigned int n) 94 90 { 91 + struct snd_es1688 *chip = card->private_data; 95 92 static long possible_ports[] = {0x220, 0x240, 0x260}; 96 93 static int possible_irqs[] = {5, 9, 10, 7, -1}; 97 94 static int possible_dmas[] = {1, 3, 0, -1}; ··· 134 117 return error; 135 118 } 136 119 137 - static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) 120 + static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n) 138 121 { 139 - struct snd_card *card; 140 - struct snd_es1688 *chip; 122 + struct snd_es1688 *chip = card->private_data; 141 123 struct snd_opl3 *opl3; 142 124 struct snd_pcm *pcm; 143 125 int error; 144 126 145 - error = snd_card_create(index[n], id[n], THIS_MODULE, 146 - sizeof(struct snd_es1688), &card); 127 + error = snd_es1688_pcm(card, chip, 0, &pcm); 147 128 if (error < 0) 148 129 return error; 149 130 150 - chip = card->private_data; 151 - 152 - error = snd_es1688_legacy_create(card, chip, dev, n); 153 - if (error < 0) 154 - goto out; 155 - 156 - error = snd_es1688_pcm(card, chip, 0, &pcm); 157 - if (error < 0) 158 - goto out; 159 - 160 131 error = snd_es1688_mixer(card, chip); 161 132 if (error < 0) 162 - goto out; 133 + return error; 163 134 164 135 strcpy(card->driver, "ES1688"); 165 136 strcpy(card->shortname, pcm->name); ··· 160 155 if (fm_port[n] > 0) { 161 156 if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2, 162 157 OPL3_HW_OPL3, 0, &opl3) < 0) 163 - dev_warn(dev, 158 + dev_warn(card->dev, 164 159 "opl3 not detected at 0x%lx\n", fm_port[n]); 165 160 else { 166 161 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 167 162 if (error < 0) 168 - goto out; 163 + return error; 169 164 } 170 165 } 171 166 ··· 175 170 chip->mpu_port, 0, 176 171 mpu_irq[n], IRQF_DISABLED, NULL); 177 172 if (error < 0) 178 - goto out; 173 + return error; 179 174 } 175 + 176 + return snd_card_register(card); 177 + } 178 + 179 + static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n) 180 + { 181 + struct snd_card *card; 182 + int error; 183 + 184 + error = snd_card_create(index[n], id[n], THIS_MODULE, 185 + sizeof(struct snd_es1688), &card); 186 + if (error < 0) 187 + return error; 188 + 189 + error = snd_es1688_legacy_create(card, dev, n); 190 + if (error < 0) 191 + goto out; 180 192 181 193 snd_card_set_dev(card, dev); 182 194 183 - error = snd_card_register(card); 195 + error = snd_es1688_probe(card, n); 184 196 if (error < 0) 185 197 goto out; 186 198 187 199 dev_set_drvdata(dev, card); 188 - return 0; 189 200 190 - out: snd_card_free(card); 201 + return 0; 202 + out: 203 + snd_card_free(card); 191 204 return error; 192 205 } 193 206 194 - static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) 207 + static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n) 195 208 { 196 209 snd_card_free(dev_get_drvdata(dev)); 197 210 dev_set_drvdata(dev, NULL); ··· 218 195 219 196 static struct isa_driver snd_es1688_driver = { 220 197 .match = snd_es1688_match, 221 - .probe = snd_es1688_probe, 222 - .remove = __devexit_p(snd_es1688_remove), 198 + .probe = snd_es1688_isa_probe, 199 + .remove = __devexit_p(snd_es1688_isa_remove), 223 200 #if 0 /* FIXME */ 224 201 .suspend = snd_es1688_suspend, 225 202 .resume = snd_es1688_resume, ··· 229 206 } 230 207 }; 231 208 209 + static int snd_es968_pnp_is_probed; 210 + 211 + #ifdef CONFIG_PNP 212 + static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n, 213 + struct pnp_card_link *pcard, 214 + const struct pnp_card_device_id *pid) 215 + { 216 + struct snd_es1688 *chip = card->private_data; 217 + struct pnp_dev *pdev; 218 + int error; 219 + 220 + pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL); 221 + if (pdev == NULL) 222 + return -ENODEV; 223 + 224 + error = pnp_activate_dev(pdev); 225 + if (error < 0) { 226 + snd_printk(KERN_ERR "ES968 pnp configure failure\n"); 227 + return error; 228 + } 229 + port[n] = pnp_port_start(pdev, 0); 230 + dma8[n] = pnp_dma(pdev, 0); 231 + irq[n] = pnp_irq(pdev, 0); 232 + 233 + return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n], 234 + mpu_irq[n], dma8[n], ES1688_HW_AUTO); 235 + } 236 + 237 + static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard, 238 + const struct pnp_card_device_id *pid) 239 + { 240 + struct snd_card *card; 241 + static unsigned int dev; 242 + int error; 243 + struct snd_es1688 *chip; 244 + 245 + if (snd_es968_pnp_is_probed) 246 + return -EBUSY; 247 + for ( ; dev < SNDRV_CARDS; dev++) { 248 + if (enable[dev] && isapnp[dev]) 249 + break; 250 + } 251 + 252 + error = snd_card_create(index[dev], id[dev], THIS_MODULE, 253 + sizeof(struct snd_es1688), &card); 254 + if (error < 0) 255 + return error; 256 + chip = card->private_data; 257 + 258 + error = snd_card_es968_pnp(card, dev, pcard, pid); 259 + if (error < 0) { 260 + snd_card_free(card); 261 + return error; 262 + } 263 + snd_card_set_dev(card, &pcard->card->dev); 264 + error = snd_es1688_probe(card, dev); 265 + if (error < 0) 266 + return error; 267 + pnp_set_card_drvdata(pcard, card); 268 + snd_es968_pnp_is_probed = 1; 269 + return 0; 270 + } 271 + 272 + static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard) 273 + { 274 + snd_card_free(pnp_get_card_drvdata(pcard)); 275 + pnp_set_card_drvdata(pcard, NULL); 276 + snd_es968_pnp_is_probed = 0; 277 + } 278 + 279 + #ifdef CONFIG_PM 280 + static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, 281 + pm_message_t state) 282 + { 283 + struct snd_card *card = pnp_get_card_drvdata(pcard); 284 + struct snd_es1688 *chip = card->private_data; 285 + 286 + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 287 + snd_pcm_suspend_all(chip->pcm); 288 + return 0; 289 + } 290 + 291 + static int snd_es968_pnp_resume(struct pnp_card_link *pcard) 292 + { 293 + struct snd_card *card = pnp_get_card_drvdata(pcard); 294 + struct snd_es1688 *chip = card->private_data; 295 + 296 + snd_es1688_reset(chip); 297 + snd_power_change_state(card, SNDRV_CTL_POWER_D0); 298 + return 0; 299 + } 300 + #endif 301 + 302 + static struct pnp_card_device_id snd_es968_pnpids[] = { 303 + { .id = "ESS0968", .devs = { { "@@@0968" }, } }, 304 + { .id = "ESS0968", .devs = { { "ESS0968" }, } }, 305 + { .id = "", } /* end */ 306 + }; 307 + 308 + MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids); 309 + 310 + static struct pnp_card_driver es968_pnpc_driver = { 311 + .flags = PNP_DRIVER_RES_DISABLE, 312 + .name = DEV_NAME " PnP", 313 + .id_table = snd_es968_pnpids, 314 + .probe = snd_es968_pnp_detect, 315 + .remove = __devexit_p(snd_es968_pnp_remove), 316 + #ifdef CONFIG_PM 317 + .suspend = snd_es968_pnp_suspend, 318 + .resume = snd_es968_pnp_resume, 319 + #endif 320 + }; 321 + #endif 322 + 232 323 static int __init alsa_card_es1688_init(void) 233 324 { 325 + #ifdef CONFIG_PNP 326 + pnp_register_card_driver(&es968_pnpc_driver); 327 + if (snd_es968_pnp_is_probed) 328 + return 0; 329 + pnp_unregister_card_driver(&es968_pnpc_driver); 330 + #endif 234 331 return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); 235 332 } 236 333 237 334 static void __exit alsa_card_es1688_exit(void) 238 335 { 239 - isa_unregister_driver(&snd_es1688_driver); 336 + if (!snd_es968_pnp_is_probed) { 337 + isa_unregister_driver(&snd_es1688_driver); 338 + return; 339 + } 340 + #ifdef CONFIG_PNP 341 + pnp_unregister_card_driver(&es968_pnpc_driver); 342 + #endif 240 343 } 241 344 242 345 module_init(alsa_card_es1688_init);
+2 -1
sound/isa/es1688/es1688_lib.c
··· 99 99 return result; 100 100 } 101 101 102 - static int snd_es1688_reset(struct snd_es1688 *chip) 102 + int snd_es1688_reset(struct snd_es1688 *chip) 103 103 { 104 104 int i; 105 105 ··· 115 115 snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */ 116 116 return 0; 117 117 } 118 + EXPORT_SYMBOL(snd_es1688_reset); 118 119 119 120 static int snd_es1688_probe(struct snd_es1688 *chip) 120 121 {
-2
sound/isa/sb/Makefile
··· 11 11 snd-sb16-objs := sb16.o 12 12 snd-sbawe-objs := sbawe.o emu8000.o 13 13 snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o 14 - snd-es968-objs := es968.o 15 14 snd-jazz16-objs := jazz16.o 16 15 17 16 # Toplevel Module Dependency ··· 20 21 obj-$(CONFIG_SND_SB8) += snd-sb8.o 21 22 obj-$(CONFIG_SND_SB16) += snd-sb16.o 22 23 obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o 23 - obj-$(CONFIG_SND_ES968) += snd-es968.o 24 24 obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o 25 25 ifeq ($(CONFIG_SND_SB16_CSP),y) 26 26 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
-248
sound/isa/sb/es968.c
··· 1 - 2 - /* 3 - card-es968.c - driver for ESS AudioDrive ES968 based soundcards. 4 - Copyright (C) 1999 by Massimo Piccioni <dafastidio@libero.it> 5 - 6 - Thanks to Pierfrancesco 'qM2' Passerini. 7 - 8 - This program is free software; you can redistribute it and/or modify 9 - it under the terms of the GNU General Public License as published by 10 - the Free Software Foundation; either version 2 of the License, or 11 - (at your option) any later version. 12 - 13 - This program is distributed in the hope that it will be useful, 14 - but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with this program; if not, write to the Free Software 20 - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 - */ 22 - 23 - #include <linux/init.h> 24 - #include <linux/time.h> 25 - #include <linux/pnp.h> 26 - #include <linux/moduleparam.h> 27 - #include <sound/core.h> 28 - #include <sound/initval.h> 29 - #include <sound/sb.h> 30 - 31 - #define PFX "es968: " 32 - 33 - MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>"); 34 - MODULE_DESCRIPTION("ESS AudioDrive ES968"); 35 - MODULE_LICENSE("GPL"); 36 - MODULE_SUPPORTED_DEVICE("{{ESS,AudioDrive ES968}}"); 37 - 38 - static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 39 - static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 40 - static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ 41 - static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 42 - static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */ 43 - static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ 44 - 45 - module_param_array(index, int, NULL, 0444); 46 - MODULE_PARM_DESC(index, "Index value for es968 based soundcard."); 47 - module_param_array(id, charp, NULL, 0444); 48 - MODULE_PARM_DESC(id, "ID string for es968 based soundcard."); 49 - module_param_array(enable, bool, NULL, 0444); 50 - MODULE_PARM_DESC(enable, "Enable es968 based soundcard."); 51 - 52 - struct snd_card_es968 { 53 - struct pnp_dev *dev; 54 - struct snd_sb *chip; 55 - }; 56 - 57 - static struct pnp_card_device_id snd_es968_pnpids[] = { 58 - { .id = "ESS0968", .devs = { { "@@@0968" }, } }, 59 - { .id = "", } /* end */ 60 - }; 61 - 62 - MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids); 63 - 64 - #define DRIVER_NAME "snd-card-es968" 65 - 66 - static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id) 67 - { 68 - struct snd_sb *chip = dev_id; 69 - 70 - if (chip->open & SB_OPEN_PCM) { 71 - return snd_sb8dsp_interrupt(chip); 72 - } else { 73 - return snd_sb8dsp_midi_interrupt(chip); 74 - } 75 - } 76 - 77 - static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard, 78 - struct pnp_card_link *card, 79 - const struct pnp_card_device_id *id) 80 - { 81 - struct pnp_dev *pdev; 82 - int err; 83 - 84 - acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); 85 - if (acard->dev == NULL) 86 - return -ENODEV; 87 - 88 - pdev = acard->dev; 89 - 90 - err = pnp_activate_dev(pdev); 91 - if (err < 0) { 92 - snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n"); 93 - return err; 94 - } 95 - port[dev] = pnp_port_start(pdev, 0); 96 - dma8[dev] = pnp_dma(pdev, 0); 97 - irq[dev] = pnp_irq(pdev, 0); 98 - 99 - return 0; 100 - } 101 - 102 - static int __devinit snd_card_es968_probe(int dev, 103 - struct pnp_card_link *pcard, 104 - const struct pnp_card_device_id *pid) 105 - { 106 - int error; 107 - struct snd_sb *chip; 108 - struct snd_card *card; 109 - struct snd_card_es968 *acard; 110 - 111 - error = snd_card_create(index[dev], id[dev], THIS_MODULE, 112 - sizeof(struct snd_card_es968), &card); 113 - if (error < 0) 114 - return error; 115 - acard = card->private_data; 116 - if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) { 117 - snd_card_free(card); 118 - return error; 119 - } 120 - snd_card_set_dev(card, &pcard->card->dev); 121 - 122 - if ((error = snd_sbdsp_create(card, port[dev], 123 - irq[dev], 124 - snd_card_es968_interrupt, 125 - dma8[dev], 126 - -1, 127 - SB_HW_AUTO, &chip)) < 0) { 128 - snd_card_free(card); 129 - return error; 130 - } 131 - acard->chip = chip; 132 - 133 - if ((error = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) { 134 - snd_card_free(card); 135 - return error; 136 - } 137 - 138 - if ((error = snd_sbmixer_new(chip)) < 0) { 139 - snd_card_free(card); 140 - return error; 141 - } 142 - 143 - if ((error = snd_sb8dsp_midi(chip, 0, NULL)) < 0) { 144 - snd_card_free(card); 145 - return error; 146 - } 147 - 148 - strcpy(card->driver, "ES968"); 149 - strcpy(card->shortname, "ESS ES968"); 150 - sprintf(card->longname, "%s soundcard, %s at 0x%lx, irq %d, dma %d", 151 - card->shortname, chip->name, chip->port, irq[dev], dma8[dev]); 152 - 153 - if ((error = snd_card_register(card)) < 0) { 154 - snd_card_free(card); 155 - return error; 156 - } 157 - pnp_set_card_drvdata(pcard, card); 158 - return 0; 159 - } 160 - 161 - static unsigned int __devinitdata es968_devices; 162 - 163 - static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card, 164 - const struct pnp_card_device_id *id) 165 - { 166 - static int dev; 167 - int res; 168 - 169 - for ( ; dev < SNDRV_CARDS; dev++) { 170 - if (!enable[dev]) 171 - continue; 172 - res = snd_card_es968_probe(dev, card, id); 173 - if (res < 0) 174 - return res; 175 - dev++; 176 - es968_devices++; 177 - return 0; 178 - } 179 - return -ENODEV; 180 - } 181 - 182 - static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard) 183 - { 184 - snd_card_free(pnp_get_card_drvdata(pcard)); 185 - pnp_set_card_drvdata(pcard, NULL); 186 - } 187 - 188 - #ifdef CONFIG_PM 189 - static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state) 190 - { 191 - struct snd_card *card = pnp_get_card_drvdata(pcard); 192 - struct snd_card_es968 *acard = card->private_data; 193 - struct snd_sb *chip = acard->chip; 194 - 195 - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 196 - snd_pcm_suspend_all(chip->pcm); 197 - snd_sbmixer_suspend(chip); 198 - return 0; 199 - } 200 - 201 - static int snd_es968_pnp_resume(struct pnp_card_link *pcard) 202 - { 203 - struct snd_card *card = pnp_get_card_drvdata(pcard); 204 - struct snd_card_es968 *acard = card->private_data; 205 - struct snd_sb *chip = acard->chip; 206 - 207 - snd_sbdsp_reset(chip); 208 - snd_sbmixer_resume(chip); 209 - snd_power_change_state(card, SNDRV_CTL_POWER_D0); 210 - return 0; 211 - } 212 - #endif 213 - 214 - static struct pnp_card_driver es968_pnpc_driver = { 215 - .flags = PNP_DRIVER_RES_DISABLE, 216 - .name = "es968", 217 - .id_table = snd_es968_pnpids, 218 - .probe = snd_es968_pnp_detect, 219 - .remove = __devexit_p(snd_es968_pnp_remove), 220 - #ifdef CONFIG_PM 221 - .suspend = snd_es968_pnp_suspend, 222 - .resume = snd_es968_pnp_resume, 223 - #endif 224 - }; 225 - 226 - static int __init alsa_card_es968_init(void) 227 - { 228 - int err = pnp_register_card_driver(&es968_pnpc_driver); 229 - if (err) 230 - return err; 231 - 232 - if (!es968_devices) { 233 - pnp_unregister_card_driver(&es968_pnpc_driver); 234 - #ifdef MODULE 235 - snd_printk(KERN_ERR "no ES968 based soundcards found\n"); 236 - #endif 237 - return -ENODEV; 238 - } 239 - return 0; 240 - } 241 - 242 - static void __exit alsa_card_es968_exit(void) 243 - { 244 - pnp_unregister_card_driver(&es968_pnpc_driver); 245 - } 246 - 247 - module_init(alsa_card_es968_init) 248 - module_exit(alsa_card_es968_exit)