0070-Added-support-for-HiFiBerry-DAC.patch 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. From 03107b2243e688b6c98042d0fd9416db2bd241f6 Mon Sep 17 00:00:00 2001
  2. From: Daniel Matuschek <info@crazy-audio.com>
  3. Date: Mon, 4 Aug 2014 10:06:56 +0200
  4. Subject: [PATCH 070/381] Added support for HiFiBerry DAC+
  5. The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses
  6. a different codec chip (PCM5122), therefore a new driver is necessary.
  7. ---
  8. sound/soc/bcm/Kconfig | 7 ++
  9. sound/soc/bcm/Makefile | 2 +
  10. sound/soc/bcm/hifiberry_dacplus.c | 141 ++++++++++++++++++++++++++++++++++++++
  11. 3 files changed, 150 insertions(+)
  12. create mode 100644 sound/soc/bcm/hifiberry_dacplus.c
  13. --- a/sound/soc/bcm/Kconfig
  14. +++ b/sound/soc/bcm/Kconfig
  15. @@ -15,6 +15,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC
  16. help
  17. Say Y or M if you want to add support for HifiBerry DAC.
  18. +config SND_BCM2708_SOC_HIFIBERRY_DACPLUS
  19. + tristate "Support for HifiBerry DAC+"
  20. + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
  21. + select SND_SOC_PCM512x
  22. + help
  23. + Say Y or M if you want to add support for HifiBerry DAC+.
  24. +
  25. config SND_BCM2708_SOC_HIFIBERRY_DIGI
  26. tristate "Support for HifiBerry Digi"
  27. depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
  28. --- a/sound/soc/bcm/Makefile
  29. +++ b/sound/soc/bcm/Makefile
  30. @@ -5,11 +5,13 @@ obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd
  31. # BCM2708 Machine Support
  32. snd-soc-hifiberry-dac-objs := hifiberry_dac.o
  33. +snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
  34. snd-soc-hifiberry-digi-objs := hifiberry_digi.o
  35. snd-soc-rpi-dac-objs := rpi-dac.o
  36. snd-soc-iqaudio-dac-objs := iqaudio-dac.o
  37. obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
  38. +obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
  39. obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
  40. obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
  41. obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
  42. --- /dev/null
  43. +++ b/sound/soc/bcm/hifiberry_dacplus.c
  44. @@ -0,0 +1,141 @@
  45. +/*
  46. + * ASoC Driver for HiFiBerry DAC+
  47. + *
  48. + * Author: Daniel Matuschek
  49. + * Copyright 2014
  50. + * based on code by Florian Meier <florian.meier@koalo.de>
  51. + *
  52. + * This program is free software; you can redistribute it and/or
  53. + * modify it under the terms of the GNU General Public License
  54. + * version 2 as published by the Free Software Foundation.
  55. + *
  56. + * This program is distributed in the hope that it will be useful, but
  57. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  58. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  59. + * General Public License for more details.
  60. + */
  61. +
  62. +#include <linux/module.h>
  63. +#include <linux/platform_device.h>
  64. +
  65. +#include <sound/core.h>
  66. +#include <sound/pcm.h>
  67. +#include <sound/pcm_params.h>
  68. +#include <sound/soc.h>
  69. +#include <sound/jack.h>
  70. +
  71. +#include "../codecs/pcm512x.h"
  72. +
  73. +static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd)
  74. +{
  75. + struct snd_soc_codec *codec = rtd->codec;
  76. + snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08);
  77. + snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02);
  78. + snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08);
  79. + return 0;
  80. +}
  81. +
  82. +static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream,
  83. + struct snd_pcm_hw_params *params)
  84. +{
  85. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  86. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  87. + return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
  88. +}
  89. +
  90. +static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) {
  91. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  92. + struct snd_soc_codec *codec = rtd->codec;
  93. + snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08);
  94. + return 0;
  95. +}
  96. +
  97. +static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) {
  98. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  99. + struct snd_soc_codec *codec = rtd->codec;
  100. + snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00);
  101. +}
  102. +
  103. +/* machine stream operations */
  104. +static struct snd_soc_ops snd_rpi_hifiberry_dacplus_ops = {
  105. + .hw_params = snd_rpi_hifiberry_dacplus_hw_params,
  106. + .startup = snd_rpi_hifiberry_dacplus_startup,
  107. + .shutdown = snd_rpi_hifiberry_dacplus_shutdown,
  108. +};
  109. +
  110. +static struct snd_soc_dai_link snd_rpi_hifiberry_dacplus_dai[] = {
  111. +{
  112. + .name = "HiFiBerry DAC+",
  113. + .stream_name = "HiFiBerry DAC+ HiFi",
  114. + .cpu_dai_name = "bcm2708-i2s.0",
  115. + .codec_dai_name = "pcm512x-hifi",
  116. + .platform_name = "bcm2708-i2s.0",
  117. + .codec_name = "pcm512x.1-004d",
  118. + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  119. + SND_SOC_DAIFMT_CBS_CFS,
  120. + .ops = &snd_rpi_hifiberry_dacplus_ops,
  121. + .init = snd_rpi_hifiberry_dacplus_init,
  122. +},
  123. +};
  124. +
  125. +/* audio machine driver */
  126. +static struct snd_soc_card snd_rpi_hifiberry_dacplus = {
  127. + .name = "snd_rpi_hifiberry_dacplus",
  128. + .dai_link = snd_rpi_hifiberry_dacplus_dai,
  129. + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai),
  130. +};
  131. +
  132. +static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev)
  133. +{
  134. + int ret = 0;
  135. +
  136. + snd_rpi_hifiberry_dacplus.dev = &pdev->dev;
  137. +
  138. + if (pdev->dev.of_node) {
  139. + struct device_node *i2s_node;
  140. + struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0];
  141. + i2s_node = of_parse_phandle(pdev->dev.of_node,
  142. + "i2s-controller", 0);
  143. +
  144. + if (i2s_node) {
  145. + dai->cpu_dai_name = NULL;
  146. + dai->cpu_of_node = i2s_node;
  147. + dai->platform_name = NULL;
  148. + dai->platform_of_node = i2s_node;
  149. + }
  150. + }
  151. +
  152. + ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus);
  153. + if (ret)
  154. + dev_err(&pdev->dev,
  155. + "snd_soc_register_card() failed: %d\n", ret);
  156. +
  157. + return ret;
  158. +}
  159. +
  160. +static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev)
  161. +{
  162. + return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus);
  163. +}
  164. +
  165. +static const struct of_device_id snd_rpi_hifiberry_dacplus_of_match[] = {
  166. + { .compatible = "hifiberry,hifiberry-dacplus", },
  167. + {},
  168. +};
  169. +MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplus_of_match);
  170. +
  171. +static struct platform_driver snd_rpi_hifiberry_dacplus_driver = {
  172. + .driver = {
  173. + .name = "snd-rpi-hifiberry-dacplus",
  174. + .owner = THIS_MODULE,
  175. + .of_match_table = snd_rpi_hifiberry_dacplus_of_match,
  176. + },
  177. + .probe = snd_rpi_hifiberry_dacplus_probe,
  178. + .remove = snd_rpi_hifiberry_dacplus_remove,
  179. +};
  180. +
  181. +module_platform_driver(snd_rpi_hifiberry_dacplus_driver);
  182. +
  183. +MODULE_AUTHOR("Daniel Matuschek <daniel@hifiberry.com>");
  184. +MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+");
  185. +MODULE_LICENSE("GPL v2");