* 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.