JIVE: Add ASoC audio support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add support for the Jive's WM8750 codec attached
to the S3C2412 IIS controller.

Signed-off-by: Ben Dooks <ben-linux@xxxxxxxxx>

Index: linux-2.6.26-rc5-quilt2/sound/soc/s3c24xx/Kconfig
===================================================================
--- linux-2.6.26-rc5-quilt2.orig/sound/soc/s3c24xx/Kconfig	2008-06-10 12:31:40.000000000 +0100
+++ linux-2.6.26-rc5-quilt2/sound/soc/s3c24xx/Kconfig	2008-06-12 11:07:04.000000000 +0100
@@ -28,6 +28,15 @@ 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_JIVE_WM8750
+	tristate "SoC I2S Audio support for Jive"
+	depends on SND_S3C24XX_SOC && MACH_JIVE
+	select SND_SOC_WM8750
+	select SND_SOC_WM8750_SPI
+	select SND_S3C2412_SOC_I2S
+	help
+	  Sat Y if you want to add support for SoC audio on the Jive.
+
 config SND_S3C24XX_SOC_SMDK2443_WM9710
 	tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
 	depends on SND_S3C24XX_SOC && MACH_SMDK2443
Index: linux-2.6.26-rc5-quilt2/sound/soc/s3c24xx/Makefile
===================================================================
--- linux-2.6.26-rc5-quilt2.orig/sound/soc/s3c24xx/Makefile	2008-06-10 12:31:40.000000000 +0100
+++ linux-2.6.26-rc5-quilt2/sound/soc/s3c24xx/Makefile	2008-06-12 11:07:04.000000000 +0100
@@ -10,10 +10,12 @@ obj-$(CONFIG_SND_S3C2443_SOC_AC97) += sn
 obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
 
 # S3C24XX Machine Support
+snd-soc-jive-wm8750-objs := jive_wm8750.o
 snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
 snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
 snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
 
+obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
 obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
 obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
 obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
Index: linux-2.6.26-rc5-quilt2/sound/soc/s3c24xx/jive_wm8750.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.26-rc5-quilt2/sound/soc/s3c24xx/jive_wm8750.c	2008-06-12 11:07:04.000000000 +0100
@@ -0,0 +1,266 @@
+/* sound/soc/s3c24xx/jive_wm8705.c
+ *
+ * Copyright 2007 Simtec Electronics
+ *
+ * Based on sound/soc/pxa/spitz.c
+ *	Copyright 2005 Wolfson Microelectronics PLC.
+ *	Copyright 2005 Openedhand Ltd.
+ *
+ *  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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/clk.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 "s3c24xx-pcm.h"
+#include "s3c2412-i2s.h"
+
+#include "../codecs/wm8750.h"
+
+static const char *audio_map[][2] = {
+	[0]	= { "Headphone Jack", "LOUT1" },
+	[1]	= { "Headphone Jack", "ROUT1" },
+	[2]	= { "Internal Speaker", "LOUT2" },
+	[3]	= { "Internal Speaker", "ROUT2" },
+	[4]	= { "LINPUT1", "Line Input" },
+	[5]	= { "RINPUT1", "Line Input" },
+	[6]	= { NULL, NULL },
+};
+
+static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
+	SND_SOC_DAPM_SPK("Internal Speaker", NULL),
+	SND_SOC_DAPM_LINE("Line In", NULL),
+};
+
+static int jive_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_codec *codec = rtd->socdev->codec;
+
+	snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1);
+	snd_soc_dapm_set_endpoint(codec, "Internal Speaker", 1);
+	snd_soc_dapm_set_endpoint(codec, "Line In", 1);
+
+	snd_soc_dapm_sync_endpoints(codec);
+
+	return 0;
+}
+
+static inline int codec_set_dai_fmt(struct snd_soc_codec_dai *dai,
+				    unsigned int format)
+{
+	return dai->dai_ops.set_fmt(dai, format);
+}
+
+static inline int codec_set_dai_sysclk(struct snd_soc_codec_dai *dai,
+				       unsigned int clk,
+				       unsigned int arg,
+				       unsigned int arg2)
+{
+	return dai->dai_ops.set_sysclk(dai, clk, arg, arg2);
+}
+
+static inline int cpu_set_dai_fmt(struct snd_soc_cpu_dai *dai,
+				  unsigned int format)
+{
+	return dai->dai_ops.set_fmt(dai, format);
+}
+
+static inline int cpu_set_dai_sysclk(struct snd_soc_cpu_dai *dai,
+				     unsigned int clk,
+				     unsigned int arg,
+				     unsigned int arg2)
+{
+	return dai->dai_ops.set_sysclk(dai, clk, arg, arg2);
+}
+
+static inline int cpu_set_dai_clkdiv(struct snd_soc_cpu_dai *dai,
+				     unsigned int clk,
+				     unsigned int arg)
+{
+	return dai->dai_ops.set_clkdiv(dai, clk, arg);
+}
+
+
+
+static int jive_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_codec_dai *codec_dai = rtd->dai->codec_dai;
+	struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct s3c2412_rate_calc div;
+	unsigned int clk = 0;
+	int ret = 0;
+
+	switch (params_rate(params)) {
+	case 8000:
+	case 16000:
+	case 48000:
+	case 96000:
+		clk = 12288000;
+		break;
+	case 11025:
+	case 22050:
+	case 44100:
+		clk = 11289600;
+		break;
+	}
+
+	s3c2412_iis_calc_rate(&div, NULL, params_rate(params),
+			      s3c2412_get_iisclk());
+
+	/* set codec DAI configuration */
+	ret = codec_set_dai_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_set_dai_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+			      SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+	if (ret < 0)
+		return ret;
+
+	/* set the codec system clock for DAC and ADC */
+	ret = codec_set_dai_sysclk(codec_dai, WM8750_SYSCLK, clk,
+				   SND_SOC_CLOCK_IN);
+	if (ret < 0)
+		return ret;
+
+	ret = cpu_set_dai_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div);
+	if (ret < 0)
+		return ret;
+
+	ret = cpu_set_dai_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER, div.clk_div - 1);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static struct snd_soc_ops jive_ops = {
+	.startup	= jive_startup,
+	.hw_params	= jive_hw_params,
+};
+
+static const struct snd_kcontrol_new wm8750_jive_controls[] = {
+
+};
+
+static int jive_wm8750_init(struct snd_soc_codec *codec)
+{
+	int i, err;
+
+	/* These endpoints are not being used. */
+	snd_soc_dapm_set_endpoint(codec, "LINPUT2", 0);
+	snd_soc_dapm_set_endpoint(codec, "RINPUT2", 0);
+	snd_soc_dapm_set_endpoint(codec, "LINPUT3", 0);
+	snd_soc_dapm_set_endpoint(codec, "RINPUT3", 0);
+	snd_soc_dapm_set_endpoint(codec, "OUT3", 0);
+	snd_soc_dapm_set_endpoint(codec, "MONO", 0);
+
+	/* Add jive specific controls */
+	for (i = 0; i < ARRAY_SIZE(wm8750_jive_controls); i++) {
+		err = snd_ctl_add(codec->card,
+			snd_soc_cnew(&wm8750_jive_controls[i], codec, NULL));
+		if (err < 0)
+			return err;
+	}
+
+	/* Add jive specific widgets */
+	for (i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++) {
+		snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]);
+	}
+
+	/* Set up jive specific audio path audio_map */
+	for (i = 0; audio_map[i][0] != NULL; i++) {
+		printk(KERN_INFO "mapping %s => %s\n", audio_map[i][0], audio_map[i][1]);
+		snd_soc_dapm_connect_input(codec, audio_map[i][0], NULL,
+					   audio_map[i][1]);
+	}
+
+	snd_soc_dapm_sync_endpoints(codec);
+	return 0;
+}
+
+static struct snd_soc_dai_link jive_dai = {
+	.name		= "wm8750",
+	.stream_name	= "WM8750",
+	.cpu_dai	= &s3c2412_i2s_dai,
+	.codec_dai	= &wm8750_dai,
+	.init		= jive_wm8750_init,
+	.ops		= &jive_ops,
+};
+
+/* jive audio machine driver */
+static struct snd_soc_machine snd_soc_machine_jive = {
+	.name		= "Jive",
+	.dai_link	= &jive_dai,
+	.num_links	= 1,
+};
+
+/* jive audio private data */
+static struct wm8750_setup_data jive_wm8750_setup = {
+};
+
+/* jive audio subsystem */
+static struct snd_soc_device jive_snd_devdata = {
+	.machine	= &snd_soc_machine_jive,
+	.platform	= &s3c24xx_soc_platform,
+	.codec_dev	= &soc_codec_dev_wm8750_spi,
+	.codec_data	= &jive_wm8750_setup,
+};
+
+static struct platform_device *jive_snd_device;
+
+static int __init jive_init(void)
+{
+	int ret;
+
+	printk("JIVE WM8750 Audio support\n");
+
+	if (!machine_is_jive())
+		return 0;
+
+	jive_snd_device = platform_device_alloc("soc-audio", -1);
+	if (!jive_snd_device)
+		return -ENOMEM;
+
+	platform_set_drvdata(jive_snd_device, &jive_snd_devdata);
+	jive_snd_devdata.dev = &jive_snd_device->dev;
+	ret = platform_device_add(jive_snd_device);
+
+	if (ret)
+		platform_device_put(jive_snd_device);
+
+	return ret;
+}
+
+static void __exit jive_exit(void)
+{
+	platform_device_unregister(jive_snd_device);
+}
+
+module_init(jive_init);
+module_exit(jive_exit);
+
+MODULE_AUTHOR("Ben Dooks <ben@xxxxxxxxxxxx>");
+MODULE_DESCRIPTION("ALSA SoC Jive");
+MODULE_LICENSE("GPL");
 

-- 
Ben (ben@xxxxxxxxx, http://www.fluff.org/)

  'a smiley only costs 4 bytes'
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux