Skip to content

Commit db84877

Browse files
authored
Merge pull request #1583 from hifiberry/digi-pro
Added HiFiBerry Digi+ Pro driver
2 parents e146e33 + d614a77 commit db84877

File tree

4 files changed

+100
-1
lines changed

4 files changed

+100
-1
lines changed

arch/arm/boot/dts/overlays/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ dtbo-$(RPI_DT_OVERLAYS) += hifiberry-amp.dtbo
3131
dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dac.dtbo
3232
dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacplus.dtbo
3333
dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi.dtbo
34+
dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi-pro.dtbo
3435
dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo
3536
dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo
3637
dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo

arch/arm/boot/dts/overlays/README

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,17 @@ Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec
377377

378378

379379
Name: hifiberry-digi
380-
Info: Configures the HifiBerry Digi audio card
380+
Info: Configures the HifiBerry Digi and Digi+ audio card
381381
Load: dtoverlay=hifiberry-digi
382382
Params: <None>
383383

384384

385+
Name: hifiberry-digi-pro
386+
Info: Configures the HifiBerry Digi+ Pro audio card
387+
Load: dtoverlay=hifiberry-digi-pro
388+
Params: <None>
389+
390+
385391
Name: hy28a
386392
Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics
387393
Default values match Texy's display shield
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Definitions for HiFiBerry Digi Pro
2+
/dts-v1/;
3+
/plugin/;
4+
5+
/ {
6+
compatible = "brcm,bcm2708";
7+
8+
fragment@0 {
9+
target = <&i2s>;
10+
__overlay__ {
11+
status = "okay";
12+
};
13+
};
14+
15+
fragment@1 {
16+
target = <&i2c1>;
17+
__overlay__ {
18+
#address-cells = <1>;
19+
#size-cells = <0>;
20+
status = "okay";
21+
22+
wm8804@3b {
23+
#sound-dai-cells = <0>;
24+
compatible = "wlf,wm8804";
25+
reg = <0x3b>;
26+
status = "okay";
27+
};
28+
};
29+
};
30+
31+
fragment@2 {
32+
target = <&sound>;
33+
__overlay__ {
34+
compatible = "hifiberry,hifiberry-digi";
35+
i2s-controller = <&i2s>;
36+
status = "okay";
37+
clock44-gpio = <&gpio 5 0>;
38+
clock48-gpio = <&gpio 6 0>;
39+
};
40+
};
41+
};

sound/soc/bcm/hifiberry_digi.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,57 @@
2323
#include <sound/pcm_params.h>
2424
#include <sound/soc.h>
2525
#include <sound/jack.h>
26+
#include <linux/gpio/consumer.h>
2627

2728
#include "../codecs/wm8804.h"
2829

2930
static short int auto_shutdown_output = 0;
3031
module_param(auto_shutdown_output, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
3132
MODULE_PARM_DESC(auto_shutdown_output, "Shutdown SP/DIF output if playback is stopped");
3233

34+
#define CLK_44EN_RATE 22579200UL
35+
#define CLK_48EN_RATE 24576000UL
36+
37+
static bool snd_rpi_hifiberry_is_digipro;
38+
static struct gpio_desc *snd_rpi_hifiberry_clk44gpio;
39+
static struct gpio_desc *snd_rpi_hifiberry_clk48gpio;
3340

3441
static int samplerate=44100;
3542

43+
static uint32_t snd_rpi_hifiberry_digi_enable_clock(int sample_rate)
44+
{
45+
switch (sample_rate) {
46+
case 11025:
47+
case 22050:
48+
case 44100:
49+
case 88200:
50+
case 176400:
51+
gpiod_set_value_cansleep(snd_rpi_hifiberry_clk44gpio, 1);
52+
gpiod_set_value_cansleep(snd_rpi_hifiberry_clk48gpio, 0);
53+
return CLK_44EN_RATE;
54+
default:
55+
gpiod_set_value_cansleep(snd_rpi_hifiberry_clk48gpio, 1);
56+
gpiod_set_value_cansleep(snd_rpi_hifiberry_clk44gpio, 0);
57+
return CLK_48EN_RATE;
58+
}
59+
}
60+
61+
3662
static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd)
3763
{
3864
struct snd_soc_codec *codec = rtd->codec;
3965

4066
/* enable TX output */
4167
snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0);
4268

69+
/* Initialize Digi+ Pro hardware */
70+
if (snd_rpi_hifiberry_is_digipro) {
71+
struct snd_soc_dai_link *dai = rtd->dai_link;
72+
73+
dai->name = "HiFiBerry Digi+ Pro";
74+
dai->stream_name = "HiFiBerry Digi+ Pro HiFi";
75+
}
76+
4377
return 0;
4478
}
4579

@@ -87,6 +121,9 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream,
87121
mclk_freq=samplerate*128;
88122
mclk_div=WM8804_MCLKDIV_128FS;
89123
}
124+
125+
if (snd_rpi_hifiberry_is_digipro)
126+
sysclk = snd_rpi_hifiberry_digi_enable_clock(samplerate);
90127

91128
switch (samplerate) {
92129
case 32000:
@@ -121,6 +158,7 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream,
121158

122159
ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL,
123160
sysclk, SND_SOC_CLOCK_OUT);
161+
124162
if (ret < 0) {
125163
dev_err(codec->dev,
126164
"Failed to set WM8804 SYSCLK: %d\n", ret);
@@ -187,6 +225,19 @@ static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev)
187225
dai->platform_name = NULL;
188226
dai->platform_of_node = i2s_node;
189227
}
228+
229+
snd_rpi_hifiberry_is_digipro = 1;
230+
231+
snd_rpi_hifiberry_clk44gpio =
232+
devm_gpiod_get(&pdev->dev, "clock44", GPIOD_OUT_LOW);
233+
if (IS_ERR(snd_rpi_hifiberry_clk44gpio))
234+
snd_rpi_hifiberry_is_digipro = 0;
235+
236+
snd_rpi_hifiberry_clk48gpio =
237+
devm_gpiod_get(&pdev->dev, "clock48", GPIOD_OUT_LOW);
238+
if (IS_ERR(snd_rpi_hifiberry_clk48gpio))
239+
snd_rpi_hifiberry_is_digipro = 0;
240+
190241
}
191242

192243
ret = snd_soc_register_card(&snd_rpi_hifiberry_digi);

0 commit comments

Comments
 (0)