* Changed ens1370.c to enable Suspend ens1371 @ 2005-11-11 17:58 Kurt J. Bosch 2005-11-11 18:06 ` Takashi Iwai 0 siblings, 1 reply; 9+ messages in thread From: Kurt J. Bosch @ 2005-11-11 17:58 UTC (permalink / raw) To: alsa-devel [-- Attachment #1: Type: text/plain, Size: 1205 bytes --] Hi, I changed driver ens1371 to enable suspend to disk only using some other drivers as kind of templates. (No special handling of any registers added.) BTW - this is my second post. The first is holded back since Nov. 6th because it was too big. - I'm sorry about that, but i'm a newbe here :-) I did some testing on Ubuntu Breezy Linux version 2.6.12-9-686 (buildd@rothera) (gcc version 3.4.5 20050809 (prerelease) (Ubuntu 3.4.4-6ubuntu8)) #1 Mon Oct 10 13:25:32 BST 2005 alsa 1.0.9b and it seems to work fine for me. I am using swsusp not swsusp2 but with script hibernate 1.07 and removed snd-ens1371 from /etc/hibernate/blacklisted-modules thus it is not longer unloaded. To avoid problems with dmix I changed /etc/hibernate/hibernate.conf : --8<-- ### misclaunch # OnSuspend 20 echo "Good night!" # OnResume 20 echo "Good morning!" # # kjb - workaround for # ALSA Bug 0001249: dmix doesn't survive suspend to RAM # this restores the socket /tmp/alsa-dmix-... (!) OnSuspend 20 sudo -H -u kurt /usr/bin/esdctl standby OnResume 20 sudo -H -u kurt /usr/bin/esdctl resume --8<-- (I use gnome, so esd is running all the time.) patch for ens1370.c CVS revision 1.90 is appended Any comments ? [-- Attachment #2: patch.diff --] [-- Type: text/x-patch, Size: 8402 bytes --] 21a22,28 > /* Power-Management-Code ( CONFIG_PM ) > * for ens1371 only ( FIXME ) > * derived from cs4281.c, atiixp.c and via82xx.c > * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm > * by Kurt J. Bosch ( kjb ) > */ > 786a794 > case SNDRV_PCM_TRIGGER_RESUME: // kjb 787a796 > case SNDRV_PCM_TRIGGER_SUSPEND: // kjb 806c815,817 < if (cmd == SNDRV_PCM_TRIGGER_START) --- > if (cmd == SNDRV_PCM_TRIGGER_START > || cmd == SNDRV_PCM_TRIGGER_RESUME // kjb > ) 1014c1025,1027 < SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), --- > SNDRV_PCM_INFO_PAUSE | > SNDRV_PCM_INFO_RESUME | // kjb > SNDRV_PCM_INFO_SYNC_START), 1040c1053,1055 < SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | --- > SNDRV_PCM_INFO_MMAP_VALID | > SNDRV_PCM_INFO_PAUSE | > SNDRV_PCM_INFO_RESUME | // kjb 1060c1075,1077 < SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START), --- > SNDRV_PCM_INFO_MMAP_VALID | > SNDRV_PCM_INFO_RESUME | // kjb > SNDRV_PCM_INFO_SYNC_START), 1926a1944,2056 > /* initialize the chips */ > // kjb - this code was part of snd_ensoniq_create > static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) > { > #ifdef CHIP1371 > int idx; > struct pci_dev *pci = ensoniq->pci; > #endif > #ifdef CHIP1370 > outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); > outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); > outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); > outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); > outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); > #else > outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); > outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); > outl(0, ES_REG(ensoniq, 1371_LEGACY)); > for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) > if (pci->vendor == es1371_ac97_reset_hack[idx].vid && > pci->device == es1371_ac97_reset_hack[idx].did && > ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { > ensoniq->cssr |= ES_1371_ST_AC97_RST; > outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); > /* need to delay around 20ms(bleech) to give > some CODECs enough time to wakeup */ > msleep(20); > break; > } > /* AC'97 warm reset to start the bitclk */ > outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); > inl(ES_REG(ensoniq, CONTROL)); > udelay(20); > outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); > /* Init the sample rate converter */ > snd_es1371_wait_src_ready(ensoniq); > outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); > for (idx = 0; idx < 0x80; idx++) > snd_es1371_src_write(ensoniq, idx, 0); > snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); > snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); > snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); > snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); > snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); > snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); > snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); > snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); > snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); > snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); > snd_es1371_adc_rate(ensoniq, 22050); > snd_es1371_dac1_rate(ensoniq, 22050); > snd_es1371_dac2_rate(ensoniq, 22050); > /* WARNING: > * enabling the sample rate converter without properly programming > * its parameters causes the chip to lock up (the SRC busy bit will > * be stuck high, and I've found no way to rectify this other than > * power cycle) - Thomas Sailer > */ > snd_es1371_wait_src_ready(ensoniq); > outl(0, ES_REG(ensoniq, 1371_SMPRATE)); > /* try reset codec directly */ > outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); > #endif > outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); > outb(0x00, ES_REG(ensoniq, UART_RES)); > outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); > synchronize_irq(ensoniq->irq); > } > > #ifdef CONFIG_PM > static int snd_ensoniq_suspend (snd_card_t * card, > pm_message_t state) > { > ensoniq_t *ensoniq = card->pm_private_data; > > snd_pcm_suspend_all(ensoniq->pcm1); > snd_pcm_suspend_all(ensoniq->pcm2); > > #ifdef CHIP1371 > if (ensoniq->u.es1371.ac97) > snd_ac97_suspend(ensoniq->u.es1371.ac97); > #else > /* FIXME */ > #endif > pci_set_power_state(ensoniq->pci, 3); > pci_disable_device(ensoniq->pci); > // snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); // only 2.6.10 > return 0; > } > > static int snd_ensoniq_resume (snd_card_t * card > ) > { > ensoniq_t *ensoniq = card->pm_private_data; > > pci_enable_device(ensoniq->pci); > pci_set_power_state(ensoniq->pci, 0); > pci_set_master(ensoniq->pci); > > snd_ensoniq_chip_init(ensoniq); > > #ifdef CHIP1371 > if (ensoniq->u.es1371.ac97) > snd_ac97_resume(ensoniq->u.es1371.ac97); > #else > /* FIXME */ > #endif > // snd_power_change_state(card, SNDRV_CTL_POWER_D0); // only 2.6.10 > return 0; > } > #endif /* CONFIG_PM */ > > 1989,1994d2118 < /* initialize the chips */ < outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); < outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); < outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); < outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); < outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); 2005,2052d2128 < /* initialize the chips */ < outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); < outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); < outl(0, ES_REG(ensoniq, 1371_LEGACY)); < for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) < if (pci->vendor == es1371_ac97_reset_hack[idx].vid && < pci->device == es1371_ac97_reset_hack[idx].did && < ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { < ensoniq->cssr |= ES_1371_ST_AC97_RST; < outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); < /* need to delay around 20ms(bleech) to give < some CODECs enough time to wakeup */ < msleep(20); < break; < } < /* AC'97 warm reset to start the bitclk */ < outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); < inl(ES_REG(ensoniq, CONTROL)); < udelay(20); < outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); < /* Init the sample rate converter */ < snd_es1371_wait_src_ready(ensoniq); < outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); < for (idx = 0; idx < 0x80; idx++) < snd_es1371_src_write(ensoniq, idx, 0); < snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); < snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); < snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); < snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); < snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); < snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); < snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); < snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); < snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); < snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); < snd_es1371_adc_rate(ensoniq, 22050); < snd_es1371_dac1_rate(ensoniq, 22050); < snd_es1371_dac2_rate(ensoniq, 22050); < /* WARNING: < * enabling the sample rate converter without properly programming < * its parameters causes the chip to lock up (the SRC busy bit will < * be stuck high, and I've found no way to rectify this other than < * power cycle) - Thomas Sailer < */ < snd_es1371_wait_src_ready(ensoniq); < outl(0, ES_REG(ensoniq, 1371_SMPRATE)); < /* try reset codec directly */ < outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); 2054,2057c2130,2131 < outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); < outb(0x00, ES_REG(ensoniq, UART_RES)); < outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); < synchronize_irq(ensoniq->irq); --- > > snd_ensoniq_chip_init(ensoniq); // kjb 2065a2140,2143 > #ifdef CHIP1371 /* FIXME */ > snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); // kjb > #endif > 2392a2471 > SND_PCI_PM_CALLBACKS // kjb ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Changed ens1370.c to enable Suspend ens1371 2005-11-11 17:58 Changed ens1370.c to enable Suspend ens1371 Kurt J. Bosch @ 2005-11-11 18:06 ` Takashi Iwai 2005-11-14 12:05 ` Kurt J. Bosch 0 siblings, 1 reply; 9+ messages in thread From: Takashi Iwai @ 2005-11-11 18:06 UTC (permalink / raw) To: Kurt J. Bosch; +Cc: alsa-devel At Fri, 11 Nov 2005 18:58:20 +0100, Kurt J. Bosch wrote: > > Hi, > > I changed driver ens1371 to enable suspend to disk > only using some other drivers as kind of templates. > (No special handling of any registers added.) > > BTW - this is my second post. The first is holded back since Nov. 6th > because it was too big. - I'm sorry about that, but i'm a newbe here :-) > > I did some testing on Ubuntu Breezy > Linux version 2.6.12-9-686 (buildd@rothera) (gcc version 3.4.5 20050809 > (prerelease) (Ubuntu 3.4.4-6ubuntu8)) #1 Mon Oct 10 13:25:32 BST 2005 > alsa 1.0.9b > and it seems to work fine for me. > > I am using swsusp not swsusp2 > but with script hibernate 1.07 > and removed snd-ens1371 from /etc/hibernate/blacklisted-modules > thus it is not longer unloaded. > > To avoid problems with dmix I changed /etc/hibernate/hibernate.conf : > --8<-- > ### misclaunch > # OnSuspend 20 echo "Good night!" > # OnResume 20 echo "Good morning!" > # > # kjb - workaround for > # ALSA Bug 0001249: dmix doesn't survive suspend to RAM > # this restores the socket /tmp/alsa-dmix-... (!) > OnSuspend 20 sudo -H -u kurt /usr/bin/esdctl standby > OnResume 20 sudo -H -u kurt /usr/bin/esdctl resume > --8<-- > (I use gnome, so esd is running all the time.) > > > patch for ens1370.c CVS revision 1.90 > > is appended > > Any comments ? Thanks for the patch. But, please make a patch with diff -u. The pcm info flag SNDRV_PCM_INFO_RESUME can't be set in your case. This INFO_RESUME flag means that the full suspend/resume is supported. That is, the PCM stream is resumed fully only by calling snd_pcm_trigger(RESUME) without snd_pcm_prepare(), etc. In your case, it's a partial suspend/resume support. That is, the resume is done by explicitly calling snd_pcm_prepare() snd restart from the app. Also, add a proper changelog with signed-off-by line. It's like below: Summary: Fix blah ... This patch fixes blah blah... ... Signed-off-by: Foo Bar <foo@bar.com> Thanks, Takashi ------------------------------------------------------- SF.Net email is sponsored by: Tame your development challenges with Apache's Geronimo App Server. Download it for free - -and be entered to win a 42" plasma tv or your very own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Changed ens1370.c to enable Suspend ens1371 2005-11-11 18:06 ` Takashi Iwai @ 2005-11-14 12:05 ` Kurt J. Bosch 2005-11-14 12:25 ` Kurt J. Bosch 2005-11-14 17:02 ` Takashi Iwai 0 siblings, 2 replies; 9+ messages in thread From: Kurt J. Bosch @ 2005-11-14 12:05 UTC (permalink / raw) To: alsa-devel [-- Attachment #1: Type: text/plain, Size: 1666 bytes --] Takashi Iwai schrieb: > At Fri, 11 Nov 2005 18:58:20 +0100, > Kurt J. Bosch wrote: > >>Hi, >> >>I changed driver ens1371 to enable suspend to disk >>only using some other drivers as kind of templates. >>(No special handling of any registers added.) >> >>I did some testing on Ubuntu Breezy >>Linux version 2.6.12-9-686 (buildd@rothera) (gcc version 3.4.5 20050809 >>(prerelease) (Ubuntu 3.4.4-6ubuntu8)) #1 Mon Oct 10 13:25:32 BST 2005 >>alsa 1.0.9b and on Ubuntu Breezy with the kernel from Hoary Linux version 2.6.10-5-686 (buildd@terranova) (gcc version 3.3.5 (Debian 1:3.3.5-8ubuntu2)) #1 Mon Oct 10 11:28:02 UTC 2005 (which I use most time) >>and it seems to work fine for me. >> >>I am using swsusp not swsusp2 >>but with script hibernate 1.07 >>and removed snd-ens1371 from /etc/hibernate/blacklisted-modules >>thus it is not longer unloaded. >> >>patch for ens1370.c CVS revision 1.90 >> >>is appended patchs for kernels 2.6.12 and 2.6.10 too :) > > > Thanks for the patch. But, please make a patch with diff -u. > > The pcm info flag SNDRV_PCM_INFO_RESUME can't be set in your case. > > This INFO_RESUME flag means that the full suspend/resume is supported. > That is, the PCM stream is resumed fully only by calling > snd_pcm_trigger(RESUME) without snd_pcm_prepare(), etc. > > In your case, it's a partial suspend/resume support. That is, the > resume is done by explicitly calling snd_pcm_prepare() snd restart > from the app. > > Also, add a proper changelog with signed-off-by line. It's like > below: > > Summary: Fix blah ... > > This patch fixes blah blah... > ... > > Signed-off-by: Foo Bar <foo@bar.com> > ok - I fixed that [-- Attachment #2: ens1370.c_2.6.10_ens1371_suspend.patch --] [-- Type: text/x-patch, Size: 9309 bytes --] Summary: Fix missing suspend/resume-code for ens1371 This patch fixes missing suspend/resume-code for snd-ens1371 (but not for snd-ens1370) Signed-off-by: Kurt J. Bosch <kjb-temp-2005@gmx.de> --- 2.6.10-5-686/ens1370.org.c 2004-12-24 22:35:24.000000000 +0100 +++ 2.6.10-5-686/ens1370.c 2005-11-14 11:36:58.000000000 +0100 @@ -19,6 +19,14 @@ * */ +/* Power-Management-Code ( CONFIG_PM ) + * for ens1371 only ( FIXME ) + * derived from cs4281.c, atiixp.c and via82xx.c + * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm + * by Kurt J. Bosch + */ + + #include <sound/driver.h> #include <asm/io.h> #include <linux/delay.h> @@ -1875,6 +1883,129 @@ }; #endif +static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) +{ +#ifdef CHIP1371 + int idx; + struct pci_dev *pci = ensoniq->pci; +#endif +// this code was part of snd_ensoniq_create +#ifdef CHIP1370 + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); + outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); + outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); +#else + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(0, ES_REG(ensoniq, 1371_LEGACY)); + for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) + if (pci->vendor == es1371_ac97_reset_hack[idx].vid && + pci->device == es1371_ac97_reset_hack[idx].did && + ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { + unsigned long tmo; + signed long tmo2; + + ensoniq->cssr |= ES_1371_ST_AC97_RST; + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + /* need to delay around 20ms(bleech) to give + some CODECs enough time to wakeup */ + tmo = jiffies + (HZ / 50) + 1; + while (1) { + tmo2 = tmo - jiffies; + if (tmo2 <= 0) + break; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(tmo2); + } + break; + } + /* AC'97 warm reset to start the bitclk */ + outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); + inl(ES_REG(ensoniq, CONTROL)); + udelay(20); + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + /* Init the sample rate converter */ + snd_es1371_wait_src_ready(ensoniq); + outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); + for (idx = 0; idx < 0x80; idx++) + snd_es1371_src_write(ensoniq, idx, 0); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); + snd_es1371_adc_rate(ensoniq, 22050); + snd_es1371_dac1_rate(ensoniq, 22050); + snd_es1371_dac2_rate(ensoniq, 22050); + /* WARNING: + * enabling the sample rate converter without properly programming + * its parameters causes the chip to lock up (the SRC busy bit will + * be stuck high, and I've found no way to rectify this other than + * power cycle) - Thomas Sailer + */ + snd_es1371_wait_src_ready(ensoniq); + outl(0, ES_REG(ensoniq, 1371_SMPRATE)); + /* try reset codec directly */ + outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); +#endif + outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); + outb(0x00, ES_REG(ensoniq, UART_RES)); + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + + synchronize_irq(ensoniq->irq); +} + +#ifdef CONFIG_PM +static int snd_ensoniq_suspend (snd_card_t * card, + unsigned int state) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + snd_pcm_suspend_all(ensoniq->pcm1); + snd_pcm_suspend_all(ensoniq->pcm2); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_suspend(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + pci_set_power_state(ensoniq->pci, 3); + pci_disable_device(ensoniq->pci); + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + return 0; +} + +static int snd_ensoniq_resume (snd_card_t * card, + unsigned int state) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + pci_enable_device(ensoniq->pci); + pci_set_power_state(ensoniq->pci, 0); + pci_set_master(ensoniq->pci); + + snd_ensoniq_chip_init(ensoniq); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_resume(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif /* CONFIG_PM */ + + static int __devinit snd_ensoniq_create(snd_card_t * card, struct pci_dev *pci, ensoniq_t ** rensoniq) @@ -1938,12 +2069,6 @@ ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); #endif ensoniq->sctrl = 0; - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); - outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); - outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); #else ensoniq->ctrl = 0; ensoniq->sctrl = 0; @@ -1954,74 +2079,17 @@ ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ break; } - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(0, ES_REG(ensoniq, 1371_LEGACY)); - for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) - if (pci->vendor == es1371_ac97_reset_hack[idx].vid && - pci->device == es1371_ac97_reset_hack[idx].did && - ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { - unsigned long tmo; - signed long tmo2; - - ensoniq->cssr |= ES_1371_ST_AC97_RST; - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - /* need to delay around 20ms(bleech) to give - some CODECs enough time to wakeup */ - tmo = jiffies + (HZ / 50) + 1; - while (1) { - tmo2 = tmo - jiffies; - if (tmo2 <= 0) - break; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(tmo2); - } - break; - } - /* AC'97 warm reset to start the bitclk */ - outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); - inl(ES_REG(ensoniq, CONTROL)); - udelay(20); - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - /* Init the sample rate converter */ - snd_es1371_wait_src_ready(ensoniq); - outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); - for (idx = 0; idx < 0x80; idx++) - snd_es1371_src_write(ensoniq, idx, 0); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); - snd_es1371_adc_rate(ensoniq, 22050); - snd_es1371_dac1_rate(ensoniq, 22050); - snd_es1371_dac2_rate(ensoniq, 22050); - /* WARNING: - * enabling the sample rate converter without properly programming - * its parameters causes the chip to lock up (the SRC busy bit will - * be stuck high, and I've found no way to rectify this other than - * power cycle) - Thomas Sailer - */ - snd_es1371_wait_src_ready(ensoniq); - outl(0, ES_REG(ensoniq, 1371_SMPRATE)); - /* try reset codec directly */ - outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); #endif - outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); - outb(0x00, ES_REG(ensoniq, UART_RES)); - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - synchronize_irq(ensoniq->irq); + + snd_ensoniq_chip_init(ensoniq); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { snd_ensoniq_free(ensoniq); return err; } +#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ + snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); +#endif snd_card_set_dev(card, &pci->dev); @@ -2342,7 +2410,7 @@ card->driver, ensoniq->port, ensoniq->irq); - + if ((err = snd_card_register(card)) < 0) { snd_card_free(card); return err; @@ -2364,6 +2432,9 @@ .id_table = snd_audiopci_ids, .probe = snd_audiopci_probe, .remove = __devexit_p(snd_audiopci_remove), +#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ + SND_PCI_PM_CALLBACKS +#endif }; static int __init alsa_card_ens137x_init(void) [-- Attachment #3: ens1370.c_2.6.12_ens1371_suspend.patch --] [-- Type: text/x-patch, Size: 8025 bytes --] Summary: Fix missing suspend/resume-code for ens1371 This patch fixes missing suspend/resume-code for snd-ens1371 (but not for snd-ens1370) Signed-off-by: Kurt J. Bosch <kjb-temp-2005@gmx.de> --- 2.6.12-9-686/ens1370.org.c 2005-10-10 14:12:34.000000000 +0200 +++ 2.6.12-9-686/ens1370.c 2005-11-14 11:22:48.000000000 +0100 @@ -19,6 +19,13 @@ * */ +/* Power-Management-Code ( CONFIG_PM ) + * for ens1371 only ( FIXME ) + * derived from cs4281.c, atiixp.c and via82xx.c + * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm + * by Kurt J. Bosch + */ + #include <sound/driver.h> #include <asm/io.h> #include <linux/delay.h> @@ -1922,85 +1929,20 @@ }; #endif -static int __devinit snd_ensoniq_create(snd_card_t * card, - struct pci_dev *pci, - ensoniq_t ** rensoniq) +static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) { - ensoniq_t *ensoniq; - unsigned short cmdw; - unsigned char cmdb; #ifdef CHIP1371 int idx; + struct pci_dev *pci = ensoniq->pci; #endif - int err; - static snd_device_ops_t ops = { - .dev_free = snd_ensoniq_dev_free, - }; - - *rensoniq = NULL; - if ((err = pci_enable_device(pci)) < 0) - return err; - ensoniq = kcalloc(1, sizeof(*ensoniq), GFP_KERNEL); - if (ensoniq == NULL) { - pci_disable_device(pci); - return -ENOMEM; - } - spin_lock_init(&ensoniq->reg_lock); - init_MUTEX(&ensoniq->src_mutex); - ensoniq->card = card; - ensoniq->pci = pci; - ensoniq->irq = -1; - if ((err = pci_request_regions(pci, "Ensoniq AudioPCI")) < 0) { - kfree(ensoniq); - pci_disable_device(pci); - return err; - } - ensoniq->port = pci_resource_start(pci, 0); - if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ, "Ensoniq AudioPCI", (void *)ensoniq)) { - snd_printk("unable to grab IRQ %d\n", pci->irq); - snd_ensoniq_free(ensoniq); - return -EBUSY; - } - ensoniq->irq = pci->irq; -#ifdef CHIP1370 - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), - 16, &ensoniq->dma_bug) < 0) { - snd_printk("unable to allocate space for phantom area - dma_bug\n"); - snd_ensoniq_free(ensoniq); - return -EBUSY; - } -#endif - pci_set_master(pci); - pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb); - ensoniq->rev = cmdb; - pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &cmdw); - ensoniq->subsystem_vendor_id = cmdw; - pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &cmdw); - ensoniq->subsystem_device_id = cmdw; +// this code was part of snd_ensoniq_create before introduction of suspend/resume #ifdef CHIP1370 -#if 0 - ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); -#else /* get microphone working */ - ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); -#endif - ensoniq->sctrl = 0; - /* initialize the chips */ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); #else - ensoniq->ctrl = 0; - ensoniq->sctrl = 0; - ensoniq->cssr = 0; - for (idx = 0; es1371_amplifier_hack[idx].svid != (unsigned short)PCI_ANY_ID; idx++) - if (ensoniq->subsystem_vendor_id == es1371_amplifier_hack[idx].svid && - ensoniq->subsystem_device_id == es1371_amplifier_hack[idx].sdid) { - ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ - break; - } - /* initialize the chips */ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); outl(0, ES_REG(ensoniq, 1371_LEGACY)); @@ -2062,7 +2004,129 @@ outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); outb(0x00, ES_REG(ensoniq, UART_RES)); outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + synchronize_irq(ensoniq->irq); +} + +#ifdef CONFIG_PM +static int snd_ensoniq_suspend (snd_card_t * card, + pm_message_t state) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + snd_pcm_suspend_all(ensoniq->pcm1); + snd_pcm_suspend_all(ensoniq->pcm2); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_suspend(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + pci_set_power_state(ensoniq->pci, 3); + pci_disable_device(ensoniq->pci); + // snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); // only 2.6.10 + return 0; +} + +static int snd_ensoniq_resume (snd_card_t * card + ) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + pci_enable_device(ensoniq->pci); + pci_set_power_state(ensoniq->pci, 0); + pci_set_master(ensoniq->pci); + + snd_ensoniq_chip_init(ensoniq); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_resume(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + // snd_power_change_state(card, SNDRV_CTL_POWER_D0); // only 2.6.10 + return 0; +} +#endif /* CONFIG_PM */ + + +static int __devinit snd_ensoniq_create(snd_card_t * card, + struct pci_dev *pci, + ensoniq_t ** rensoniq) +{ + ensoniq_t *ensoniq; + unsigned short cmdw; + unsigned char cmdb; +#ifdef CHIP1371 + int idx; +#endif + int err; + static snd_device_ops_t ops = { + .dev_free = snd_ensoniq_dev_free, + }; + + *rensoniq = NULL; + if ((err = pci_enable_device(pci)) < 0) + return err; + ensoniq = kcalloc(1, sizeof(*ensoniq), GFP_KERNEL); + if (ensoniq == NULL) { + pci_disable_device(pci); + return -ENOMEM; + } + spin_lock_init(&ensoniq->reg_lock); + init_MUTEX(&ensoniq->src_mutex); + ensoniq->card = card; + ensoniq->pci = pci; + ensoniq->irq = -1; + if ((err = pci_request_regions(pci, "Ensoniq AudioPCI")) < 0) { + kfree(ensoniq); + pci_disable_device(pci); + return err; + } + ensoniq->port = pci_resource_start(pci, 0); + if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ, "Ensoniq AudioPCI", (void *)ensoniq)) { + snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_ensoniq_free(ensoniq); + return -EBUSY; + } + ensoniq->irq = pci->irq; +#ifdef CHIP1370 + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), + 16, &ensoniq->dma_bug) < 0) { + snd_printk("unable to allocate space for phantom area - dma_bug\n"); + snd_ensoniq_free(ensoniq); + return -EBUSY; + } +#endif + pci_set_master(pci); + pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb); + ensoniq->rev = cmdb; + pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &cmdw); + ensoniq->subsystem_vendor_id = cmdw; + pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &cmdw); + ensoniq->subsystem_device_id = cmdw; +#ifdef CHIP1370 +#if 0 + ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); +#else /* get microphone working */ + ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); +#endif + ensoniq->sctrl = 0; +#else + ensoniq->ctrl = 0; + ensoniq->sctrl = 0; + ensoniq->cssr = 0; + for (idx = 0; es1371_amplifier_hack[idx].svid != (unsigned short)PCI_ANY_ID; idx++) + if (ensoniq->subsystem_vendor_id == es1371_amplifier_hack[idx].svid && + ensoniq->subsystem_device_id == es1371_amplifier_hack[idx].sdid) { + ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ + break; + } +#endif + + snd_ensoniq_chip_init(ensoniq); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { snd_ensoniq_free(ensoniq); @@ -2071,6 +2135,10 @@ snd_ensoniq_proc_init(ensoniq); +#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ + snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); +#endif + snd_card_set_dev(card, &pci->dev); *rensoniq = ensoniq; @@ -2397,6 +2465,9 @@ .id_table = snd_audiopci_ids, .probe = snd_audiopci_probe, .remove = __devexit_p(snd_audiopci_remove), +#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ + SND_PCI_PM_CALLBACKS +#endif }; static int __init alsa_card_ens137x_init(void) [-- Attachment #4: ens1370.c_CVS_rev_1.90_ens1371_suspend.patch --] [-- Type: text/x-patch, Size: 8787 bytes --] Summary: Fix missing suspend/resume-code for ens1371 This patch fixes missing suspend/resume-code for snd-ens1371 (but not for snd-ens1370) Signed-off-by: Kurt J. Bosch <kjb-temp-2005@gmx.de> --- CVS/ens1370.CVS-rev-1.90.c 2005-11-06 11:11:38.000000000 +0100 +++ CVS/ens1370.c 2005-11-14 11:21:58.000000000 +0100 @@ -19,6 +19,13 @@ * */ +/* Power-Management-Code ( CONFIG_PM ) + * for ens1371 only ( FIXME ) + * derived from cs4281.c, atiixp.c and via82xx.c + * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm + * by Kurt J. Bosch + */ + #include <sound/driver.h> #include <asm/io.h> #include <linux/delay.h> @@ -1924,6 +1931,118 @@ }; #endif +static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) +{ +#ifdef CHIP1371 + int idx; + struct pci_dev *pci = ensoniq->pci; +#endif +// this code was part of snd_ensoniq_create before intruduction of suspend/resume +#ifdef CHIP1370 + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); + outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); + outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); +#else + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(0, ES_REG(ensoniq, 1371_LEGACY)); + for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) + if (pci->vendor == es1371_ac97_reset_hack[idx].vid && + pci->device == es1371_ac97_reset_hack[idx].did && + ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { + ensoniq->cssr |= ES_1371_ST_AC97_RST; + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + /* need to delay around 20ms(bleech) to give + some CODECs enough time to wakeup */ + msleep(20); + break; + } + /* AC'97 warm reset to start the bitclk */ + outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); + inl(ES_REG(ensoniq, CONTROL)); + udelay(20); + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + /* Init the sample rate converter */ + snd_es1371_wait_src_ready(ensoniq); + outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); + for (idx = 0; idx < 0x80; idx++) + snd_es1371_src_write(ensoniq, idx, 0); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); + snd_es1371_adc_rate(ensoniq, 22050); + snd_es1371_dac1_rate(ensoniq, 22050); + snd_es1371_dac2_rate(ensoniq, 22050); + /* WARNING: + * enabling the sample rate converter without properly programming + * its parameters causes the chip to lock up (the SRC busy bit will + * be stuck high, and I've found no way to rectify this other than + * power cycle) - Thomas Sailer + */ + snd_es1371_wait_src_ready(ensoniq); + outl(0, ES_REG(ensoniq, 1371_SMPRATE)); + /* try reset codec directly */ + outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); +#endif + outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); + outb(0x00, ES_REG(ensoniq, UART_RES)); + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + synchronize_irq(ensoniq->irq); +} + +#ifdef CONFIG_PM +static int snd_ensoniq_suspend (snd_card_t * card, + pm_message_t state) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + snd_pcm_suspend_all(ensoniq->pcm1); + snd_pcm_suspend_all(ensoniq->pcm2); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_suspend(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + pci_set_power_state(ensoniq->pci, 3); + pci_disable_device(ensoniq->pci); + // snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); // only 2.6.10 + return 0; +} + +static int snd_ensoniq_resume (snd_card_t * card + ) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + pci_enable_device(ensoniq->pci); + pci_set_power_state(ensoniq->pci, 0); + pci_set_master(ensoniq->pci); + + snd_ensoniq_chip_init(ensoniq); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_resume(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + // snd_power_change_state(card, SNDRV_CTL_POWER_D0); // only 2.6.10 + return 0; +} +#endif /* CONFIG_PM */ + + static int __devinit snd_ensoniq_create(snd_card_t * card, struct pci_dev *pci, ensoniq_t ** rensoniq) @@ -1986,12 +2105,6 @@ ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); #endif ensoniq->sctrl = 0; - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); - outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); - outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); #else ensoniq->ctrl = 0; ensoniq->sctrl = 0; @@ -2002,59 +2115,9 @@ ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ break; } - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(0, ES_REG(ensoniq, 1371_LEGACY)); - for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) - if (pci->vendor == es1371_ac97_reset_hack[idx].vid && - pci->device == es1371_ac97_reset_hack[idx].did && - ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { - ensoniq->cssr |= ES_1371_ST_AC97_RST; - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - /* need to delay around 20ms(bleech) to give - some CODECs enough time to wakeup */ - msleep(20); - break; - } - /* AC'97 warm reset to start the bitclk */ - outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); - inl(ES_REG(ensoniq, CONTROL)); - udelay(20); - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - /* Init the sample rate converter */ - snd_es1371_wait_src_ready(ensoniq); - outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); - for (idx = 0; idx < 0x80; idx++) - snd_es1371_src_write(ensoniq, idx, 0); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); - snd_es1371_adc_rate(ensoniq, 22050); - snd_es1371_dac1_rate(ensoniq, 22050); - snd_es1371_dac2_rate(ensoniq, 22050); - /* WARNING: - * enabling the sample rate converter without properly programming - * its parameters causes the chip to lock up (the SRC busy bit will - * be stuck high, and I've found no way to rectify this other than - * power cycle) - Thomas Sailer - */ - snd_es1371_wait_src_ready(ensoniq); - outl(0, ES_REG(ensoniq, 1371_SMPRATE)); - /* try reset codec directly */ - outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); #endif - outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); - outb(0x00, ES_REG(ensoniq, UART_RES)); - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - synchronize_irq(ensoniq->irq); + + snd_ensoniq_chip_init(ensoniq); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { snd_ensoniq_free(ensoniq); @@ -2063,6 +2126,10 @@ snd_ensoniq_proc_init(ensoniq); +#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ + snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); +#endif + snd_card_set_dev(card, &pci->dev); *rensoniq = ensoniq; @@ -2390,6 +2457,9 @@ .id_table = snd_audiopci_ids, .probe = snd_audiopci_probe, .remove = __devexit_p(snd_audiopci_remove), +#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ + SND_PCI_PM_CALLBACKS +#endif }; static int __init alsa_card_ens137x_init(void) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Changed ens1370.c to enable Suspend ens1371 2005-11-14 12:05 ` Kurt J. Bosch @ 2005-11-14 12:25 ` Kurt J. Bosch 2005-11-14 17:02 ` Takashi Iwai 1 sibling, 0 replies; 9+ messages in thread From: Kurt J. Bosch @ 2005-11-14 12:25 UTC (permalink / raw) To: alsa-devel BTW theres a bug-report for this too: https://bugtrack.alsa-project.org/alsa-bug/view.php?id=1355 ------------------------------------------------------- SF.Net email is sponsored by: Tame your development challenges with Apache's Geronimo App Server. Download it for free - -and be entered to win a 42" plasma tv or your very own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Changed ens1370.c to enable Suspend ens1371 2005-11-14 12:05 ` Kurt J. Bosch 2005-11-14 12:25 ` Kurt J. Bosch @ 2005-11-14 17:02 ` Takashi Iwai 2005-11-16 13:03 ` Kurt J. Bosch 1 sibling, 1 reply; 9+ messages in thread From: Takashi Iwai @ 2005-11-14 17:02 UTC (permalink / raw) To: Kurt J. Bosch; +Cc: alsa-devel At Mon, 14 Nov 2005 13:05:30 +0100, Kurt J. Bosch wrote: > > Summary: Fix missing suspend/resume-code for ens1371 > > This patch fixes missing suspend/resume-code for snd-ens1371 > (but not for snd-ens1370) > > Signed-off-by: Kurt J. Bosch <kjb-temp-2005@gmx.de> > > --- 2.6.10-5-686/ens1370.org.c 2004-12-24 22:35:24.000000000 +0100 > +++ 2.6.10-5-686/ens1370.c 2005-11-14 11:36:58.000000000 +0100 > @@ -19,6 +19,14 @@ > * > */ > > +/* Power-Management-Code ( CONFIG_PM ) > + * for ens1371 only ( FIXME ) > + * derived from cs4281.c, atiixp.c and via82xx.c > + * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm > + * by Kurt J. Bosch > + */ > + > + > #include <sound/driver.h> > #include <asm/io.h> > #include <linux/delay.h> > @@ -1875,6 +1883,129 @@ > }; > #endif > > +static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) > +{ > +#ifdef CHIP1371 > + int idx; > + struct pci_dev *pci = ensoniq->pci; > +#endif > +// this code was part of snd_ensoniq_create > +#ifdef CHIP1370 > + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); > + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); > + outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); > + outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); > + outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); > +#else > + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); > + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); > + outl(0, ES_REG(ensoniq, 1371_LEGACY)); > + for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) > + if (pci->vendor == es1371_ac97_reset_hack[idx].vid && > + pci->device == es1371_ac97_reset_hack[idx].did && > + ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { > + unsigned long tmo; > + signed long tmo2; > + > + ensoniq->cssr |= ES_1371_ST_AC97_RST; ensoniq->cssr shouldn't be overridden here. > +static int snd_ensoniq_resume (snd_card_t * card, > + unsigned int state) > +{ > + ensoniq_t *ensoniq = card->pm_private_data; > + > + pci_enable_device(ensoniq->pci); > + pci_set_power_state(ensoniq->pci, 0); > + pci_set_master(ensoniq->pci); Don't mix up tab and spaces. > +#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ > + snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); > +#endif It's still better than nothing. Better to remove this ifdef. > @@ -2364,6 +2432,9 @@ > .id_table = snd_audiopci_ids, > .probe = snd_audiopci_probe, > .remove = __devexit_p(snd_audiopci_remove), > +#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ > + SND_PCI_PM_CALLBACKS > +#endif Ditto. Takashi ------------------------------------------------------- SF.Net email is sponsored by: Tame your development challenges with Apache's Geronimo App Server. Download it for free - -and be entered to win a 42" plasma tv or your very own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Changed ens1370.c to enable Suspend ens1371 2005-11-14 17:02 ` Takashi Iwai @ 2005-11-16 13:03 ` Kurt J. Bosch 2005-11-16 13:14 ` Takashi Iwai 0 siblings, 1 reply; 9+ messages in thread From: Kurt J. Bosch @ 2005-11-16 13:03 UTC (permalink / raw) To: Takashi Iwai; +Cc: alsa-devel [-- Attachment #1: Type: text/plain, Size: 2866 bytes --] Takashi Iwai schrieb: > At Mon, 14 Nov 2005 13:05:30 +0100, > Kurt J. Bosch wrote: > >>Summary: Fix missing suspend/resume-code for ens1371 >> >>This patch fixes missing suspend/resume-code for snd-ens1371 >>(but not for snd-ens1370) >> >>Signed-off-by: Kurt J. Bosch <kjb-temp-2005@gmx.de> >> >>--- 2.6.10-5-686/ens1370.org.c 2004-12-24 22:35:24.000000000 +0100 >>+++ 2.6.10-5-686/ens1370.c 2005-11-14 11:36:58.000000000 +0100 >>@@ -19,6 +19,14 @@ >> * >> */ >> >>+/* Power-Management-Code ( CONFIG_PM ) >>+ * for ens1371 only ( FIXME ) >>+ * derived from cs4281.c, atiixp.c and via82xx.c >>+ * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm >>+ * by Kurt J. Bosch >>+ */ >>+ >>+ >> #include <sound/driver.h> >> #include <asm/io.h> >> #include <linux/delay.h> >>@@ -1875,6 +1883,129 @@ >> }; >> #endif >> >>+static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) >>+{ >>+#ifdef CHIP1371 >>+ int idx; >>+ struct pci_dev *pci = ensoniq->pci; >>+#endif >>+// this code was part of snd_ensoniq_create >>+#ifdef CHIP1370 >>+ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); >>+ outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); >>+ outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); >>+ outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); >>+ outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); >>+#else >>+ outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); >>+ outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); >>+ outl(0, ES_REG(ensoniq, 1371_LEGACY)); >>+ for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) >>+ if (pci->vendor == es1371_ac97_reset_hack[idx].vid && >>+ pci->device == es1371_ac97_reset_hack[idx].did && >>+ ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { >>+ unsigned long tmo; >>+ signed long tmo2; >>+ >>+ ensoniq->cssr |= ES_1371_ST_AC97_RST; > > > > ensoniq->cssr shouldn't be overridden here. > > >>+static int snd_ensoniq_resume (snd_card_t * card, >>+ unsigned int state) >>+{ >>+ ensoniq_t *ensoniq = card->pm_private_data; >>+ >>+ pci_enable_device(ensoniq->pci); >>+ pci_set_power_state(ensoniq->pci, 0); >>+ pci_set_master(ensoniq->pci); > > > Don't mix up tab and spaces. > > >>+#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ >>+ snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); >>+#endif > > > It's still better than nothing. Better to remove this ifdef. > > > >>@@ -2364,6 +2432,9 @@ >> .id_table = snd_audiopci_ids, >> .probe = snd_audiopci_probe, >> .remove = __devexit_p(snd_audiopci_remove), >>+#ifdef CHIP1371 /* FIXME - this should apply to 1370 too as soon as 1370-suspend-code is written by some one :) */ >>+ SND_PCI_PM_CALLBACKS >>+#endif > > > Ditto. > > OK - fixed that too [-- Attachment #2: ens1370.c_2.6.10_ens1371_suspend.patch --] [-- Type: text/x-patch, Size: 9045 bytes --] Summary: Fix missing suspend/resume-code for ens1371 This patch fixes missing suspend/resume-code for snd-ens1371 (but not for snd-ens1370) Signed-off-by: Kurt J. Bosch <kjb-temp-2005@gmx.de> --- 2.6.10-5-686/ens1370.org.c 2004-12-24 22:35:24.000000000 +0100 +++ 2.6.10-5-686/ens1370.c 2005-11-16 12:05:36.000000000 +0100 @@ -19,6 +19,14 @@ * */ +/* Power-Management-Code ( CONFIG_PM ) + * for ens1371 only ( FIXME ) + * derived from cs4281.c, atiixp.c and via82xx.c + * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm + * by Kurt J. Bosch + */ + + #include <sound/driver.h> #include <asm/io.h> #include <linux/delay.h> @@ -1875,6 +1883,128 @@ }; #endif +static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) +{ +#ifdef CHIP1371 + int idx; + struct pci_dev *pci = ensoniq->pci; +#endif +// this code was part of snd_ensoniq_create before introduction of suspend/resume +#ifdef CHIP1370 + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); + outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); + outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); +#else + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(0, ES_REG(ensoniq, 1371_LEGACY)); + for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) + if (pci->vendor == es1371_ac97_reset_hack[idx].vid && + pci->device == es1371_ac97_reset_hack[idx].did && + ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { + unsigned long tmo; + signed long tmo2; + + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + /* need to delay around 20ms(bleech) to give + some CODECs enough time to wakeup */ + tmo = jiffies + (HZ / 50) + 1; + while (1) { + tmo2 = tmo - jiffies; + if (tmo2 <= 0) + break; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(tmo2); + } + break; + } + /* AC'97 warm reset to start the bitclk */ + outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); + inl(ES_REG(ensoniq, CONTROL)); + udelay(20); + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + /* Init the sample rate converter */ + snd_es1371_wait_src_ready(ensoniq); + outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); + for (idx = 0; idx < 0x80; idx++) + snd_es1371_src_write(ensoniq, idx, 0); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); + snd_es1371_adc_rate(ensoniq, 22050); + snd_es1371_dac1_rate(ensoniq, 22050); + snd_es1371_dac2_rate(ensoniq, 22050); + /* WARNING: + * enabling the sample rate converter without properly programming + * its parameters causes the chip to lock up (the SRC busy bit will + * be stuck high, and I've found no way to rectify this other than + * power cycle) - Thomas Sailer + */ + snd_es1371_wait_src_ready(ensoniq); + outl(0, ES_REG(ensoniq, 1371_SMPRATE)); + /* try reset codec directly */ + outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); +#endif + outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); + outb(0x00, ES_REG(ensoniq, UART_RES)); + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + + synchronize_irq(ensoniq->irq); +} + +#ifdef CONFIG_PM +static int snd_ensoniq_suspend (snd_card_t * card, + unsigned int state) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + snd_pcm_suspend_all(ensoniq->pcm1); + snd_pcm_suspend_all(ensoniq->pcm2); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_suspend(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + pci_set_power_state(ensoniq->pci, 3); + pci_disable_device(ensoniq->pci); + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + return 0; +} + +static int snd_ensoniq_resume (snd_card_t * card, + unsigned int state) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + pci_enable_device(ensoniq->pci); + pci_set_power_state(ensoniq->pci, 0); + pci_set_master(ensoniq->pci); + + snd_ensoniq_chip_init(ensoniq); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_resume(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif /* CONFIG_PM */ + + static int __devinit snd_ensoniq_create(snd_card_t * card, struct pci_dev *pci, ensoniq_t ** rensoniq) @@ -1938,12 +2068,6 @@ ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); #endif ensoniq->sctrl = 0; - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); - outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); - outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); #else ensoniq->ctrl = 0; ensoniq->sctrl = 0; @@ -1954,74 +2078,22 @@ ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ break; } - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(0, ES_REG(ensoniq, 1371_LEGACY)); for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) if (pci->vendor == es1371_ac97_reset_hack[idx].vid && pci->device == es1371_ac97_reset_hack[idx].did && ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { - unsigned long tmo; - signed long tmo2; - ensoniq->cssr |= ES_1371_ST_AC97_RST; - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - /* need to delay around 20ms(bleech) to give - some CODECs enough time to wakeup */ - tmo = jiffies + (HZ / 50) + 1; - while (1) { - tmo2 = tmo - jiffies; - if (tmo2 <= 0) - break; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(tmo2); - } break; } - /* AC'97 warm reset to start the bitclk */ - outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); - inl(ES_REG(ensoniq, CONTROL)); - udelay(20); - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - /* Init the sample rate converter */ - snd_es1371_wait_src_ready(ensoniq); - outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); - for (idx = 0; idx < 0x80; idx++) - snd_es1371_src_write(ensoniq, idx, 0); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); - snd_es1371_adc_rate(ensoniq, 22050); - snd_es1371_dac1_rate(ensoniq, 22050); - snd_es1371_dac2_rate(ensoniq, 22050); - /* WARNING: - * enabling the sample rate converter without properly programming - * its parameters causes the chip to lock up (the SRC busy bit will - * be stuck high, and I've found no way to rectify this other than - * power cycle) - Thomas Sailer - */ - snd_es1371_wait_src_ready(ensoniq); - outl(0, ES_REG(ensoniq, 1371_SMPRATE)); - /* try reset codec directly */ - outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); #endif - outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); - outb(0x00, ES_REG(ensoniq, UART_RES)); - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - synchronize_irq(ensoniq->irq); + + snd_ensoniq_chip_init(ensoniq); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { snd_ensoniq_free(ensoniq); return err; } + snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); snd_card_set_dev(card, &pci->dev); @@ -2342,7 +2414,7 @@ card->driver, ensoniq->port, ensoniq->irq); - + if ((err = snd_card_register(card)) < 0) { snd_card_free(card); return err; @@ -2364,6 +2436,7 @@ .id_table = snd_audiopci_ids, .probe = snd_audiopci_probe, .remove = __devexit_p(snd_audiopci_remove), + SND_PCI_PM_CALLBACKS }; static int __init alsa_card_ens137x_init(void) [-- Attachment #3: ens1370.c_2.6.12_ens1371_suspend.patch --] [-- Type: text/x-patch, Size: 8958 bytes --] Summary: Fix missing suspend/resume-code for ens1371 This patch fixes missing suspend/resume-code for snd-ens1371 (but not for snd-ens1370) Signed-off-by: Kurt J. Bosch <kjb-temp-2005@gmx.de> --- 2.6.12-9-686/ens1370.org.c 2005-10-10 14:12:34.000000000 +0200 +++ 2.6.12-9-686/ens1370.c 2005-11-16 12:04:04.000000000 +0100 @@ -19,6 +19,13 @@ * */ +/* Power-Management-Code ( CONFIG_PM ) + * for ens1371 only ( FIXME ) + * derived from cs4281.c, atiixp.c and via82xx.c + * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm + * by Kurt J. Bosch + */ + #include <sound/driver.h> #include <asm/io.h> #include <linux/delay.h> @@ -1922,6 +1929,128 @@ }; #endif +static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) +{ +#ifdef CHIP1371 + int idx; + struct pci_dev *pci = ensoniq->pci; +#endif +// this code was part of snd_ensoniq_create before introduction of suspend/resume +#ifdef CHIP1370 + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); + outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); + outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); +#else + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(0, ES_REG(ensoniq, 1371_LEGACY)); + for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) + if (pci->vendor == es1371_ac97_reset_hack[idx].vid && + pci->device == es1371_ac97_reset_hack[idx].did && + ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { + unsigned long tmo; + signed long tmo2; + + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + /* need to delay around 20ms(bleech) to give + some CODECs enough time to wakeup */ + tmo = jiffies + (HZ / 50) + 1; + while (1) { + tmo2 = tmo - jiffies; + if (tmo2 <= 0) + break; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(tmo2); + } + break; + } + /* AC'97 warm reset to start the bitclk */ + outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); + inl(ES_REG(ensoniq, CONTROL)); + udelay(20); + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + /* Init the sample rate converter */ + snd_es1371_wait_src_ready(ensoniq); + outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); + for (idx = 0; idx < 0x80; idx++) + snd_es1371_src_write(ensoniq, idx, 0); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); + snd_es1371_adc_rate(ensoniq, 22050); + snd_es1371_dac1_rate(ensoniq, 22050); + snd_es1371_dac2_rate(ensoniq, 22050); + /* WARNING: + * enabling the sample rate converter without properly programming + * its parameters causes the chip to lock up (the SRC busy bit will + * be stuck high, and I've found no way to rectify this other than + * power cycle) - Thomas Sailer + */ + snd_es1371_wait_src_ready(ensoniq); + outl(0, ES_REG(ensoniq, 1371_SMPRATE)); + /* try reset codec directly */ + outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); +#endif + outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); + outb(0x00, ES_REG(ensoniq, UART_RES)); + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + + synchronize_irq(ensoniq->irq); +} + +#ifdef CONFIG_PM +static int snd_ensoniq_suspend (snd_card_t * card, + pm_message_t state) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + snd_pcm_suspend_all(ensoniq->pcm1); + snd_pcm_suspend_all(ensoniq->pcm2); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_suspend(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + pci_set_power_state(ensoniq->pci, 3); + pci_disable_device(ensoniq->pci); + // snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); // only 2.6.10 + return 0; +} + +static int snd_ensoniq_resume (snd_card_t * card + ) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + pci_enable_device(ensoniq->pci); + pci_set_power_state(ensoniq->pci, 0); + pci_set_master(ensoniq->pci); + + snd_ensoniq_chip_init(ensoniq); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_resume(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + // snd_power_change_state(card, SNDRV_CTL_POWER_D0); // only 2.6.10 + return 0; +} +#endif /* CONFIG_PM */ + + static int __devinit snd_ensoniq_create(snd_card_t * card, struct pci_dev *pci, ensoniq_t ** rensoniq) @@ -1984,12 +2113,6 @@ ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); #endif ensoniq->sctrl = 0; - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); - outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); - outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); #else ensoniq->ctrl = 0; ensoniq->sctrl = 0; @@ -2000,69 +2123,16 @@ ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ break; } - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(0, ES_REG(ensoniq, 1371_LEGACY)); for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) if (pci->vendor == es1371_ac97_reset_hack[idx].vid && pci->device == es1371_ac97_reset_hack[idx].did && ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { - unsigned long tmo; - signed long tmo2; - ensoniq->cssr |= ES_1371_ST_AC97_RST; - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - /* need to delay around 20ms(bleech) to give - some CODECs enough time to wakeup */ - tmo = jiffies + (HZ / 50) + 1; - while (1) { - tmo2 = tmo - jiffies; - if (tmo2 <= 0) - break; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(tmo2); - } break; } - /* AC'97 warm reset to start the bitclk */ - outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); - inl(ES_REG(ensoniq, CONTROL)); - udelay(20); - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - /* Init the sample rate converter */ - snd_es1371_wait_src_ready(ensoniq); - outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); - for (idx = 0; idx < 0x80; idx++) - snd_es1371_src_write(ensoniq, idx, 0); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); - snd_es1371_adc_rate(ensoniq, 22050); - snd_es1371_dac1_rate(ensoniq, 22050); - snd_es1371_dac2_rate(ensoniq, 22050); - /* WARNING: - * enabling the sample rate converter without properly programming - * its parameters causes the chip to lock up (the SRC busy bit will - * be stuck high, and I've found no way to rectify this other than - * power cycle) - Thomas Sailer - */ - snd_es1371_wait_src_ready(ensoniq); - outl(0, ES_REG(ensoniq, 1371_SMPRATE)); - /* try reset codec directly */ - outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); #endif - outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); - outb(0x00, ES_REG(ensoniq, UART_RES)); - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - synchronize_irq(ensoniq->irq); + + snd_ensoniq_chip_init(ensoniq); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { snd_ensoniq_free(ensoniq); @@ -2071,6 +2141,8 @@ snd_ensoniq_proc_init(ensoniq); + snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); + snd_card_set_dev(card, &pci->dev); *rensoniq = ensoniq; @@ -2397,6 +2469,7 @@ .id_table = snd_audiopci_ids, .probe = snd_audiopci_probe, .remove = __devexit_p(snd_audiopci_remove), + SND_PCI_PM_CALLBACKS }; static int __init alsa_card_ens137x_init(void) [-- Attachment #4: ens1370.c_CVS_rev_1.90_ens1371_suspend.patch --] [-- Type: text/x-patch, Size: 8505 bytes --] Summary: Fix missing suspend/resume-code for ens1371 This patch fixes missing suspend/resume-code for snd-ens1371 (but not for snd-ens1370) Signed-off-by: Kurt J. Bosch <kjb-temp-2005@gmx.de> --- Alsa_CVS_rev_1.90/ens1370.org.c 2005-11-06 11:11:38.000000000 +0100 +++ Alsa_CVS_rev_1.90/ens1370.c 2005-11-16 12:06:08.000000000 +0100 @@ -19,6 +19,13 @@ * */ +/* Power-Management-Code ( CONFIG_PM ) + * for ens1371 only ( FIXME ) + * derived from cs4281.c, atiixp.c and via82xx.c + * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm + * by Kurt J. Bosch + */ + #include <sound/driver.h> #include <asm/io.h> #include <linux/delay.h> @@ -1924,6 +1931,117 @@ }; #endif +static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) +{ +#ifdef CHIP1371 + int idx; + struct pci_dev *pci = ensoniq->pci; +#endif +// this code was part of snd_ensoniq_create before intruduction of suspend/resume +#ifdef CHIP1370 + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); + outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); + outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); +#else + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); + outl(0, ES_REG(ensoniq, 1371_LEGACY)); + for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) + if (pci->vendor == es1371_ac97_reset_hack[idx].vid && + pci->device == es1371_ac97_reset_hack[idx].did && + ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + /* need to delay around 20ms(bleech) to give + some CODECs enough time to wakeup */ + msleep(20); + break; + } + /* AC'97 warm reset to start the bitclk */ + outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); + inl(ES_REG(ensoniq, CONTROL)); + udelay(20); + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + /* Init the sample rate converter */ + snd_es1371_wait_src_ready(ensoniq); + outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); + for (idx = 0; idx < 0x80; idx++) + snd_es1371_src_write(ensoniq, idx, 0); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); + snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); + snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); + snd_es1371_adc_rate(ensoniq, 22050); + snd_es1371_dac1_rate(ensoniq, 22050); + snd_es1371_dac2_rate(ensoniq, 22050); + /* WARNING: + * enabling the sample rate converter without properly programming + * its parameters causes the chip to lock up (the SRC busy bit will + * be stuck high, and I've found no way to rectify this other than + * power cycle) - Thomas Sailer + */ + snd_es1371_wait_src_ready(ensoniq); + outl(0, ES_REG(ensoniq, 1371_SMPRATE)); + /* try reset codec directly */ + outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); +#endif + outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); + outb(0x00, ES_REG(ensoniq, UART_RES)); + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + synchronize_irq(ensoniq->irq); +} + +#ifdef CONFIG_PM +static int snd_ensoniq_suspend (snd_card_t * card, + pm_message_t state) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + snd_pcm_suspend_all(ensoniq->pcm1); + snd_pcm_suspend_all(ensoniq->pcm2); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_suspend(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + pci_set_power_state(ensoniq->pci, 3); + pci_disable_device(ensoniq->pci); + // snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); // only 2.6.10 + return 0; +} + +static int snd_ensoniq_resume (snd_card_t * card + ) +{ + ensoniq_t *ensoniq = card->pm_private_data; + + pci_enable_device(ensoniq->pci); + pci_set_power_state(ensoniq->pci, 0); + pci_set_master(ensoniq->pci); + + snd_ensoniq_chip_init(ensoniq); + +#ifdef CHIP1371 + if (ensoniq->u.es1371.ac97) + snd_ac97_resume(ensoniq->u.es1371.ac97); +#else + /* FIXME */ +#endif + // snd_power_change_state(card, SNDRV_CTL_POWER_D0); // only 2.6.10 + return 0; +} +#endif /* CONFIG_PM */ + + static int __devinit snd_ensoniq_create(snd_card_t * card, struct pci_dev *pci, ensoniq_t ** rensoniq) @@ -1986,12 +2104,6 @@ ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); #endif ensoniq->sctrl = 0; - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); - outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); - outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); #else ensoniq->ctrl = 0; ensoniq->sctrl = 0; @@ -2002,59 +2114,16 @@ ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ break; } - /* initialize the chips */ - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); - outl(0, ES_REG(ensoniq, 1371_LEGACY)); for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) if (pci->vendor == es1371_ac97_reset_hack[idx].vid && pci->device == es1371_ac97_reset_hack[idx].did && ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { ensoniq->cssr |= ES_1371_ST_AC97_RST; - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - /* need to delay around 20ms(bleech) to give - some CODECs enough time to wakeup */ - msleep(20); break; } - /* AC'97 warm reset to start the bitclk */ - outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); - inl(ES_REG(ensoniq, CONTROL)); - udelay(20); - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - /* Init the sample rate converter */ - snd_es1371_wait_src_ready(ensoniq); - outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); - for (idx = 0; idx < 0x80; idx++) - snd_es1371_src_write(ensoniq, idx, 0); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); - snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); - snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); - snd_es1371_adc_rate(ensoniq, 22050); - snd_es1371_dac1_rate(ensoniq, 22050); - snd_es1371_dac2_rate(ensoniq, 22050); - /* WARNING: - * enabling the sample rate converter without properly programming - * its parameters causes the chip to lock up (the SRC busy bit will - * be stuck high, and I've found no way to rectify this other than - * power cycle) - Thomas Sailer - */ - snd_es1371_wait_src_ready(ensoniq); - outl(0, ES_REG(ensoniq, 1371_SMPRATE)); - /* try reset codec directly */ - outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); #endif - outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); - outb(0x00, ES_REG(ensoniq, UART_RES)); - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - synchronize_irq(ensoniq->irq); + + snd_ensoniq_chip_init(ensoniq); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { snd_ensoniq_free(ensoniq); @@ -2063,6 +2132,8 @@ snd_ensoniq_proc_init(ensoniq); + snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); + snd_card_set_dev(card, &pci->dev); *rensoniq = ensoniq; @@ -2390,6 +2461,7 @@ .id_table = snd_audiopci_ids, .probe = snd_audiopci_probe, .remove = __devexit_p(snd_audiopci_remove), + SND_PCI_PM_CALLBACKS }; static int __init alsa_card_ens137x_init(void) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Changed ens1370.c to enable Suspend ens1371 2005-11-16 13:03 ` Kurt J. Bosch @ 2005-11-16 13:14 ` Takashi Iwai 2005-11-16 15:04 ` Thierry Vignaud 0 siblings, 1 reply; 9+ messages in thread From: Takashi Iwai @ 2005-11-16 13:14 UTC (permalink / raw) To: Kurt J. Bosch; +Cc: alsa-devel At Wed, 16 Nov 2005 14:03:56 +0100, Kurt J. Bosch wrote: > > OK - fixed that too Thanks. I'll apply it after 1.0.10-final is released. I also have a PM code for ak4531, so ens1370 should work, too. It'll be merged together. Takashi ------------------------------------------------------- This SF.Net email is sponsored by the JBoss Inc. Get Certified Today Register for a JBoss Training Course. Free Certification Exam for All Training Attendees Through End of 2005. For more info visit: http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Changed ens1370.c to enable Suspend ens1371 2005-11-16 13:14 ` Takashi Iwai @ 2005-11-16 15:04 ` Thierry Vignaud 2005-11-16 15:16 ` Jaroslav Kysela 0 siblings, 1 reply; 9+ messages in thread From: Thierry Vignaud @ 2005-11-16 15:04 UTC (permalink / raw) To: Takashi Iwai; +Cc: alsa-devel Takashi Iwai <tiwai@suse.de> writes: > Thanks. I'll apply it after 1.0.10-final is released. btw, CVS is tagged so when will it be released? ------------------------------------------------------- This SF.Net email is sponsored by the JBoss Inc. Get Certified Today Register for a JBoss Training Course. Free Certification Exam for All Training Attendees Through End of 2005. For more info visit: http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Changed ens1370.c to enable Suspend ens1371 2005-11-16 15:04 ` Thierry Vignaud @ 2005-11-16 15:16 ` Jaroslav Kysela 0 siblings, 0 replies; 9+ messages in thread From: Jaroslav Kysela @ 2005-11-16 15:16 UTC (permalink / raw) To: Thierry Vignaud; +Cc: Takashi Iwai, alsa-devel On Wed, 16 Nov 2005, Thierry Vignaud wrote: > Takashi Iwai <tiwai@suse.de> writes: > > > Thanks. I'll apply it after 1.0.10-final is released. > > btw, CVS is tagged so when will it be released? In a few hours. The packages are building now, so after testing from the ALSA team, the 1.0.10-final will be out. Jaroslav ----- Jaroslav Kysela <perex@suse.cz> Linux Kernel Sound Maintainer ALSA Project, SUSE Labs ------------------------------------------------------- This SF.Net email is sponsored by the JBoss Inc. Get Certified Today Register for a JBoss Training Course. Free Certification Exam for All Training Attendees Through End of 2005. For more info visit: http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-11-16 15:16 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-11-11 17:58 Changed ens1370.c to enable Suspend ens1371 Kurt J. Bosch 2005-11-11 18:06 ` Takashi Iwai 2005-11-14 12:05 ` Kurt J. Bosch 2005-11-14 12:25 ` Kurt J. Bosch 2005-11-14 17:02 ` Takashi Iwai 2005-11-16 13:03 ` Kurt J. Bosch 2005-11-16 13:14 ` Takashi Iwai 2005-11-16 15:04 ` Thierry Vignaud 2005-11-16 15:16 ` Jaroslav Kysela
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.