0430-Added-HiFiBerry-Digi-Pro-driver.patch 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. From 1a770fa3b51e674ba573628b1ad08153d9dbc39b Mon Sep 17 00:00:00 2001
  2. From: "Daniel Matuschek (HiFiBerry)" <daniel@hifiberry.com>
  3. Date: Tue, 26 Jul 2016 19:16:25 +0200
  4. Subject: [PATCH] Added HiFiBerry Digi+ Pro driver
  5. Signed-off-by: Daniel Matuschek <daniel@hifiberry.com>
  6. ---
  7. arch/arm/boot/dts/overlays/Makefile | 1 +
  8. arch/arm/boot/dts/overlays/README | 8 +++-
  9. .../dts/overlays/hifiberry-digi-pro-overlay.dts | 41 +++++++++++++++++
  10. sound/soc/bcm/hifiberry_digi.c | 51 ++++++++++++++++++++++
  11. 4 files changed, 100 insertions(+), 1 deletion(-)
  12. create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
  13. --- a/arch/arm/boot/dts/overlays/Makefile
  14. +++ b/arch/arm/boot/dts/overlays/Makefile
  15. @@ -31,6 +31,7 @@ dtbo-$(RPI_DT_OVERLAYS) += hifiberry-amp
  16. dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dac.dtbo
  17. dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacplus.dtbo
  18. dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi.dtbo
  19. +dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi-pro.dtbo
  20. dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo
  21. dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo
  22. dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo
  23. --- a/arch/arm/boot/dts/overlays/README
  24. +++ b/arch/arm/boot/dts/overlays/README
  25. @@ -377,11 +377,17 @@ Params: 24db_digital_gain Allow ga
  26. Name: hifiberry-digi
  27. -Info: Configures the HifiBerry Digi audio card
  28. +Info: Configures the HifiBerry Digi and Digi+ audio card
  29. Load: dtoverlay=hifiberry-digi
  30. Params: <None>
  31. +Name: hifiberry-digi-pro
  32. +Info: Configures the HifiBerry Digi+ Pro audio card
  33. +Load: dtoverlay=hifiberry-digi-pro
  34. +Params: <None>
  35. +
  36. +
  37. Name: hy28a
  38. Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics
  39. Default values match Texy's display shield
  40. --- /dev/null
  41. +++ b/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
  42. @@ -0,0 +1,41 @@
  43. +// Definitions for HiFiBerry Digi Pro
  44. +/dts-v1/;
  45. +/plugin/;
  46. +
  47. +/ {
  48. + compatible = "brcm,bcm2708";
  49. +
  50. + fragment@0 {
  51. + target = <&i2s>;
  52. + __overlay__ {
  53. + status = "okay";
  54. + };
  55. + };
  56. +
  57. + fragment@1 {
  58. + target = <&i2c1>;
  59. + __overlay__ {
  60. + #address-cells = <1>;
  61. + #size-cells = <0>;
  62. + status = "okay";
  63. +
  64. + wm8804@3b {
  65. + #sound-dai-cells = <0>;
  66. + compatible = "wlf,wm8804";
  67. + reg = <0x3b>;
  68. + status = "okay";
  69. + };
  70. + };
  71. + };
  72. +
  73. + fragment@2 {
  74. + target = <&sound>;
  75. + __overlay__ {
  76. + compatible = "hifiberry,hifiberry-digi";
  77. + i2s-controller = <&i2s>;
  78. + status = "okay";
  79. + clock44-gpio = <&gpio 5 0>;
  80. + clock48-gpio = <&gpio 6 0>;
  81. + };
  82. + };
  83. +};
  84. --- a/sound/soc/bcm/hifiberry_digi.c
  85. +++ b/sound/soc/bcm/hifiberry_digi.c
  86. @@ -23,6 +23,7 @@
  87. #include <sound/pcm_params.h>
  88. #include <sound/soc.h>
  89. #include <sound/jack.h>
  90. +#include <linux/gpio/consumer.h>
  91. #include "../codecs/wm8804.h"
  92. @@ -30,9 +31,34 @@ static short int auto_shutdown_output =
  93. module_param(auto_shutdown_output, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
  94. MODULE_PARM_DESC(auto_shutdown_output, "Shutdown SP/DIF output if playback is stopped");
  95. +#define CLK_44EN_RATE 22579200UL
  96. +#define CLK_48EN_RATE 24576000UL
  97. +
  98. +static bool snd_rpi_hifiberry_is_digipro;
  99. +static struct gpio_desc *snd_rpi_hifiberry_clk44gpio;
  100. +static struct gpio_desc *snd_rpi_hifiberry_clk48gpio;
  101. static int samplerate=44100;
  102. +static uint32_t snd_rpi_hifiberry_digi_enable_clock(int sample_rate)
  103. +{
  104. + switch (sample_rate) {
  105. + case 11025:
  106. + case 22050:
  107. + case 44100:
  108. + case 88200:
  109. + case 176400:
  110. + gpiod_set_value_cansleep(snd_rpi_hifiberry_clk44gpio, 1);
  111. + gpiod_set_value_cansleep(snd_rpi_hifiberry_clk48gpio, 0);
  112. + return CLK_44EN_RATE;
  113. + default:
  114. + gpiod_set_value_cansleep(snd_rpi_hifiberry_clk48gpio, 1);
  115. + gpiod_set_value_cansleep(snd_rpi_hifiberry_clk44gpio, 0);
  116. + return CLK_48EN_RATE;
  117. + }
  118. +}
  119. +
  120. +
  121. static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd)
  122. {
  123. struct snd_soc_codec *codec = rtd->codec;
  124. @@ -40,6 +66,14 @@ static int snd_rpi_hifiberry_digi_init(s
  125. /* enable TX output */
  126. snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0);
  127. + /* Initialize Digi+ Pro hardware */
  128. + if (snd_rpi_hifiberry_is_digipro) {
  129. + struct snd_soc_dai_link *dai = rtd->dai_link;
  130. +
  131. + dai->name = "HiFiBerry Digi+ Pro";
  132. + dai->stream_name = "HiFiBerry Digi+ Pro HiFi";
  133. + }
  134. +
  135. return 0;
  136. }
  137. @@ -87,6 +121,9 @@ static int snd_rpi_hifiberry_digi_hw_par
  138. mclk_freq=samplerate*128;
  139. mclk_div=WM8804_MCLKDIV_128FS;
  140. }
  141. +
  142. + if (snd_rpi_hifiberry_is_digipro)
  143. + sysclk = snd_rpi_hifiberry_digi_enable_clock(samplerate);
  144. switch (samplerate) {
  145. case 32000:
  146. @@ -121,6 +158,7 @@ static int snd_rpi_hifiberry_digi_hw_par
  147. ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL,
  148. sysclk, SND_SOC_CLOCK_OUT);
  149. +
  150. if (ret < 0) {
  151. dev_err(codec->dev,
  152. "Failed to set WM8804 SYSCLK: %d\n", ret);
  153. @@ -187,6 +225,19 @@ static int snd_rpi_hifiberry_digi_probe(
  154. dai->platform_name = NULL;
  155. dai->platform_of_node = i2s_node;
  156. }
  157. +
  158. + snd_rpi_hifiberry_is_digipro = 1;
  159. +
  160. + snd_rpi_hifiberry_clk44gpio =
  161. + devm_gpiod_get(&pdev->dev, "clock44", GPIOD_OUT_LOW);
  162. + if (IS_ERR(snd_rpi_hifiberry_clk44gpio))
  163. + snd_rpi_hifiberry_is_digipro = 0;
  164. +
  165. + snd_rpi_hifiberry_clk48gpio =
  166. + devm_gpiod_get(&pdev->dev, "clock48", GPIOD_OUT_LOW);
  167. + if (IS_ERR(snd_rpi_hifiberry_clk48gpio))
  168. + snd_rpi_hifiberry_is_digipro = 0;
  169. +
  170. }
  171. ret = snd_soc_register_card(&snd_rpi_hifiberry_digi);