Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for the AudioInjector.net Isolated and Pro. soundcards. #14

Merged
merged 1 commit into from
Jul 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion arch/arm64/boot/dts/rockchip/overlay/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ dtbo-$(CONFIG_ARCH_ROCKCHIP) += \
rock-3ab-rpi-camera-v1p3-ov5647.dtbo \
rock-3b-disable-hdmicec.dtbo \
rock-3b-hdmi-and-sharp-lq133t1jw01-edp-lcd.dtbo \
rock-3b-radxa-10p1inch-display.dtbo
rock-3b-radxa-10p1inch-display.dtbo \
audioinjector-isolated-soundcard.dtbo

scr-$(CONFIG_ARCH_ROCKCHIP) += \
rockchip-fixup.scr
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Definitions for audioinjector.net audio isolated soundcard
/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>

/ {
compatible = "brcm,bcm2835";

fragment@0 {
target = <&i2s3_2ch>;
__overlay__ {
status = "okay";
};
};

fragment@1 {
target-path = "/";
__overlay__ {
cs4272_mclk: codec-mclk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24576000>;
};
};
};

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

cs4272: cs4272@10 {
#sound-dai-cells = <0>;
compatible = "cirrus,cs4271";
reg = <0x10>;
//reset-gpio = <&gpio 5 0>;
reset-gpio = <&gpio2 RK_PD7 GPIO_ACTIVE_HIGH>;
clocks = <&cs4272_mclk>;
clock-names = "mclk";
status = "okay";
};
};
};

fragment@3 {
target-path = "/";
__overlay__ {
sound {
compatible = "ai,audioinjector-isolated-soundcard";
//mute-gpios = <&gpio 17 0>;
mute-gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
i2s-controller = <&i2s3_2ch>;
codec = <&cs4272>;
status = "okay";
};
};
};
};
1 change: 1 addition & 0 deletions arch/arm64/configs/rockchip_linux_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,7 @@ CONFIG_SND_SOC_ROCKCHIP_MAX98090=y
CONFIG_SND_SOC_ROCKCHIP_MULTICODECS=y
CONFIG_SND_SOC_ROCKCHIP_RT5645=y
CONFIG_SND_SOC_ROCKCHIP_RT5651_RK628=y
CONFIG_SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD=m
CONFIG_SND_SOC_DUMMY_CODEC=y
CONFIG_SND_SOC_ES7202=y
CONFIG_SND_SOC_ES7243E=y
Expand Down
8 changes: 8 additions & 0 deletions sound/soc/rockchip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,11 @@ config SND_SOC_RK3399_GRU_SOUND
help
Say Y or M here if you want to add support multiple codecs for SoC
audio on Rockchip RK3399 GRU boards.

config SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD
tristate "Support for audioinjector.net isolated DAC and ADC soundcard"
depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
select SND_SOC_ROCKCHIP_I2S
select SND_SOC_CS4271_I2C
help
Say Y or M if you want to add support for audioinjector.net isolated soundcard
2 changes: 2 additions & 0 deletions sound/soc/rockchip/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ snd-soc-rockchip-rt5651-objs := rockchip_rt5651.o
snd-soc-rockchip-rt5651-rk628-objs := rockchip_rt5651_rk628.o
snd-soc-rk3288-hdmi-analog-objs := rk3288_hdmi_analog.o
snd-soc-rk3399-gru-sound-objs := rk3399_gru_sound.o
snd-soc-audioinjector-isolated-soundcard-objs := audioinjector-isolated-soundcard.o

obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_MULTICODECS) += snd-soc-rockchip-multicodecs.o
Expand All @@ -37,3 +38,4 @@ obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5651) += snd-soc-rockchip-rt5651.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5651_RK628) += snd-soc-rockchip-rt5651-rk628.o
obj-$(CONFIG_SND_SOC_RK3288_HDMI_ANALOG) += snd-soc-rk3288-hdmi-analog.o
obj-$(CONFIG_SND_SOC_RK3399_GRU_SOUND) += snd-soc-rk3399-gru-sound.o
obj-$(CONFIG_SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD) += snd-soc-audioinjector-isolated-soundcard.o
167 changes: 167 additions & 0 deletions sound/soc/rockchip/audioinjector-isolated-soundcard.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* ASoC Driver for AudioInjector.net isolated soundcard
*
* Created on: 20-February-2020
* Author: flatmax@flatmax.org
* based on audioinjector-octo-soundcard.c
*
* Copyright (C) 2020 Flatmax Pty. Ltd.
*
* 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/types.h>
#include <linux/gpio/consumer.h>

#include <sound/core.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <sound/control.h>

static struct gpio_desc *mute_gpio;

static const unsigned int audioinjector_isolated_rates[] = {
192000, 96000, 48000, 32000, 24000, 16000, 8000
};

static struct snd_pcm_hw_constraint_list audioinjector_isolated_constraints = {
.list = audioinjector_isolated_rates,
.count = ARRAY_SIZE(audioinjector_isolated_rates),
};

static int audioinjector_isolated_dai_init(struct snd_soc_pcm_runtime *rtd)
{
int ret=snd_soc_dai_set_sysclk(rtd->codec_dai, 0, 24576000, 0);
if (ret)
return ret;
return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, 64);
}

static int audioinjector_isolated_startup(struct snd_pcm_substream *substream)
{
snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &audioinjector_isolated_constraints);

gpiod_set_value(mute_gpio, 1);
return 0;
}

static struct snd_soc_ops audioinjector_isolated_ops = {
.startup = audioinjector_isolated_startup,
};

static struct snd_soc_dai_link audioinjector_isolated_dai[] = {
{
.name = "AudioInjector ISO",
.stream_name = "AI-HIFI",
.codec_dai_name = "cs4271-hifi",
.ops = &audioinjector_isolated_ops,
.init = audioinjector_isolated_dai_init,
.symmetric_rates = 1,
.symmetric_channels = 1,
.dai_fmt = SND_SOC_DAIFMT_CBM_CFM|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF,
}
};

static const struct snd_soc_dapm_widget audioinjector_isolated_widgets[] = {
SND_SOC_DAPM_OUTPUT("OUTPUTS"),
SND_SOC_DAPM_INPUT("INPUTS"),
};

static const struct snd_soc_dapm_route audioinjector_isolated_route[] = {
/* Balanced outputs */
{"OUTPUTS", NULL, "AOUTA+"},
{"OUTPUTS", NULL, "AOUTA-"},
{"OUTPUTS", NULL, "AOUTB+"},
{"OUTPUTS", NULL, "AOUTB-"},

/* Balanced inputs */
{"AINA", NULL, "INPUTS"},
{"AINB", NULL, "INPUTS"},
};

static struct snd_soc_card snd_soc_audioinjector_isolated = {
.name = "audioinjector-isolated-soundcard",
.dai_link = audioinjector_isolated_dai,
.num_links = ARRAY_SIZE(audioinjector_isolated_dai),

.dapm_widgets = audioinjector_isolated_widgets,
.num_dapm_widgets = ARRAY_SIZE(audioinjector_isolated_widgets),
.dapm_routes = audioinjector_isolated_route,
.num_dapm_routes = ARRAY_SIZE(audioinjector_isolated_route),
};

static int audioinjector_isolated_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &snd_soc_audioinjector_isolated;
int ret;

card->dev = &pdev->dev;

if (pdev->dev.of_node) {
struct snd_soc_dai_link *dai = &audioinjector_isolated_dai[0];
struct device_node *i2s_node =
of_parse_phandle(pdev->dev.of_node, "i2s-controller", 0);
struct device_node *codec_node =
of_parse_phandle(pdev->dev.of_node, "codec", 0);

mute_gpio = devm_gpiod_get_optional(&pdev->dev, "mute", GPIOD_OUT_LOW);
if (IS_ERR(mute_gpio)){
dev_err(&pdev->dev, "mute gpio not found in dt overlay\n");
return PTR_ERR(mute_gpio);
}
gpiod_set_value(mute_gpio, 0);

if (i2s_node && codec_node) {
dai->cpu_dai_name = NULL;
dai->cpu_of_node = i2s_node;
dai->platform_name = NULL;
dai->platform_of_node = i2s_node;
dai->codec_name = NULL;
dai->codec_of_node = codec_node;
} else
if (!i2s_node) {
dev_err(&pdev->dev,
"i2s-controller missing or invalid in DT\n");
return -EINVAL;
} else {
dev_err(&pdev->dev,
"Property 'codec' missing or invalid\n");
return -EINVAL;
}
}

ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret != 0)
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
return ret;
}

static const struct of_device_id audioinjector_isolated_of_match[] = {
{ .compatible = "ai,audioinjector-isolated-soundcard", },
{},
};
MODULE_DEVICE_TABLE(of, audioinjector_isolated_of_match);

static struct platform_driver audioinjector_isolated_driver = {
.driver = {
.name = "audioinjector-isolated",
.owner = THIS_MODULE,
.of_match_table = audioinjector_isolated_of_match,
},
.probe = audioinjector_isolated_probe,
};

module_platform_driver(audioinjector_isolated_driver);
MODULE_AUTHOR("Matt Flax <flatmax@flatmax.org>");
MODULE_DESCRIPTION("AudioInjector.net isolated Soundcard");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:audioinjector-isolated-soundcard");