Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Aki M Laukkanen <amlaukka@cc.helsinki.fi>
To: linux-sound@vger.kernel.org
Subject: [RFT/PATCH] Re: Sound problem after suspend.  Kernel version
Date: Tue, 28 Mar 2000 12:45:02 +0000	[thread overview]
Message-ID: <marc-linux-sound-95424773409649@msgid-missing> (raw)

[-- Attachment #1: Type: TEXT/PLAIN, Size: 769 bytes --]

On Mon, 27 Mar 2000, HvR wrote:
> the gpm killing is really necessary without this the
> sound module will not unload!!!

Really? That seems odd.

> > With kernel version 2.3.99-pre3 sound words until I
> > suspend my Toshiba
> > Satellite Pro 445CDX, but after resuming it will
> > produce no sound.
> > This problem came in with the sound clean-ups after
> > version 2.3.49.  

I have a Toshiba Satellite 220CS laptop which has a OPL3-SA1 sound
chip. However I've never gotten the opl3sa1 driver to recognise it as such
so I've used the bare ad1848 (MS Sound System) driver instead. Unlike in
the case above I've never had working sound after suspend.

This is an experimental patch which fixes the suspend problem for me and
I'd appreciate if people would test it.


[-- Attachment #2: Type: TEXT/PLAIN, Size: 5846 bytes --]

--- linux/drivers/sound/ad1848.c.bak	Mon Mar 20 23:56:41 2000
+++ linux/drivers/sound/ad1848.c	Tue Mar 21 10:09:04 2000
@@ -27,6 +27,7 @@
  * Alan Cox		: reformatted. Fixed SMP bugs. Moved to kernel alloc/free
  *		          of irqs. Use dev_id.
  * Christoph Hellwig	: adapted to module_init/module_exit
+ * Aki Laukkanen	: added power management support
  *
  * Status:
  *		Tested. Believed fully functional.
@@ -36,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/stddef.h>
+#include <linux/pm.h>
 
 #include "soundmodule.h"
 
@@ -52,6 +54,7 @@
 	int             irq;
 	int             dma1, dma2;
 	int             dual_dma;	/* 1, when two DMA channels allocated */
+	int 		subtype;
 	unsigned char   MCE_bit;
 	unsigned char   saved_regs[32];
 	int             debug_flag;
@@ -87,6 +90,9 @@
 	int             irq_ok;
 	mixer_ents     *mix_devices;
 	int             mixer_output_port;
+
+	/* Power management */
+	struct		pm_dev *pmdev;
 } ad1848_info;
 
 typedef struct ad1848_port_info
@@ -100,7 +106,9 @@
 }
 ad1848_port_info;
 
+static struct address_info cfg;
 static int nr_ad1848_devs = 0;
+
 int deskpro_xl = 0;
 int deskpro_m = 0;
 int soundpro = 0;
@@ -163,11 +171,11 @@
 static void     ad1848_halt_input(int dev);
 static void     ad1848_halt_output(int dev);
 static void     ad1848_trigger(int dev, int bits);
+static int	ad1848_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data);
 
 #ifndef EXCLUDE_TIMERS
 static int ad1848_tmr_install(int dev);
 static void ad1848_tmr_reprogram(int dev);
-
 #endif
 
 static int ad_read(ad1848_info * devc, int reg)
@@ -1415,7 +1423,7 @@
 		if (devc->model == MD_IWAVE)
 			ad_write(devc, 12, 0x6c);	/* Select codec mode 3 */
 
-		if (devc-> model != MD_1845_SSCAPE)
+		if (devc->model != MD_1845_SSCAPE)
 			for (i = 16; i < 32; i++)
 				ad_write(devc, i, init_values[i]);
 
@@ -1849,7 +1857,6 @@
 	 *   The actually used IRQ is ABS(irq).
 	 */
 
-
 	int my_dev;
 	char dev_name[100];
 	int e;
@@ -1863,6 +1870,7 @@
 	devc->timer_ticks = 0;
 	devc->dma1 = dma_playback;
 	devc->dma2 = dma_capture;
+	devc->subtype = cfg.card_subtype;
 	devc->audio_flags = DMA_AUTOMODE;
 	devc->playback_dev = devc->record_dev = 0;
 	if (name != NULL)
@@ -1915,6 +1923,10 @@
 
 	nr_ad1848_devs++;
 
+	devc->pmdev = pm_register(PM_ISA_DEV, my_dev, ad1848_pm_callback);
+	if (devc->pmdev)
+		devc->pmdev->data = devc;
+
 	ad1848_init_hw(devc);
 
 	if (irq > 0)
@@ -1950,7 +1962,7 @@
 				devc->irq_ok = 1;
 			}
 #else
-			devc->irq_ok=1;
+			devc->irq_ok = 1;
 #endif			
 		}
 		else
@@ -2076,6 +2088,9 @@
 		if(mixer>=0)
 			sound_unload_mixerdev(mixer);
 
+		if (devc->pmdev)
+			pm_unregister(devc->pmdev);
+
 		nr_ad1848_devs--;
 		for ( ; i < nr_ad1848_devs ; i++)
 			adev_info[i] = adev_info[i+1];
@@ -2507,7 +2522,8 @@
 		hw_config->slots[0] = ad1848_init("MS Sound System", hw_config->io_base + 4,
 						    hw_config->irq,
 						    hw_config->dma,
-				     hw_config->dma2, 0, hw_config->osp);
+						    hw_config->dma2, 0, 
+						    hw_config->osp);
 		request_region(hw_config->io_base, 4, "WSS config");
 		return;
 	}
@@ -2562,10 +2578,9 @@
 
 	outb((bits | dma_bits[dma] | dma2_bit), config_port);	/* Write IRQ+DMA setup */
 
-	hw_config->slots[0] = ad1848_init("MSS audio codec", hw_config->io_base + 4,
+	hw_config->slots[0] = ad1848_init("MS Sound System", hw_config->io_base + 4,
 					  hw_config->irq,
-					  dma,
-					  dma2, 0,
+					  dma, dma2, 0,
 					  hw_config->osp);
 	request_region(hw_config->io_base, 4, "WSS config");
 }
@@ -2692,6 +2707,83 @@
 }
 #endif /* EXCLUDE_TIMERS */
 
+static int ad1848_suspend(ad1848_info *devc)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	ad_mute(devc);
+	
+	restore_flags(flags);
+	return 0;
+}
+
+static int ad1848_resume(ad1848_info *devc)
+{
+	unsigned long flags;
+	int mixer_levels[32], i;
+
+	save_flags(flags);
+	cli();
+
+	/* store old mixer levels */
+	memcpy(mixer_levels, devc->levels, sizeof (mixer_levels));  
+	ad1848_init_hw(devc);
+
+	/* restore mixer levels */
+	for (i = 0; i < 32; i++)
+		ad1848_mixer_set(devc, devc->dev_no, mixer_levels[i]);
+
+	if (!devc->subtype) {
+		static signed char interrupt_bits[12] = { -1, -1, -1, -1, -1, 0x00, -1, 0x08, -1, 0x10, 0x18, 0x20 };
+		static char dma_bits[4] = { 1, 2, 0, 3 };
+
+		signed char bits;
+		char dma2_bit = 0;
+
+		int config_port = devc->base + 0;
+
+		bits = interrupt_bits[devc->irq];
+		if (bits == -1) {
+			printk(KERN_ERR "MSS: Bad IRQ %d\n", devc->irq);
+			return -1;
+		}
+
+		outb((bits | 0x40), config_port); 
+
+		if (devc->dma2 != -1 && devc->dma2 != devc->dma1)
+			if ( (devc->dma1 == 0 && devc->dma2 == 1) ||
+			     (devc->dma1 == 1 && devc->dma2 == 0) ||
+			     (devc->dma1 == 3 && devc->dma2 == 0))
+				dma2_bit = 0x04;
+
+		outb((bits | dma_bits[devc->dma1] | dma2_bit), config_port);
+	}
+
+	restore_flags(flags);
+      	return 0;
+}
+
+static int ad1848_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) 
+{
+	ad1848_info *devc = dev->data;
+	if (devc) {
+		DEB(printk("ad1848: pm event received: 0x%x\n", rqst));
+
+		switch (rqst) {
+		case PM_SUSPEND:
+			ad1848_suspend(devc);
+			break;
+		case PM_RESUME:
+			ad1848_resume(devc);
+			break;
+		}
+	}
+	return 0;
+}
+
 
 EXPORT_SYMBOL(ad1848_detect);
 EXPORT_SYMBOL(ad1848_init);
@@ -2707,8 +2799,6 @@
 static int __initdata dma = -1;
 static int __initdata dma2 = -1;
 static int __initdata type = 0;
-
-static struct address_info cfg;
 
 MODULE_PARM(io, "i");                   /* I/O for a raw AD1848 card */
 MODULE_PARM(irq, "i");                  /* IRQ to use */

             reply	other threads:[~2000-03-28 12:45 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-03-28 12:45 Aki M Laukkanen [this message]
2000-03-28 16:55 ` [RFT/PATCH] Re: Sound problem after suspend. Kernel Jeff Garzik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=marc-linux-sound-95424773409649@msgid-missing \
    --to=amlaukka@cc.helsinki.fi \
    --cc=linux-sound@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox