654 |
return result; |
return result; |
655 |
} |
} |
656 |
|
|
657 |
|
#define big_mdelay(msec) do {\ |
658 |
|
set_current_state(TASK_UNINTERRUPTIBLE);\ |
659 |
|
schedule_timeout(((msec) * HZ + 999) / 1000);\ |
660 |
|
} while (0) |
661 |
|
|
662 |
/* Wait for the codec bus to be free */ |
/* Wait for the codec bus to be free */ |
663 |
static int snd_es1968_ac97_wait(es1968_t *chip) |
static int snd_es1968_ac97_wait(es1968_t *chip) |
664 |
{ |
{ |
2114 |
outw(0x0000, ioaddr + 0x60); /* write 0 to gpio 0 */ |
outw(0x0000, ioaddr + 0x60); /* write 0 to gpio 0 */ |
2115 |
udelay(20); |
udelay(20); |
2116 |
outw(0x0001, ioaddr + 0x60); /* write 1 to gpio 1 */ |
outw(0x0001, ioaddr + 0x60); /* write 1 to gpio 1 */ |
2117 |
mdelay(20); |
big_mdelay(20); |
2118 |
|
|
2119 |
outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */ |
outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */ |
2120 |
outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38); |
outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38); |
2130 |
outw(0x0001, ioaddr + 0x60); /* write 1 to gpio */ |
outw(0x0001, ioaddr + 0x60); /* write 1 to gpio */ |
2131 |
udelay(20); |
udelay(20); |
2132 |
outw(0x0009, ioaddr + 0x60); /* write 9 to gpio */ |
outw(0x0009, ioaddr + 0x60); /* write 9 to gpio */ |
2133 |
mdelay(500); /* .. ouch.. */ |
big_mdelay(500); |
2134 |
//outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); |
//outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); |
2135 |
outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a); |
outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a); |
2136 |
outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c); |
outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c); |
2156 |
|
|
2157 |
if (w > 10000) { |
if (w > 10000) { |
2158 |
outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37); /* do a software reset */ |
outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37); /* do a software reset */ |
2159 |
mdelay(500); /* oh my.. */ |
big_mdelay(500); /* oh my.. */ |
2160 |
outb(inb(ioaddr + 0x37) & ~0x08, |
outb(inb(ioaddr + 0x37) & ~0x08, |
2161 |
ioaddr + 0x37); |
ioaddr + 0x37); |
2162 |
udelay(1); |
udelay(1); |
2345 |
outb(3, iobase + ASSP_CONTROL_A); /* M: Reserved bits... */ |
outb(3, iobase + ASSP_CONTROL_A); /* M: Reserved bits... */ |
2346 |
outb(0, iobase + ASSP_CONTROL_C); /* M: Disable ASSP, ASSP IRQ's and FM Port */ |
outb(0, iobase + ASSP_CONTROL_C); /* M: Disable ASSP, ASSP IRQ's and FM Port */ |
2347 |
|
|
|
/* Enable IRQ's */ |
|
|
w = ESM_HIRQ_DSIE | ESM_HIRQ_MPU401 | ESM_HIRQ_HW_VOLUME; |
|
|
outw(w, iobase + ESM_PORT_HOST_IRQ); |
|
|
|
|
|
|
|
2348 |
/* |
/* |
2349 |
* set up wavecache |
* set up wavecache |
2350 |
*/ |
*/ |
2414 |
} |
} |
2415 |
} |
} |
2416 |
|
|
2417 |
|
/* Enable IRQ's */ |
2418 |
|
static void snd_es1968_start_irq(es1968_t *chip) |
2419 |
|
{ |
2420 |
|
unsigned short w; |
2421 |
|
w = ESM_HIRQ_DSIE | ESM_HIRQ_MPU401 | ESM_HIRQ_HW_VOLUME; |
2422 |
|
outw(w, chip->io_port + ESM_PORT_HOST_IRQ); |
2423 |
|
} |
2424 |
|
|
2425 |
#ifdef CONFIG_PM |
#ifdef CONFIG_PM |
2426 |
/* |
/* |
2427 |
* PM support |
* PM support |
2461 |
wave_set_register(chip, 0x01FC, chip->dma.addr >> 12); |
wave_set_register(chip, 0x01FC, chip->dma.addr >> 12); |
2462 |
} |
} |
2463 |
|
|
2464 |
|
snd_es1968_start_irq(chip); |
2465 |
|
|
2466 |
/* restore ac97 state */ |
/* restore ac97 state */ |
2467 |
snd_ac97_resume(chip->ac97); |
snd_ac97_resume(chip->ac97); |
2468 |
|
|
2469 |
/* start timer again */ |
/* start timer again */ |
2470 |
if (atomic_read(&chip->bobclient)) |
if (atomic_read(&chip->bobclient)) |
2471 |
snd_es1968_bob_start(chip); |
snd_es1968_bob_start(chip); |
2472 |
|
|
2473 |
snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
2474 |
} |
} |
2475 |
|
|
|
#ifndef PCI_OLD_SUSPEND |
|
2476 |
static int snd_es1968_suspend(struct pci_dev *dev, u32 state) |
static int snd_es1968_suspend(struct pci_dev *dev, u32 state) |
2477 |
{ |
{ |
2478 |
es1968_t *chip = snd_magic_cast(es1968_t, pci_get_drvdata(dev), return -ENXIO); |
es1968_t *chip = snd_magic_cast(es1968_t, pci_get_drvdata(dev), return -ENXIO); |
2485 |
es1968_resume(chip); |
es1968_resume(chip); |
2486 |
return 0; |
return 0; |
2487 |
} |
} |
|
#else |
|
|
static void snd_es1968_suspend(struct pci_dev *dev) |
|
|
{ |
|
|
es1968_t *chip = snd_magic_cast(es1968_t, pci_get_drvdata(dev), return); |
|
|
es1968_suspend(chip); |
|
|
} |
|
|
static void snd_es1968_resume(struct pci_dev *dev) |
|
|
{ |
|
|
es1968_t *chip = snd_magic_cast(es1968_t, pci_get_drvdata(dev), return); |
|
|
es1968_resume(chip); |
|
|
} |
|
|
#endif |
|
2488 |
|
|
2489 |
/* callback */ |
/* callback */ |
2490 |
static int snd_es1968_set_power_state(snd_card_t *card, unsigned int power_state) |
static int snd_es1968_set_power_state(snd_card_t *card, unsigned int power_state) |
2610 |
/* disable power-management if not maestro2e or |
/* disable power-management if not maestro2e or |
2611 |
* if not on the whitelist |
* if not on the whitelist |
2612 |
*/ |
*/ |
2613 |
unsigned int vend; |
unsigned short vend; |
2614 |
pci_read_config_dword(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend); |
pci_read_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend); |
2615 |
if (chip->type != TYPE_MAESTRO2E || (vend & 0xffff) != 0x1028) { |
if (chip->type != TYPE_MAESTRO2E || (vend != 0x1028 && vend != 0x1179)) { |
2616 |
printk(KERN_INFO "es1968: not attempting power management.\n"); |
printk(KERN_INFO "es1968: not attempting power management.\n"); |
2617 |
do_pm = 0; |
do_pm = 0; |
2618 |
} |
} |
2767 |
} |
} |
2768 |
} |
} |
2769 |
|
|
2770 |
|
snd_es1968_start_irq(chip); |
2771 |
|
|
2772 |
chip->clock = clock[dev]; |
chip->clock = clock[dev]; |
2773 |
if (! chip->clock) |
if (! chip->clock) |
2774 |
es1968_measure_clock(chip); |
es1968_measure_clock(chip); |