1 From e528c5d3f8cffca37abf9c69f7178f0221974225 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
6 Signed-off-by: Daniel Matuschek <daniel@hifiberry.com>
8 arch/arm/boot/dts/overlays/Makefile | 1 +
9 arch/arm/boot/dts/overlays/README | 8 +++-
10 .../dts/overlays/hifiberry-digi-pro-overlay.dts | 41 +++++++++++++++++
11 sound/soc/bcm/hifiberry_digi.c | 51 ++++++++++++++++++++++
12 4 files changed, 100 insertions(+), 1 deletion(-)
13 create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
15 --- a/arch/arm/boot/dts/overlays/Makefile
16 +++ b/arch/arm/boot/dts/overlays/Makefile
17 @@ -31,6 +31,7 @@ dtbo-$(RPI_DT_OVERLAYS) += hifiberry-amp
18 dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dac.dtbo
19 dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacplus.dtbo
20 dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi.dtbo
21 +dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi-pro.dtbo
22 dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo
23 dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo
24 dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo
25 --- a/arch/arm/boot/dts/overlays/README
26 +++ b/arch/arm/boot/dts/overlays/README
27 @@ -377,11 +377,17 @@ Params: 24db_digital_gain Allow ga
31 -Info: Configures the HifiBerry Digi audio card
32 +Info: Configures the HifiBerry Digi and Digi+ audio card
33 Load: dtoverlay=hifiberry-digi
37 +Name: hifiberry-digi-pro
38 +Info: Configures the HifiBerry Digi+ Pro audio card
39 +Load: dtoverlay=hifiberry-digi-pro
44 Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics
45 Default values match Texy's display shield
47 +++ b/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
49 +// Definitions for HiFiBerry Digi Pro
54 + compatible = "brcm,bcm2708";
66 + #address-cells = <1>;
71 + #sound-dai-cells = <0>;
72 + compatible = "wlf,wm8804";
82 + compatible = "hifiberry,hifiberry-digi";
83 + i2s-controller = <&i2s>;
85 + clock44-gpio = <&gpio 5 0>;
86 + clock48-gpio = <&gpio 6 0>;
90 --- a/sound/soc/bcm/hifiberry_digi.c
91 +++ b/sound/soc/bcm/hifiberry_digi.c
93 #include <sound/pcm_params.h>
94 #include <sound/soc.h>
95 #include <sound/jack.h>
96 +#include <linux/gpio/consumer.h>
98 #include "../codecs/wm8804.h"
100 @@ -30,9 +31,34 @@ static short int auto_shutdown_output =
101 module_param(auto_shutdown_output, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
102 MODULE_PARM_DESC(auto_shutdown_output, "Shutdown SP/DIF output if playback is stopped");
104 +#define CLK_44EN_RATE 22579200UL
105 +#define CLK_48EN_RATE 24576000UL
107 +static bool snd_rpi_hifiberry_is_digipro;
108 +static struct gpio_desc *snd_rpi_hifiberry_clk44gpio;
109 +static struct gpio_desc *snd_rpi_hifiberry_clk48gpio;
111 static int samplerate=44100;
113 +static uint32_t snd_rpi_hifiberry_digi_enable_clock(int sample_rate)
115 + switch (sample_rate) {
121 + gpiod_set_value_cansleep(snd_rpi_hifiberry_clk44gpio, 1);
122 + gpiod_set_value_cansleep(snd_rpi_hifiberry_clk48gpio, 0);
123 + return CLK_44EN_RATE;
125 + gpiod_set_value_cansleep(snd_rpi_hifiberry_clk48gpio, 1);
126 + gpiod_set_value_cansleep(snd_rpi_hifiberry_clk44gpio, 0);
127 + return CLK_48EN_RATE;
132 static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd)
134 struct snd_soc_codec *codec = rtd->codec;
135 @@ -40,6 +66,14 @@ static int snd_rpi_hifiberry_digi_init(s
136 /* enable TX output */
137 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0);
139 + /* Initialize Digi+ Pro hardware */
140 + if (snd_rpi_hifiberry_is_digipro) {
141 + struct snd_soc_dai_link *dai = rtd->dai_link;
143 + dai->name = "HiFiBerry Digi+ Pro";
144 + dai->stream_name = "HiFiBerry Digi+ Pro HiFi";
150 @@ -87,6 +121,9 @@ static int snd_rpi_hifiberry_digi_hw_par
151 mclk_freq=samplerate*128;
152 mclk_div=WM8804_MCLKDIV_128FS;
155 + if (snd_rpi_hifiberry_is_digipro)
156 + sysclk = snd_rpi_hifiberry_digi_enable_clock(samplerate);
158 switch (samplerate) {
160 @@ -121,6 +158,7 @@ static int snd_rpi_hifiberry_digi_hw_par
162 ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL,
163 sysclk, SND_SOC_CLOCK_OUT);
167 "Failed to set WM8804 SYSCLK: %d\n", ret);
168 @@ -187,6 +225,19 @@ static int snd_rpi_hifiberry_digi_probe(
169 dai->platform_name = NULL;
170 dai->platform_of_node = i2s_node;
173 + snd_rpi_hifiberry_is_digipro = 1;
175 + snd_rpi_hifiberry_clk44gpio =
176 + devm_gpiod_get(&pdev->dev, "clock44", GPIOD_OUT_LOW);
177 + if (IS_ERR(snd_rpi_hifiberry_clk44gpio))
178 + snd_rpi_hifiberry_is_digipro = 0;
180 + snd_rpi_hifiberry_clk48gpio =
181 + devm_gpiod_get(&pdev->dev, "clock48", GPIOD_OUT_LOW);
182 + if (IS_ERR(snd_rpi_hifiberry_clk48gpio))
183 + snd_rpi_hifiberry_is_digipro = 0;
187 ret = snd_soc_register_card(&snd_rpi_hifiberry_digi);