#define ESM_MODE_PLAY 0
#define ESM_MODE_CAPTURE 1
-/* acpi states */
-enum {
- ACPI_D0=0,
- ACPI_D1,
- ACPI_D2,
- ACPI_D3
-};
-
-/* bits in the acpi masks */
-#define ACPI_12MHZ ( 1 << 15)
-#define ACPI_24MHZ ( 1 << 14)
-#define ACPI_978 ( 1 << 13)
-#define ACPI_SPDIF ( 1 << 12)
-#define ACPI_GLUE ( 1 << 11)
-#define ACPI__10 ( 1 << 10) /* reserved */
-#define ACPI_PCIINT ( 1 << 9)
-#define ACPI_HV ( 1 << 8) /* hardware volume */
-#define ACPI_GPIO ( 1 << 7)
-#define ACPI_ASSP ( 1 << 6)
-#define ACPI_SB ( 1 << 5) /* sb emul */
-#define ACPI_FM ( 1 << 4) /* fm emul */
-#define ACPI_RB ( 1 << 3) /* ringbus / aclink */
-#define ACPI_MIDI ( 1 << 2)
-#define ACPI_GP ( 1 << 1) /* game port */
-#define ACPI_WP ( 1 << 0) /* wave processor */
-
-#define ACPI_ALL (0xffff)
-#define ACPI_SLEEP (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \
- ACPI_MIDI|ACPI_GP|ACPI_WP))
-#define ACPI_NONE (ACPI__10)
-
-/* these masks indicate which units we care about at
- which states */
-static u16 acpi_state_mask[] = {
- [ACPI_D0] = ACPI_ALL,
- [ACPI_D1] = ACPI_SLEEP,
- [ACPI_D2] = ACPI_SLEEP,
- [ACPI_D3] = ACPI_NONE
-};
-
/* APU use in the driver */
enum snd_enum_apu_type {
#endif
};
-static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
static struct pci_device_id snd_es1968_ids[] = {
/* Maestro 1 */
struct esm_memory *buf;
struct list_head *p;
- size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN;
+ size = ALIGN(size, ESM_MEM_ALIGN);
mutex_lock(&chip->memory_mutex);
list_for_each(p, &chip->buf_list) {
buf = list_entry(p, struct esm_memory, list);
/* Figure out which volume control button was pushed,
based on differences from the default register
values. */
- x = inb(chip->io_port + 0x1c);
+ x = inb(chip->io_port + 0x1c) & 0xee;
/* Reset the volume control registers. */
outb(0x88, chip->io_port + 0x1c);
outb(0x88, chip->io_port + 0x1d);
/* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
spin_lock_irqsave(&chip->ac97_lock, flags);
val = chip->ac97->regs[AC97_MASTER];
- if (x & 1) {
+ switch (x) {
+ case 0x88:
/* mute */
val ^= 0x8000;
chip->ac97->regs[AC97_MASTER] = val;
outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->master_switch->id);
- } else {
- val &= 0x7fff;
- if (((x>>1) & 7) > 4) {
- /* volume up */
- if ((val & 0xff) > 0)
- val--;
- if ((val & 0xff00) > 0)
- val -= 0x0100;
- } else {
- /* volume down */
- if ((val & 0xff) < 0x1f)
- val++;
- if ((val & 0xff00) < 0x1f00)
- val += 0x0100;
- }
+ break;
+ case 0xaa:
+ /* volume up */
+ if ((val & 0x7f) > 0)
+ val--;
+ if ((val & 0x7f00) > 0)
+ val -= 0x0100;
+ chip->ac97->regs[AC97_MASTER] = val;
+ outw(val, chip->io_port + ESM_AC97_DATA);
+ outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &chip->master_volume->id);
+ break;
+ case 0x66:
+ /* volume down */
+ if ((val & 0x7f) < 0x1f)
+ val++;
+ if ((val & 0x7f00) < 0x1f00)
+ val += 0x0100;
chip->ac97->regs[AC97_MASTER] = val;
outw(val, chip->io_port + ESM_AC97_DATA);
outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->master_volume->id);
+ break;
}
spin_unlock_irqrestore(&chip->ac97_lock, flags);
}
/*
* interrupt handler
*/
-static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
{
struct es1968 *chip = dev_id;
u32 event;
outb(0xFF, chip->io_port + 0x1A);
if ((event & ESM_MPU401_IRQ) && chip->rmidi) {
- snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+ snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
}
if (event & ESM_SOUND_IRQ) {
udelay(10);
}
-/*
- * power management
- */
-static void snd_es1968_set_acpi(struct es1968 *chip, int state)
-{
- u16 active_mask = acpi_state_mask[state];
-
- pci_set_power_state(chip->pci, state);
- /* make sure the units we care about are on
- XXX we might want to do this before state flipping? */
- pci_write_config_word(chip->pci, 0x54, ~ active_mask);
- pci_write_config_word(chip->pci, 0x56, ~ active_mask);
-}
-
-
/*
* initialize maestro chip
*/
* IRQs.
*/
- /* do config work at full power */
- snd_es1968_set_acpi(chip, ACPI_D0);
-
/* Config Reg A */
pci_read_config_word(pci, ESM_CONFIG_A, &w);
snd_pcm_suspend_all(chip->pcm);
snd_ac97_suspend(chip->ac97);
snd_es1968_bob_stop(chip);
- snd_es1968_set_acpi(chip, ACPI_D3);
+
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
return 0;
/* restore all our config */
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "es1968: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
+
snd_es1968_chip_init(chip);
/* need to restore the base pointers.. */
}
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
snd_es1968_free_gameport(chip);
- snd_es1968_set_acpi(chip, ACPI_D3);
chip->master_switch = NULL;
chip->master_volume = NULL;
pci_release_regions(chip->pci);
return err;
}
chip->io_port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_DISABLED|IRQF_SHARED,
- "ESS Maestro", (void*)chip)) {
+ if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
+ "ESS Maestro", chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_es1968_free(chip);
return -EBUSY;