X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fpci%2Fes1968.c;h=faf63ff19c42abf17d15f22c7223f631e2ef58f6;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=12ac754801a6b677063b4b06e3a7dc49bcb748cb;hpb=e3f6fb6212a7102bdb56ba38fa1e98fe72950475;p=linux-2.6.git diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 12ac75480..faf63ff19 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -586,6 +586,7 @@ struct snd_es1968 { spinlock_t reg_lock; spinlock_t ac97_lock; struct tasklet_struct hwvol_tq; + unsigned int in_suspend; /* Maestro Stuff */ u16 maestro_map[32]; @@ -605,8 +606,7 @@ struct snd_es1968 { #endif #ifdef SUPPORT_JOYSTICK - struct gameport gameport; - struct resource *res_joystick; + struct gameport *gameport; #endif }; @@ -1938,6 +1938,9 @@ static void es1968_update_hw_volume(unsigned long private_data) outb(0x88, chip->io_port + 0x1e); outb(0x88, chip->io_port + 0x1f); + if (chip->in_suspend) + return; + if (! chip->master_switch || ! chip->master_volume) return; @@ -2404,13 +2407,14 @@ static void snd_es1968_start_irq(es1968_t *chip) /* * PM support */ -static int es1968_suspend(snd_card_t *card, unsigned int state) +static int es1968_suspend(snd_card_t *card, pm_message_t state) { es1968_t *chip = card->pm_private_data; if (! chip->do_pm) return 0; + chip->in_suspend = 1; snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); snd_es1968_bob_stop(chip); @@ -2419,9 +2423,10 @@ static int es1968_suspend(snd_card_t *card, unsigned int state) return 0; } -static int es1968_resume(snd_card_t *card, unsigned int state) +static int es1968_resume(snd_card_t *card) { es1968_t *chip = card->pm_private_data; + struct list_head *p; if (! chip->do_pm) return 0; @@ -2442,14 +2447,81 @@ static int es1968_resume(snd_card_t *card, unsigned int state) /* restore ac97 state */ snd_ac97_resume(chip->ac97); + list_for_each(p, &chip->substream_list) { + esschan_t *es = list_entry(p, esschan_t, list); + switch (es->mode) { + case ESM_MODE_PLAY: + snd_es1968_playback_setup(chip, es, es->substream->runtime); + break; + case ESM_MODE_CAPTURE: + snd_es1968_capture_setup(chip, es, es->substream->runtime); + break; + } + } + /* start timer again */ if (chip->bobclient) snd_es1968_bob_start(chip); + chip->in_suspend = 0; return 0; } #endif /* CONFIG_PM */ +#ifdef SUPPORT_JOYSTICK +#define JOYSTICK_ADDR 0x200 +static int __devinit snd_es1968_create_gameport(es1968_t *chip, int dev) +{ + struct gameport *gp; + struct resource *r; + u16 val; + + if (!joystick[dev]) + return -ENODEV; + + r = request_region(JOYSTICK_ADDR, 8, "ES1968 gameport"); + if (!r) + return -EBUSY; + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "es1968: cannot allocate memory for gameport\n"); + release_resource(r); + kfree_nocheck(r); + return -ENOMEM; + } + + pci_read_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, &val); + pci_write_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, val | 0x04); + + gameport_set_name(gp, "ES1968 Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gameport_set_dev_parent(gp, &chip->pci->dev); + gp->io = JOYSTICK_ADDR; + gameport_set_port_data(gp, r); + + gameport_register_port(gp); + + return 0; +} + +static void snd_es1968_free_gameport(es1968_t *chip) +{ + if (chip->gameport) { + struct resource *r = gameport_get_port_data(chip->gameport); + + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + + release_resource(r); + kfree_nocheck(r); + } +} +#else +static inline int snd_es1968_create_gameport(es1968_t *chip, int dev) { return -ENOSYS; } +static inline void snd_es1968_free_gameport(es1968_t *chip) { } +#endif + static int snd_es1968_free(es1968_t *chip) { if (chip->io_port) { @@ -2460,13 +2532,7 @@ static int snd_es1968_free(es1968_t *chip) if (chip->irq >= 0) free_irq(chip->irq, (void *)chip); -#ifdef SUPPORT_JOYSTICK - if (chip->res_joystick) { - gameport_unregister_port(&chip->gameport); - release_resource(chip->res_joystick); - kfree_nocheck(chip->res_joystick); - } -#endif + snd_es1968_free_gameport(chip); snd_es1968_set_acpi(chip, ACPI_D3); chip->master_switch = NULL; chip->master_volume = NULL; @@ -2693,17 +2759,7 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, } } -#ifdef SUPPORT_JOYSTICK -#define JOYSTICK_ADDR 0x200 - if (joystick[dev] && - (chip->res_joystick = request_region(JOYSTICK_ADDR, 8, "ES1968 gameport")) != NULL) { - u16 val; - pci_read_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, &val); - pci_write_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, val | 0x04); - chip->gameport.io = JOYSTICK_ADDR; - gameport_register_port(&chip->gameport); - } -#endif + snd_es1968_create_gameport(chip, dev); snd_es1968_start_irq(chip);