From: Rodolfo Giometti <giometti@linux.it>
To: alsa-devel@alsa-project.org
Subject: [PATCH] Au1xxx sound registration and power management
Date: Thu, 13 Jul 2006 14:26:53 +0200 [thread overview]
Message-ID: <20060713122653.GI13250@hulk.enneenne.com> (raw)
[-- Attachment #1.1.1: Type: text/plain, Size: 451 bytes --]
Hello,
here a patch to support device registration and power management for
the au1xxx ALSA driver.
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
Ciao,
Rodolfo
--
GNU/Linux Solutions e-mail: giometti@enneenne.com
Linux Device Driver giometti@gnudd.com
Embedded Systems giometti@linux.it
UNIX programming phone: +39 349 2432127
[-- Attachment #1.1.2: patch-au1000_snd-pm-and-registration --]
[-- Type: text/plain, Size: 8920 bytes --]
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index 0088889..34de6d3 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -88,6 +88,31 @@ static struct platform_device au1xxx_eth
#endif
#endif
+#if defined(CONFIG_SND_AU1X00)
+/* AC97 controller */
+static struct resource au1xxx_snd_resources[] = {
+ [0] = {
+ .name = "snd-base",
+ .start = AC97C_BASE,
+ .end = AC97C_BASE + AC97_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "snd-irq",
+ .start = AU1000_AC97C_INT,
+ .end = AU1000_AC97C_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device au1xxx_snd_device = {
+ .name = "au1xxx-snd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(au1xxx_snd_resources),
+ .resource = au1xxx_snd_resources,
+};
+#endif
+
/* OHCI (USB full speed host controller) */
static struct resource au1xxx_usb_ohci_resources[] = {
[0] = {
@@ -376,6 +401,9 @@ #if defined(CONFIG_SOC_AU1000) || \
&au1xxx_eth1_device,
#endif
#endif
+#if defined(CONFIG_SND_AU1X00)
+ &au1xxx_snd_device,
+#endif
&au1xxx_usb_ohci_device,
&au1x00_pcmcia_device,
#ifdef CONFIG_FB_AU1100
diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
index 0988af9..cb8939a 100644
--- a/include/asm-mips/mach-au1x00/au1000.h
+++ b/include/asm-mips/mach-au1x00/au1000.h
@@ -1600,6 +1600,9 @@ #define SYS_CPUPLL 0xB190
#define SYS_AUXPLL 0xB1900064
/* AC97 Controller */
+#define AC97C_BASE AC97_PHYS_ADDR
+#define AC97_IOSIZE 0x14
+
#define AC97C_CONFIG 0xB0000000
#define AC97C_RECV_SLOTS_BIT 13
#define AC97C_RECV_SLOTS_MASK (0x3ff << AC97C_RECV_SLOTS_BIT)
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index cf476fe..2dd6862 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -5,6 +5,8 @@
* Copyright 2004 Cooper Street Innovations Inc.
* Author: Charles Eidsness <charles@cooper-street.com>
*
+ * PM support added by Rodolfo Giometti <giometti@linux.it>
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
@@ -40,6 +42,7 @@ #include <sound/driver.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/version.h>
+#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
@@ -53,6 +56,8 @@ MODULE_DESCRIPTION("Au1000 AC'97 ALSA Dr
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{AMD,Au1000 AC'97}}");
+#define DRV_NAME "au1xxx-snd"
+
#define PLAYBACK 0
#define CAPTURE 1
#define AC97_SLOT_3 0x01
@@ -526,7 +531,6 @@ get the interupt driven case to work eff
}
-
static void
snd_au1000_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
{
@@ -550,24 +554,17 @@ get the interupt driven case to work eff
spin_unlock(&au1000->ac97_lock);
}
+static struct snd_ac97_bus_ops au1000_ac97_ops = {
+ .write = snd_au1000_ac97_write,
+ .read = snd_au1000_ac97_read,
+};
+
static int __devinit
snd_au1000_ac97_new(struct snd_au1000 *au1000)
{
int err;
struct snd_ac97_bus *pbus;
struct snd_ac97_template ac97;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_au1000_ac97_write,
- .read = snd_au1000_ac97_read,
- };
-
- if ((au1000->ac97_res_port = request_mem_region(CPHYSADDR(AC97C_CONFIG),
- 0x100000, "Au1x00 AC97")) == NULL) {
- snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n");
- return -EBUSY;
- }
- au1000->ac97_ioport = (struct au1000_ac97_reg *)
- KSEG1ADDR(au1000->ac97_res_port->start);
spin_lock_init(&au1000->ac97_lock);
@@ -588,7 +585,7 @@ snd_au1000_ac97_new(struct snd_au1000 *a
mdelay(5);
/* Initialise AC97 middle-layer */
- if ((err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus)) < 0)
+ if ((err = snd_ac97_bus(au1000->card, 0, &au1000_ac97_ops, au1000, &pbus)) < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
@@ -626,68 +623,154 @@ snd_au1000_free(struct snd_card *card)
}
}
+#ifdef CONFIG_PM
+static u32 au1000_ac97_config;
+
+static int au1000_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_au1000 *au1000 = card->private_data;
+
+ if (!card)
+ return 0;
-static struct snd_card *au1000_card;
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
+ snd_pcm_suspend_all(au1000->pcm);
+ snd_ac97_suspend(au1000->ac97);
+
+ /* Save Au1000's AC'97 Control Block and disable the controller */
+ au1000_ac97_config = au1000->ac97_ioport->config;
+ au1000->ac97_ioport->cntrl = AC97C_RS;
+
+ return 0;
+}
-static int __init
-au1000_init(void)
+static int au1000_drv_resume(struct platform_device *pdev)
{
- int err;
- struct snd_card *card;
- struct snd_au1000 *au1000;
+ struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_au1000 *au1000 = card->private_data;
+
+ if (!card)
+ return 0;
+ /* Initialise Au1000's AC'97 Control Block and restore previous
+ * configuration */
+ au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
+ udelay(10);
+ au1000->ac97_ioport->cntrl = AC97C_CE;
+ udelay(10);
+ au1000->ac97_ioport->config = au1000_ac97_config;
+
+ snd_ac97_resume(au1000->ac97);
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+
+ return 0;
+}
+#endif
+
+static int __init au1000_drv_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct snd_card *card = NULL;
+ struct snd_au1000 *au1000 = NULL;
+ int ret;
+
+ /* Get the resource info */
+ ret = -ENODEV;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "snd-base");
+ if (!res)
+ goto exit;
+
+ ret = -ENOMEM;
card = snd_card_new(-1, "AC97", THIS_MODULE, sizeof(struct snd_au1000));
if (card == NULL)
- return -ENOMEM;
+ goto exit;
+ card->dev = &pdev->dev;
card->private_free = snd_au1000_free;
au1000 = card->private_data;
au1000->card = card;
+ au1000->ac97_res_port = res;
+ au1000->ac97_ioport = ioremap(res->start, res->end - res->start + 1);
+ ret = -ENOMEM;
+ if (!au1000->ac97_ioport) {
+ printk (KERN_ERR "%s: unable to remap address %lx\n",
+ DRV_NAME, res->start);
+ goto exit;
+ }
+
au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
/* so that snd_au1000_free will work as intended */
- au1000->ac97_res_port = NULL;
if (au1000->stream[PLAYBACK])
au1000->stream[PLAYBACK]->dma = -1;
if (au1000->stream[CAPTURE ])
au1000->stream[CAPTURE ]->dma = -1;
if (au1000->stream[PLAYBACK] == NULL ||
- au1000->stream[CAPTURE ] == NULL) {
- snd_card_free(card);
- return -ENOMEM;
- }
+ au1000->stream[CAPTURE ] == NULL)
+ goto exit;
- if ((err = snd_au1000_ac97_new(au1000)) < 0 ) {
- snd_card_free(card);
- return err;
- }
+ if ((ret = snd_au1000_ac97_new(au1000)) < 0)
+ goto exit;
- if ((err = snd_au1000_pcm_new(au1000)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((ret = snd_au1000_pcm_new(au1000)) < 0)
+ goto exit;
strcpy(card->driver, "Au1000-AC97");
strcpy(card->shortname, "AMD Au1000-AC97");
sprintf(card->longname, "AMD Au1000--AC97 ALSA Driver");
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ if ((ret = snd_card_register(card)) < 0)
+ goto exit;
+ platform_set_drvdata(pdev, card);
printk( KERN_INFO "ALSA AC97: Driver Initialized\n" );
- au1000_card = card;
+
return 0;
+
+exit :
+ if (au1000 && au1000->ac97_ioport)
+ iounmap(au1000->ac97_ioport);
+ if (card)
+ snd_card_free(card);
+
+ return ret;
}
-static void __exit au1000_exit(void)
+static int __exit au1000_drv_remove(struct platform_device *pdev)
{
- snd_card_free(au1000_card);
+ struct snd_card *card = platform_get_drvdata(pdev);
+
+ if (card)
+ snd_card_free(card);
+
+ return 0;
}
-module_init(au1000_init);
-module_exit(au1000_exit);
+static struct platform_driver au1000_driver = {
+ .probe = au1000_drv_probe,
+ .remove = au1000_drv_remove,
+#ifdef CONFIG_PM
+ .suspend = au1000_drv_suspend,
+ .resume = au1000_drv_resume,
+#endif
+ .driver = {
+ .name = DRV_NAME,
+ },
+};
+
+
+static int __init au1000_snd_init(void)
+{
+ return platform_driver_register(&au1000_driver);
+}
+
+static void __exit au1000_snd_exit(void)
+{
+ platform_driver_unregister(&au1000_driver);
+}
+module_init(au1000_snd_init);
+module_exit(au1000_snd_exit);
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 375 bytes --]
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
[-- Attachment #3: Type: text/plain, Size: 161 bytes --]
_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel
next reply other threads:[~2006-07-17 10:44 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-13 12:26 Rodolfo Giometti [this message]
-- strict thread matches above, loose matches on Subject: below --
2006-07-20 7:37 [PATCH] Au1xxx sound registration and power management Rodolfo Giometti
2006-07-25 13:26 ` Takashi Iwai
2006-06-30 10:02 Rodolfo Giometti
2006-06-30 12:12 ` Ralf Baechle
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=20060713122653.GI13250@hulk.enneenne.com \
--to=giometti@linux.it \
--cc=alsa-devel@alsa-project.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.