Linux Sound subsystem development
 help / color / mirror / Atom feed
* [RFT] PM patch to sb driver
@ 2000-06-21 17:59 Aki M Laukkanen
  0 siblings, 0 replies; only message in thread
From: Aki M Laukkanen @ 2000-06-21 17:59 UTC (permalink / raw)
  To: linux-sound


Hello, this is an experimental patch to add pm support to the soundblaster
driver. Contrary to what I earlier said I couldn't test it myself because
sound worked with the sb driver just fine after suspend (On a Toshiba 220CS). 
I happened to test it only after making this patch so now I need testers who 
have troubles with suspend and the sb driver.


diff -urN --exclude=*.flc linux-2.4.0-test1-ac22/drivers/sound/sb.h linux-2.4.0-test1-ac22.sb/drivers/sound/sb.h
--- linux-2.4.0-test1-ac22/drivers/sound/sb.h	Sun Apr 16 19:33:22 2000
+++ linux-2.4.0-test1-ac22.sb/drivers/sound/sb.h	Wed Jun 21 01:57:06 2000
@@ -1,3 +1,5 @@
+#include <linux/pm.h>
+
 #define DSP_RESET	(devc->base + 0x6)
 #define DSP_READ	(devc->base + 0xA)
 #define DSP_WRITE	(devc->base + 0xC)
@@ -138,7 +140,9 @@
            void *midi_irq_cookie;		/* IRQ cookie for the midi */
 
            struct sb_module_options sbmo;	/* Module options */
-
+       
+	/* Power management */
+	   struct pm_dev *pmdev;
         } sb_devc;
         
 /*
@@ -160,18 +164,16 @@
 int sb_dsp_detect (struct address_info *hw_config, int pci, int pciio, struct sb_module_options *sbmo);
 int sb_dsp_init (struct address_info *hw_config);
 void sb_dsp_unload(struct address_info *hw_config, int sbmpu);
-int sb_mixer_init(sb_devc *devc);
-void sb_mixer_unload(sb_devc *devc);
-void sb_mixer_set_stereo (sb_devc *devc, int mode);
-void smw_mixer_init(sb_devc *devc);
 void sb_dsp_midi_init (sb_devc *devc);
 void sb_audio_init (sb_devc *devc, char *name);
 void sb_midi_interrupt (sb_devc *devc);
 void sb_chgmixer (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val);
 int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right);
 
+
 int sb_audio_open(int dev, int mode);
 void sb_audio_close(int dev);
+int sb_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data);
 
 extern sb_devc *last_sb;
 
@@ -184,3 +186,11 @@
 
 void unload_sb16(struct address_info *hw_info);
 void unload_sb16midi(struct address_info *hw_info);
+
+/*	From sb_mixer.c */
+int sb_mixer_set(sb_devc *devc, int dev, int value);
+int sb_set_recmask(sb_devc *devc, int mask);
+int sb_mixer_init(sb_devc *devc);
+void sb_mixer_unload(sb_devc *devc);
+void sb_mixer_set_stereo (sb_devc *devc, int mode);
+void smw_mixer_init(sb_devc *devc);
diff -urN --exclude=*.flc linux-2.4.0-test1-ac22/drivers/sound/sb_audio.c linux-2.4.0-test1-ac22.sb/drivers/sound/sb_audio.c
--- linux-2.4.0-test1-ac22/drivers/sound/sb_audio.c	Mon Feb 28 17:18:20 2000
+++ linux-2.4.0-test1-ac22.sb/drivers/sound/sb_audio.c	Wed Jun 21 01:57:38 2000
@@ -1122,4 +1122,10 @@
         }
         audio_devs[devc->dev]->mixer_dev = devc->my_mixerdev;
         audio_devs[devc->dev]->min_fragment = 5;
+
+	/* FIXME: PM_PCI_ID() needed but no access to pcidev */
+	devc->pmdev = pm_register(devc->caps&SB_PCI_IRQ?PM_PCI_DEV:PM_ISA_DEV, 
+				  devc->dev, sb_pm_callback);
+	if (devc->pmdev)
+		devc->pmdev->data = devc;
 }
diff -urN --exclude=*.flc linux-2.4.0-test1-ac22/drivers/sound/sb_card.c linux-2.4.0-test1-ac22.sb/drivers/sound/sb_card.c
--- linux-2.4.0-test1-ac22/drivers/sound/sb_card.c	Wed Jun 21 00:03:52 2000
+++ linux-2.4.0-test1-ac22.sb/drivers/sound/sb_card.c	Wed Jun 21 20:11:48 2000
@@ -45,6 +45,8 @@
  * 25-05-2000 Added Creative SB AWE64 Gold (CTL00B2). 
  * 	Pål-Kristian Engstad <engstad@att.net>
  * 
+ * 21-06-2000 Power Management support. 
+ *	Aki Laukkanen <amlaukka@cs.helsinki.fi>
  */
 
 #include <linux/config.h>
@@ -489,6 +491,7 @@
         }
         return(dev);
 }
+
 
 static struct pci_dev *sb_init(struct pci_bus *bus, struct address_info *hw_config, struct address_info *mpu_config, int slot, int card)
 {
diff -urN --exclude=*.flc linux-2.4.0-test1-ac22/drivers/sound/sb_common.c linux-2.4.0-test1-ac22.sb/drivers/sound/sb_common.c
--- linux-2.4.0-test1-ac22/drivers/sound/sb_common.c	Sat Apr 29 14:27:55 2000
+++ linux-2.4.0-test1-ac22.sb/drivers/sound/sb_common.c	Wed Jun 21 20:14:23 2000
@@ -891,6 +891,9 @@
 
         if (devc && devc->base = hw_config->io_base)
         {
+		if (devc->pmdev)
+			pm_unregister(devc->pmdev);
+
                 if ((devc->model & MDL_ESS) && devc->pcibase)
                         release_region(devc->pcibase, 8);
 
@@ -915,6 +918,7 @@
                                 sound_unload_mididev(devc->my_mididev);
                         sound_unload_audiodev(devc->dev);
                 }
+
                 kfree(devc);
         }
         else
@@ -1291,6 +1295,65 @@
 #endif
         unload_uart401(hw_config);
 }
+
+static int sb_suspend(sb_devc *devc)
+{
+	return 0;
+}
+
+static int sb_resume(sb_devc *devc)
+{
+	int mixer_levels[SOUND_MIXER_NRDEVICES], i;
+
+	/* store old mixer levels */
+	memcpy(mixer_levels, devc->levels, sizeof (mixer_levels));
+
+	/* FIXME: can not test this */
+#if 0
+	if (!((devc->caps & SB_NO_AUDIO) && (devc->caps & SB_NO_MIDI)) && hw_config->irq > 0) {
+		/* rewrite incase was forgotten */
+		if (devc->major = 4) {
+			sb16_set_irq_hw(devc, devc->irq);
+			sb16_set_dma_hw(devc, devc);
+		}
+	}
+#endif
+
+	if (!sb_dsp_reset(devc)) {
+		DDB(printk("SB reset failed\n"));
+#ifdef MODULE
+		printk(KERN_INFO "sb: dsp reset failed.\n");
+#endif
+		return 0;
+	}
+
+	/* restore mixer settings */
+	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+		sb_mixer_set(devc, i, mixer_levels[i]);
+
+	if (devc->model != MDL_ESS || !ess_mixer_reset (devc))
+		sb_set_recmask(devc, SOUND_MASK_MIC);
+	return 0;
+}
+
+
+int sb_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+	sb_devc *devc = dev->data;
+	if (devc) {
+		DEB(printk(KERN_DEBUG "sb: dev %p pm_event: %d\n", devc, rqst));
+		switch (rqst) {
+		case PM_SUSPEND:
+			sb_suspend(devc);
+			break;
+		case PM_RESUME:
+			sb_resume(devc);
+			break;
+		}
+	}
+	return 0;
+}
+
 
 EXPORT_SYMBOL(sb_dsp_init);
 EXPORT_SYMBOL(sb_dsp_detect);
diff -urN --exclude=*.flc linux-2.4.0-test1-ac22/drivers/sound/sb_mixer.c linux-2.4.0-test1-ac22.sb/drivers/sound/sb_mixer.c
--- linux-2.4.0-test1-ac22/drivers/sound/sb_mixer.c	Sun Apr 16 19:33:22 2000
+++ linux-2.4.0-test1-ac22.sb/drivers/sound/sb_mixer.c	Wed Jun 21 01:36:30 2000
@@ -344,7 +344,7 @@
         return left | (right << 8);
 }
 
-static int sb_mixer_set(sb_devc * devc, int dev, int value)
+int sb_mixer_set(sb_devc * devc, int dev, int value)
 {
         int left = value & 0x000000ff;
         int right = (value & 0x0000ff00) >> 8;
@@ -387,7 +387,7 @@
         sb_setmixer(devc, RECORD_SRC, (sb_getmixer(devc, RECORD_SRC) & ~7) | (src & 0x7));
 }
 
-static int set_recmask(sb_devc * devc, int mask)
+int sb_set_recmask(sb_devc * devc, int mask)
 {
         int devmask, i;
         unsigned char  regimageL, regimageR;
@@ -569,7 +569,7 @@
                         switch (cmd & 0xff) 
                         {
                                 case SOUND_MIXER_RECSRC:
-					ret = set_recmask(devc, val);
+					ret = sb_set_recmask(devc, val);
                                         break;
 
                                 case SOUND_MIXER_OUTSRC:
@@ -654,7 +654,7 @@
                 sb_mixer_set(devc, i, devc->levels[i]);
 
         if (devc->model != MDL_ESS || !ess_mixer_reset (devc)) {
-		set_recmask(devc, SOUND_MASK_MIC);
+		sb_set_recmask(devc, SOUND_MASK_MIC);
         };
 }
 



-- 
D.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2000-06-21 17:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-06-21 17:59 [RFT] PM patch to sb driver Aki M Laukkanen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox