All of lore.kernel.org
 help / color / mirror / Atom feed
From: Norm Proffitt <normp@us.ibm.com>
To: linux-sound@vger.kernel.org
Subject: [PATCH] APM Support for 2.2.19 ad1848 driver
Date: Mon, 04 Jun 2001 21:05:49 +0000	[thread overview]
Message-ID: <marc-linux-sound-99168883905117@msgid-missing> (raw)

This patch modifies drivers/sound/ad1848.c to provide APM suspend/resume
support to the AD1848 driver in Linux 2.2.19.

To apply this patch,

        cd to the top linux source directory

        patch --dry-run -p0 < this_file

If the patch program doesn't complain then use the command

        patch -p0 < this_file

to really apply the patch.  Then issue

        make modules; make modules_install

NOTES:
        - OSS drivers support (together with the correct driver modules)
          must be enabled in the kernel config.

        - APM support must be enabled in the kernel config.

        - This patch was developed for linux-2.2.19 although it should
          apply to linux-2.2.14 through linux-2.2.19

        - There's absolutely no warranty of any kind.

Please reply directly to normp@us.ibm.com since I'm not subscribed to
the
mailing list.

Thanks,
  Norm Proffitt

--- drivers/sound/ad1848.c.org  Mon Mar 19 14:28:31 2001
+++ drivers/sound/ad1848.c      Wed Mar 21 15:07:14 2001
@@ -26,6 +26,7 @@
  *                  general sleep/wakeup clean up.
  * Alan Cox       : reformatted. Fixed SMP bugs. Moved to kernel
alloc/free
  *                  of irqs. Use dev_id.
+ * Norm Proffitt   : backport Aki Laukkanen's power management support
  *
  * Status:
  *             Tested. Believed fully functional.
@@ -34,6 +35,9 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/stddef.h>
+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+#endif

 #include "soundmodule.h"

@@ -51,6 +55,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;
@@ -99,6 +104,7 @@
 }
 ad1848_port_info;

+static struct address_info cfg;
 static int nr_ad1848_devs = 0;
 int deskpro_xl = 0;
 int deskpro_m = 0;
@@ -166,6 +172,7 @@
 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_apm_callback(apm_event_t apm_event);

 #if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
 static int ad1848_tmr_install(int dev);
@@ -1866,6 +1873,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)
@@ -1918,6 +1926,12 @@

        nr_ad1848_devs++;

+#ifdef CONFIG_APM
+        if (apm_register_callback(ad1848_apm_callback))
+        {
+                printk(KERN_WARNING "ad1848: APM suspend might not
work.\n");
+        }
+#endif
        ad1848_init_hw(devc);

        if (irq > 0)
@@ -2079,6 +2093,13 @@
                if(mixer>=0)
                        sound_unload_mixerdev(mixer);

+#ifdef CONFIG_APM
+        if (apm_register_callback(ad1848_apm_callback))
+        {
+                printk(KERN_WARNING "ad1848: APM suspend might not
work.\n");
+        }
+#endif
+
                nr_ad1848_devs--;
                for ( ; i < nr_ad1848_devs ; i++)
                        adev_info[i] = adev_info[i+1];
@@ -2695,6 +2716,104 @@
 }
 #endif

+#ifdef CONFIG_APM
+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);
+                        restore_flags(flags);
+                        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_apm_callback(apm_event_t apm_event)
+{
+        int             n;
+
+        switch (apm_event)
+        {
+                case APM_SYS_SUSPEND:
+                case APM_CRITICAL_SUSPEND:
+                case APM_USER_SUSPEND:
+                        for (n = 0; n < nr_ad1848_devs; n++)
+                                ad1848_suspend(&adev_info[n]);
+                        break;
+
+                case APM_NORMAL_RESUME:
+                case APM_CRITICAL_RESUME:
+                case APM_STANDBY_RESUME:
+                        for (n = 0; n < nr_ad1848_devs; n++)
+                                ad1848_resume(&adev_info[n]);
+                        break;
+
+                default:
+                        break;
+        }
+
+        return 0;
+}
+
+#endif

 EXPORT_SYMBOL(ad1848_detect);
 EXPORT_SYMBOL(ad1848_init);
@@ -2724,8 +2843,6 @@

 static int loaded = 0;

-struct address_info hw_config;
-
 int init_module(void)
 {
        printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by
Hannu Savolainen 1993-1996\n");
@@ -2736,14 +2853,14 @@
                        printk(KERN_WARNING "ad1848: must give I/O , IRQ
and DMA.\n");
                        return -EINVAL;
                }
-               hw_config.irq = irq;
-               hw_config.io_base = io;
-               hw_config.dma = dma;
-               hw_config.dma2 = dma2;
-               hw_config.card_subtype = type;
-               if(!probe_ms_sound(&hw_config))
+               cfg.irq = irq;
+               cfg.io_base = io;
+               cfg.dma = dma;
+               cfg.dma2 = dma2;
+               cfg.card_subtype = type;
+               if(!probe_ms_sound(&cfg))
                        return -ENODEV;
-               attach_ms_sound(&hw_config);
+               attach_ms_sound(&cfg);
                loaded=1;
        }
        SOUND_LOCK;
@@ -2754,7 +2871,7 @@
 {
        SOUND_LOCK_END;
        if(loaded)
-               unload_ms_sound(&hw_config);
+               unload_ms_sound(&cfg);
 }

 #endif
-
To unsubscribe from this list: send the line "unsubscribe linux-sound" in
the body of a message to majordomo@vger.kernel.org

                 reply	other threads:[~2001-06-04 21:05 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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-99168883905117@msgid-missing \
    --to=normp@us.ibm.com \
    --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 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.