]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00179127 Audio integration for AMFM module to ARD platform
authorAlejandro Sierra <b18039@freescale.com>
Tue, 17 Apr 2012 18:52:34 +0000 (13:52 -0500)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:34:27 +0000 (08:34 +0200)
Audio integration of AMFM module to ARD platform IMX6Q and IMX6DL
rev A and rev B boards. Supported on ALSA for kernel 3.0.15.

Signed-off-by: Alejandro Sierra <b18039@freescale.com>
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/si4763.c [new file with mode: 0644]
sound/soc/imx/Kconfig
sound/soc/imx/Makefile
sound/soc/imx/imx-si4763.c [new file with mode: 0644]
sound/soc/imx/imx-si4763.h [new file with mode: 0644]

index 99d3806e75351f663276bb6f14ca2750f61c3866..af1c3a9444cac8df8a30a4b868b81a1a1aff9a7a 100644 (file)
@@ -221,6 +221,9 @@ config SND_SOC_SN95031
 config SND_SOC_CS42888
        tristate
 
+config SND_SOC_SI4763
+        tristate
+
 config SND_SOC_SPDIF
        tristate
 
index 8efb5130dc1fdd32c91b726d93ba33fd1fbaa24a..e08ff304aa9d3f32a3db629b18accd9a4be8bf89 100644 (file)
@@ -27,6 +27,7 @@ snd-soc-max9850-objs := max9850.o
 snd-soc-pcm3008-objs := pcm3008.o
 snd-soc-sgtl5000-objs := sgtl5000.o
 snd-soc-cs42888-objs := cs42888.o
+snd-soc-si4763-objs := si4763.o
 snd-soc-alc5623-objs := alc5623.o
 snd-soc-sn95031-objs := sn95031.o
 snd-soc-spdif-objs := spdif_transciever.o
@@ -123,6 +124,7 @@ obj-$(CONFIG_SND_SOC_MAX98095)      += snd-soc-max98095.o
 obj-$(CONFIG_SND_SOC_MAX9850)  += snd-soc-max9850.o
 obj-$(CONFIG_SND_SOC_PCM3008)  += snd-soc-pcm3008.o
 obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
+obj-$(CONFIG_SND_SOC_SI4763)    += snd-soc-si4763.o
 obj-$(CONFIG_SND_SOC_SN95031)  +=snd-soc-sn95031.o
 obj-$(CONFIG_SND_SOC_SPDIF)    += snd-soc-spdif.o
 obj-$(CONFIG_SND_SOC_SSM2602)  += snd-soc-ssm2602.o
diff --git a/sound/soc/codecs/si4763.c b/sound/soc/codecs/si4763.c
new file mode 100644 (file)
index 0000000..b2c5dc9
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#define SI4763_RATES SNDRV_PCM_RATE_48000
+
+#define SI4763_FORMATS SNDRV_PCM_FMTBIT_S16_LE
+
+static struct snd_soc_dai_driver si4763_codec_dai = {
+       .name = "si4763",
+       .capture = {
+                   .stream_name = "Capture",
+                   .channels_min = 1,
+                   .channels_max = 2,
+                   .rates = SI4763_RATES,
+                   .formats = SI4763_FORMATS,
+                   },
+};
+
+static int mxc_si4763_codec_soc_probe(struct snd_soc_codec *codec)
+{
+       return 0;
+}
+static struct snd_soc_codec_driver soc_codec_dev_si4763 = {
+       .probe = mxc_si4763_codec_soc_probe,
+};
+
+static int si4763_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       dev_info(&pdev->dev, "SI4763 Audio codec\n");
+
+       ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_si4763,
+                                       &si4763_codec_dai, 1);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register codec\n");
+               return ret;
+       }
+
+       return 0;
+
+}
+
+/* power down chip */
+static int si4763_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static int si4763_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       return 0;
+}
+
+static int si4763_resume(struct platform_device *pdev)
+{
+       return 0;
+}
+struct platform_driver si4763_driver = {
+       .driver = {
+               .name = "si4763",
+               .owner = THIS_MODULE,
+               },
+       .probe = si4763_probe,
+       .remove = si4763_remove,
+       .suspend = si4763_suspend,
+       .resume = si4763_resume,
+};
+
+static int __init si4763_codec_init(void)
+{
+       return platform_driver_register(&si4763_driver);
+}
+
+static void __exit si4763_codec_exit(void)
+{
+       return platform_driver_unregister(&si4763_driver);
+}
+
+module_init(si4763_codec_init);
+module_exit(si4763_codec_exit);
+
+MODULE_DESCRIPTION("ASoC si4763 codec driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
index 35472e835cf9e435b2fb1f05c288d7f9959c8e8a..e4b57c7ea337e2eafedc5fc820ab67496f93d525 100644 (file)
@@ -86,6 +86,14 @@ config SND_SOC_IMX_CS42888
          Say Y if you want to add support for SoC audio on an i.MX board with
          a cs42888 codec
 
+config SND_SOC_IMX_SI4763
+       tristate "SoC Audio support for IMX SI4763"
+       select SND_MXC_SOC_SSI
+       select SND_SOC_SI4763
+       help
+         Say Y if you want to add support for Soc audio for the AMFM Tuner chip
+         SI4763 module.
+
 config SND_SOC_EUKREA_TLV320
        tristate "Eukrea TLV320"
        depends on MACH_EUKREA_MBIMX27_BASEBOARD \
index 3df711671b15115bea57060ca0dfe17501a1b416..177c77ffb746e76cb392560d0e2a0fa7dbb6b321 100644 (file)
@@ -20,6 +20,7 @@ snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
 snd-soc-imx-cs42888-objs := imx-cs42888.o
 snd-soc-imx-spdif-objs := imx-spdif.o
 snd-soc-imx-hdmi-objs := imx-hdmi.o imx-hdmi-dai.o imx-hdmi-dma.o
+snd-soc-imx-si4763-objs := imx-si4763.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -30,4 +31,5 @@ obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
 obj-$(CONFIG_SND_SOC_IMX_CS42888) += snd-soc-imx-cs42888.o
 obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
-obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
\ No newline at end of file
+obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
+obj-$(CONFIG_SND_SOC_IMX_SI4763) += snd-soc-imx-si4763.o
diff --git a/sound/soc/imx/imx-si4763.c b/sound/soc/imx/imx-si4763.c
new file mode 100644 (file)
index 0000000..3bf7f03
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/fsl_devices.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <mach/audmux.h>
+#include <mach/ssi.h>
+
+#include "imx-ssi.h"
+
+static struct imx_si4763_priv {
+       int sysclk;
+       int hw;
+       int active;
+       struct platform_device *pdev;
+} card_priv;
+
+static int imx_audmux_config(int slave, int master)
+{
+       unsigned int ptcr, pdcr;
+       slave = slave - 1;
+       master = master - 1;
+
+       ptcr = MXC_AUDMUX_V2_PTCR_SYN |
+               MXC_AUDMUX_V2_PTCR_TFSDIR |
+               MXC_AUDMUX_V2_PTCR_TFSEL(slave) |
+               MXC_AUDMUX_V2_PTCR_TCLKDIR |
+               MXC_AUDMUX_V2_PTCR_TCSEL(slave);
+       pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(slave);
+       mxc_audmux_v2_configure_port(master, ptcr, pdcr);
+
+       ptcr = MXC_AUDMUX_V2_PTCR_SYN;
+       pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(master);
+       mxc_audmux_v2_configure_port(slave, ptcr, pdcr);
+
+       return 0;
+}
+
+
+static int imx_3stack_si4763_startup(struct snd_pcm_substream *substream)
+{
+       struct imx_si4763_priv *priv = &card_priv;
+
+       priv->active++;
+       return 0;
+}
+
+static int imx_3stack_si4763_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 *cpu_dai = rtd->cpu_dai;
+       unsigned int channels = params_channels(params);
+       struct imx_ssi *ssi_mode = snd_soc_dai_get_drvdata(cpu_dai);
+       int ret = 0;
+       u32 dai_format;
+       dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+           SND_SOC_DAIFMT_CBS_CFS;
+
+       ssi_mode->flags |= IMX_SSI_SYN;
+
+       /* set i.MX active slot mask */
+       snd_soc_dai_set_tdm_slot(cpu_dai,
+                       channels == 1 ? 0xfffffffe : 0xfffffffc,
+                       channels == 1 ? 0xfffffffe : 0xfffffffc,
+                       2, 32);
+
+       /* set cpu DAI configuration */
+       ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
+       if (ret < 0)
+               return ret;
+
+       /* set the SSI system clock as input (unused) */
+       snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, SND_SOC_CLOCK_IN);
+
+       snd_soc_dai_set_clkdiv(cpu_dai, IMX_SSI_TX_DIV_PM, 9);
+       snd_soc_dai_set_clkdiv(cpu_dai, IMX_SSI_TX_DIV_2, 1);
+       snd_soc_dai_set_clkdiv(cpu_dai, IMX_SSI_TX_DIV_PSR, 0);
+       return 0;
+}
+
+static void imx_3stack_si4763_shutdown(struct snd_pcm_substream *substream)
+{
+       struct imx_si4763_priv *priv = &card_priv;
+       priv->active--;
+}
+
+/*
+ * imx_3stack bt DAI opserations.
+ */
+static struct snd_soc_ops imx_3stack_si4763_ops = {
+       .startup = imx_3stack_si4763_startup,
+       .hw_params = imx_3stack_si4763_hw_params,
+       .shutdown = imx_3stack_si4763_shutdown,
+};
+
+static struct snd_soc_dai_link imx_3stack_dai = {
+       .name = "imx-si4763",
+       .stream_name = "imx-si4763",
+       .codec_dai_name = "si4763",
+       .codec_name     = "si4763.0",
+       .cpu_dai_name   = "imx-ssi.1",
+       .platform_name  = "imx-pcm-audio.1",
+       .ops = &imx_3stack_si4763_ops,
+};
+
+static struct snd_soc_card snd_soc_card_imx_3stack = {
+       .name = "imx-audio-si4763",
+       .dai_link = &imx_3stack_dai,
+       .num_links = 1,
+};
+
+static int __init imx_3stack_si4763_probe(struct platform_device *pdev)
+{
+       struct mxc_audio_platform_data *plat = pdev->dev.platform_data;
+
+       card_priv.pdev = pdev;
+       card_priv.sysclk = plat->sysclk;
+       imx_audmux_config(plat->src_port, plat->ext_port);
+
+       return 0;
+
+}
+
+static int __devexit imx_3stack_si4763_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static struct platform_driver imx_3stack_si4763_driver = {
+       .probe = imx_3stack_si4763_probe,
+       .remove = __devexit_p(imx_3stack_si4763_remove),
+       .driver = {
+                  .name = "imx-tuner-si4763",
+                  .owner = THIS_MODULE,
+                  },
+};
+
+static struct platform_device *imx_3stack_snd_device;
+
+static int __init imx_3stack_asoc_init(void)
+{
+       int ret;
+       ret = platform_driver_register(&imx_3stack_si4763_driver);
+       if (ret < 0)
+               goto exit;
+
+       imx_3stack_snd_device = platform_device_alloc("soc-audio", 6);
+       if (!imx_3stack_snd_device)
+               goto err_device_alloc;
+
+       platform_set_drvdata(imx_3stack_snd_device, &snd_soc_card_imx_3stack);
+       ret = platform_device_add(imx_3stack_snd_device);
+       if (0 == ret)
+               goto exit;
+
+
+       platform_device_put(imx_3stack_snd_device);
+err_device_alloc:
+       platform_driver_unregister(&imx_3stack_si4763_driver);
+exit:
+       return ret;
+}
+
+static void __exit imx_3stack_asoc_exit(void)
+{
+       platform_driver_unregister(&imx_3stack_si4763_driver);
+       platform_device_unregister(imx_3stack_snd_device);
+}
+
+module_init(imx_3stack_asoc_init);
+module_exit(imx_3stack_asoc_exit);
+
+/* Module information */
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("ALSA SoC si4763 imx");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/imx-si4763.h b/sound/soc/imx/imx-si4763.h
new file mode 100644 (file)
index 0000000..8a641a6
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _MXC_SI4763PCM_H
+#define _MXC_SI4763PCM_H
+
+extern struct snd_soc_dai si4763_dai;
+extern struct snd_soc_codec_device soc_codec_dev_si4763;
+#endif