diff options
Diffstat (limited to 'packages/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch')
-rw-r--r-- | packages/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch | 724 |
1 files changed, 724 insertions, 0 deletions
diff --git a/packages/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch b/packages/linux/linux-smdk2443/0038-Add-smdk2443-s3c2443-ac97-and-wm9710-support.patch new file mode 100644 index 0000000000..9fa7e557f0 --- /dev/null +++ b/packages/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 + |