Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Copyright (C) GNU.
- *
- * Author: Aurelien BOUIN
- *
- *
- * 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <linux/module.h> /* Needed by all modules */
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("[email protected], 2014");
- MODULE_DESCRIPTION("Module that enable ESAI on iMX6 based board");
- MODULE_ALIAS("platform:imx-generic-esai");
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/of_platform.h>
- #include <linux/slab.h>
- #include <linux/device.h>
- #include <linux/clk.h>
- #include <linux/delay.h>
- #include <sound/core.h>
- #include <sound/pcm.h>
- #include <sound/soc.h>
- #include <sound/initval.h>
- #include <sound/pcm_params.h>
- #define DEBUG 1
- //#include <fsl_esai.h>
- /* ESAI clock source */
- #define ESAI_HCKT_FSYS 0
- #define ESAI_HCKT_EXTAL 1
- #define ESAI_HCKR_FSYS 2
- #define ESAI_HCKR_EXTAL 3
- #define SUPPORT_RATE_NUM 10
- struct imx_priv {
- unsigned int mclk_freq;
- struct platform_device *pdev;
- };
- static struct imx_priv card_priv;
- static int imx_generic_esai_surround_startup(struct snd_pcm_substream *substream)
- {
- struct snd_pcm_runtime *runtime = substream->runtime;
- static struct snd_pcm_hw_constraint_list constraint_rates;
- static u32 support_rates[SUPPORT_RATE_NUM];
- int ret;
- //Initial clock frequency of ESAi module : 33868800MHz
- support_rates[0] = 8000;
- support_rates[1] = 48000;
- support_rates[2] = 96000;
- support_rates[3] = 192000;
- constraint_rates.list = support_rates;
- constraint_rates.count = 4;
- ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &constraint_rates);
- if (ret)
- return ret;
- return 0;
- }
- static int imx_generic_esai_surround_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;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct imx_priv *priv = &card_priv;
- u32 dai_format = 0;
- printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
- dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM;
- printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
- #ifdef CLOCK_FROM_EXTAL
- snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKT_EXTAL, priv->mclk_freq, SND_SOC_CLOCK_OUT);
- snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKR_EXTAL, priv->mclk_freq, SND_SOC_CLOCK_OUT);
- #else
- snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKT_FSYS, priv->mclk_freq, SND_SOC_CLOCK_OUT);
- snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKR_FSYS, priv->mclk_freq, SND_SOC_CLOCK_OUT);
- #endif
- printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
- snd_soc_dai_set_sysclk(codec_dai, 0, priv->mclk_freq, SND_SOC_CLOCK_IN);
- printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
- /* set codec DAI configuration */
- snd_soc_dai_set_fmt(cpu_dai, dai_format);
- printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
- /* set i.MX active slot mask */
- #if 1
- snd_soc_dai_set_tdm_slot(cpu_dai, 0xFFFFFFFF, 0xFFFFFFFF, 32, 8);//32 slots de 8bits
- #else
- //snd_soc_dai_set_tdm_slot(cpu_dai, 0xFFFF, 0xFFFF, 1, 8);//1 slot de 8bits //les 8 bits ne sont pas prise en compte ici !ça depend du fichier son à jouer...
- snd_soc_dai_set_tdm_slot(cpu_dai, 0xFFFF, 0xFFFF, 2, 8);//2 slots de 8bits //les 8 bits ne sont pas prise en compte ici !ça depend du fichier son à jouer...
- #endif
- printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
- snd_soc_dai_set_fmt(codec_dai, dai_format);
- printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
- return 0;
- }
- static struct snd_soc_ops imx_generic_esai_surround_ops = {
- .startup = imx_generic_esai_surround_startup,
- .hw_params = imx_generic_esai_surround_hw_params,
- };
- static struct snd_soc_dai_link snd_soc_dapm_route[] = {
- {
- .name = "HiFi",
- .stream_name = "HiFi",
- .codec_name = "snd-soc-dummy",
- .codec_dai_name = "snd-soc-dummy-dai",
- .ignore_pmdown_time = 1,
- .ops = &imx_generic_esai_surround_ops,
- },
- };
- static struct snd_soc_card snd_soc_card_imx_generic_esai = {
- .name = "generic-esai-audio",
- .dai_link = snd_soc_dapm_route,
- #if 0
- .dapm_widgets = imx_cs42888_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(imx_cs42888_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
- #endif
- };
- /*
- * This function will register the snd_soc_pcm_link drivers.
- */
- static int imx_generic_esai_probe(struct platform_device *pdev)
- {
- struct device_node *esai_np;
- struct platform_device *esai_pdev;
- struct imx_priv *priv = &card_priv;
- int ret;
- priv->pdev = pdev;
- dev_err(&pdev->dev, "%s(%d) starting\n",__func__,__LINE__);
- esai_np = of_parse_phandle(pdev->dev.of_node, "esai-controller", 0);
- if (!esai_np) {
- dev_err(&pdev->dev, "phandle missing or invalid\n");
- ret = -EINVAL;
- goto fail;
- }
- dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
- esai_pdev = of_find_device_by_node(esai_np);
- if (!esai_pdev) {
- dev_err(&pdev->dev, "failed to find ESAI platform device\n");
- ret = -EINVAL;
- goto fail;
- }
- dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
- //snd_soc_dapm_route[0].codec_of_node = codec_np;
- snd_soc_dapm_route[0].cpu_dai_name = dev_name(&esai_pdev->dev);
- snd_soc_dapm_route[0].platform_of_node = esai_np;
- snd_soc_card_imx_generic_esai.num_links = 1;
- dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
- //priv->mclk_freq = 33868800;//TODO : is the default value
- //priv->mclk_freq = 32*8000*8;//TODO : is the default value
- priv->mclk_freq = 2000000;
- dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
- snd_soc_card_imx_generic_esai.dev = &pdev->dev;
- platform_set_drvdata(pdev, &snd_soc_card_imx_generic_esai);
- dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
- ret = snd_soc_register_card(&snd_soc_card_imx_generic_esai);
- dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
- if (ret)
- dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
- fail:
- if (esai_np)
- of_node_put(esai_np);
- dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
- return ret;
- }
- static int imx_generic_esai_remove(struct platform_device *pdev)
- {
- dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
- snd_soc_unregister_card(&snd_soc_card_imx_generic_esai);
- dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
- return 0;
- }
- static const struct of_device_id imx_generic_esai_dt_ids[] = {
- { .compatible = "fsl,imx-audio-generic-esai", },
- { /* sentinel */ }
- };
- static struct platform_driver imx_generic_esai_driver = {
- .probe = imx_generic_esai_probe,
- .remove = imx_generic_esai_remove,
- .driver = {
- .name = "imx-generic-esai",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- .of_match_table = imx_generic_esai_dt_ids,
- },
- };
- module_platform_driver(imx_generic_esai_driver);
Advertisement
Add Comment
Please, Sign In to add comment