Skip to content

Commit d892761

Browse files
miquel83blauwpopcornmix
authored andcommitted
sound: Support for Dion Audio LOCO-V2 DAC-AMP HAT
Signed-off-by: Miquel Blauw <[email protected]>
1 parent a26969d commit d892761

File tree

8 files changed

+220
-0
lines changed

8 files changed

+220
-0
lines changed

arch/arm/boot/dts/overlays/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
1313
bmp085_i2c-sensor.dtbo \
1414
dht11.dtbo \
1515
dionaudio-loco.dtbo \
16+
dionaudio-loco-v2.dtbo \
1617
dpi18.dtbo \
1718
dpi24.dtbo \
1819
dwc-otg.dtbo \

arch/arm/boot/dts/overlays/README

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,25 @@ Load: dtoverlay=dionaudio-loco
308308
Params: <None>
309309

310310

311+
Name: dionaudio-loco-v2
312+
Info: Configures the Dion Audio LOCO-V2 DAC-AMP
313+
Load: dtoverlay=dionaudio-loco-v2,<param>=<val>
314+
Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec
315+
Digital volume control. Enable with
316+
"dtoverlay=hifiberry-dacplus,24db_digital_gain"
317+
(The default behaviour is that the Digital
318+
volume control is limited to a maximum of
319+
0dB. ie. it can attenuate but not provide
320+
gain. For most users, this will be desired
321+
as it will prevent clipping. By appending
322+
the 24dB_digital_gain parameter, the Digital
323+
volume control will allow up to 24dB of
324+
gain. If this parameter is enabled, it is the
325+
responsibility of the user to ensure that
326+
the Digital volume control is set to a value
327+
that does not result in clipping/distortion!)
328+
329+
311330
Name: dpi18
312331
Info: Overlay for a generic 18-bit DPI display
313332
This uses GPIOs 0-21 (so no I2C, uart etc.), and activates the output
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Definitions for Dion Audio LOCO-V2 DAC-AMP
3+
* eg. dtoverlay=dionaudio-loco-v2
4+
*
5+
* PCM5242 DAC (in software mode) and TPA3255 AMP.
6+
*/
7+
8+
/dts-v1/;
9+
/plugin/;
10+
11+
/ {
12+
compatible = "brcm,bcm2708";
13+
14+
fragment@0 {
15+
target = <&sound>;
16+
frag0: __overlay__ {
17+
compatible = "dionaudio,dionaudio-loco-v2";
18+
i2s-controller = <&i2s>;
19+
status = "okay";
20+
};
21+
};
22+
23+
fragment@1 {
24+
target = <&i2s>;
25+
__overlay__ {
26+
status = "okay";
27+
};
28+
};
29+
30+
fragment@2 {
31+
target = <&i2c1>;
32+
__overlay__ {
33+
#address-cells = <1>;
34+
#size-cells = <0>;
35+
status = "okay";
36+
37+
pcm5122@4c {
38+
#sound-dai-cells = <0>;
39+
compatible = "ti,pcm5122";
40+
reg = <0x4d>;
41+
status = "okay";
42+
};
43+
};
44+
};
45+
46+
__overrides__ {
47+
24db_digital_gain = <&frag0>,"dionaudio,24db_digital_gain?";
48+
};
49+
};

arch/arm/configs/bcm2709_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m
883883
CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m
884884
CONFIG_SND_DIGIDAC1_SOUNDCARD=m
885885
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m
886+
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m
886887
CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m
887888
CONFIG_SND_PISOUND=m
888889
CONFIG_SND_SOC_ADAU1701=m

arch/arm/configs/bcmrpi_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m
877877
CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m
878878
CONFIG_SND_DIGIDAC1_SOUNDCARD=m
879879
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m
880+
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m
880881
CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m
881882
CONFIG_SND_PISOUND=m
882883
CONFIG_SND_SOC_ADAU1701=m

sound/soc/bcm/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,13 @@ config SND_BCM2708_SOC_DIONAUDIO_LOCO
134134
help
135135
Say Y or M if you want to add support for Dion Audio LOCO.
136136

137+
config SND_BCM2708_SOC_DIONAUDIO_LOCO_V2
138+
tristate "Support for Dion Audio LOCO-V2 DAC-AMP"
139+
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
140+
select SND_SOC_PCM5122
141+
help
142+
Say Y or M if you want to add support for Dion Audio LOCO-V2.
143+
137144
config SND_BCM2708_SOC_ALLO_PIANO_DAC
138145
tristate "Support for Allo Piano DAC"
139146
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S

sound/soc/bcm/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ snd-soc-raspidac3-objs := raspidac3.o
2525
snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
2626
snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o
2727
snd-soc-dionaudio-loco-objs := dionaudio_loco.o
28+
snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o
2829
snd-soc-allo-piano-dac-objs := allo-piano-dac.o
2930
snd-soc-pisound-objs := pisound.o
3031

@@ -44,5 +45,6 @@ obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o
4445
obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o
4546
obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o
4647
obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o
48+
obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o
4749
obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o
4850
obj-$(CONFIG_SND_PISOUND) += snd-soc-pisound.o

sound/soc/bcm/dionaudio_loco-v2.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* ASoC Driver for Dion Audio LOCO-V2 DAC-AMP
3+
*
4+
* Author: Miquel Blauw <[email protected]>
5+
* Copyright 2017
6+
*
7+
* Based on the software of the RPi-DAC writen by Florian Meier
8+
*
9+
* This program is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU General Public License
11+
* version 2 as published by the Free Software Foundation.
12+
*
13+
* This program is distributed in the hope that it will be useful, but
14+
* WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* General Public License for more details.
17+
*/
18+
19+
#include <linux/module.h>
20+
#include <linux/platform_device.h>
21+
22+
#include <sound/core.h>
23+
#include <sound/pcm.h>
24+
#include <sound/pcm_params.h>
25+
#include <sound/soc.h>
26+
#include <sound/jack.h>
27+
28+
static bool digital_gain_0db_limit = true;
29+
30+
static int snd_rpi_dionaudio_loco_v2_init(struct snd_soc_pcm_runtime *rtd)
31+
{
32+
if (digital_gain_0db_limit) {
33+
int ret;
34+
struct snd_soc_card *card = rtd->card;
35+
36+
ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207);
37+
if (ret < 0)
38+
dev_warn(card->dev, "Failed to set volume limit: %d\n", ret);
39+
}
40+
41+
return 0;
42+
}
43+
44+
static int snd_rpi_dionaudio_loco_v2_hw_params(
45+
struct snd_pcm_substream *substream,
46+
struct snd_pcm_hw_params *params)
47+
{
48+
struct snd_soc_pcm_runtime *rtd = substream->private_data;
49+
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
50+
51+
unsigned int sample_bits =
52+
snd_pcm_format_physical_width(params_format(params));
53+
54+
return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
55+
}
56+
57+
/* machine stream operations */
58+
static struct snd_soc_ops snd_rpi_dionaudio_loco_v2_ops = {
59+
.hw_params = snd_rpi_dionaudio_loco_v2_hw_params,
60+
};
61+
62+
static struct snd_soc_dai_link snd_rpi_dionaudio_loco_v2_dai[] = {
63+
{
64+
.name = "DionAudio LOCO-V2",
65+
.stream_name = "DionAudio LOCO-V2 DAC-AMP",
66+
.cpu_dai_name = "bcm2708-i2s.0",
67+
.codec_dai_name = "pcm512x-hifi",
68+
.platform_name = "bcm2708-i2s.0",
69+
.codec_name = "pcm512x.1-004d",
70+
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
71+
SND_SOC_DAIFMT_CBS_CFS,
72+
.ops = &snd_rpi_dionaudio_loco_v2_ops,
73+
.init = snd_rpi_dionaudio_loco_v2_init,
74+
},};
75+
76+
/* audio machine driver */
77+
static struct snd_soc_card snd_rpi_dionaudio_loco_v2 = {
78+
.name = "Dion Audio LOCO-V2",
79+
.dai_link = snd_rpi_dionaudio_loco_v2_dai,
80+
.num_links = ARRAY_SIZE(snd_rpi_dionaudio_loco_v2_dai),
81+
};
82+
83+
static int snd_rpi_dionaudio_loco_v2_probe(struct platform_device *pdev)
84+
{
85+
int ret = 0;
86+
87+
snd_rpi_dionaudio_loco_v2.dev = &pdev->dev;
88+
89+
if (pdev->dev.of_node) {
90+
struct device_node *i2s_node;
91+
struct snd_soc_dai_link *dai =
92+
&snd_rpi_dionaudio_loco_v2_dai[0];
93+
94+
i2s_node = of_parse_phandle(pdev->dev.of_node,
95+
"i2s-controller", 0);
96+
if (i2s_node) {
97+
dai->cpu_dai_name = NULL;
98+
dai->cpu_of_node = i2s_node;
99+
dai->platform_name = NULL;
100+
dai->platform_of_node = i2s_node;
101+
}
102+
103+
digital_gain_0db_limit = !of_property_read_bool(
104+
pdev->dev.of_node, "dionaudio,24db_digital_gain");
105+
}
106+
107+
ret = snd_soc_register_card(&snd_rpi_dionaudio_loco_v2);
108+
if (ret)
109+
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
110+
ret);
111+
112+
return ret;
113+
}
114+
115+
static int snd_rpi_dionaudio_loco_v2_remove(struct platform_device *pdev)
116+
{
117+
return snd_soc_unregister_card(&snd_rpi_dionaudio_loco_v2);
118+
}
119+
120+
static const struct of_device_id dionaudio_of_match[] = {
121+
{ .compatible = "dionaudio,dionaudio-loco-v2", },
122+
{},
123+
};
124+
MODULE_DEVICE_TABLE(of, dionaudio_of_match);
125+
126+
static struct platform_driver snd_rpi_dionaudio_loco_v2_driver = {
127+
.driver = {
128+
.name = "snd-rpi-dionaudio-loco-v2",
129+
.owner = THIS_MODULE,
130+
.of_match_table = dionaudio_of_match,
131+
},
132+
.probe = snd_rpi_dionaudio_loco_v2_probe,
133+
.remove = snd_rpi_dionaudio_loco_v2_remove,
134+
};
135+
136+
module_platform_driver(snd_rpi_dionaudio_loco_v2_driver);
137+
138+
MODULE_AUTHOR("Miquel Blauw <[email protected]>");
139+
MODULE_DESCRIPTION("ASoC Driver for DionAudio LOCO-V2");
140+
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)