1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
From 3f38eac723b07d22f70a77ae006d18eb84218a9e Mon Sep 17 00:00:00 2001
From: Digital Dreamtime <clive.messer@digitaldreamtime.co.uk>
Date: Thu, 4 Feb 2016 20:04:00 +0000
Subject: [PATCH] Limit PCM512x "Digital" gain to 0dB by default with HiFiBerry
DAC+
24db_digital_gain DT param can be used to specify that PCM512x
codec "Digital" volume control should not be limited to 0dB gain,
and if specified will allow the full 24dB gain.
---
arch/arm/boot/dts/overlays/README | 17 +++++++++++++++--
.../arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts | 6 +++++-
sound/soc/bcm/hifiberry_dacplus.c | 14 ++++++++++++++
3 files changed, 34 insertions(+), 3 deletions(-)
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -273,8 +273,21 @@ Params: <None>
Name: hifiberry-dacplus
Info: Configures the HifiBerry DAC+ audio card
-Load: dtoverlay=hifiberry-dacplus
-Params: <None>
+Load: dtoverlay=hifiberry-dacplus,<param>=<val>
+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec
+ Digital volume control. Enable with
+ "dtoverlay=hifiberry-dacplus,24db_digital_gain"
+ (The default behaviour is that the Digital
+ volume control is limited to a maximum of
+ 0dB. ie. it can attenuate but not provide
+ gain. For most users, this will be desired
+ as it will prevent clipping. By appending
+ the 24dB_digital_gain parameter, the Digital
+ volume control will allow up to 24dB of
+ gain. If this parameter is enabled, it is the
+ responsibility of the user to ensure that
+ the Digital volume control is set to a value
+ that does not result in clipping/distortion!)
Name: hifiberry-digi
--- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts
+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts
@@ -17,7 +17,7 @@
fragment@1 {
target = <&sound>;
- __overlay__ {
+ frag1: __overlay__ {
compatible = "hifiberry,hifiberry-dacplus";
i2s-controller = <&i2s>;
status = "okay";
@@ -47,4 +47,8 @@
};
};
};
+
+ __overrides__ {
+ 24db_digital_gain = <&frag1>,"hifiberry,24db_digital_gain?";
+ };
};
--- a/sound/soc/bcm/hifiberry_dacplus.c
+++ b/sound/soc/bcm/hifiberry_dacplus.c
@@ -48,6 +48,7 @@ struct pcm512x_priv {
#define CLK_48EN_RATE 24576000UL
static bool snd_rpi_hifiberry_is_dacpro;
+static bool digital_gain_0db_limit = true;
static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec,
int clk_id)
@@ -167,6 +168,16 @@ static int snd_rpi_hifiberry_dacplus_ini
snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02);
snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08);
+ if (digital_gain_0db_limit)
+ {
+ int ret;
+ struct snd_soc_card *card = rtd->card;
+
+ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207);
+ if (ret < 0)
+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret);
+ }
+
return 0;
}
@@ -299,6 +310,9 @@ static int snd_rpi_hifiberry_dacplus_pro
dai->platform_name = NULL;
dai->platform_of_node = i2s_node;
}
+
+ digital_gain_0db_limit = !of_property_read_bool(
+ pdev->dev.of_node, "hifiberry,24db_digital_gain");
}
ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus);
|