spinlock_t reg_lock;
spinlock_t ac97_lock;
struct tasklet_struct hwvol_tq;
+ unsigned int in_suspend;
/* Maestro Stuff */
u16 maestro_map[32];
#endif
#ifdef SUPPORT_JOYSTICK
- struct gameport gameport;
- struct resource *res_joystick;
+ struct gameport *gameport;
#endif
};
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;
/*
* 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);
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;
/* 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) {
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;
}
}
-#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);