summaryrefslogtreecommitdiff
path: root/sound/soc/au1x/sample-ac97.c
diff options
context:
space:
mode:
authorManuel Lauss <mano@roarinelk.homelinux.net>2008-07-09 18:27:56 +0400
committerJaroslav Kysela <perex@perex.cz>2008-07-10 11:33:07 +0400
commit4a161d235b68eb7234f40106560c488a1bdb3851 (patch)
treeef88570d98c10f1bfeef56bfeddbe8009d1fcaa5 /sound/soc/au1x/sample-ac97.c
parentbf41534506a0572c06c8f34d12aa489be4c8780e (diff)
downloadlinux-4a161d235b68eb7234f40106560c488a1bdb3851.tar.xz
ALSA: ASoC: Au12x0/Au1550 PSC Audio support
Audio for Au12x0/Au1550 PSCs in AC97 and I2S mode, for ASoC v1 framework. - DBDMA, AC97 and I2S drivers - sample AC97 machine code (Db1200) Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net> Signed-off-by: Liam Girdwood <lg@opensource.wolfsonmicro.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/soc/au1x/sample-ac97.c')
-rw-r--r--sound/soc/au1x/sample-ac97.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c
new file mode 100644
index 000000000000..f75ae7f62c3d
--- /dev/null
+++ b/sound/soc/au1x/sample-ac97.c
@@ -0,0 +1,144 @@
+/*
+ * Sample Au12x0/Au1550 PSC AC97 sound machine.
+ *
+ * Copyright (c) 2007-2008 Manuel Lauss <mano@roarinelk.homelinux.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms outlined in the file COPYING at the root of this
+ * source archive.
+ *
+ * This is a very generic AC97 sound machine driver for boards which
+ * have (AC97) audio at PSC1 (e.g. DB1200 demoboards).
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#include "../codecs/ac97.h"
+#include "psc.h"
+
+static int au1xpsc_sample_ac97_init(struct snd_soc_codec *codec)
+{
+ snd_soc_dapm_sync(codec);
+ return 0;
+}
+
+static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = {
+ .name = "AC97",
+ .stream_name = "AC97 HiFi",
+ .cpu_dai = &au1xpsc_ac97_dai, /* see psc-ac97.c */
+ .codec_dai = &ac97_dai, /* see codecs/ac97.c */
+ .init = au1xpsc_sample_ac97_init,
+ .ops = NULL,
+};
+
+static struct snd_soc_machine au1xpsc_sample_ac97_machine = {
+ .name = "Au1xxx PSC AC97 Audio",
+ .dai_link = &au1xpsc_sample_ac97_dai,
+ .num_links = 1,
+};
+
+static struct snd_soc_device au1xpsc_sample_ac97_devdata = {
+ .machine = &au1xpsc_sample_ac97_machine,
+ .platform = &au1xpsc_soc_platform, /* see dbdma2.c */
+ .codec_dev = &soc_codec_dev_ac97,
+};
+
+static struct resource au1xpsc_psc1_res[] = {
+ [0] = {
+ .start = CPHYSADDR(PSC1_BASE_ADDR),
+ .end = CPHYSADDR(PSC1_BASE_ADDR) + 0x000fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+#ifdef CONFIG_SOC_AU1200
+ .start = AU1200_PSC1_INT,
+ .end = AU1200_PSC1_INT,
+#elif defined(CONFIG_SOC_AU1550)
+ .start = AU1550_PSC1_INT,
+ .end = AU1550_PSC1_INT,
+#endif
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DSCR_CMD0_PSC1_TX,
+ .end = DSCR_CMD0_PSC1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DSCR_CMD0_PSC1_RX,
+ .end = DSCR_CMD0_PSC1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device *au1xpsc_sample_ac97_dev;
+
+static int __init au1xpsc_sample_ac97_load(void)
+{
+ int ret;
+
+#ifdef CONFIG_SOC_AU1200
+ unsigned long io;
+
+ /* modify sys_pinfunc for AC97 on PSC1 */
+ io = au_readl(SYS_PINFUNC);
+ io |= SYS_PINFUNC_P1C;
+ io &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B);
+ au_writel(io, SYS_PINFUNC);
+ au_sync();
+#endif
+
+ ret = -ENOMEM;
+
+ /* setup PSC clock source for AC97 part: external clock provided
+ * by codec. The psc-ac97.c driver depends on this setting!
+ */
+ au_writel(PSC_SEL_CLK_SERCLK, PSC1_BASE_ADDR + PSC_SEL_OFFSET);
+ au_sync();
+
+ au1xpsc_sample_ac97_dev = platform_device_alloc("soc-audio", -1);
+ if (!au1xpsc_sample_ac97_dev)
+ goto out;
+
+ au1xpsc_sample_ac97_dev->resource =
+ kmemdup(au1xpsc_psc1_res, sizeof(struct resource) *
+ ARRAY_SIZE(au1xpsc_psc1_res), GFP_KERNEL);
+ au1xpsc_sample_ac97_dev->num_resources = ARRAY_SIZE(au1xpsc_psc1_res);
+ au1xpsc_sample_ac97_dev->id = 1;
+
+ platform_set_drvdata(au1xpsc_sample_ac97_dev,
+ &au1xpsc_sample_ac97_devdata);
+ au1xpsc_sample_ac97_devdata.dev = &au1xpsc_sample_ac97_dev->dev;
+ ret = platform_device_add(au1xpsc_sample_ac97_dev);
+
+ if (ret) {
+ platform_device_put(au1xpsc_sample_ac97_dev);
+ au1xpsc_sample_ac97_dev = NULL;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit au1xpsc_sample_ac97_exit(void)
+{
+ platform_device_unregister(au1xpsc_sample_ac97_dev);
+}
+
+module_init(au1xpsc_sample_ac97_load);
+module_exit(au1xpsc_sample_ac97_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Au1xxx PSC sample AC97 machine");
+MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");