aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch')
-rw-r--r--recipes/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch724
1 files changed, 724 insertions, 0 deletions
diff --git a/recipes/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch b/recipes/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch
new file mode 100644
index 0000000000..9fa7e557f0
--- /dev/null
+++ b/recipes/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch
@@ -0,0 +1,724 @@
+From e3a91813a659447bd20de014902fc5b1d95272aa Mon Sep 17 00:00:00 2001
+From: Graeme Gregory <gg@a10082.wolfsonmicro.main>
+Date: Mon, 26 Mar 2007 15:47:09 +0100
+Subject: [PATCH] Add smdk2443 s3c2443-ac97 and wm9710 support
+
+This is the machine driver for smdk2443 with wm9710
+
+Also the s3c2443-ac97 driver for use with the above machine driver.
+
+Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com>
+---
+ sound/soc/s3c24xx/Kconfig | 15 ++
+ sound/soc/s3c24xx/Makefile | 5 +-
+ sound/soc/s3c24xx/s3c2443-ac97.c | 438 +++++++++++++++++++++++++++++++++++
+ sound/soc/s3c24xx/s3c24xx-ac97.h | 25 ++
+ sound/soc/s3c24xx/smdk2443_wm9710.c | 162 +++++++++++++
+ 5 files changed, 644 insertions(+), 1 deletions(-)
+ create mode 100644 sound/soc/s3c24xx/s3c2443-ac97.c
+ create mode 100644 sound/soc/s3c24xx/s3c24xx-ac97.h
+ create mode 100644 sound/soc/s3c24xx/smdk2443_wm9710.c
+
+diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
+index 2b4bd21..c41ac49 100644
+--- a/sound/soc/s3c24xx/Kconfig
++++ b/sound/soc/s3c24xx/Kconfig
+@@ -12,6 +12,12 @@ config SND_S3C24XX_SOC
+ config SND_S3C24XX_SOC_I2S
+ tristate
+
++config SND_S3C2443_SOC_AC97
++ tristate
++ select AC97_BUS
++ select SND_AC97_CODEC
++ select SND_SOC_AC97_BUS
++
+ config SND_S3C24XX_SOC_NEO1973_WM8753
+ tristate "SoC I2S Audio support for NEO1973 - WM8753"
+ depends on SND_S3C24XX_SOC && MACH_GTA01
+@@ -37,5 +43,14 @@ config SND_S3C24XX_SOC_SMDK2440_WM8956
+ Say Y if you want to add support for SoC audio on SMDK2440
+ with WM8956.
+
++config SND_S3C24XX_SOC_SMDK2443_WM9710
++ tristate "SoC I2S Audio support for SMDK2443 - WM9710"
++ depends on SND_S3C24XX_SOC && MACH_SMDK2443
++ select SND_S3C2443_SOC_AC97
++ select SND_SOC_AC97_CODEC
++ help
++ Say Y if you want to add support for SoC audio on smdk2443
++ with the WM9710.
++
+ endmenu
+
+diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
+index 2759e88..3594155 100644
+--- a/sound/soc/s3c24xx/Makefile
++++ b/sound/soc/s3c24xx/Makefile
+@@ -1,16 +1,19 @@
+ # S3c24XX Platform Support
+ snd-soc-s3c24xx-objs := s3c24xx-pcm.o
+ snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
++snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o
+
+ obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
+ obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
++obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o
+
+ # S3C24XX Machine Support
+ snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
+ snd-soc-smdk2440-objs := smdk2440.o
+ snd-soc-smdk2440-wm8956-objs := smdk2440-wm8956.o
++snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
+
+ obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
+ obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2440) += snd-soc-smdk2440.o
+ obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2440_WM8956) += snd-soc-smdk2440-wm8956.o
+-
++obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
+diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
+new file mode 100644
+index 0000000..db5996b
+--- /dev/null
++++ b/sound/soc/s3c24xx/s3c2443-ac97.c
+@@ -0,0 +1,438 @@
++/*
++ * s3c24xx-i2s.c -- ALSA Soc Audio Layer
++ *
++ * (c) 2006 Wolfson Microelectronics PLC.
++ * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
++ *
++ * Copyright (C) 2005, Sean Choi <sh428.choi@samsung.com>
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Revision history
++ * 21st Mar 2007 Initial Version
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/wait.h>
++#include <linux/delay.h>
++#include <linux/clk.h>
++
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/ac97_codec.h>
++#include <sound/initval.h>
++#include <sound/soc.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/arch/regs-ac97.h>
++#include <asm/arch/regs-gpio.h>
++#include <asm/arch/regs-clock.h>
++#include <asm/arch/audio.h>
++#include <asm/dma.h>
++#include <asm/arch/dma.h>
++
++#include "s3c24xx-pcm.h"
++#include "s3c24xx-ac97.h"
++
++#define S3C2443_I2S_DEBUG 1
++#if S3C2443_I2S_DEBUG
++#define DBG(x...) printk(KERN_DEBUG x)
++#else
++#define DBG(x...)
++#endif
++
++struct s3c24xx_ac97_info {
++ void __iomem *regs;
++ struct clk *ac97_clk;
++};
++static struct s3c24xx_ac97_info s3c24xx_ac97;
++
++static struct completion CAR_completion;
++static u32 waitingForMask;
++static DECLARE_MUTEX(CAR_mutex);
++
++static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97,
++ unsigned short reg)
++{
++ u32 ac_glbctrl;
++ u32 ac_codec_cmd;
++ u32 stat, addr, data;
++
++ DBG("Entered %s\n",__FUNCTION__);
++
++ down(&CAR_mutex);
++
++ // Initialise the completion used in ISR
++ init_completion(&CAR_completion);
++
++ waitingForMask = S3C_AC97_GLBSTAT_CODECREADY;
++ ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
++ ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg);
++ writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
++
++ udelay(50);
++
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++
++ wait_for_completion(&CAR_completion);
++
++ stat = readl(s3c24xx_ac97.regs + S3C_AC97_STAT);
++ addr = (stat >> 16) & 0x7f;
++ data = (stat & 0xffff);
++
++ DBG("AC97 Read %x %x\n", addr, data);
++
++ if (addr != reg) {
++ printk("req addr = %02x, rep addr = %02x\n", reg, addr);
++ }
++
++ up(&CAR_mutex);
++
++ return (unsigned short)data;
++}
++
++static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
++ unsigned short val)
++{
++ u32 ac_glbctrl;
++ u32 ac_codec_cmd;
++
++ DBG("Entered %s\n",__FUNCTION__);
++
++ down(&CAR_mutex);
++
++ DBG("AC97 Write %x:%x\n", reg,val);
++
++ init_completion(&CAR_completion);
++
++ waitingForMask = S3C_AC97_GLBSTAT_CODECREADY;
++ ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
++ ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val);
++ writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
++
++ udelay(50);
++
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++
++ wait_for_completion(&CAR_completion);
++
++ ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
++ ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
++ writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
++
++ up(&CAR_mutex);
++
++}
++
++static void s3c2443_ac97_warm_reset(struct snd_ac97 *ac97)
++{
++ u32 ac_glbctrl;
++
++ DBG("Entered %s\n", __FUNCTION__);
++
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ udelay(1000);
++
++ ac_glbctrl = 0;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ udelay(1000);
++}
++
++static void s3c2443_ac97_cold_reset(struct snd_ac97 *ac97)
++{
++ u32 ac_glbctrl;
++
++ DBG("Entered %s\n", __FUNCTION__);
++
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ udelay(1000);
++
++ ac_glbctrl = 0;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ udelay(1000);
++
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ udelay(1000);
++
++ ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ udelay(1000);
++
++ ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA | S3C_AC97_GLBCTRL_PCMINTM_DMA |
++ S3C_AC97_GLBCTRL_MICINTM_DMA;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++
++}
++
++static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id)
++{
++ int gsr;
++ u32 ac_glbctrl;
++
++ gsr = readl(s3c24xx_ac97.regs + S3C_AC97_GLBSTAT) & waitingForMask;
++
++ if (gsr) {
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ complete(&CAR_completion);
++ }
++ return IRQ_HANDLED;
++}
++
++struct snd_ac97_bus_ops soc_ac97_ops = {
++ .read = s3c2443_ac97_read,
++ .write = s3c2443_ac97_write,
++ .warm_reset = s3c2443_ac97_warm_reset,
++ .reset = s3c2443_ac97_cold_reset,
++};
++
++static struct s3c2410_dma_client s3c2443_dma_client_out = {
++ .name = "AC97 PCM Stereo out"
++};
++
++static struct s3c2410_dma_client s3c2443_dma_client_in = {
++ .name = "AC97 PCM Stereo in"
++};
++
++static struct s3c2410_dma_client s3c2443_dma_client_micin = {
++ .name = "AC97 Mic Mono in"
++};
++
++static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_out = {
++ .client = &s3c2443_dma_client_out,
++ .channel = DMACH_PCM_OUT,
++ .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
++ .dma_size = 4,
++};
++
++static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_in = {
++ .client = &s3c2443_dma_client_in,
++ .channel = DMACH_PCM_IN,
++ .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
++ .dma_size = 4,
++};
++
++static struct s3c24xx_pcm_dma_params s3c2443_ac97_mic_mono_in = {
++ .client = &s3c2443_dma_client_micin,
++ .channel = DMACH_MIC_IN,
++ .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
++ .dma_size = 4,
++};
++
++#ifdef CONFIG_PM
++static int s3c2443_ac97_suspend(struct platform_device *pdev,
++ struct snd_soc_cpu_dai *dai)
++{
++
++ return 0;
++}
++
++static int s3c2443_ac97_resume(struct platform_device *pdev,
++ struct snd_soc_cpu_dai *dai)
++{
++ return 0;
++}
++
++#else
++#define s3c2443_ac97_suspend NULL
++#define s3c2443_ac97_resume NULL
++#endif
++
++static int s3c2443_ac97_probe(struct platform_device *pdev)
++{
++ int ret;
++ u32 ac_glbctrl;
++
++ s3c24xx_ac97.regs = ioremap(S3C2440_PA_AC97, 0x100);
++ if (s3c24xx_ac97.regs == NULL)
++ return -ENXIO;
++
++ s3c24xx_ac97.ac97_clk=clk_get(&pdev->dev, "ac97");
++ if (s3c24xx_ac97.ac97_clk == NULL) {
++ DBG("failed to get ac97_clock\n");
++ return -ENODEV;
++ }
++ clk_enable(s3c24xx_ac97.ac97_clk);
++
++ s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2443_GPE0_AC_nRESET);
++ s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2443_GPE1_AC_SYNC);
++ s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2443_GPE2_AC_BITCLK);
++ s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2443_GPE3_AC_SDI);
++ s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2443_GPE4_AC_SDO);
++
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ udelay(1000);
++
++ ac_glbctrl = 0;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ udelay(1000);
++
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ udelay(1000);
++
++ ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++
++ ret = request_irq(IRQ_S3C2443_AC97, s3c2443_ac97_irq, SA_INTERRUPT, "AC97", NULL);
++ if (ret)
++ printk("Interrupt request failed.\n");
++
++ return ret;
++}
++
++static void s3c2443_ac97_remove(struct platform_device *pdev)
++{
++
++}
++
++static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
++
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out;
++ else
++ cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_in;
++
++ return 0;
++}
++
++static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ u32 ac_glbctrl;
++
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ switch(cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
++ ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
++ else
++ ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
++ ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
++ else
++ ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
++ break;
++ }
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++
++ return 0;
++}
++
++static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
++
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ return -ENODEV;
++ else
++ cpu_dai->dma_data = &s3c2443_ac97_mic_mono_in;
++
++ return 0;
++}
++
++static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ u32 ac_glbctrl;
++
++ ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++ switch(cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
++ }
++ writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
++
++ return 0;
++}
++
++#define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
++ SNDRV_PCM_RATE_48000)
++
++struct snd_soc_cpu_dai s3c2443_ac97_dai[] = {
++{
++ .name = "s3c2443-ac97",
++ .id = 0,
++ .type = SND_SOC_DAI_AC97,
++ .probe = s3c2443_ac97_probe,
++ .remove = s3c2443_ac97_remove,
++ .suspend = s3c2443_ac97_suspend,
++ .resume = s3c2443_ac97_resume,
++ .playback = {
++ .stream_name = "AC97 Playback",
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = s3c2443_AC97_RATES,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,},
++ .capture = {
++ .stream_name = "AC97 Capture",
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = s3c2443_AC97_RATES,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,},
++ .ops = {
++ .hw_params = s3c2443_ac97_hw_params,
++ .trigger = s3c2443_ac97_trigger},
++},
++{
++ .name = "pxa2xx-ac97-mic",
++ .id = 1,
++ .type = SND_SOC_DAI_AC97,
++ .capture = {
++ .stream_name = "AC97 Mic Capture",
++ .channels_min = 1,
++ .channels_max = 1,
++ .rates = s3c2443_AC97_RATES,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,},
++ .ops = {
++ .hw_params = s3c2443_ac97_hw_mic_params,
++ .trigger = s3c2443_ac97_mic_trigger,},
++},
++};
++
++EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
++EXPORT_SYMBOL_GPL(soc_ac97_ops);
++
++MODULE_AUTHOR("Graeme Gregory");
++MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
++MODULE_LICENSE("GPL");
+diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h
+new file mode 100644
+index 0000000..afddff0
+--- /dev/null
++++ b/sound/soc/s3c24xx/s3c24xx-ac97.h
+@@ -0,0 +1,25 @@
++/*
++ * s3c24xx-i2s.c -- ALSA Soc Audio Layer
++ *
++ * Copyright 2005 Wolfson Microelectronics PLC.
++ * Author: Graeme Gregory
++ * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
++ *
++ * 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
++ * option) any later version.
++ *
++ * Revision history
++ * 10th Nov 2006 Initial version.
++ */
++
++#ifndef S3C24XXAC97_H_
++#define S3C24XXAC97_H_
++
++#define AC_CMD_ADDR(x) (x<<16)
++#define AC_CMD_DATA(x) (x&0xffff)
++
++extern struct snd_soc_cpu_dai s3c2443_ac97_dai[];
++
++#endif /*S3C24XXI2S_H_*/
+diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
+new file mode 100644
+index 0000000..66c13cf
+--- /dev/null
++++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
+@@ -0,0 +1,162 @@
++/*
++ * smdk2443_wm9710.c -- SoC audio for smdk2443
++ *
++ * Copyright 2007 Wolfson Microelectronics PLC.
++ * Author: Graeme Gregory
++ * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
++ *
++ * 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
++ * option) any later version.
++ *
++ * Revision history
++ * 8th Mar 2007 Initial version.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/device.h>
++#include <linux/i2c.h>
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#include <asm/mach-types.h>
++#include <asm/hardware/scoop.h>
++#include <asm/arch/regs-iis.h>
++#include <asm/arch/regs-clock.h>
++#include <asm/arch/regs-gpio.h>
++#include <asm/hardware.h>
++#include <asm/arch/audio.h>
++#include <asm/io.h>
++#include <asm/arch/spi-gpio.h>
++#include "../codecs/ac97.h"
++#include "s3c24xx-pcm.h"
++#include "s3c24xx-ac97.h"
++
++#define SMDK2443_DEBUG 1
++#if SMDK2443_DEBUG
++#define DBG(x...) printk(KERN_DEBUG x)
++#else
++#define DBG(x...)
++#endif
++
++static struct snd_soc_machine smdk2443;
++
++static int smdk2443_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ return 0;
++}
++
++static int smdk2443_resume(struct platform_device *pdev)
++{
++ return 0;
++}
++
++static int smdk2443_probe(struct platform_device *pdev)
++{
++ return 0;
++}
++
++static int smdk2443_remove(struct platform_device *pdev)
++{
++ return 0;
++}
++
++static const struct snd_soc_dapm_widget smdk2443_dapm_widgets[] = {
++ SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
++};
++
++/* example machine interconnections */
++static const char* intercon[][3] = {
++
++ /* mic is connected to mic1 - with bias */
++ {"MIC1", NULL, "Mic Bias"},
++ {"Mic Bias", NULL, "Mic (Internal)"},
++
++ {NULL, NULL, NULL},
++};
++
++static int smdk2443_wm9710_init(struct snd_soc_codec *codec)
++{
++ int i;
++
++ /* set up smdk2443 NC codec pins */
++ snd_soc_dapm_set_endpoint(codec, "RXP", 0);
++ snd_soc_dapm_set_endpoint(codec, "RXN", 0);
++
++ /* Add smdk2443 specific widgets */
++ for(i = 0; i < ARRAY_SIZE(smdk2443_dapm_widgets); i++) {
++ snd_soc_dapm_new_control(codec, &smdk2443_dapm_widgets[i]);
++ }
++
++ /* set up smdk2443 specific audio path interconnects */
++ for(i = 0; intercon[i][0] != NULL; i++) {
++ snd_soc_dapm_connect_input(codec, intercon[i][0], intercon[i][1], intercon[i][2]);
++ }
++
++ snd_soc_dapm_sync_endpoints(codec);
++ return 0;
++}
++
++static struct snd_soc_dai_link smdk2443_dai[] = {
++{
++ .name = "AC97",
++ .stream_name = "AC97 HiFi",
++ .cpu_dai = &s3c2443_ac97_dai[0],
++ .codec_dai = &ac97_dai,
++ .init = smdk2443_wm9710_init,
++},
++};
++
++static struct snd_soc_machine smdk2443 = {
++ .name = "SMDK2443",
++ .probe = smdk2443_probe,
++ .remove = smdk2443_remove,
++ .suspend_pre = smdk2443_suspend,
++ .resume_post = smdk2443_resume,
++ .dai_link = smdk2443_dai,
++ .num_links = ARRAY_SIZE(smdk2443_dai),
++};
++
++static struct snd_soc_device smdk2443_snd_ac97_devdata = {
++ .machine = &smdk2443,
++ .platform = &s3c24xx_soc_platform,
++ .codec_dev = &soc_codec_dev_ac97,
++};
++
++static struct platform_device *smdk2443_snd_ac97_device;
++
++static int __init smdk2443_init(void)
++{
++ int ret;
++
++ smdk2443_snd_ac97_device = platform_device_alloc("soc-audio", -1);
++ if (!smdk2443_snd_ac97_device)
++ return -ENOMEM;
++
++ platform_set_drvdata(smdk2443_snd_ac97_device, &smdk2443_snd_ac97_devdata);
++ smdk2443_snd_ac97_devdata.dev = &smdk2443_snd_ac97_device->dev;
++
++ if((ret = platform_device_add(smdk2443_snd_ac97_device)) != 0)
++ platform_device_put(smdk2443_snd_ac97_device);
++
++ return ret;
++}
++
++static void __exit smdk2443_exit(void)
++{
++ platform_device_unregister(smdk2443_snd_ac97_device);
++}
++
++module_init(smdk2443_init);
++module_exit(smdk2443_exit);
++
++/* Module information */
++MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com");
++MODULE_DESCRIPTION("ALSA SoC WM9710 SMDK2443");
++MODULE_LICENSE("GPL");
+--
+1.5.0.3
+