Skip to content

Commit

Permalink
sound: Support for Dion Audio LOCO-V2 DAC-AMP HAT
Browse files Browse the repository at this point in the history
Signed-off-by: Miquel Blauw <[email protected]>
  • Loading branch information
miquel83blauw authored and popcornmix committed Mar 12, 2017
1 parent f617a34 commit f95d07f
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/arm/boot/dts/overlays/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
bmp085_i2c-sensor.dtbo \
dht11.dtbo \
dionaudio-loco.dtbo \
dionaudio-loco-v2.dtbo \
dpi18.dtbo \
dpi24.dtbo \
dwc-otg.dtbo \
Expand Down
19 changes: 19 additions & 0 deletions arch/arm/boot/dts/overlays/README
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,25 @@ Load: dtoverlay=dionaudio-loco
Params: <None>


Name: dionaudio-loco-v2
Info: Configures the Dion Audio LOCO-V2 DAC-AMP
Load: dtoverlay=dionaudio-loco-v2,<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: dpi18
Info: Overlay for a generic 18-bit DPI display
This uses GPIOs 0-21 (so no I2C, uart etc.), and activates the output
Expand Down
49 changes: 49 additions & 0 deletions arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Definitions for Dion Audio LOCO-V2 DAC-AMP
* eg. dtoverlay=dionaudio-loco-v2
*
* PCM5242 DAC (in software mode) and TPA3255 AMP.
*/

/dts-v1/;
/plugin/;

/ {
compatible = "brcm,bcm2708";

fragment@0 {
target = <&sound>;
frag0: __overlay__ {
compatible = "dionaudio,dionaudio-loco-v2";
i2s-controller = <&i2s>;
status = "okay";
};
};

fragment@1 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};

fragment@2 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";

pcm5122@4c {
#sound-dai-cells = <0>;
compatible = "ti,pcm5122";
reg = <0x4d>;
status = "okay";
};
};
};

__overrides__ {
24db_digital_gain = <&frag0>,"dionaudio,24db_digital_gain?";
};
};
1 change: 1 addition & 0 deletions arch/arm/configs/bcm2709_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m
CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m
CONFIG_SND_DIGIDAC1_SOUNDCARD=m
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m
CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m
CONFIG_SND_PISOUND=m
CONFIG_SND_SOC_ADAU1701=m
Expand Down
1 change: 1 addition & 0 deletions arch/arm/configs/bcmrpi_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m
CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m
CONFIG_SND_DIGIDAC1_SOUNDCARD=m
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m
CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m
CONFIG_SND_PISOUND=m
CONFIG_SND_SOC_ADAU1701=m
Expand Down
7 changes: 7 additions & 0 deletions sound/soc/bcm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ config SND_BCM2708_SOC_DIONAUDIO_LOCO
help
Say Y or M if you want to add support for Dion Audio LOCO.

config SND_BCM2708_SOC_DIONAUDIO_LOCO_V2
tristate "Support for Dion Audio LOCO-V2 DAC-AMP"
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
select SND_SOC_PCM5122
help
Say Y or M if you want to add support for Dion Audio LOCO-V2.

config SND_BCM2708_SOC_ALLO_PIANO_DAC
tristate "Support for Allo Piano DAC"
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/bcm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ snd-soc-raspidac3-objs := raspidac3.o
snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o
snd-soc-dionaudio-loco-objs := dionaudio_loco.o
snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o
snd-soc-allo-piano-dac-objs := allo-piano-dac.o
snd-soc-pisound-objs := pisound.o

Expand All @@ -44,5 +45,6 @@ obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o
obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o
obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o
obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o
obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o
obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o
obj-$(CONFIG_SND_PISOUND) += snd-soc-pisound.o
140 changes: 140 additions & 0 deletions sound/soc/bcm/dionaudio_loco-v2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* ASoC Driver for Dion Audio LOCO-V2 DAC-AMP
*
* Author: Miquel Blauw <[email protected]>
* Copyright 2017
*
* Based on the software of the RPi-DAC writen by Florian Meier
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/

#include <linux/module.h>
#include <linux/platform_device.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/jack.h>

static bool digital_gain_0db_limit = true;

static int snd_rpi_dionaudio_loco_v2_init(struct snd_soc_pcm_runtime *rtd)
{
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;
}

static int snd_rpi_dionaudio_loco_v2_hw_params(
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

unsigned int sample_bits =
snd_pcm_format_physical_width(params_format(params));

return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
}

/* machine stream operations */
static struct snd_soc_ops snd_rpi_dionaudio_loco_v2_ops = {
.hw_params = snd_rpi_dionaudio_loco_v2_hw_params,
};

static struct snd_soc_dai_link snd_rpi_dionaudio_loco_v2_dai[] = {
{
.name = "DionAudio LOCO-V2",
.stream_name = "DionAudio LOCO-V2 DAC-AMP",
.cpu_dai_name = "bcm2708-i2s.0",
.codec_dai_name = "pcm512x-hifi",
.platform_name = "bcm2708-i2s.0",
.codec_name = "pcm512x.1-004d",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ops = &snd_rpi_dionaudio_loco_v2_ops,
.init = snd_rpi_dionaudio_loco_v2_init,
},};

/* audio machine driver */
static struct snd_soc_card snd_rpi_dionaudio_loco_v2 = {
.name = "Dion Audio LOCO-V2",
.dai_link = snd_rpi_dionaudio_loco_v2_dai,
.num_links = ARRAY_SIZE(snd_rpi_dionaudio_loco_v2_dai),
};

static int snd_rpi_dionaudio_loco_v2_probe(struct platform_device *pdev)
{
int ret = 0;

snd_rpi_dionaudio_loco_v2.dev = &pdev->dev;

if (pdev->dev.of_node) {
struct device_node *i2s_node;
struct snd_soc_dai_link *dai =
&snd_rpi_dionaudio_loco_v2_dai[0];

i2s_node = of_parse_phandle(pdev->dev.of_node,
"i2s-controller", 0);
if (i2s_node) {
dai->cpu_dai_name = NULL;
dai->cpu_of_node = i2s_node;
dai->platform_name = NULL;
dai->platform_of_node = i2s_node;
}

digital_gain_0db_limit = !of_property_read_bool(
pdev->dev.of_node, "dionaudio,24db_digital_gain");
}

ret = snd_soc_register_card(&snd_rpi_dionaudio_loco_v2);
if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret);

return ret;
}

static int snd_rpi_dionaudio_loco_v2_remove(struct platform_device *pdev)
{
return snd_soc_unregister_card(&snd_rpi_dionaudio_loco_v2);
}

static const struct of_device_id dionaudio_of_match[] = {
{ .compatible = "dionaudio,dionaudio-loco-v2", },
{},
};
MODULE_DEVICE_TABLE(of, dionaudio_of_match);

static struct platform_driver snd_rpi_dionaudio_loco_v2_driver = {
.driver = {
.name = "snd-rpi-dionaudio-loco-v2",
.owner = THIS_MODULE,
.of_match_table = dionaudio_of_match,
},
.probe = snd_rpi_dionaudio_loco_v2_probe,
.remove = snd_rpi_dionaudio_loco_v2_remove,
};

module_platform_driver(snd_rpi_dionaudio_loco_v2_driver);

MODULE_AUTHOR("Miquel Blauw <[email protected]>");
MODULE_DESCRIPTION("ASoC Driver for DionAudio LOCO-V2");
MODULE_LICENSE("GPL v2");

0 comments on commit f95d07f

Please sign in to comment.