diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile index 3d8de479d0a5a1..02acf884753c2f 100644 --- a/arch/arm/boot/dts/overlays/Makefile +++ b/arch/arm/boot/dts/overlays/Makefile @@ -16,6 +16,7 @@ dtbo-$(RPI_DT_OVERLAYS) += adau1977-adc.dtbo dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo dtbo-$(RPI_DT_OVERLAYS) += akkordion-iqdacplus.dtbo dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo +dtbo-$(RPI_DT_OVERLAYS) += audioinjector-wm8731-audio.dtbo dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo dtbo-$(RPI_DT_OVERLAYS) += boomberry-dac.dtbo dtbo-$(RPI_DT_OVERLAYS) += boomberry-digi.dtbo diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index 97dff3597a8621..279802a1ec1e92 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -225,6 +225,12 @@ Params: interrupt GPIO used for INT (default 23) arrays (0=+0pF, 15=+4.5pF, default 15) +Name: audioinjector-wm8731-audio +Info: Configures the audioinjector.net audio add on soundcard +Load: dtoverlay=audioinjector-wm8731-audio +Params: + + Name: bmp085_i2c-sensor Info: Configures the BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec diff --git a/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts b/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts new file mode 100644 index 00000000000000..4ed66577fa1d59 --- /dev/null +++ b/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts @@ -0,0 +1,39 @@ +// Definitions for audioinjector.net audio add on soundcard +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8731@1a { + #sound-dai-cells = <0>; + compatible = "wlf,wm8731"; + reg = <0x1a>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "ai,audioinjector-pi-soundcard"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig index 0bdc63180a149e..666811f5ac56c4 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig @@ -862,6 +862,7 @@ CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m CONFIG_SND_BCM2708_SOC_RASPIDAC3=m +CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m CONFIG_SND_SOC_ADAU1701=m CONFIG_SND_SOC_WM8804_I2C=m diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig index 57393b5e216f80..9ebfd0c96aeac6 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig @@ -854,6 +854,7 @@ CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m CONFIG_SND_BCM2708_SOC_RASPIDAC3=m +CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m CONFIG_SND_SOC_ADAU1701=m CONFIG_SND_SOC_WM8804_I2C=m diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig index c05e656eaa9684..30f8208371ee81 100644 --- a/sound/soc/bcm/Kconfig +++ b/sound/soc/bcm/Kconfig @@ -85,3 +85,10 @@ config SND_BCM2708_SOC_ADAU1977_ADC select SND_SOC_ADAU1977_I2C help Say Y or M if you want to add support for ADAU1977 ADC. + +config SND_AUDIOINJECTOR_PI_SOUNDCARD + tristate "Support for audioinjector.net Pi add on soundcard" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S + select SND_SOC_WM8731 + help + Say Y or M if you want to add support for audioinjector.net Pi Hat diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile index 7de2ef13a0d3c7..4af578211f4c55 100644 --- a/sound/soc/bcm/Makefile +++ b/sound/soc/bcm/Makefile @@ -15,6 +15,7 @@ snd-soc-rpi-dac-objs := rpi-dac.o snd-soc-rpi-proto-objs := rpi-proto.o snd-soc-iqaudio-dac-objs := iqaudio-dac.o snd-soc-raspidac3-objs := raspidac3.o +snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o @@ -27,3 +28,5 @@ obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o +obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o + diff --git a/sound/soc/bcm/audioinjector-pi-soundcard.c b/sound/soc/bcm/audioinjector-pi-soundcard.c new file mode 100644 index 00000000000000..39f29e26897226 --- /dev/null +++ b/sound/soc/bcm/audioinjector-pi-soundcard.c @@ -0,0 +1,142 @@ +/* + * ASoC Driver for AudioInjector Pi add on soundcard + * + * Created on: 13-May-2016 + * Author: flatmax@flatmax.org + * based on code by Cliff Cai for the ssm2602 machine blackfin. + * with help from Lars-Peter Clausen for simplifying the original code to use the dai_fmt field. + * i2s_node code taken from the other sound/soc/bcm machine drivers. + * + * Copyright (C) 2016 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 "../codecs/wm8731.h" + +static int audioinjector_pi_soundcard_dai_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + + // not connected + snd_soc_dapm_nc_pin(dapm, "Mic Bias"); + snd_soc_dapm_nc_pin(dapm, "MICIN"); + snd_soc_dapm_nc_pin(dapm, "RHPOUT"); + snd_soc_dapm_nc_pin(dapm, "LHPOUT"); + + return snd_soc_dai_set_sysclk(rtd->codec_dai, WM8731_SYSCLK_XTAL, 12000000, SND_SOC_CLOCK_IN); +} + +static struct snd_soc_dai_link audioinjector_pi_soundcard_dai[] = { + { + .name = "AudioInjector audio", + .stream_name = "AudioInjector audio", + .cpu_dai_name = "bcm2708-i2s.0", + .codec_dai_name = "wm8731-hifi", + .platform_name = "bcm2835-i2s.0", + .codec_name = "wm8731.1-001a", + .init = audioinjector_pi_soundcard_dai_init, + .dai_fmt = SND_SOC_DAIFMT_CBM_CFM|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF, + }, +}; + +static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_LINE("Line In Jacks", NULL), +}; + +/* Corgi machine connections to the codec pins */ +static const struct snd_soc_dapm_route audioinjector_audio_map[] = { + /* speaker connected to LOUT, ROUT */ + {"Ext Spk", NULL, "ROUT"}, + {"Ext Spk", NULL, "LOUT"}, + + /* line inputs */ + {"Line In Jacks", NULL, "Line Input"}, +}; + +static struct snd_soc_card snd_soc_audioinjector = { + .name = "audioinjector-pi-soundcard", + .dai_link = audioinjector_pi_soundcard_dai, + .num_links = 1, + + .dapm_widgets = wm8731_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), + .dapm_routes = audioinjector_audio_map, + .num_dapm_routes = ARRAY_SIZE(audioinjector_audio_map), +}; + +static int audioinjector_pi_soundcard_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &snd_soc_audioinjector; + int ret; + + card->dev = &pdev->dev; + + if (pdev->dev.of_node) { + struct snd_soc_dai_link *dai = &audioinjector_pi_soundcard_dai[0]; + struct device_node *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; + } else + if (!dai->cpu_of_node) { + dev_err(&pdev->dev, "Property 'i2s-controller' missing or invalid\n"); + return -EINVAL; + } + } + + if ((ret = snd_soc_register_card(card))) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + } + return ret; +} + +static int audioinjector_pi_soundcard_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + return snd_soc_unregister_card(card); + +} + +static const struct of_device_id audioinjector_pi_soundcard_of_match[] = { + { .compatible = "ai,audioinjector-pi-soundcard", }, + {}, +}; +MODULE_DEVICE_TABLE(of, audioinjector_pi_soundcard_of_match); + +static struct platform_driver audioinjector_pi_soundcard_driver = { + .driver = { + .name = "audioinjector-audio", + .owner = THIS_MODULE, + .of_match_table = audioinjector_pi_soundcard_of_match, + }, + .probe = audioinjector_pi_soundcard_probe, + .remove = audioinjector_pi_soundcard_remove, +}; + +module_platform_driver(audioinjector_pi_soundcard_driver); +MODULE_AUTHOR("Matt Flax "); +MODULE_DESCRIPTION("AudioInjector.net Pi Soundcard"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:audioinjector-pi-soundcard"); +