All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/4] ASoC: pxa add Marvell Littleton platform audio support
@ 2009-06-03 12:35 Eric Miao
  2009-06-03 13:28 ` Mark Brown
  2009-06-04 12:42 ` Mark Brown
  0 siblings, 2 replies; 3+ messages in thread
From: Eric Miao @ 2009-06-03 12:35 UTC (permalink / raw)
  To: linux-arm-kernel, alsa-devel; +Cc: Paul Shen, Mark Brown

Signed-off-by: Paul Shen <bshen9@marvell.com>
Signed-off-by: Eric Miao <eric.miao@marvell.com>
---
 sound/soc/pxa/Kconfig     |    9 ++
 sound/soc/pxa/Makefile    |    2 +
 sound/soc/pxa/littleton.c |  228 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 239 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/pxa/littleton.c

diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index ad8a10f..a4ad5ba 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -134,3 +134,12 @@ config SND_PXA2XX_SOC_MIOA701
         help
           Say Y if you want to add support for SoC audio on the
           MIO A701.
+
+config SND_PXA2XX_SOC_LITTLETON
+        tristate "SoC Audio support for Marvell littleton"
+        depends on SND_PXA2XX_SOC && MACH_LITTLETON
+        select SND_PXA_SOC_SSP
+        select SND_SOC_DA9034
+        help
+          Say Y if you want to add support for SoC audio on the
+          Marvell Littleton.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 4b90c3c..94c719d 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o
 snd-soc-zylonite-objs := zylonite.o
 snd-soc-magician-objs := magician.o
 snd-soc-mioa701-objs := mioa701_wm9713.o
+snd-soc-littleton-objs := littleton.o

 obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
 obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -34,4 +35,5 @@ obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
 obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
 obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
 obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
+obj-$(CONFIG_SND_PXA2XX_SOC_LITTLETON) += snd-soc-littleton.o
 obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
diff --git a/sound/soc/pxa/littleton.c b/sound/soc/pxa/littleton.c
new file mode 100644
index 0000000..911a5ef
--- /dev/null
+++ b/sound/soc/pxa/littleton.c
@@ -0,0 +1,228 @@
+/*
+ * littleton.c  --  SoC audio for Littleton
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *
+ *   Author: Paul Shen <bshen9@marvell.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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <asm/mach-types.h>
+#include <mach/ssp.h>
+#include <mach/regs-ssp.h>
+
+#include "pxa2xx-pcm.h"
+#include "pxa-ssp.h"
+
+static int hifi_mode;
+
+extern struct snd_soc_dai da9034_dais[2];
+extern struct snd_soc_codec_device soc_codec_dev_da9034;
+
+static const char *hifi_mode_select[] = {
+	"HIFI 64FS LEFT_J, SSP CLK Master FRM Master",
+	"HIFI 64FS I2S ,   SSP CLK Master FRM Master",
+	"HIFI 32FS LEFT_J, SSP CLK Master FRM Master",
+	"HIFI 32FS I2S ,   SSP CLK Master FRM Master",
+};
+
+static const struct soc_enum littleton_enum[] = {
+	SOC_ENUM_SINGLE_EXT(4, hifi_mode_select),
+};
+
+static int littleton_get_hifi_mode(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = hifi_mode;
+	return 0;
+}
+
+static int littleton_set_hifi_mode(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	hifi_mode = ucontrol->value.integer.value[0];
+	return 1;
+}
+
+static const struct snd_kcontrol_new littleton_da9034_controls[] = {
+	SOC_ENUM_EXT("Hifi Mode Select", littleton_enum[0],
+		littleton_get_hifi_mode, littleton_set_hifi_mode),
+};
+
+static int littleton_da9034_init(struct snd_soc_codec *codec)
+{
+	snd_soc_add_controls(codec, littleton_da9034_controls,
+			ARRAY_SIZE(littleton_da9034_controls));
+	return snd_soc_dapm_sync(codec);
+}
+
+struct ssp_clk_div {
+	unsigned int rate;
+	unsigned int pll;
+	unsigned int scdb;
+	unsigned int acds;
+};
+
+static struct ssp_clk_div littleton_hifi_clk_div_64fs[] = {
+	{ 48000, 12288000, PXA_SSP_CLK_SCDB_4, 0 },
+	{ 44100, 11289600, PXA_SSP_CLK_SCDB_4, 0 },
+	{ 32000,  4096000, PXA_SSP_CLK_SCDB_1, 1 },
+	{ 22050, 11289600, PXA_SSP_CLK_SCDB_8, 0 },
+	{ 16000,  4096000, PXA_SSP_CLK_SCDB_4, 0 },
+	{ 11025, 11289600, PXA_SSP_CLK_SCDB_4, 2 },
+	{  8000,  4096000, PXA_SSP_CLK_SCDB_4, 1 },
+	{},
+};
+
+static struct ssp_clk_div littleton_hifi_clk_div_32fs[] = {
+	{ 48000, 12288000, PXA_SSP_CLK_SCDB_4, 1 },
+	{ 44100, 11289600, PXA_SSP_CLK_SCDB_4, 1 },
+	{ 32000,  4096000, PXA_SSP_CLK_SCDB_1, 2 },
+	{ 22050, 11289600, PXA_SSP_CLK_SCDB_8, 1 },
+	{ 16000,  4096000, PXA_SSP_CLK_SCDB_4, 1 },
+	{ 11025, 11289600, PXA_SSP_CLK_SCDB_8, 2 },
+	{  8000,  4096000, PXA_SSP_CLK_SCDB_8, 1 },
+	{},
+};
+
+static int littleton_hifi_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_dai *codec_dai = rtd->dai->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct ssp_clk_div *clkdiv;
+	struct clk *clk_pout;
+	int format;
+
+	clk_pout = clk_get(NULL, "CLK_POUT");
+	if (IS_ERR(clk_pout)) {
+		pr_err("failed to get POUT clock\n");
+		return PTR_ERR(clk_pout);
+	}
+
+	clk_enable(clk_pout);
+
+	switch (hifi_mode) {
+	case 0:
+		format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
+			 SND_SOC_DAIFMT_CBS_CFS | PXA_SSP_FRM_64FS;
+		clkdiv = littleton_hifi_clk_div_64fs;
+		break;
+	case 1:
+		format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+			 SND_SOC_DAIFMT_CBS_CFS | PXA_SSP_FRM_64FS;
+		clkdiv = littleton_hifi_clk_div_64fs;
+		break;
+	case 2:
+		format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_IF |
+			 SND_SOC_DAIFMT_CBS_CFS | PXA_SSP_FRM_32FS;
+		clkdiv = littleton_hifi_clk_div_32fs;
+		break;
+	case 3:
+		format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+			 SND_SOC_DAIFMT_CBS_CFS | PXA_SSP_FRM_32FS;
+		clkdiv = littleton_hifi_clk_div_32fs;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	snd_soc_dai_set_fmt(codec_dai, format);
+	snd_soc_dai_set_fmt(cpu_dai, format);
+	snd_soc_dai_set_tdm_slot(cpu_dai, 3, 2);
+
+	for (; clkdiv->rate; clkdiv++) {
+		if (clkdiv->rate == params_rate(params))
+			break;
+	}
+
+	if (!clkdiv->rate)
+		return -EINVAL;
+
+	snd_soc_dai_set_pll(cpu_dai, 0, 0, clkdiv->pll);
+	snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
+	snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_SCDB, clkdiv->scdb);
+	snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_ACDS, clkdiv->acds);
+	return 0;
+}
+
+static struct snd_soc_ops littleton_hifi_ops = {
+	.hw_params = littleton_hifi_hw_params,
+};
+
+static struct snd_soc_dai_link littleton_dai[] = {
+	/* HiFi */
+	{
+		.name		= "DA9034 HiFi",
+		.stream_name	= "DA9034 HiFi",
+		.cpu_dai	= &pxa_ssp_dai[PXA_DAI_SSP3],
+		.codec_dai	= &da9034_dais[0],
+		.init		= littleton_da9034_init,
+		.ops		= &littleton_hifi_ops,
+	},
+};
+
+static struct snd_soc_card littleton = {
+	.name		= "Littleton",
+	.platform	= &pxa2xx_soc_platform,
+	.dai_link	= littleton_dai,
+	.num_links	= ARRAY_SIZE(littleton_dai),
+};
+
+static struct snd_soc_device littleton_snd_devdata = {
+	.card		= &littleton,
+	.codec_dev	= &soc_codec_dev_da9034,
+};
+
+static struct platform_device *littleton_snd_device;
+
+static int __init littleton_audio_init(void)
+{
+	int ret;
+
+	if (!machine_is_littleton()) {
+		pr_err("Only Littleton hardware supported by ASoC driver\n");
+		return -ENODEV;
+	}
+
+	littleton_snd_device = platform_device_alloc("soc-audio", -1);
+	if (!littleton_snd_device)
+		return -ENOMEM;
+
+	platform_set_drvdata(littleton_snd_device, &littleton_snd_devdata);
+	littleton_snd_devdata.dev = &littleton_snd_device->dev;
+
+	ret = platform_device_add(littleton_snd_device);
+	if (ret != 0)
+		platform_device_put(littleton_snd_device);
+
+	return ret;
+}
+
+static void __exit littleton_audio_exit(void)
+{
+	platform_device_unregister(littleton_snd_device);
+}
+
+module_init(littleton_audio_init);
+module_exit(littleton_audio_exit);
+
+MODULE_AUTHOR("Paul Shen <bshen9@marvell.com>");
+MODULE_DESCRIPTION("ALSA SoC Da9034 Littleton");
+MODULE_LICENSE("GPL");
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 3/4] ASoC: pxa add Marvell Littleton platform audio support
  2009-06-03 12:35 [PATCH 3/4] ASoC: pxa add Marvell Littleton platform audio support Eric Miao
@ 2009-06-03 13:28 ` Mark Brown
  2009-06-04 12:42 ` Mark Brown
  1 sibling, 0 replies; 3+ messages in thread
From: Mark Brown @ 2009-06-03 13:28 UTC (permalink / raw)
  To: Eric Miao; +Cc: alsa-devel, Paul Shen, linux-arm-kernel

On Wed, Jun 03, 2009 at 08:35:23PM +0800, Eric Miao wrote:
> Signed-off-by: Paul Shen <bshen9@marvell.com>
> Signed-off-by: Eric Miao <eric.miao@marvell.com>

This is OK but obviously depends on the CODEC driver so not applied just
now.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 3/4] ASoC: pxa add Marvell Littleton platform audio support
  2009-06-03 12:35 [PATCH 3/4] ASoC: pxa add Marvell Littleton platform audio support Eric Miao
  2009-06-03 13:28 ` Mark Brown
@ 2009-06-04 12:42 ` Mark Brown
  1 sibling, 0 replies; 3+ messages in thread
From: Mark Brown @ 2009-06-04 12:42 UTC (permalink / raw)
  To: Eric Miao; +Cc: alsa-devel, Paul Shen, linux-arm-kernel

On Wed, Jun 03, 2009 at 08:35:23PM +0800, Eric Miao wrote:

Sorry, missed a couple of things earlier:

> +static const char *hifi_mode_select[] = {
> +	"HIFI 64FS LEFT_J, SSP CLK Master FRM Master",
> +	"HIFI 64FS I2S ,   SSP CLK Master FRM Master",
> +	"HIFI 32FS LEFT_J, SSP CLK Master FRM Master",
> +	"HIFI 32FS I2S ,   SSP CLK Master FRM Master",
> +};
> +
> +static const struct soc_enum littleton_enum[] = {
> +	SOC_ENUM_SINGLE_EXT(4, hifi_mode_select),
> +};

BTW, for this control you really should add a comment explaining that
this is for test purposes only and that normal systems would not wish to
expose this control to applications but should just pick a suitable
configuration.

> +static int littleton_hifi_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_dai *codec_dai = rtd->dai->codec_dai;
> +	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
> +	struct ssp_clk_div *clkdiv;
> +	struct clk *clk_pout;
> +	int format;
> +
> +	clk_pout = clk_get(NULL, "CLK_POUT");
> +	if (IS_ERR(clk_pout)) {
> +		pr_err("failed to get POUT clock\n");
> +		return PTR_ERR(clk_pout);
> +	}
> +
> +	clk_enable(clk_pout);

At the minute clk_put is never released.

hw_params() can be repeatedly called while the stream is open,
especially by OSS emulation.  You should acquire the clock once at
driver startup time and probably move the enable and disable to
startup() and shutdown().

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-06-04 12:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-03 12:35 [PATCH 3/4] ASoC: pxa add Marvell Littleton platform audio support Eric Miao
2009-06-03 13:28 ` Mark Brown
2009-06-04 12:42 ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.