All of lore.kernel.org
 help / color / mirror / Atom feed
* 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

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.