Advertisement
Guest User

Untitled

a guest
Oct 9th, 2017
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.17 KB | None | 0 0
  1. /*
  2.  * This program is free software; you can redistribute  it and/or modify it
  3.  * under  the terms of  the GNU General  Public License as published by the
  4.  * Free Software Foundation;  either version 2 of the  License, or (at your
  5.  * option) any later version.
  6.  */
  7.  
  8. #include <linux/module.h>
  9. #include <linux/i2c.h>
  10. #include <linux/delay.h>
  11. #include <sound/pcm.h>
  12. #include <sound/soc.h>
  13. #include <linux/io.h>
  14.  
  15. #include <asm/mach-types.h>
  16.  
  17. static int snd_rpi_bathat_init(struct snd_soc_pcm_runtime *rtd)
  18. {
  19.     struct snd_soc_codec *codec = rtd->codec;
  20.     dev_info(codec->dev, "Bathat init");
  21.     return 0;
  22. }
  23.  
  24. /* CS4270 */
  25. static int snd_rpi_bathat_startup(struct snd_pcm_substream *substream)
  26. {
  27.     struct snd_soc_pcm_runtime *rtd = substream->private_data;
  28.     struct snd_soc_dai *codec_dai = rtd->codec_dai;
  29.     struct snd_soc_codec *codec = rtd->codec;
  30.  
  31.     int sysclk = 24576000;
  32.     int ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, 0);
  33.  
  34.     dev_info(codec->dev, "Bathat startup");
  35.  
  36.     if (ret < 0) {
  37.         dev_err(codec->dev, "Unable to set CS4270 system clock.");
  38.     }
  39.  
  40.     return ret;
  41. }
  42.  
  43. static void snd_rpi_bathat_shutdown(struct snd_pcm_substream *substream) {
  44.     struct snd_soc_pcm_runtime *rtd = substream->private_data;
  45.     struct snd_soc_codec *codec = rtd->codec;
  46.     dev_info(codec->dev, "Bathat shutdown");
  47. }
  48.  
  49. static int snd_rpi_bathat_hw_params(struct snd_pcm_substream *substream,
  50.                      struct snd_pcm_hw_params *params)
  51. {
  52.     struct snd_soc_pcm_runtime *rtd = substream->private_data;
  53.     struct snd_soc_dai *codec_dai = rtd->codec_dai;
  54.     struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  55.     struct snd_soc_codec *codec = rtd->codec;
  56.  
  57.     int sysclk = 24576000;
  58.     int ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, 0);
  59.  
  60.     dev_info(codec->dev, "Bathat HW params");
  61.  
  62.     if (ret < 0) {
  63.         dev_err(codec->dev, "Unable to set CS4270 system clock.");
  64.     }
  65.  
  66.     return ret;
  67. }
  68.  
  69. static struct snd_soc_ops snd_rpi_bathat_ops = {
  70.     .startup = snd_rpi_bathat_startup,
  71.     .shutdown = snd_rpi_bathat_shutdown,
  72.     .hw_params = snd_rpi_bathat_hw_params,
  73. };
  74.  
  75. static struct snd_soc_dai_link snd_soc_rpi_bathat_dai[] = {
  76. {
  77.     .name       = "BatHat",        
  78.     .stream_name    = "BatHat",        
  79.     .cpu_dai_name   = "bcm2708-i2s.0",     
  80.     .codec_dai_name = "cs4270-hifi",   
  81.     .platform_name  = "bcm2708-pcm-audio.0",
  82.     .codec_name = "cs4270.1-0048", 
  83.     .dai_fmt    = SND_SOC_DAIFMT_I2S
  84.                 | SND_SOC_DAIFMT_NB_NF
  85.                 | SND_SOC_DAIFMT_CBS_CFS,
  86.     .ops        = &snd_rpi_bathat_ops,
  87.     .init = snd_rpi_bathat_init,
  88. }
  89. };
  90.  
  91. static struct snd_soc_card snd_rpi_bathat = {
  92.     .name       = "snd_rpi_bathat",
  93.     .owner      = THIS_MODULE,
  94.     .dai_link   = snd_soc_rpi_bathat_dai,
  95.     .num_links  = ARRAY_SIZE(snd_soc_rpi_bathat_dai),
  96. };
  97.  
  98. static int snd_rpi_bathat_probe(struct platform_device *pdev)
  99. {
  100.     int ret = 0;
  101.  
  102.     snd_rpi_bathat.dev = &pdev->dev;
  103.     dev_info(&pdev->dev, "Bathat probe");
  104.     if (pdev->dev.of_node) {
  105.         struct device_node *i2s_node;
  106.         struct snd_soc_dai_link *dai = &snd_soc_rpi_bathat_dai[0];
  107.         i2s_node = of_parse_phandle(pdev->dev.of_node,
  108.                     "i2s-controller", 0);
  109.  
  110.         dev_info(&pdev->dev, "Bathat has of_node");
  111.         if (i2s_node) {
  112.             dev_info(&pdev->dev, "Bathat has i2s_node");
  113.             dai->cpu_dai_name = NULL;
  114.             dai->cpu_of_node = i2s_node;
  115.             dai->platform_name = NULL;
  116.             dai->platform_of_node = i2s_node;
  117.         }
  118.     }
  119.  
  120.     ret = snd_soc_register_card(&snd_rpi_bathat);
  121.     if (ret)
  122.         dev_err(&pdev->dev,
  123.             "snd_soc_register_card() failed: %d\n", ret);
  124.  
  125.     return ret;
  126. }
  127.  
  128. static int snd_rpi_bathat_remove(struct platform_device *pdev)
  129. {
  130.     dev_info(&pdev->dev, "Bathat remove");
  131.     return snd_soc_unregister_card(&snd_rpi_bathat);
  132. }
  133.  
  134. static const struct of_device_id snd_rpi_bathat_of_match[] = {
  135.     { .compatible = "bathat", },
  136.     {},
  137. };
  138. MODULE_DEVICE_TABLE(of, snd_rpi_bathat_of_match);
  139.  
  140. static struct platform_driver snd_rpi_bathat_driver = {
  141.     .driver = {
  142.         .name   = "snd-rpi-bathat",
  143.         .owner  = THIS_MODULE,
  144.         .of_match_table = snd_rpi_bathat_of_match,
  145.     },
  146.     .probe    = snd_rpi_bathat_probe,
  147.     .remove  = snd_rpi_bathat_remove,
  148. };
  149.  
  150. module_platform_driver(snd_rpi_bathat_driver);
  151.  
  152. /* Module information */
  153. MODULE_AUTHOR("REDACTED");
  154. MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to BatHat board (CS4270)");
  155. MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement