From: Matt Flax Date: Wed, 8 Apr 2020 10:00:30 +0000 (+1000) Subject: Add support for the AudioInjector.net Isolated sound card X-Git-Tag: accepted/tizen/unified/20200709.164653~581 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=63cb2be3165b6642ed5a97da20cc60d230e34699;p=platform%2Fkernel%2Flinux-rpi.git Add support for the AudioInjector.net Isolated sound card This patch adds support for the Audio Injector Isolated sound card. Signed-off-by: Matt Flax --- diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile index 658fca1..3f60596 100644 --- a/arch/arm/boot/dts/overlays/Makefile +++ b/arch/arm/boot/dts/overlays/Makefile @@ -22,6 +22,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ applepi-dac.dtbo \ at86rf233.dtbo \ audioinjector-addons.dtbo \ + audioinjector-isolated-soundcard.dtbo \ audioinjector-ultra.dtbo \ audioinjector-wm8731-audio.dtbo \ audiosense-pi.dtbo \ diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index 0db75e63..38459f6 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -505,6 +505,12 @@ Params: non-stop-clocks Keeps the clocks running even when the stream is paused or stopped (default off) +Name: audioinjector-isolated-soundcard +Info: Configures the audioinjector.net isolated soundcard +Load: dtoverlay=audioinjector-isolated-soundcard +Params: + + Name: audioinjector-ultra Info: Configures the audioinjector.net ultra soundcard Load: dtoverlay=audioinjector-ultra diff --git a/arch/arm/boot/dts/overlays/audioinjector-isolated-soundcard-overlay.dts b/arch/arm/boot/dts/overlays/audioinjector-isolated-soundcard-overlay.dts new file mode 100644 index 0000000..63e05cf --- /dev/null +++ b/arch/arm/boot/dts/overlays/audioinjector-isolated-soundcard-overlay.dts @@ -0,0 +1,55 @@ +// Definitions for audioinjector.net audio isolated soundcard +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + cs4272_mclk: codec-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + cs4272: cs4271@10 { + #sound-dai-cells = <0>; + compatible = "cirrus,cs4271"; + reg = <0x10>; + reset-gpio = <&gpio 5 0>; + clocks = <&cs4272_mclk>; + clock-names = "mclk"; + status = "okay"; + }; + }; + }; + + fragment@3 { + target = <&sound>; + snd: __overlay__ { + compatible = "ai,audioinjector-isolated-soundcard"; + mute-gpios = <&gpio 17 0>; + i2s-controller = <&i2s>; + codec = <&cs4272>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig index 0dbec1e..12ea7ed 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig @@ -970,6 +970,7 @@ CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +CONFIG_SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD=m CONFIG_SND_AUDIOSENSE_PI=m CONFIG_SND_DIGIDAC1_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m @@ -987,7 +988,6 @@ CONFIG_SND_SOC_ADAU1701=m CONFIG_SND_SOC_ADAU7002=m CONFIG_SND_SOC_AK4554=m CONFIG_SND_SOC_CS4265=m -CONFIG_SND_SOC_CS4271_I2C=m CONFIG_SND_SOC_ICS43432=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_WM8804_I2C=m diff --git a/arch/arm/configs/bcm2711_defconfig b/arch/arm/configs/bcm2711_defconfig index ffe4065..13d386f7 100644 --- a/arch/arm/configs/bcm2711_defconfig +++ b/arch/arm/configs/bcm2711_defconfig @@ -947,6 +947,7 @@ CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +CONFIG_SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD=m CONFIG_SND_AUDIOSENSE_PI=m CONFIG_SND_DIGIDAC1_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m @@ -964,7 +965,6 @@ CONFIG_SND_SOC_ADAU1701=m CONFIG_SND_SOC_ADAU7002=m CONFIG_SND_SOC_AK4554=m CONFIG_SND_SOC_CS4265=m -CONFIG_SND_SOC_CS4271_I2C=m CONFIG_SND_SOC_ICS43432=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_WM8804_I2C=m diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig index 7cf9f2f..414daa6 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig @@ -962,6 +962,7 @@ CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +CONFIG_SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD=m CONFIG_SND_AUDIOSENSE_PI=m CONFIG_SND_DIGIDAC1_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m @@ -979,7 +980,6 @@ CONFIG_SND_SOC_ADAU1701=m CONFIG_SND_SOC_ADAU7002=m CONFIG_SND_SOC_AK4554=m CONFIG_SND_SOC_CS4265=m -CONFIG_SND_SOC_CS4271_I2C=m CONFIG_SND_SOC_ICS43432=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_WM8804_I2C=m diff --git a/arch/arm64/configs/bcm2711_defconfig b/arch/arm64/configs/bcm2711_defconfig index bd631b8..24260d0 100644 --- a/arch/arm64/configs/bcm2711_defconfig +++ b/arch/arm64/configs/bcm2711_defconfig @@ -977,6 +977,7 @@ CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +CONFIG_SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD=m CONFIG_SND_AUDIOSENSE_PI=m CONFIG_SND_DIGIDAC1_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m @@ -994,7 +995,6 @@ CONFIG_SND_SOC_ADAU1701=m CONFIG_SND_SOC_ADAU7002=m CONFIG_SND_SOC_AK4554=m CONFIG_SND_SOC_CS4265=m -CONFIG_SND_SOC_CS4271_I2C=m CONFIG_SND_SOC_ICS43432=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_WM8804_I2C=m diff --git a/arch/arm64/configs/bcmrpi3_defconfig b/arch/arm64/configs/bcmrpi3_defconfig index 544c16a..a24cbb4 100644 --- a/arch/arm64/configs/bcmrpi3_defconfig +++ b/arch/arm64/configs/bcmrpi3_defconfig @@ -839,6 +839,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m +CONFIG_SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD=m CONFIG_SND_AUDIOSENSE_PI=m CONFIG_SND_DIGIDAC1_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m @@ -849,7 +850,6 @@ CONFIG_SND_SOC_AD193X_I2C=m CONFIG_SND_SOC_ADAU1701=m CONFIG_SND_SOC_AK4554=m CONFIG_SND_SOC_CS4265=m -CONFIG_SND_SOC_CS4271_I2C=m CONFIG_SND_SOC_ICS43432=m CONFIG_SND_SOC_WM8804_I2C=m CONFIG_SND_SIMPLE_CARD=m diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig index 0067bae..fdaccbf 100644 --- a/sound/soc/bcm/Kconfig +++ b/sound/soc/bcm/Kconfig @@ -192,6 +192,13 @@ config SND_AUDIOINJECTOR_OCTO_SOUNDCARD help Say Y or M if you want to add support for audioinjector.net octo add on +config SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD + tristate "Support for audioinjector.net isolated DAC and ADC soundcard" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S + select SND_SOC_CS4271_I2C + help + Say Y or M if you want to add support for audioinjector.net isolated soundcard + config SND_AUDIOSENSE_PI tristate "Support for AudioSense Add-On Soundcard" depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile index 6ab480d..cab3926 100644 --- a/sound/soc/bcm/Makefile +++ b/sound/soc/bcm/Makefile @@ -27,6 +27,7 @@ snd-soc-iqaudio-dac-objs := iqaudio-dac.o snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o +snd-soc-audioinjector-isolated-soundcard-objs := audioinjector-isolated-soundcard.o snd-soc-audiosense-pi-objs := audiosense-pi.o snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o snd-soc-dionaudio-loco-objs := dionaudio_loco.o @@ -55,6 +56,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o +obj-$(CONFIG_SND_AUDIOINJECTOR_ISOLATED_SOUNDCARD) += snd-soc-audioinjector-isolated-soundcard.o obj-$(CONFIG_SND_AUDIOSENSE_PI) += snd-soc-audiosense-pi.o obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o diff --git a/sound/soc/bcm/audioinjector-isolated-soundcard.c b/sound/soc/bcm/audioinjector-isolated-soundcard.c new file mode 100644 index 0000000..6524646 --- /dev/null +++ b/sound/soc/bcm/audioinjector-isolated-soundcard.c @@ -0,0 +1,183 @@ +/* + * 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 +#include +#include + +#include +#include +#include +#include + +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); + + return 0; +} + +static int audioinjector_isolated_trigger(struct snd_pcm_substream *substream, + int cmd){ + + switch (cmd) { + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + gpiod_set_value(mute_gpio, 0); + break; + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + gpiod_set_value(mute_gpio, 1); + break; + default: + return -EINVAL; + } + return 0; +} + +static struct snd_soc_ops audioinjector_isolated_ops = { + .startup = audioinjector_isolated_startup, + .trigger = audioinjector_isolated_trigger, +}; + +SND_SOC_DAILINK_DEFS(audioinjector_isolated, + DAILINK_COMP_ARRAY(COMP_CPU("bcm2708-i2s.0")), + DAILINK_COMP_ARRAY(COMP_CODEC("cs4271.1-0010", "cs4271-hifi")), + DAILINK_COMP_ARRAY(COMP_PLATFORM("bcm2708-i2s.0"))); + +static struct snd_soc_dai_link audioinjector_isolated_dai[] = { + { + .name = "AudioInjector ISO", + .stream_name = "AI-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, + SND_SOC_DAILINK_REG(audioinjector_isolated), + } +}; + +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); + + if (i2s_node) { + dai->cpus->dai_name = NULL; + dai->cpus->of_node = i2s_node; + dai->platforms->name = NULL; + dai->platforms->of_node = i2s_node; + } else { + dev_err(&pdev->dev, + "i2s-controller missing or invalid in DT\n"); + return -EINVAL; + } + + 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); + } + } + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret && ret != -EPROBE_DEFER) + 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 "); +MODULE_DESCRIPTION("AudioInjector.net isolated Soundcard"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:audioinjector-isolated-soundcard");