Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/3] ASoC: add machine driver for i.mx27_visstrim_m10 board
@ 2009-08-04 15:18 javier Martin
  2009-08-04 16:38 ` Controling wave amplitude using alsa api !! (pcm interface ???????) Guilherme Longo
  2009-08-04 19:54 ` [PATCH 3/3] ASoC: add machine driver for i.mx27_visstrim_m10 board Mark Brown
  0 siblings, 2 replies; 5+ messages in thread
From: javier Martin @ 2009-08-04 15:18 UTC (permalink / raw)
  To: alsa-devel; +Cc: Mark Brown, Liam Girdwood

This adds support for i.mx27_visstrim_sm10 board machine driver which
uses an i.mx27 processor plus a wm8974 codec.

It has been tested on a visstrim_sm10 board.

Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
---
 sound/soc/imx/Kconfig          |    8 +
 sound/soc/imx/Makefile         |    4 +
 sound/soc/imx/mx27vis_wm8974.c |  317 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 329 insertions(+), 0 deletions(-)

diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 886dadd..2c6f568 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -9,5 +9,13 @@ config SND_MX1_MX2_SOC
 config SND_MXC_SOC_SSI
 	tristate

+config SND_SOC_MX27VIS_WM8974
+	tristate "SoC Audio support for MX27 - WM8974 Visstrim_sm10 board"
+	depends on SND_MX1_MX2_SOC && MACH_MX27 && MACH_IMX27_VISSTRIM_M10
+	select SND_MXC_SOC_SSI
+	select SND_SOC_WM8974
+	help
+	  Say Y if you want to add support for SoC audio on Visstrim SM10
+	  board with WM8974.


diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index 6552cb2..c2ffd2c 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -4,3 +4,7 @@ snd-soc-mxc-ssi-objs := mxc-ssi.o

 obj-$(CONFIG_SND_MX1_MX2_SOC) += snd-soc-mx1_mx2.o
 obj-$(CONFIG_SND_MXC_SOC_SSI) += snd-soc-mxc-ssi.o
+
+# i.MX Machine Support
+snd-soc-mx27vis-wm8974-objs := mx27vis_wm8974.o
+obj-$(CONFIG_SND_SOC_MX27VIS_WM8974) += snd-soc-mx27vis-wm8974.o
diff --git a/sound/soc/imx/mx27vis_wm8974.c b/sound/soc/imx/mx27vis_wm8974.c
new file mode 100644
index 0000000..e4dcb53
--- /dev/null
+++ b/sound/soc/imx/mx27vis_wm8974.c
@@ -0,0 +1,317 @@
+/*
+ * mx27vis_wm8974.c  --  SoC audio for mx27vis
+ *
+ * Copyright 2009 Vista Silicon S.L.
+ * Author: Javier Martin
+ *         javier.martin@vista-silicon.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/i2c.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+
+#include "../codecs/wm8974.h"
+#include "mx1_mx2-pcm.h"
+#include "mxc-ssi.h"
+#include <mach/gpio.h>
+#include <mach/iomux.h>
+
+#define IGNORED_ARG 0
+
+
+static struct snd_soc_card mx27vis;
+
+/**
+  * This function connects SSI1 (HPCR1) as slave to
+  * SSI1 external signals (PPCR1)
+  * As slave, HPCR1 must set TFSDIR and TCLKDIR as inputs from
+  * port 4
+  */
+void audmux_connect_1_4(void)
+{
+	pr_debug("AUDMUX: normal operation mode\n");
+	/* Reset HPCR1 and PPCR1 */
+
+	DAM_HPCR1 = 0x00000000;
+	DAM_PPCR1 = 0x00000000;
+
+	/* set to synchronous */
+	DAM_HPCR1 |= AUDMUX_HPCR_SYN;
+	DAM_PPCR1 |= AUDMUX_PPCR_SYN;
+
+
+	/* set Rx sources 1 <--> 4 */
+	DAM_HPCR1 |= AUDMUX_HPCR_RXDSEL(3); /* port 4 */
+	DAM_PPCR1 |= AUDMUX_PPCR_RXDSEL(0); /* port 1 */
+
+	/* set Tx frame and Clock direction and source  4 --> 1 output */
+	DAM_HPCR1 |= AUDMUX_HPCR_TFSDIR | AUDMUX_HPCR_TCLKDIR;
+	DAM_HPCR1 |= AUDMUX_HPCR_TFCSEL(3); /* TxDS and TxCclk from port 4 */
+
+	return;
+}
+
+static int mx27vis_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;
+	unsigned int pll_out = 0, bclk = 0, fmt = 0, mclk = 0;
+	int ret = 0;
+
+	/*
+	 * The WM8974 is better at generating accurate audio clocks than the
+	 * MX27 SSI controller, so we will use it as master when we can.
+	 */
+	switch (params_rate(params)) {
+	case 8000:
+		fmt = SND_SOC_DAIFMT_CBM_CFM;
+		mclk = WM8974_MCLKDIV_12;
+		pll_out = 24576000;
+		break;
+	case 16000:
+		fmt = SND_SOC_DAIFMT_CBM_CFM;
+		pll_out = 12288000;
+		break;
+	case 48000:
+		fmt = SND_SOC_DAIFMT_CBM_CFM;
+		bclk = WM8974_BCLKDIV_4;
+		pll_out = 12288000;
+		break;
+	case 96000:
+		fmt = SND_SOC_DAIFMT_CBM_CFM;
+		bclk = WM8974_BCLKDIV_2;
+		pll_out = 12288000;
+		break;
+	case 11025:
+		fmt = SND_SOC_DAIFMT_CBM_CFM;
+		bclk = WM8974_BCLKDIV_16;
+		pll_out = 11289600;
+		break;
+	case 22050:
+		fmt = SND_SOC_DAIFMT_CBM_CFM;
+		bclk = WM8974_BCLKDIV_8;
+		pll_out = 11289600;
+		break;
+	case 44100:
+		fmt = SND_SOC_DAIFMT_CBM_CFM;
+		bclk = WM8974_BCLKDIV_4;
+		mclk = WM8974_MCLKDIV_2;
+		pll_out = 11289600;
+		break;
+	case 88200:
+		fmt = SND_SOC_DAIFMT_CBM_CFM;
+		bclk = WM8974_BCLKDIV_2;
+		pll_out = 11289600;
+		break;
+	}
+
+	/* set codec DAI configuration */
+	ret = codec_dai->ops->set_fmt(codec_dai,
+		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
+		SND_SOC_DAIFMT_SYNC | fmt);
+	if (ret < 0) {
+		printk(KERN_ERR "Error from codec DAI configuration\n");
+		return ret;
+	}
+
+	/* set cpu DAI configuration */
+	ret = cpu_dai->ops->set_fmt(cpu_dai,
+		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+		SND_SOC_DAIFMT_SYNC | fmt);
+	if (ret < 0) {
+		printk(KERN_ERR "Error from cpu DAI configuration\n");
+		return ret;
+	}
+
+	/* Put DC field of STCCR to 1 (not zero) */
+	ret = cpu_dai->ops->set_tdm_slot(cpu_dai, 0, 2);
+
+	/* set the SSI system clock as input */
+	ret = cpu_dai->ops->set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
+		SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		printk(KERN_ERR "Error when setting system SSI clk\n");
+		return ret;
+	}
+
+	/* set codec BCLK division for sample rate */
+	ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_BCLKDIV, bclk);
+	if (ret < 0) {
+		printk(KERN_ERR "Error when setting BCLK division\n");
+		return ret;
+	}
+
+
+	/* codec PLL input is 25 MHz */
+	ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG,
+					25000000, pll_out);
+	if (ret < 0) {
+		printk(KERN_ERR "Error when setting PLL input\n");
+		return ret;
+	}
+
+	/*set codec MCLK division for sample rate */
+	ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_MCLKDIV, mclk);
+	if (ret < 0) {
+		printk(KERN_ERR "Error when setting MCLK division\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mx27vis_hifi_hw_free(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+
+	/* disable the PLL */
+	return codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, 0, 0);
+}
+
+/*
+ * mx27vis WM8974 HiFi DAI opserations.
+ */
+static struct snd_soc_ops mx27vis_hifi_ops = {
+	.hw_params = mx27vis_hifi_hw_params,
+	.hw_free = mx27vis_hifi_hw_free,
+};
+
+
+static int mx27vis_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	return 0;
+}
+
+static int mx27vis_resume(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int mx27vis_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	ret = get_ssi_clk(0, &pdev->dev);
+
+	if (ret < 0) {
+		printk(KERN_ERR "%s: cant get ssi clock\n", __func__);
+		return ret;
+	}
+
+
+	return 0;
+}
+
+static int mx27vis_remove(struct platform_device *pdev)
+{
+	put_ssi_clk(0);
+	return 0;
+}
+
+static struct snd_soc_dai_link mx27vis_dai[] = {
+{ /* Hifi Playback*/
+	.name = "WM8974",
+	.stream_name = "WM8974 HiFi",
+	.cpu_dai = &imx_ssi_pcm_dai[0],
+	.codec_dai = &wm8974_dai,
+	.ops = &mx27vis_hifi_ops,
+},
+};
+
+static struct snd_soc_card mx27vis = {
+	.name = "mx27vis",
+	.platform = &mx1_mx2_soc_platform,
+	.probe = mx27vis_probe,
+	.remove = mx27vis_remove,
+	.suspend_pre = mx27vis_suspend,
+	.resume_post = mx27vis_resume,
+	.dai_link = mx27vis_dai,
+	.num_links = ARRAY_SIZE(mx27vis_dai),
+};
+
+static struct snd_soc_device mx27vis_snd_devdata = {
+	.card = &mx27vis,
+	.codec_dev = &soc_codec_dev_wm8974,
+};
+
+static struct platform_device *mx27vis_snd_device;
+
+/* Temporal definition of board specific behaviour */
+void gpio_ssi_active(int ssi_num)
+{
+	int ret = 0;
+
+	unsigned int ssi1_pins[] = {
+		PC20_PF_SSI1_FS,
+		PC21_PF_SSI1_RXD,
+		PC22_PF_SSI1_TXD,
+		PC23_PF_SSI1_CLK,
+	};
+	unsigned int ssi2_pins[] = {
+		PC24_PF_SSI2_FS,
+		PC25_PF_SSI2_RXD,
+		PC26_PF_SSI2_TXD,
+		PC27_PF_SSI2_CLK,
+	};
+	if (ssi_num == 0)
+		ret = mxc_gpio_setup_multiple_pins(ssi1_pins,
+				ARRAY_SIZE(ssi1_pins), "USB OTG");
+	else
+		ret = mxc_gpio_setup_multiple_pins(ssi2_pins,
+				ARRAY_SIZE(ssi2_pins), "USB OTG");
+	if (ret)
+		printk(KERN_ERR "Error requesting ssi %x pins\n", ssi_num);
+}
+
+
+static int __init mx27vis_init(void)
+{
+	int ret;
+
+	mx27vis_snd_device = platform_device_alloc("soc-audio", -1);
+	if (!mx27vis_snd_device)
+		return -ENOMEM;
+
+	platform_set_drvdata(mx27vis_snd_device, &mx27vis_snd_devdata);
+	mx27vis_snd_devdata.dev = &mx27vis_snd_device->dev;
+	ret = platform_device_add(mx27vis_snd_device);
+
+	if (ret) {
+		printk(KERN_ERR "ASoC: Platform device allocation failed\n");
+		platform_device_put(mx27vis_snd_device);
+	}
+
+	/* WM8974 uses SSI1 (HPCR1) via AUDMUX port 4 for audio (PPCR1) */
+	gpio_ssi_active(0);
+	audmux_connect_1_4();
+
+	return ret;
+}
+
+static void __exit mx27vis_exit(void)
+{
+	/* We should call some "ssi_gpio_inactive()" properly */
+}
+
+module_init(mx27vis_init);
+module_exit(mx27vis_exit);
+
+
+MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
+MODULE_DESCRIPTION("ALSA SoC WM8974 mx27vis");
+MODULE_LICENSE("GPL");
---

-- 
Javier Martin
Vista Silicon S.L.
Universidad de Cantabria
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com

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

* Controling wave amplitude using alsa api !! (pcm interface ???????)
  2009-08-04 15:18 [PATCH 3/3] ASoC: add machine driver for i.mx27_visstrim_m10 board javier Martin
@ 2009-08-04 16:38 ` Guilherme Longo
  2009-08-04 17:08   ` John L. Utz III
  2009-08-05 11:35   ` Guilherme Longo
  2009-08-04 19:54 ` [PATCH 3/3] ASoC: add machine driver for i.mx27_visstrim_m10 board Mark Brown
  1 sibling, 2 replies; 5+ messages in thread
From: Guilherme Longo @ 2009-08-04 16:38 UTC (permalink / raw)
  To: alsa-devel

Hi all!

Mates, I am following the example PCM.C that I found at alsa web site. 
its a sine wave generator.
I am looking for a control that alsa provides to control the amplitude 
of the wave.

As I could found so for, there is just frequency control... I didn't 
find any amplitude control.

* I don't want to control the volume using alsamixer or even my sound... 
I want to generate a wave with predefined amplitude.

Does anyone could give me a little help??

Thanks a lot!

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

* Re: Controling wave amplitude using alsa api !! (pcm interface ???????)
  2009-08-04 16:38 ` Controling wave amplitude using alsa api !! (pcm interface ???????) Guilherme Longo
@ 2009-08-04 17:08   ` John L. Utz III
  2009-08-05 11:35   ` Guilherme Longo
  1 sibling, 0 replies; 5+ messages in thread
From: John L. Utz III @ 2009-08-04 17:08 UTC (permalink / raw)
  To: Guilherme Longo; +Cc: alsa-devel

Guilherme Longo wrote:
> Hi all!
> 
> Mates, I am following the example PCM.C that I found at alsa web site. 
> its a sine wave generator.
> I am looking for a control that alsa provides to control the amplitude 
> of the wave.
> 
> As I could found so for, there is just frequency control... I didn't 
> find any amplitude control.

This line int pcm.c is not amplitude control?

unsigned int maxval = (1 << (snd_pcm_format_width(format) - 1)) - 1;

it's an int, so you probably need to alter this a bit to allow you to
have arbitrary control over the amplitude (ie: multiply by a float less
than 1.0)

HTH

johnu


> * I don't want to control the volume using alsamixer or even my sound... 
> I want to generate a wave with predefined amplitude.
> 
> Does anyone could give me a little help??
> 
> Thanks a lot!
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

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

* Re: [PATCH 3/3] ASoC: add machine driver for i.mx27_visstrim_m10 board
  2009-08-04 15:18 [PATCH 3/3] ASoC: add machine driver for i.mx27_visstrim_m10 board javier Martin
  2009-08-04 16:38 ` Controling wave amplitude using alsa api !! (pcm interface ???????) Guilherme Longo
@ 2009-08-04 19:54 ` Mark Brown
  1 sibling, 0 replies; 5+ messages in thread
From: Mark Brown @ 2009-08-04 19:54 UTC (permalink / raw)
  To: javier Martin; +Cc: alsa-devel, Liam Girdwood

On Tue, Aug 04, 2009 at 05:18:02PM +0200, javier Martin wrote:
> This adds support for i.mx27_visstrim_sm10 board machine driver which
> uses an i.mx27 processor plus a wm8974 codec.

> It has been tested on a visstrim_sm10 board.

> Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>

Again, this all looks good with some relatively small nits.

> +/**
> +  * This function connects SSI1 (HPCR1) as slave to
> +  * SSI1 external signals (PPCR1)
> +  * As slave, HPCR1 must set TFSDIR and TCLKDIR as inputs from
> +  * port 4
> +  */
> +void audmux_connect_1_4(void)
> +{

Obviously this ought to get pulled out, either into an arch AUXMUX thing
or a separate file in here.  However, neither of those things exist
right now.  I'll just go prod the last AUXMUX thread on linux-arm-kernel.

> +	return;
> +}

No need for the return; here.

> +	/*
> +	 * The WM8974 is better at generating accurate audio clocks than the
> +	 * MX27 SSI controller, so we will use it as master when we can.
> +	 */
> +	switch (params_rate(params)) {
> +	case 8000:

Unless I'm missing something the "when we can" is "in all cases" :)

> +	/* set codec DAI configuration */
> +	ret = codec_dai->ops->set_fmt(codec_dai,
> +		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
> +		SND_SOC_DAIFMT_SYNC | fmt);
> +	if (ret < 0) {
> +		printk(KERN_ERR "Error from codec DAI configuration\n");
> +		return ret;
> +	}

Printing the value of ret would be nice.

> +	/* Put DC field of STCCR to 1 (not zero) */
> +	ret = cpu_dai->ops->set_tdm_slot(cpu_dai, 0, 2);

Rats, you are using the TDM slot configuration.  Oh well.  Should check
this error.

> +static int mx27vis_suspend(struct platform_device *pdev, pm_message_t state)
> +{
> +	return 0;
> +}
> +
> +static int mx27vis_resume(struct platform_device *pdev)
> +{
> +	return 0;
> +}

These can be omitted if empty.

> +	unsigned int ssi1_pins[] = {
> +		PC20_PF_SSI1_FS,
> +		PC21_PF_SSI1_RXD,
> +		PC22_PF_SSI1_TXD,
> +		PC23_PF_SSI1_CLK,
> +	};
> +	unsigned int ssi2_pins[] = {
> +		PC24_PF_SSI2_FS,
> +		PC25_PF_SSI2_RXD,
> +		PC26_PF_SSI2_TXD,
> +		PC27_PF_SSI2_CLK,
> +	};
> +	if (ssi_num == 0)
> +		ret = mxc_gpio_setup_multiple_pins(ssi1_pins,
> +				ARRAY_SIZE(ssi1_pins), "USB OTG");
> +	else
> +		ret = mxc_gpio_setup_multiple_pins(ssi2_pins,
> +				ARRAY_SIZE(ssi2_pins), "USB OTG");

This would normally be done under arch/arm in the board setup code.

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

* Re: Controling wave amplitude using alsa api !! (pcm interface ???????)
  2009-08-04 16:38 ` Controling wave amplitude using alsa api !! (pcm interface ???????) Guilherme Longo
  2009-08-04 17:08   ` John L. Utz III
@ 2009-08-05 11:35   ` Guilherme Longo
  1 sibling, 0 replies; 5+ messages in thread
From: Guilherme Longo @ 2009-08-05 11:35 UTC (permalink / raw)
  To: alsa-devel

Hi again.

I've got half of my work done with it. I found the values of the samples 
been analyzed, **BUT* *it is given in a strange unity!

while (count-- > 0) {
                 res = sin(phase) * 15000;
                 ires.i = res;
                 tmp = ires.c;
               * printf("som -> %g\n", res);  // Here I get the values*
                 for (chn = 0; chn < channels; chn++) {
                        for (byte = 0; byte < (unsigned int)bps; byte++)
                                 *(samples[chn] + byte) = tmp[1];
                                  samples[chn] += steps[chn];
                 }

Now, how can I transform this samples in a more human understandable 
notation as in Db unity for example?
Is there any alsa api function to control it? Should I use the mixer  
interface somehow?

This is the output:

som -> 11976.3
som -> 11387
som -> 10752.9
som -> 10076.6
som -> 9360.7
som -> 8608.02
som -> 7821.53
som -> 7004.31
som -> 6159.56
som -> 5290.63
som -> 4400.9
som -> 3493.89
som -> 2573.15
som -> 1642.3
som -> 704.996
som -> -235.076
som -> -1174.22
som -> -2108.76
som -> -3035.01
som -> -3949.33
som -> -4848.14
som -> -5727.91

Thanks!
Guilherme Longo wrote:
> Hi all!
>
> Mates, I am following the example PCM.C that I found at alsa web site. 
> its a sine wave generator.
> I am looking for a control that alsa provides to control the amplitude 
> of the wave.
>
> As I could found so for, there is just frequency control... I didn't 
> find any amplitude control.
>
> * I don't want to control the volume using alsamixer or even my 
> sound... I want to generate a wave with predefined amplitude.
>
> Does anyone could give me a little help??
>
> Thanks a lot!
>
>

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

end of thread, other threads:[~2009-08-05 11:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-04 15:18 [PATCH 3/3] ASoC: add machine driver for i.mx27_visstrim_m10 board javier Martin
2009-08-04 16:38 ` Controling wave amplitude using alsa api !! (pcm interface ???????) Guilherme Longo
2009-08-04 17:08   ` John L. Utz III
2009-08-05 11:35   ` Guilherme Longo
2009-08-04 19:54 ` [PATCH 3/3] ASoC: add machine driver for i.mx27_visstrim_m10 board Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox