aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-smdk2443/0022-Add-initial-ASoC-SMDK2440-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/linux/linux-smdk2443/0022-Add-initial-ASoC-SMDK2440-support.patch')
-rw-r--r--recipes/linux/linux-smdk2443/0022-Add-initial-ASoC-SMDK2440-support.patch373
1 files changed, 373 insertions, 0 deletions
diff --git a/recipes/linux/linux-smdk2443/0022-Add-initial-ASoC-SMDK2440-support.patch b/recipes/linux/linux-smdk2443/0022-Add-initial-ASoC-SMDK2440-support.patch
new file mode 100644
index 0000000000..01b51d925e
--- /dev/null
+++ b/recipes/linux/linux-smdk2443/0022-Add-initial-ASoC-SMDK2440-support.patch
@@ -0,0 +1,373 @@
+From a6171bfad4671fe525ae2c8cddd4f6a7f739e346 Mon Sep 17 00:00:00 2001
+From: Liam Girdwood <liam@localhost.localdomain>
+Date: Sun, 4 Mar 2007 17:00:59 +0000
+Subject: [PATCH] Add initial ASoC SMDK2440 support.
+
+Signed-off-by: Ben Dooks <ben@simtec.co.uk>
+Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com>
+Signed-off-by: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+---
+ sound/soc/s3c24xx/Kconfig | 7 +
+ sound/soc/s3c24xx/Makefile | 2 +
+ sound/soc/s3c24xx/smdk2440.c | 320 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 329 insertions(+), 0 deletions(-)
+ create mode 100644 sound/soc/s3c24xx/smdk2440.c
+
+diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
+index c414886..99fe902 100644
+--- a/sound/soc/s3c24xx/Kconfig
++++ b/sound/soc/s3c24xx/Kconfig
+@@ -21,5 +21,12 @@ config SND_S3C24XX_SOC_NEO1973_WM8753
+ Say Y if you want to add support for SoC audio on smdk2440
+ with the WM8753.
+
++config SND_S3C24XX_SOC_SMDK2440
++ tristate "SoC I2S Audio support for SMDK2440"
++ depends on SND_S3C24XX_SOC && MACH_SMDK
++ select SND_S3C24XX_SOC_I2S
++ help
++ Say Y if you want to add support for SoC audio on SMDK2440
++
+ endmenu
+
+diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
+index 7b5c6fe..b991052 100644
+--- a/sound/soc/s3c24xx/Makefile
++++ b/sound/soc/s3c24xx/Makefile
+@@ -7,5 +7,7 @@ obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
+
+ # S3C24XX Machine Support
+ snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
++snd-soc-smdk2440-objs := smdk2440.o
+
+ obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
++obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2440) += snd-soc-smdk2440.o
+diff --git a/sound/soc/s3c24xx/smdk2440.c b/sound/soc/s3c24xx/smdk2440.c
+new file mode 100644
+index 0000000..9885a5e
+--- /dev/null
++++ b/sound/soc/s3c24xx/smdk2440.c
+@@ -0,0 +1,320 @@
++/*
++ * smdk2440.c -- ALSA Soc Audio Layer
++ *
++ * (c) 2006 Wolfson Microelectronics PLC.
++ * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
++ *
++ * (c) 2004-2005 Simtec Electronics
++ * http://armlinux.simtec.co.uk/
++ * Ben Dooks <ben@simtec.co.uk>
++ *
++ * 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.
++ *
++ * This module is a modified version of the s3c24xx I2S driver supplied by
++ * Ben Dooks of Simtec and rejigged to the ASoC style at Wolfson Microelectronics
++ *
++ * Revision history
++ * 11th Dec 2006 Merged with Simtec driver
++ * 10th Nov 2006 Initial version.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.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/arch/hardware.h>
++#include <asm/arch/audio.h>
++#include <asm/io.h>
++#include <asm/arch/spi-gpio.h>
++#include "../codecs/uda1380.h"
++#include "s3c24xx-pcm.h"
++#include "s3c24xx-i2s.h"
++
++#define SMDK2440_DEBUG 0
++#if SMDK2440_DEBUG
++#define DBG(x...) printk(KERN_DEBUG x)
++#else
++#define DBG(x...)
++#endif
++
++/* audio clock in Hz */
++#define SMDK_CLOCK_SOURCE S3C24XX_CLKSRC_MPLL
++#define SMDK_CRYSTAL_CLOCK 16934400
++
++static int smdk2440_startup(struct snd_pcm_substream *substream)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_codec *codec = rtd->socdev->codec;
++
++ DBG("Entered smdk2440_startup\n");
++
++ return 0;
++}
++
++static int smdk2440_shutdown(struct snd_pcm_substream *substream)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_codec *codec = rtd->socdev->codec;
++
++ DBG("Entered smdk2440_shutdown\n");
++
++ return 0;
++}
++
++static int smdk2440_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;
++ struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
++ unsigned long iis_clkrate;
++ int div, div256, div384, diff256, diff384, bclk, mclk;
++ int ret;
++ unsigned int rate=params_rate(params);
++
++ DBG("Entered %s\n",__FUNCTION__);
++
++ iis_clkrate = s3c24xx_i2s_get_clockrate();
++
++ /* Using PCLK doesnt seem to suit audio particularly well on these cpu's
++ */
++
++ div256 = iis_clkrate / (rate * 256);
++ div384 = iis_clkrate / (rate * 384);
++
++ if (((iis_clkrate / div256) - (rate * 256)) <
++ ((rate * 256) - (iis_clkrate / (div256 + 1)))) {
++ diff256 = (iis_clkrate / div256) - (rate * 256);
++ } else {
++ div256++;
++ diff256 = (iis_clkrate / div256) - (rate * 256);
++ }
++
++ if (((iis_clkrate / div384) - (rate * 384)) <
++ ((rate * 384) - (iis_clkrate / (div384 + 1)))) {
++ diff384 = (iis_clkrate / div384) - (rate * 384);
++ } else {
++ div384++;
++ diff384 = (iis_clkrate / div384) - (rate * 384);
++ }
++
++ DBG("diff256 %d, diff384 %d\n", diff256, diff384);
++
++ if (diff256<=diff384) {
++ DBG("Selected 256FS\n");
++ div = div256 - 1;
++ bclk = S3C2410_IISMOD_256FS;
++ } else {
++ DBG("Selected 384FS\n");
++ div = div384 - 1;
++ bclk = S3C2410_IISMOD_384FS;
++ }
++
++ /* set codec DAI configuration */
++ ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
++ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
++ if (ret < 0)
++ return ret;
++
++ /* set cpu DAI configuration */
++ ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
++ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
++ if (ret < 0)
++ return ret;
++
++ /* set the audio system clock for DAC and ADC */
++ ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK,
++ rate, SND_SOC_CLOCK_OUT);
++ if (ret < 0)
++ return ret;
++
++ /* set MCLK division for sample rate */
++ ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, S3C2410_IISMOD_32FS );
++ if (ret < 0)
++ return ret;
++
++ /* set BCLK division for sample rate */
++ ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK, bclk);
++ if (ret < 0)
++ return ret;
++
++ /* set prescaler division for sample rate */
++ ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
++ S3C24XX_PRESCALE(div,div));
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static struct snd_soc_ops smdk2440_ops = {
++ .startup = smdk2440_startup,
++ .shutdown = smdk2440_shutdown,
++ .hw_params = smdk2440_hw_params,
++};
++
++/* smdk2440 machine dapm widgets */
++static const struct snd_soc_dapm_widget smdk2440_dapm_widgets[] = {
++SND_SOC_DAPM_HP("Headphone Jack", NULL),
++SND_SOC_DAPM_MIC("Mic Jack", NULL),
++SND_SOC_DAPM_LINE("Line Jack", NULL),
++};
++
++/* smdk2440 machine audio map (connections to the codec pins) */
++static const char* audio_map[][3] = {
++ /* headphone connected to HPOUT */
++ {"Headphone Jack", NULL, "HPOUT"},
++
++ /* mic is connected to MICIN (via right channel of headphone jack) */
++ {"MICIN", NULL, "Mic Jack"},
++ {"MICIN", NULL, "Line Jack"},
++
++ {NULL, NULL, NULL},
++};
++
++/*
++ * Logic for a UDA1341 as attached to SMDK2440
++ */
++static int smdk2440_uda1341_init(struct snd_soc_codec *codec)
++{
++ int i, err;
++
++ DBG("Staring smdk2440 init\n");
++
++ /* Add smdk2440 specific widgets */
++ for(i = 0; i < ARRAY_SIZE(smdk2440_dapm_widgets); i++) {
++ snd_soc_dapm_new_control(codec, &smdk2440_dapm_widgets[i]);
++ }
++
++ /* Set up smdk2440 specific audio path audio_mapnects */
++ for(i = 0; audio_map[i][0] != NULL; i++) {
++ snd_soc_dapm_connect_input(codec, audio_map[i][0],
++ audio_map[i][1], audio_map[i][2]);
++ }
++
++ snd_soc_dapm_sync_endpoints(codec);
++
++ DBG("Ending smdk2440 init\n");
++
++ return 0;
++}
++
++/* s3c24xx digital audio interface glue - connects codec <--> CPU */
++static struct snd_soc_dai_link s3c24xx_dai = {
++ .name = "WM8731",
++ .stream_name = "WM8731",
++ .cpu_dai = &s3c24xx_i2s_dai,
++ .codec_dai = &uda1380_dai,
++ .init = smdk2440_uda1341_init,
++ .ops = &smdk2440_ops,
++};
++
++/* smdk2440 audio machine driver */
++static struct snd_soc_machine snd_soc_machine_smdk2440 = {
++ .name = "SMDK2440",
++ .dai_link = &s3c24xx_dai,
++ .num_links = 1,
++};
++
++static struct uda1380_setup_data smdk2440_uda1380_setup = {
++ .i2c_address = 0x00,
++};
++
++/* s3c24xx audio subsystem */
++static struct snd_soc_device s3c24xx_snd_devdata = {
++ .machine = &snd_soc_machine_smdk2440,
++ .platform = &s3c24xx_soc_platform,
++ .codec_dev = &soc_codec_dev_uda1380,
++ .codec_data = &smdk2440_uda1380_setup,
++};
++
++static struct platform_device *s3c24xx_snd_device;
++
++struct smdk2440_spi_device {
++ struct device *dev;
++};
++
++static struct smdk2440_spi_device smdk2440_spi_devdata = {
++};
++
++struct s3c2410_spigpio_info smdk2440_spi_devinfo = {
++ .pin_clk = S3C2410_GPF4,
++ .pin_mosi = S3C2410_GPF5,
++ .pin_miso = S3C2410_GPF6,
++ //.board_size,
++ //.board_info,
++ .chip_select=NULL,
++};
++
++static struct platform_device *smdk2440_spi_device;
++
++static int __init smdk2440_init(void)
++{
++ int ret;
++
++ if (!machine_is_smdk2440() && !machine_is_s3c2440()) {
++ DBG("%d\n",machine_arch_type);
++ DBG("Not a SMDK2440\n");
++ return -ENODEV;
++ }
++
++ s3c24xx_snd_device = platform_device_alloc("soc-audio", -1);
++ if (!s3c24xx_snd_device) {
++ DBG("platform_dev_alloc failed\n");
++ return -ENOMEM;
++ }
++
++ platform_set_drvdata(s3c24xx_snd_device, &s3c24xx_snd_devdata);
++ s3c24xx_snd_devdata.dev = &s3c24xx_snd_device->dev;
++ ret = platform_device_add(s3c24xx_snd_device);
++
++ if (ret)
++ platform_device_put(s3c24xx_snd_device);
++
++ // Create a bitbanged SPI device
++
++ smdk2440_spi_device = platform_device_alloc("s3c24xx-spi-gpio",-1);
++ if (!smdk2440_spi_device) {
++ DBG("smdk2440_spi_device : platform_dev_alloc failed\n");
++ return -ENOMEM;
++ }
++ DBG("Return Code %d\n",ret);
++
++ platform_set_drvdata(smdk2440_spi_device, &smdk2440_spi_devdata);
++ smdk2440_spi_devdata.dev = &smdk2440_spi_device->dev;
++ smdk2440_spi_devdata.dev->platform_data = &smdk2440_spi_devinfo;
++ ret = platform_device_add(smdk2440_spi_device);
++
++ if (ret)
++ platform_device_put(smdk2440_spi_device);
++
++ return ret;
++}
++
++static void __exit smdk2440_exit(void)
++{
++ platform_device_unregister(s3c24xx_snd_device);
++}
++
++module_init(smdk2440_init);
++module_exit(smdk2440_exit);
++
++/* Module information */
++MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
++MODULE_DESCRIPTION("ALSA SoC SMDK2440");
++MODULE_LICENSE("GPL");
+--
+1.5.0.3
+