Guest User

generic-esai.c

a guest
Dec 17th, 2014
389
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.20 KB | None | 0 0
  1. /*
  2. * Copyright (C) GNU.
  3. *
  4. * Author: Aurelien BOUIN
  5. *
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20.  
  21. #include <linux/module.h> /* Needed by all modules */
  22.  
  23. MODULE_LICENSE("GPL");
  24. MODULE_AUTHOR("[email protected], 2014");
  25. MODULE_DESCRIPTION("Module that enable ESAI on iMX6 based board");
  26. MODULE_ALIAS("platform:imx-generic-esai");
  27.  
  28. #include <linux/module.h>
  29. #include <linux/of.h>
  30. #include <linux/of_platform.h>
  31. #include <linux/slab.h>
  32. #include <linux/device.h>
  33. #include <linux/clk.h>
  34. #include <linux/delay.h>
  35. #include <sound/core.h>
  36. #include <sound/pcm.h>
  37. #include <sound/soc.h>
  38. #include <sound/initval.h>
  39. #include <sound/pcm_params.h>
  40.  
  41. #define DEBUG 1
  42.  
  43. //#include <fsl_esai.h>
  44.  
  45. /* ESAI clock source */
  46. #define ESAI_HCKT_FSYS 0
  47. #define ESAI_HCKT_EXTAL 1
  48. #define ESAI_HCKR_FSYS 2
  49. #define ESAI_HCKR_EXTAL 3
  50.  
  51. #define SUPPORT_RATE_NUM 10
  52.  
  53. struct imx_priv {
  54. unsigned int mclk_freq;
  55. struct platform_device *pdev;
  56. };
  57.  
  58. static struct imx_priv card_priv;
  59.  
  60. static int imx_generic_esai_surround_startup(struct snd_pcm_substream *substream)
  61. {
  62. struct snd_pcm_runtime *runtime = substream->runtime;
  63. static struct snd_pcm_hw_constraint_list constraint_rates;
  64. static u32 support_rates[SUPPORT_RATE_NUM];
  65. int ret;
  66.  
  67. //Initial clock frequency of ESAi module : 33868800MHz
  68. support_rates[0] = 8000;
  69. support_rates[1] = 48000;
  70. support_rates[2] = 96000;
  71. support_rates[3] = 192000;
  72. constraint_rates.list = support_rates;
  73. constraint_rates.count = 4;
  74.  
  75. ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  76. &constraint_rates);
  77. if (ret)
  78. return ret;
  79.  
  80. return 0;
  81. }
  82.  
  83. static int imx_generic_esai_surround_hw_params(struct snd_pcm_substream *substream,
  84. struct snd_pcm_hw_params *params)
  85. {
  86. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  87. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  88. struct snd_soc_dai *codec_dai = rtd->codec_dai;
  89. struct imx_priv *priv = &card_priv;
  90. u32 dai_format = 0;
  91.  
  92. printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
  93. dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM;
  94. printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
  95. #ifdef CLOCK_FROM_EXTAL
  96. snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKT_EXTAL, priv->mclk_freq, SND_SOC_CLOCK_OUT);
  97. snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKR_EXTAL, priv->mclk_freq, SND_SOC_CLOCK_OUT);
  98. #else
  99. snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKT_FSYS, priv->mclk_freq, SND_SOC_CLOCK_OUT);
  100. snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKR_FSYS, priv->mclk_freq, SND_SOC_CLOCK_OUT);
  101.  
  102. #endif
  103. printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
  104. snd_soc_dai_set_sysclk(codec_dai, 0, priv->mclk_freq, SND_SOC_CLOCK_IN);
  105. printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
  106. /* set codec DAI configuration */
  107. snd_soc_dai_set_fmt(cpu_dai, dai_format);
  108. printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
  109. /* set i.MX active slot mask */
  110. #if 1
  111. snd_soc_dai_set_tdm_slot(cpu_dai, 0xFFFFFFFF, 0xFFFFFFFF, 32, 8);//32 slots de 8bits
  112. #else
  113. //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...
  114. 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...
  115. #endif
  116. printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
  117. snd_soc_dai_set_fmt(codec_dai, dai_format);
  118. printk(KERN_ERR"%s(%d)\n",__func__,__LINE__);
  119. return 0;
  120. }
  121.  
  122. static struct snd_soc_ops imx_generic_esai_surround_ops = {
  123. .startup = imx_generic_esai_surround_startup,
  124. .hw_params = imx_generic_esai_surround_hw_params,
  125. };
  126.  
  127. static struct snd_soc_dai_link snd_soc_dapm_route[] = {
  128. {
  129. .name = "HiFi",
  130. .stream_name = "HiFi",
  131. .codec_name = "snd-soc-dummy",
  132. .codec_dai_name = "snd-soc-dummy-dai",
  133. .ignore_pmdown_time = 1,
  134. .ops = &imx_generic_esai_surround_ops,
  135. },
  136. };
  137.  
  138. static struct snd_soc_card snd_soc_card_imx_generic_esai = {
  139. .name = "generic-esai-audio",
  140. .dai_link = snd_soc_dapm_route,
  141. #if 0
  142. .dapm_widgets = imx_cs42888_dapm_widgets,
  143. .num_dapm_widgets = ARRAY_SIZE(imx_cs42888_dapm_widgets),
  144. .dapm_routes = audio_map,
  145. .num_dapm_routes = ARRAY_SIZE(audio_map),
  146. #endif
  147. };
  148.  
  149. /*
  150. * This function will register the snd_soc_pcm_link drivers.
  151. */
  152. static int imx_generic_esai_probe(struct platform_device *pdev)
  153. {
  154. struct device_node *esai_np;
  155. struct platform_device *esai_pdev;
  156. struct imx_priv *priv = &card_priv;
  157. int ret;
  158.  
  159. priv->pdev = pdev;
  160.  
  161. dev_err(&pdev->dev, "%s(%d) starting\n",__func__,__LINE__);
  162.  
  163. esai_np = of_parse_phandle(pdev->dev.of_node, "esai-controller", 0);
  164. if (!esai_np) {
  165. dev_err(&pdev->dev, "phandle missing or invalid\n");
  166. ret = -EINVAL;
  167. goto fail;
  168. }
  169. dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
  170.  
  171. esai_pdev = of_find_device_by_node(esai_np);
  172. if (!esai_pdev) {
  173. dev_err(&pdev->dev, "failed to find ESAI platform device\n");
  174. ret = -EINVAL;
  175. goto fail;
  176. }
  177. dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
  178.  
  179. //snd_soc_dapm_route[0].codec_of_node = codec_np;
  180. snd_soc_dapm_route[0].cpu_dai_name = dev_name(&esai_pdev->dev);
  181. snd_soc_dapm_route[0].platform_of_node = esai_np;
  182. snd_soc_card_imx_generic_esai.num_links = 1;
  183.  
  184. dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
  185. //priv->mclk_freq = 33868800;//TODO : is the default value
  186. //priv->mclk_freq = 32*8000*8;//TODO : is the default value
  187. priv->mclk_freq = 2000000;
  188.  
  189. dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
  190. snd_soc_card_imx_generic_esai.dev = &pdev->dev;
  191.  
  192. platform_set_drvdata(pdev, &snd_soc_card_imx_generic_esai);
  193. dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
  194.  
  195. ret = snd_soc_register_card(&snd_soc_card_imx_generic_esai);
  196. dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
  197. if (ret)
  198. dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
  199. fail:
  200. if (esai_np)
  201. of_node_put(esai_np);
  202. dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
  203. return ret;
  204. }
  205.  
  206. static int imx_generic_esai_remove(struct platform_device *pdev)
  207. {
  208. dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
  209. snd_soc_unregister_card(&snd_soc_card_imx_generic_esai);
  210. dev_err(&pdev->dev, "%s(%d)\n",__func__,__LINE__);
  211. return 0;
  212. }
  213.  
  214. static const struct of_device_id imx_generic_esai_dt_ids[] = {
  215. { .compatible = "fsl,imx-audio-generic-esai", },
  216. { /* sentinel */ }
  217. };
  218.  
  219. static struct platform_driver imx_generic_esai_driver = {
  220. .probe = imx_generic_esai_probe,
  221. .remove = imx_generic_esai_remove,
  222. .driver = {
  223. .name = "imx-generic-esai",
  224. .owner = THIS_MODULE,
  225. .pm = &snd_soc_pm_ops,
  226. .of_match_table = imx_generic_esai_dt_ids,
  227. },
  228. };
  229. module_platform_driver(imx_generic_esai_driver);
Advertisement
Add Comment
Please, Sign In to add comment