0075-Add-driver-for-rpi-proto.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. From 56a753118a1446feedb1845f37f3e5d3cc4f31a1 Mon Sep 17 00:00:00 2001
  2. From: Waldemar Brodkorb <wbrodkorb@conet.de>
  3. Date: Wed, 25 Mar 2015 09:26:17 +0100
  4. Subject: [PATCH 075/381] Add driver for rpi-proto
  5. Forward port of 3.10.x driver from https://github.com/koalo
  6. We are using a custom board and would like to use rpi 3.18.x
  7. kernel. Patch works fine for our embedded system.
  8. URL to the audio chip:
  9. http://www.mikroe.com/add-on-boards/audio-voice/audio-codec-proto/
  10. Playback tested with devicetree enabled.
  11. Signed-off-by: Waldemar Brodkorb <wbrodkorb@conet.de>
  12. ---
  13. sound/soc/bcm/Kconfig | 7 +++
  14. sound/soc/bcm/Makefile | 2 +
  15. sound/soc/bcm/rpi-proto.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++
  16. 3 files changed, 162 insertions(+)
  17. create mode 100644 sound/soc/bcm/rpi-proto.c
  18. --- a/sound/soc/bcm/Kconfig
  19. +++ b/sound/soc/bcm/Kconfig
  20. @@ -43,6 +43,13 @@ config SND_BCM2708_SOC_RPI_DAC
  21. help
  22. Say Y or M if you want to add support for RPi-DAC.
  23. +config SND_BCM2708_SOC_RPI_PROTO
  24. + tristate "Support for Rpi-PROTO"
  25. + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
  26. + select SND_SOC_WM8731
  27. + help
  28. + Say Y or M if you want to add support for Audio Codec Board PROTO (WM8731).
  29. +
  30. config SND_BCM2708_SOC_IQAUDIO_DAC
  31. tristate "Support for IQaudIO-DAC"
  32. depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
  33. --- a/sound/soc/bcm/Makefile
  34. +++ b/sound/soc/bcm/Makefile
  35. @@ -9,6 +9,7 @@ snd-soc-hifiberry-dacplus-objs := hifibe
  36. snd-soc-hifiberry-digi-objs := hifiberry_digi.o
  37. snd-soc-hifiberry-amp-objs := hifiberry_amp.o
  38. snd-soc-rpi-dac-objs := rpi-dac.o
  39. +snd-soc-rpi-proto-objs := rpi-proto.o
  40. snd-soc-iqaudio-dac-objs := iqaudio-dac.o
  41. obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
  42. @@ -16,4 +17,5 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_D
  43. obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
  44. obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
  45. obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
  46. +obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o
  47. obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
  48. --- /dev/null
  49. +++ b/sound/soc/bcm/rpi-proto.c
  50. @@ -0,0 +1,153 @@
  51. +/*
  52. + * ASoC driver for PROTO AudioCODEC (with a WM8731)
  53. + * connected to a Raspberry Pi
  54. + *
  55. + * Author: Florian Meier, <koalo@koalo.de>
  56. + * Copyright 2013
  57. + *
  58. + * This program is free software; you can redistribute it and/or modify
  59. + * it under the terms of the GNU General Public License version 2 as
  60. + * published by the Free Software Foundation.
  61. + */
  62. +
  63. +#include <linux/module.h>
  64. +#include <linux/platform_device.h>
  65. +
  66. +#include <sound/core.h>
  67. +#include <sound/pcm.h>
  68. +#include <sound/soc.h>
  69. +#include <sound/jack.h>
  70. +
  71. +#include "../codecs/wm8731.h"
  72. +
  73. +static const unsigned int wm8731_rates_12288000[] = {
  74. + 8000, 32000, 48000, 96000,
  75. +};
  76. +
  77. +static struct snd_pcm_hw_constraint_list wm8731_constraints_12288000 = {
  78. + .list = wm8731_rates_12288000,
  79. + .count = ARRAY_SIZE(wm8731_rates_12288000),
  80. +};
  81. +
  82. +static int snd_rpi_proto_startup(struct snd_pcm_substream *substream)
  83. +{
  84. + /* Setup constraints, because there is a 12.288 MHz XTAL on the board */
  85. + snd_pcm_hw_constraint_list(substream->runtime, 0,
  86. + SNDRV_PCM_HW_PARAM_RATE,
  87. + &wm8731_constraints_12288000);
  88. + return 0;
  89. +}
  90. +
  91. +static int snd_rpi_proto_hw_params(struct snd_pcm_substream *substream,
  92. + struct snd_pcm_hw_params *params)
  93. +{
  94. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  95. + struct snd_soc_codec *codec = rtd->codec;
  96. + struct snd_soc_dai *codec_dai = rtd->codec_dai;
  97. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  98. + int sysclk = 12288000; /* This is fixed on this board */
  99. +
  100. + /* Set proto bclk */
  101. + int ret = snd_soc_dai_set_bclk_ratio(cpu_dai,32*2);
  102. + if (ret < 0){
  103. + dev_err(codec->dev,
  104. + "Failed to set BCLK ratio %d\n", ret);
  105. + return ret;
  106. + }
  107. +
  108. + /* Set proto sysclk */
  109. + ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
  110. + sysclk, SND_SOC_CLOCK_IN);
  111. + if (ret < 0) {
  112. + dev_err(codec->dev,
  113. + "Failed to set WM8731 SYSCLK: %d\n", ret);
  114. + return ret;
  115. + }
  116. +
  117. + return 0;
  118. +}
  119. +
  120. +/* machine stream operations */
  121. +static struct snd_soc_ops snd_rpi_proto_ops = {
  122. + .startup = snd_rpi_proto_startup,
  123. + .hw_params = snd_rpi_proto_hw_params,
  124. +};
  125. +
  126. +static struct snd_soc_dai_link snd_rpi_proto_dai[] = {
  127. +{
  128. + .name = "WM8731",
  129. + .stream_name = "WM8731 HiFi",
  130. + .cpu_dai_name = "bcm2708-i2s.0",
  131. + .codec_dai_name = "wm8731-hifi",
  132. + .platform_name = "bcm2708-i2s.0",
  133. + .codec_name = "wm8731.1-001a",
  134. + .dai_fmt = SND_SOC_DAIFMT_I2S
  135. + | SND_SOC_DAIFMT_NB_NF
  136. + | SND_SOC_DAIFMT_CBM_CFM,
  137. + .ops = &snd_rpi_proto_ops,
  138. +},
  139. +};
  140. +
  141. +/* audio machine driver */
  142. +static struct snd_soc_card snd_rpi_proto = {
  143. + .name = "snd_rpi_proto",
  144. + .dai_link = snd_rpi_proto_dai,
  145. + .num_links = ARRAY_SIZE(snd_rpi_proto_dai),
  146. +};
  147. +
  148. +static int snd_rpi_proto_probe(struct platform_device *pdev)
  149. +{
  150. + int ret = 0;
  151. +
  152. + snd_rpi_proto.dev = &pdev->dev;
  153. +
  154. + if (pdev->dev.of_node) {
  155. + struct device_node *i2s_node;
  156. + struct snd_soc_dai_link *dai = &snd_rpi_proto_dai[0];
  157. + i2s_node = of_parse_phandle(pdev->dev.of_node,
  158. + "i2s-controller", 0);
  159. +
  160. + if (i2s_node) {
  161. + dai->cpu_dai_name = NULL;
  162. + dai->cpu_of_node = i2s_node;
  163. + dai->platform_name = NULL;
  164. + dai->platform_of_node = i2s_node;
  165. + }
  166. + }
  167. +
  168. + ret = snd_soc_register_card(&snd_rpi_proto);
  169. + if (ret) {
  170. + dev_err(&pdev->dev,
  171. + "snd_soc_register_card() failed: %d\n", ret);
  172. + }
  173. +
  174. + return ret;
  175. +}
  176. +
  177. +
  178. +static int snd_rpi_proto_remove(struct platform_device *pdev)
  179. +{
  180. + return snd_soc_unregister_card(&snd_rpi_proto);
  181. +}
  182. +
  183. +static const struct of_device_id snd_rpi_proto_of_match[] = {
  184. + { .compatible = "rpi,rpi-proto", },
  185. + {},
  186. +};
  187. +MODULE_DEVICE_TABLE(of, snd_rpi_proto_of_match);
  188. +
  189. +static struct platform_driver snd_rpi_proto_driver = {
  190. + .driver = {
  191. + .name = "snd-rpi-proto",
  192. + .owner = THIS_MODULE,
  193. + .of_match_table = snd_rpi_proto_of_match,
  194. + },
  195. + .probe = snd_rpi_proto_probe,
  196. + .remove = snd_rpi_proto_remove,
  197. +};
  198. +
  199. +module_platform_driver(snd_rpi_proto_driver);
  200. +
  201. +MODULE_AUTHOR("Florian Meier");
  202. +MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to PROTO board (WM8731)");
  203. +MODULE_LICENSE("GPL");