From c6aeb7de226dd08ad9b343fc6cbaf2ff36f69c84 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 16:24:08 +0100 Subject: ASoC: Add support for BCM2835 This driver adds support for digital audio (I2S) for the BCM2835 SoC that is used by the Raspberry Pi. External audio codecs can be connected to the Raspberry Pi via P5 header. It relies on cyclic DMA engine support for BCM2835. Signed-off-by: Florian Meier Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/bcm2835-i2s.txt | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/bcm2835-i2s.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/bcm2835-i2s.txt b/Documentation/devicetree/bindings/sound/bcm2835-i2s.txt new file mode 100644 index 000000000000..65783de0aedf --- /dev/null +++ b/Documentation/devicetree/bindings/sound/bcm2835-i2s.txt @@ -0,0 +1,25 @@ +* Broadcom BCM2835 SoC I2S/PCM module + +Required properties: +- compatible: "brcm,bcm2835-i2s" +- reg: A list of base address and size entries: + * The first entry should cover the PCM registers + * The second entry should cover the PCM clock registers +- dmas: List of DMA controller phandle and DMA request line ordered pairs. +- dma-names: Identifier string for each DMA request line in the dmas property. + These strings correspond 1:1 with the ordered pairs in dmas. + + One of the DMA channels will be responsible for transmission (should be + named "tx") and one for reception (should be named "rx"). + +Example: + +bcm2835_i2s: i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; + reg = <0x7e203000 0x20>, + <0x7e101098 0x02>; + + dmas = <&dma 2>, + <&dma 3>; + dma-names = "tx", "rx"; +}; -- cgit v1.2.3 From 3a85ca9d8a06c873b7a5fb24319572926fa20e10 Mon Sep 17 00:00:00 2001 From: Brian Austin Date: Fri, 15 Nov 2013 09:35:34 -0600 Subject: ASoC: dt: binding: sound cs42l52 driver Signed-off-by: Brian Austin Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/cs42l52.txt | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/cs42l52.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/cs42l52.txt b/Documentation/devicetree/bindings/sound/cs42l52.txt new file mode 100644 index 000000000000..bc03c9312a19 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cs42l52.txt @@ -0,0 +1,46 @@ +CS42L52 audio CODEC + +Required properties: + + - compatible : "cirrus,cs42l52" + + - reg : the I2C address of the device for I2C + +Optional properties: + + - cirrus,reset-gpio : GPIO controller's phandle and the number + of the GPIO used to reset the codec. + + - cirrus,chgfreq-divisor : Values used to set the Charge Pump Frequency. + Allowable values of 0x00 through 0x0F. These are raw values written to the + register, not the actual frequency. The frequency is determined by the following. + Frequency = (64xFs)/(N+2) + N = chgfreq_val + Fs = Sample Rate (variable) + + - cirrus,mica-differential-cfg : boolean, If present, then the MICA input is configured + as a differential input. If not present then the MICA input is configured as + Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input. + + - cirrus,micb-differential-cfg : boolean, If present, then the MICB input is configured + as a differential input. If not present then the MICB input is configured as + Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input. + + - cirrus,micbias-lvl: Set the output voltage level on the MICBIAS Pin + 0 = 0.5 x VA + 1 = 0.6 x VA + 2 = 0.7 x VA + 3 = 0.8 x VA + 4 = 0.83 x VA + 5 = 0.91 x VA + +Example: + +codec: codec@4a { + compatible = "cirrus,cs42l52"; + reg = <0x4a>; + reset-gpio = <&gpio 10 0>; + cirrus,chgfreq-divisor = <0x05>; + cirrus.mica-differential-cfg; + cirrus,micbias-lvl = <5>; +}; -- cgit v1.2.3 From 7637af2e17f18bfe6264d834c6edee7706a0f15c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 4 Dec 2013 15:19:27 -0700 Subject: ASoC: tegra: add tegra+MAX98090 machine driver Initially, this binding and driver only describe/support playback to headphones and speakers, and capture from the external microphone, with GPIO-based jack detection for the headphone jack only. This driver is useful for the Venice2 board. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- .../bindings/sound/nvidia,tegra-audio-max98090.txt | 51 ++++ sound/soc/tegra/Kconfig | 10 + sound/soc/tegra/Makefile | 2 + sound/soc/tegra/tegra_max98090.c | 275 +++++++++++++++++++++ 4 files changed, 338 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt create mode 100644 sound/soc/tegra/tegra_max98090.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt new file mode 100644 index 000000000000..9c7c55c71370 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt @@ -0,0 +1,51 @@ +NVIDIA Tegra audio complex, with MAX98090 CODEC + +Required properties: +- compatible : "nvidia,tegra-audio-max98090" +- clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names : Must include the following entries: + - pll_a + - pll_a_out0 + - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) +- nvidia,model : The user-visible name of this sound complex. +- nvidia,audio-routing : A list of the connections between audio components. + Each entry is a pair of strings, the first being the connection's sink, + the second being the connection's source. Valid names for sources and + sinks are the MAX98090's pins (as documented in its binding), and the jacks + on the board: + + * Headphones + * Speakers + * Mic Jack + +- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's + connected to the CODEC. +- nvidia,audio-codec : The phandle of the MAX98090 audio codec. + +Optional properties: +- nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in + +Example: + +sound { + compatible = "nvidia,tegra-audio-max98090-venice2", + "nvidia,tegra-audio-max98090"; + nvidia,model = "NVIDIA Tegra Venice2"; + + nvidia,audio-routing = + "Headphones", "HPR", + "Headphones", "HPL", + "Speakers", "SPKR", + "Speakers", "SPKL", + "Mic Jack", "MICBIAS", + "IN34", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&acodec>; + + clocks = <&tegra_car TEGRA124_CLK_PLL_A>, + <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA124_CLK_EXTERN1>; + clock-names = "pll_a", "pll_a_out0", "mclk"; +}; diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 8fc653ca3ab4..65a85f542521 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -116,3 +116,13 @@ config SND_SOC_TEGRA_ALC5632 help Say Y or M here if you want to add support for SoC audio on the Toshiba AC100 netbook. + +config SND_SOC_TEGRA_MAX98090 + tristate "SoC Audio support for Tegra boards using a MAX98090 codec" + depends on SND_SOC_TEGRA && I2C && GPIOLIB + select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC + select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC + select SND_SOC_MAX98090 + help + Say Y or M here if you want to add support for SoC audio on Tegra + boards using the MAX98090 codec, such as Venice2. diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 21d2550a08a4..5ae588cd96c4 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -24,6 +24,7 @@ snd-soc-tegra-wm8903-objs := tegra_wm8903.o snd-soc-tegra-wm9712-objs := tegra_wm9712.o snd-soc-tegra-trimslice-objs := trimslice.o snd-soc-tegra-alc5632-objs := tegra_alc5632.o +snd-soc-tegra-max98090-objs := tegra_max98090.o obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o @@ -31,3 +32,4 @@ obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o +obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c new file mode 100644 index 000000000000..0283cfb7c031 --- /dev/null +++ b/sound/soc/tegra/tegra_max98090.c @@ -0,0 +1,275 @@ +/* + * Tegra machine ASoC driver for boards using a MAX90809 CODEC. + * + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Based on code copyright/by: + * + * Copyright (C) 2010-2012 - NVIDIA, Inc. + * Copyright (C) 2011 The AC100 Kernel Team + * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd. + * Copyright 2007 Wolfson Microelectronics PLC. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "tegra_asoc_utils.h" + +#define DRV_NAME "tegra-snd-max98090" + +struct tegra_max98090 { + struct tegra_asoc_utils_data util_data; + int gpio_hp_det; +}; + +static int tegra_max98090_asoc_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 *codec_dai = rtd->codec_dai; + struct snd_soc_codec *codec = codec_dai->codec; + struct snd_soc_card *card = codec->card; + struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); + int srate, mclk; + int err; + + srate = params_rate(params); + switch (srate) { + case 8000: + case 16000: + case 24000: + case 32000: + case 48000: + case 64000: + case 96000: + mclk = 12288000; + break; + case 11025: + case 22050: + case 44100: + case 88200: + mclk = 11289600; + break; + default: + mclk = 12000000; + break; + } + + err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); + if (err < 0) { + dev_err(card->dev, "Can't configure clocks\n"); + return err; + } + + err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, + SND_SOC_CLOCK_IN); + if (err < 0) { + dev_err(card->dev, "codec_dai clock not set\n"); + return err; + } + + return 0; +} + +static struct snd_soc_ops tegra_max98090_ops = { + .hw_params = tegra_max98090_asoc_hw_params, +}; + +static struct snd_soc_jack tegra_max98090_hp_jack; + +static struct snd_soc_jack_pin tegra_max98090_hp_jack_pins[] = { + { + .pin = "Headphones", + .mask = SND_JACK_HEADPHONE, + }, +}; + +static struct snd_soc_jack_gpio tegra_max98090_hp_jack_gpio = { + .name = "Headphone detection", + .report = SND_JACK_HEADPHONE, + .debounce_time = 150, + .invert = 1, +}; + +static const struct snd_soc_dapm_widget tegra_max98090_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphones", NULL), + SND_SOC_DAPM_SPK("Speakers", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), +}; + +static const struct snd_kcontrol_new tegra_max98090_controls[] = { + SOC_DAPM_PIN_SWITCH("Speakers"), +}; + +static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_codec *codec = codec_dai->codec; + struct tegra_max98090 *machine = snd_soc_card_get_drvdata(codec->card); + + if (gpio_is_valid(machine->gpio_hp_det)) { + snd_soc_jack_new(codec, "Headphones", SND_JACK_HEADPHONE, + &tegra_max98090_hp_jack); + snd_soc_jack_add_pins(&tegra_max98090_hp_jack, + ARRAY_SIZE(tegra_max98090_hp_jack_pins), + tegra_max98090_hp_jack_pins); + + tegra_max98090_hp_jack_gpio.gpio = machine->gpio_hp_det; + snd_soc_jack_add_gpios(&tegra_max98090_hp_jack, + 1, + &tegra_max98090_hp_jack_gpio); + } + + return 0; +} + +static struct snd_soc_dai_link tegra_max98090_dai = { + .name = "max98090", + .stream_name = "max98090 PCM", + .codec_dai_name = "HiFi", + .init = tegra_max98090_asoc_init, + .ops = &tegra_max98090_ops, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, +}; + +static struct snd_soc_card snd_soc_tegra_max98090 = { + .name = "tegra-max98090", + .owner = THIS_MODULE, + .dai_link = &tegra_max98090_dai, + .num_links = 1, + .controls = tegra_max98090_controls, + .num_controls = ARRAY_SIZE(tegra_max98090_controls), + .dapm_widgets = tegra_max98090_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tegra_max98090_dapm_widgets), + .fully_routed = true, +}; + +static int tegra_max98090_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct snd_soc_card *card = &snd_soc_tegra_max98090; + struct tegra_max98090 *machine; + int ret; + + machine = devm_kzalloc(&pdev->dev, + sizeof(struct tegra_max98090), GFP_KERNEL); + if (!machine) { + dev_err(&pdev->dev, "Can't allocate tegra_max98090\n"); + return -ENOMEM; + } + + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, machine); + + machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); + if (machine->gpio_hp_det == -EPROBE_DEFER) + return -EPROBE_DEFER; + + ret = snd_soc_of_parse_card_name(card, "nvidia,model"); + if (ret) + goto err; + + ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); + if (ret) + goto err; + + tegra_max98090_dai.codec_of_node = of_parse_phandle(np, + "nvidia,audio-codec", 0); + if (!tegra_max98090_dai.codec_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,audio-codec' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + tegra_max98090_dai.cpu_of_node = of_parse_phandle(np, + "nvidia,i2s-controller", 0); + if (!tegra_max98090_dai.cpu_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,i2s-controller' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + tegra_max98090_dai.platform_of_node = tegra_max98090_dai.cpu_of_node; + + ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); + if (ret) + goto err; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err_fini_utils; + } + + return 0; + +err_fini_utils: + tegra_asoc_utils_fini(&machine->util_data); +err: + return ret; +} + +static int tegra_max98090_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); + + snd_soc_jack_free_gpios(&tegra_max98090_hp_jack, 1, + &tegra_max98090_hp_jack_gpio); + + snd_soc_unregister_card(card); + + tegra_asoc_utils_fini(&machine->util_data); + + return 0; +} + +static const struct of_device_id tegra_max98090_of_match[] = { + { .compatible = "nvidia,tegra-audio-max98090", }, + {}, +}; + +static struct platform_driver tegra_max98090_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = tegra_max98090_of_match, + }, + .probe = tegra_max98090_probe, + .remove = tegra_max98090_remove, +}; +module_platform_driver(tegra_max98090_driver); + +MODULE_AUTHOR("Stephen Warren "); +MODULE_DESCRIPTION("Tegra max98090 machine ASoC driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, tegra_max98090_of_match); -- cgit v1.2.3 From 308a0f3f24db5e5943ef0aad722e8b3d125dbddb Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 4 Dec 2013 15:19:26 -0700 Subject: ASoC: max98090: add DT binding document for MAX98090 CODEC This binding mainly serves to document the list of input and output pins that may be used in a sound card's audio routing table. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/max98090.txt | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/max98090.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/max98090.txt b/Documentation/devicetree/bindings/sound/max98090.txt new file mode 100644 index 000000000000..e4c8b36dcf89 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max98090.txt @@ -0,0 +1,43 @@ +MAX98090 audio CODEC + +This device supports I2C only. + +Required properties: + +- compatible : "maxim,max98090". + +- reg : The I2C address of the device. + +- interrupts : The CODEC's interrupt output. + +Pins on the device (for linking into audio routes): + + * MIC1 + * MIC2 + * DMICL + * DMICR + * IN1 + * IN2 + * IN3 + * IN4 + * IN5 + * IN6 + * IN12 + * IN34 + * IN56 + * HPL + * HPR + * SPKL + * SPKR + * RCVL + * RCVR + * MICBIAS + +Example: + +audio-codec@10 { + compatible = "maxim,max98090"; + reg = <0x10>; + interrupt-parent = <&gpio>; + interrupts = ; +}; -- cgit v1.2.3 From 00e6cb2aed48a86e97a244c6f96ac1f934e2272c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 6 Dec 2013 11:02:49 +0100 Subject: dt: Add bindings documentation for the ADI AXI-I2S controller This patch adds the devicetree documentation for the ADI AXI-SPDIF audio controller. The controller has: * One set of memory mapped register * Two clocks, one for the memory mapped register interface, one used as the audio reference clock * One DMA interface each for the transmit and receive data Signed-off-by: Lars-Peter Clausen Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Stephen Warren Cc: Ian Campbell Cc: devicetree@vger.kernel.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/adi,axi-i2s.txt | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/adi,axi-i2s.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt b/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt new file mode 100644 index 000000000000..5875ca459ed1 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt @@ -0,0 +1,31 @@ +ADI AXI-I2S controller + +Required properties: + - compatible : Must be "adi,axi-i2s-1.00.a" + - reg : Must contain I2S core's registers location and length + - clocks : Pairs of phandle and specifier referencing the controller's clocks. + The controller expects two clocks, the clock used for the AXI interface and + the clock used as the sampling rate reference clock sample. + - clock-names : "axi" for the clock to the AXI interface, "ref" for the sample + rate reference clock. + - dmas: Pairs of phandle and specifier for the DMA channels that are used by + the core. The core expects two dma channels, one for transmit and one for + receive. + - dma-names : "tx" for the transmit channel, "rx" for the receive channel. + +For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties +please check: + * resource-names.txt + * clock/clock-bindings.txt + * dma/dma.txt + +Example: + + i2s: i2s@0x77600000 { + compatible = "adi,axi-i2s-1.00.a"; + reg = <0x77600000 0x1000>; + clocks = <&clk 15>, <&audio_clock>; + clock-names = "axi", "ref"; + dmas = <&ps7_dma 0>, <&ps7_dma 1>; + dma-names = "tx", "rx"; + }; -- cgit v1.2.3 From d7b528eff9277b83b315500f44ade178035ed0d1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 6 Dec 2013 11:02:51 +0100 Subject: dt: Add bindings documentation for the ADI AXI-SPDIF audio controller This patch adds the devicetree documentation for the ADI AXI-SPDIF audio controller. The controller has: * One set of memory mapped register * Two clocks, one for the memory mapped register interface, one used as the audio reference clock * A DMA interface for the transmit data Signed-off-by: Lars-Peter Clausen Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Stephen Warren Cc: Ian Campbell Cc: devicetree@vger.kernel.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/adi,axi-spdif-tx.txt | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt b/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt new file mode 100644 index 000000000000..46f344965313 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt @@ -0,0 +1,30 @@ +ADI AXI-SPDIF controller + +Required properties: + - compatible : Must be "adi,axi-spdif-1.00.a" + - reg : Must contain SPDIF core's registers location and length + - clocks : Pairs of phandle and specifier referencing the controller's clocks. + The controller expects two clocks, the clock used for the AXI interface and + the clock used as the sampling rate reference clock sample. + - clock-names: "axi" for the clock to the AXI interface, "ref" for the sample + rate reference clock. + - dmas: Pairs of phandle and specifier for the DMA channel that is used by + the core. The core expects one dma channel for transmit. + - dma-names : Must be "tx" + +For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties +please check: + * resource-names.txt + * clock/clock-bindings.txt + * dma/dma.txt + +Example: + + spdif: spdif@0x77400000 { + compatible = "adi,axi-spdif-tx-1.00.a"; + reg = <0x77600000 0x1000>; + clocks = <&clk 15>, <&audio_clock>; + clock-names = "axi", "ref"; + dmas = <&ps7_dma 0>; + dma-names = "tx"; + }; -- cgit v1.2.3 From a42efd97f7471c78617c6329ed39919e2f31a7cc Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 14 Nov 2013 11:35:19 +0200 Subject: ASoC: davinci: kconfig: Prepare for AM43xx support AM43xx have the same McASP IP as AM33xx and both platform uses eDMA. Modify the Kconfig so it will be possible to add audio support for AM43xx based boards later. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt | 2 +- sound/soc/davinci/Kconfig | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt index ed785b3f67be..1eed972d4719 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt @@ -4,7 +4,7 @@ Required properties: - compatible : "ti,dm646x-mcasp-audio" : for DM646x platforms "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms - "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, TI81xx) + "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx) - reg : Should contain reg specifiers for the entries in the reg-names property. - reg-names : Should contain: diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index be667719d44e..a8ec1fc3e4d0 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -1,6 +1,6 @@ config SND_DAVINCI_SOC - tristate "SoC Audio for the TI DAVINCI or AM33XX chip" - depends on ARCH_DAVINCI || SOC_AM33XX + tristate "SoC Audio for TI DAVINCI or AM33XX/AM43XX chips" + depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX config SND_DAVINCI_SOC_I2S tristate -- cgit v1.2.3 From 453c499028bf2ecf3b31ccb7c3657fe1b0b28943 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 14 Nov 2013 11:35:34 +0200 Subject: ASoC: davinci-mcasp: Support for McASP version found in DRA7xx The IP in DRA7xx is similar to the IP found in TI81xxAM3xxx/AM4xxx type of SoCs but it is is integrated with sDMA instead of eDMA. The suitable pcm driver for DRA7xx is the omap-pcm driver which is using dmaengine. In the driver we can configure both dma related structures used for eDMA and sDMA. The only thing we need to make sure that we set the correct dma_data at startup with snd_soc_dai_set_dma_data() Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- .../bindings/sound/davinci-mcasp-audio.txt | 1 + include/linux/platform_data/davinci_asp.h | 1 + sound/soc/davinci/davinci-mcasp.c | 52 +++++++++++++++++++--- 3 files changed, 47 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt index 1eed972d4719..990fa71ce804 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt @@ -5,6 +5,7 @@ Required properties: "ti,dm646x-mcasp-audio" : for DM646x platforms "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx) + "ti,dra7-mcasp-audio" : for DRA7xx platforms - reg : Should contain reg specifiers for the entries in the reg-names property. - reg-names : Should contain: diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h index 689a856b86f9..5245992b0367 100644 --- a/include/linux/platform_data/davinci_asp.h +++ b/include/linux/platform_data/davinci_asp.h @@ -92,6 +92,7 @@ enum { MCASP_VERSION_1 = 0, /* DM646x */ MCASP_VERSION_2, /* DA8xx/OMAPL1x */ MCASP_VERSION_3, /* TI81xx/AM33xx */ + MCASP_VERSION_4, /* DRA7xxx */ }; enum mcbsp_clk_input_pin { diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 93f2e294d649..fc8c13d2f31e 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -31,12 +31,14 @@ #include #include #include +#include #include "davinci-pcm.h" #include "davinci-mcasp.h" struct davinci_mcasp { struct davinci_pcm_dma_params dma_params[2]; + struct snd_dmaengine_dai_dma_data dma_data[2]; void __iomem *base; u32 fifo_base; struct device *dev; @@ -458,7 +460,9 @@ static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, u8 max_active_serializers = (channels + slots - 1) / slots; u32 reg; /* Default configuration */ - mcasp_set_bits(mcasp->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); + if (mcasp->version != MCASP_VERSION_4) + mcasp_set_bits(mcasp->base + DAVINCI_MCASP_PWREMUMGT_REG, + MCASP_SOFT); /* All PINS as McASP */ mcasp_set_reg(mcasp->base + DAVINCI_MCASP_PFUNC_REG, 0x00000000); @@ -605,6 +609,8 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[substream->stream]; + struct snd_dmaengine_dai_dma_data *dma_data = + &mcasp->dma_data[substream->stream]; int word_length; u8 fifo_level; u8 slots = mcasp->tdm_slots; @@ -666,6 +672,8 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, dma_params->acnt = dma_params->data_type; dma_params->fifo_level = fifo_level; + dma_data->maxburst = fifo_level; + davinci_config_channel_size(mcasp, word_length); return 0; @@ -711,7 +719,12 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); - snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); + if (mcasp->version == MCASP_VERSION_4) + snd_soc_dai_set_dma_data(dai, substream, + &mcasp->dma_data[substream->stream]); + else + snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); + return 0; } @@ -794,6 +807,13 @@ static struct snd_platform_data omap2_mcasp_pdata = { .version = MCASP_VERSION_3, }; +static struct snd_platform_data dra7_mcasp_pdata = { + .tx_dma_offset = 0x200, + .rx_dma_offset = 0x284, + .asp_chan_q = EVENTQ_0, + .version = MCASP_VERSION_4, +}; + static const struct of_device_id mcasp_dt_ids[] = { { .compatible = "ti,dm646x-mcasp-audio", @@ -807,6 +827,10 @@ static const struct of_device_id mcasp_dt_ids[] = { .compatible = "ti,am33xx-mcasp-audio", .data = &omap2_mcasp_pdata, }, + { + .compatible = "ti,dra7-mcasp-audio", + .data = &dra7_mcasp_pdata, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mcasp_dt_ids); @@ -999,6 +1023,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev) else dma_data->dma_addr = mem->start + pdata->tx_dma_offset; + /* Unconditional dmaengine stuff */ + mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_data->dma_addr; + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (res) dma_data->channel = res->start; @@ -1015,6 +1042,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev) else dma_data->dma_addr = mem->start + pdata->rx_dma_offset; + /* Unconditional dmaengine stuff */ + mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_data->dma_addr; + if (mcasp->version < MCASP_VERSION_3) { mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; /* dma_data->dma_addr is pointing to the data port address */ @@ -1029,6 +1059,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev) else dma_data->channel = pdata->rx_dma_channel; + /* Unconditional dmaengine stuff */ + mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx"; + mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = "rx"; + dev_set_drvdata(&pdev->dev, mcasp); ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, &davinci_mcasp_dai[pdata->op_mode], 1); @@ -1036,10 +1070,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) if (ret != 0) goto err_release_clk; - ret = davinci_soc_platform_register(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "register PCM failed: %d\n", ret); - goto err_unregister_component; + if (mcasp->version != MCASP_VERSION_4) { + ret = davinci_soc_platform_register(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "register PCM failed: %d\n", ret); + goto err_unregister_component; + } } return 0; @@ -1054,9 +1090,11 @@ err_release_clk: static int davinci_mcasp_remove(struct platform_device *pdev) { + struct davinci_mcasp *mcasp = dev_get_drvdata(&pdev->dev); snd_soc_unregister_component(&pdev->dev); - davinci_soc_platform_unregister(&pdev->dev); + if (mcasp->version != MCASP_VERSION_4) + davinci_soc_platform_unregister(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); -- cgit v1.2.3 From ae726e93946403b14f8cad20d5cbd22d015c9106 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 14 Nov 2013 11:35:35 +0200 Subject: ASoC: davinci-mcasp: Support for fck reparenting Optional DT property to specify the desired parent clock for the McASP fck clock. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- .../bindings/sound/davinci-mcasp-audio.txt | 3 +- sound/soc/davinci/davinci-mcasp.c | 44 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt index 990fa71ce804..569b26c4a81e 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt @@ -37,7 +37,8 @@ Optional properties: - pinctrl-0: Should specify pin control group used for this controller. - pinctrl-names: Should contain only one value - "default", for more details please refer to pinctrl-bindings.txt - +- fck_parent : Should contain a valid clock name which will be used as parent + for the McASP fck Example: diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 8ec879548488..b7858bfa0295 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -823,6 +824,46 @@ static const struct of_device_id mcasp_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, mcasp_dt_ids); +static int mcasp_reparent_fck(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct clk *gfclk, *parent_clk; + const char *parent_name; + int ret; + + if (!node) + return 0; + + parent_name = of_get_property(node, "fck_parent", NULL); + if (!parent_name) + return 0; + + gfclk = clk_get(&pdev->dev, "fck"); + if (IS_ERR(gfclk)) { + dev_err(&pdev->dev, "failed to get fck\n"); + return PTR_ERR(gfclk); + } + + parent_clk = clk_get(NULL, parent_name); + if (IS_ERR(parent_clk)) { + dev_err(&pdev->dev, "failed to get parent clock\n"); + ret = PTR_ERR(parent_clk); + goto err1; + } + + ret = clk_set_parent(gfclk, parent_clk); + if (ret) { + dev_err(&pdev->dev, "failed to reparent fck\n"); + goto err2; + } + +err2: + clk_put(parent_clk); +err1: + clk_put(gfclk); + return ret; +} + static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( struct platform_device *pdev) { @@ -1052,6 +1093,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev) mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = "rx"; dev_set_drvdata(&pdev->dev, mcasp); + + mcasp_reparent_fck(pdev); + ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, &davinci_mcasp_dai[pdata->op_mode], 1); -- cgit v1.2.3 From b6344859b911990152e5ee411e62b82eb968004f Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Tue, 17 Dec 2013 11:24:41 +0800 Subject: ASoC: fsl-sai: Add device tree bindings for Freescale SAI. This adds the Document for Freescale SAI driver under Documentation/devicetree/bindings/sound/. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl-sai.txt | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl-sai.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt new file mode 100644 index 000000000000..98611a6761c0 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -0,0 +1,40 @@ +Freescale Synchronous Audio Interface (SAI). + +The SAI is based on I2S module that used communicating with audio codecs, +which provides a synchronous audio interface that supports fullduplex +serial interfaces with frame synchronization such as I2S, AC97, TDM, and +codec/DSP interfaces. + + +Required properties: +- compatible: Compatible list, contains "fsl,vf610-sai". +- reg: Offset and length of the register set for the device. +- clocks: Must contain an entry for each entry in clock-names. +- clock-names : Must include the "sai" entry. +- dmas : Generic dma devicetree binding as described in + Documentation/devicetree/bindings/dma/dma.txt. +- dma-names : Two dmas have to be defined, "tx" and "rx". +- pinctrl-names: Must contain a "default" entry. +- pinctrl-NNN: One property must exist for each entry in pinctrl-names. + See ../pinctrl/pinctrl-bindings.txt for details of the property values. +- big-endian-regs: If this property is absent, the little endian mode will + be in use as default, or the big endian mode will be in use for all the + device registers. +- big-endian-data: If this property is absent, the little endian mode will + be in use as default, or the big endian mode will be in use for all the + fifo data. + +Example: +sai2: sai@40031000 { + compatible = "fsl,vf610-sai"; + reg = <0x40031000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2_1>; + clocks = <&clks VF610_CLK_SAI2>; + clock-names = "sai"; + dma-names = "tx", "rx"; + dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>, + <&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>; + big-endian-regs; + big-endian-data; +}; -- cgit v1.2.3 From d4c22094b256a7327346738721b89a78d4680b08 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Mon, 23 Dec 2013 12:57:01 +0800 Subject: ASoC: simple-card: Add DAPM routes parse from device tree Parses a simple DAPM route table from device tree. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/simple-card.txt | 13 +++++++++++-- sound/soc/generic/simple-card.c | 11 +++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index 769a346f890c..2ee80c76ca64 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -9,8 +9,13 @@ Required properties: Optional properties: - simple-audio-card,format : CPU/CODEC common audio format. - "i2s", "right_j", "left_j" , "dsp_a" - "dsp_b", "ac97", "pdm", "msb", "lsb" + "i2s", "right_j", "left_j" , "dsp_a" + "dsp_b", "ac97", "pdm", "msb", "lsb" +- simple-audio-routing : A list of the connections between audio components. + Each entry is a pair of strings, the first being the + connection's sink, the second being the connection's + source. + Required subnodes: - simple-audio-card,cpu : CPU sub-node @@ -38,6 +43,10 @@ Example: sound { compatible = "simple-audio-card"; simple-audio-card,format = "left_j"; + simple-audio-routing = + "MIC_IN", "Mic Jack", + "Headphone Jack", "HP_OUT", + "Ext Spk", "LINE_OUT"; simple-audio-card,cpu { sound-dai = <&sh_fsi2 0>; diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 3d190d05ad4a..6230efb05fd7 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -116,12 +116,18 @@ static int asoc_simple_card_parse_of(struct device_node *node, { struct device_node *np; char *name; - int ret = 0; + int ret; /* get CPU/CODEC common format via simple-audio-card,format */ info->daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK); + /* DAPM routes */ + ret = snd_soc_of_parse_audio_routing(&info->snd_card, + "simple-audio-routing"); + if (ret) + return ret; + /* CPU sub-node */ ret = -EINVAL; np = of_get_child_by_name(node, "simple-audio-card,cpu"); @@ -182,6 +188,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev) cinfo = devm_kzalloc(dev, sizeof(*cinfo), GFP_KERNEL); if (cinfo) { int ret; + cinfo->snd_card.dev = &pdev->dev; ret = asoc_simple_card_parse_of(np, cinfo, dev, &of_cpu, &of_codec, @@ -193,6 +200,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev) } } } else { + cinfo->snd_card.dev = &pdev->dev; cinfo = pdev->dev.platform_data; } @@ -232,7 +240,6 @@ static int asoc_simple_card_probe(struct platform_device *pdev) cinfo->snd_card.owner = THIS_MODULE; cinfo->snd_card.dai_link = &cinfo->snd_link; cinfo->snd_card.num_links = 1; - cinfo->snd_card.dev = &pdev->dev; return devm_snd_soc_register_card(&pdev->dev, &cinfo->snd_card); } -- cgit v1.2.3 From 0f7f3d1f17c2e4d73e449e6acb2007b13813c58e Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 20 Dec 2013 12:40:16 +0200 Subject: ASoC: hdmi-codec: Add devicetree binding with documentation Signed-off-by: Jyri Sarha cc: bcousson@baylibre.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/hdmi.txt | 17 +++++++++++++++++ sound/soc/codecs/hdmi.c | 10 ++++++++++ 2 files changed, 27 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/hdmi.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/hdmi.txt b/Documentation/devicetree/bindings/sound/hdmi.txt new file mode 100644 index 000000000000..31af7bca3099 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/hdmi.txt @@ -0,0 +1,17 @@ +Device-Tree bindings for dummy HDMI codec + +Required properties: + - compatible: should be "linux,hdmi-audio". + +CODEC output pins: + * TX + +CODEC input pins: + * RX + +Example node: + + hdmi_audio: hdmi_audio@0 { + compatible = "linux,hdmi-audio"; + status = "okay"; + }; diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c index 32797a8e4ee9..9cb1c7d3e1dc 100644 --- a/sound/soc/codecs/hdmi.c +++ b/sound/soc/codecs/hdmi.c @@ -20,6 +20,7 @@ */ #include #include +#include #define DRV_NAME "hdmi-audio-codec" @@ -60,6 +61,14 @@ static struct snd_soc_dai_driver hdmi_codec_dai = { }; +#ifdef CONFIG_OF +static const struct of_device_id hdmi_audio_codec_ids[] = { + { .compatible = "linux,hdmi-audio", }, + { } +}; +MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids); +#endif + static struct snd_soc_codec_driver hdmi_codec = { .dapm_widgets = hdmi_widgets, .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), @@ -83,6 +92,7 @@ static struct platform_driver hdmi_codec_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(hdmi_audio_codec_ids), }, .probe = hdmi_codec_probe, -- cgit v1.2.3