From patchwork Wed Jan 25 18:49:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Romanovsky X-Patchwork-Id: 137825 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id D0EC11007D2 for ; Thu, 26 Jan 2012 05:49:38 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751406Ab2AYSti (ORCPT ); Wed, 25 Jan 2012 13:49:38 -0500 Received: from mail-ey0-f174.google.com ([209.85.215.174]:44312 "EHLO mail-ey0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751182Ab2AYSth (ORCPT ); Wed, 25 Jan 2012 13:49:37 -0500 Received: by eaac13 with SMTP id c13so1712394eaa.19 for ; Wed, 25 Jan 2012 10:49:36 -0800 (PST) MIME-Version: 1.0 Received: by 10.213.11.19 with SMTP id r19mr82977ebr.92.1327517375839; Wed, 25 Jan 2012 10:49:35 -0800 (PST) Received: from localhost.localdomain (bzq-84-109-86-120.red.bezeqint.net. [84.109.86.120]) by mx.google.com with ESMTPS id n17sm4903054eei.3.2012.01.25.10.49.33 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 25 Jan 2012 10:49:35 -0800 (PST) From: Leon Romanovsky To: grant.likely@secretlab.ca, rdunlap@xenotime.net, lrg@ti.com, broonie@opensource.wolfsonmicro.com, swarren@nvidia.com, olof@lixom.net, ccross@android.com Cc: devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, alsa-devel@alsa-project.org, linux-tegra@vger.kernel.org, Leon Romanovsky , Marc Dietrich Subject: [PATCH 1/3] ARM: dt: tegra: Enable device tree audio on PAZ00 board. Date: Wed, 25 Jan 2012 20:49:23 +0200 Message-Id: <1327517363-29698-1-git-send-email-leon@leon.nu> X-Mailer: git-send-email 1.7.3.4 X-Gm-Message-State: ALoCoQlVlI7Umz6VJ5VrywkeJ++VkqQix45MMMda6yYh5nfhgUf2ktggfAMaf5FJGwQbsXSuZ0B6 Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org This patch adds initial device tree support of ALC5632 sound codec and machine driver for PAZ00 board. The implementation is based on the WM8903 codec. Signed-off-by: Marc Dietrich Signed-off-by: Leon Romanovsky --- .../devicetree/bindings/sound/alc5632.txt | 24 ++++++ .../bindings/sound/tegra-audio-alc5632.txt | 55 ++++++++++++++ arch/arm/boot/dts/tegra-paz00.dts | 29 ++++++-- sound/soc/tegra/tegra_alc5632.c | 78 ++++++++++++++++++-- 4 files changed, 173 insertions(+), 13 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/alc5632.txt create mode 100644 Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt diff --git a/Documentation/devicetree/bindings/sound/alc5632.txt b/Documentation/devicetree/bindings/sound/alc5632.txt new file mode 100644 index 0000000..8608f74 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/alc5632.txt @@ -0,0 +1,24 @@ +ALC5632 audio CODEC + +This device supports I2C only. + +Required properties: + + - compatible : "realtek,alc5632" + + - reg : the I2C address of the device. + + - gpio-controller : Indicates this device is a GPIO controller. + + - #gpio-cells : Should be two. The first cell is the pin number and the + second cell is used to specify optional parameters (currently unused). + +Example: + +alc5632: alc5632@1e { + compatible = "realtek,alc5632"; + reg = <0x1a>; + + gpio-controller; + #gpio-cells = <2>; +}; diff --git a/Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt b/Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt new file mode 100644 index 0000000..315213f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt @@ -0,0 +1,55 @@ +NVIDIA Tegra audio complex + +Required properties: +- compatible : "nvidia,tegra-audio-alc5632" +- 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 ALC5632's pins: + + ALC5632 pins: + + * SPKOUT + * SPKOUTN + * HPL + * HPR + * AUXOUT + * LINEINL + * LINEINR + * PHONEP + * PHONEP + * MIC1 + * MIC2 + * MICBIAS1 + * MICBIAS2 + + Board connectors: + + * Headset Stereophone + * Int Spk + * MIC1 + * MICBIAS1 + +- nvidia,i2s-controller : The phandle of the Tegra I2S controller +- nvidia,audio-codec : The phandle of the ALC5632 audio codec + +Example: + +sound { + compatible = "nvidia,tegra-audio-alc5632-paz00", + "nvidia,tegra-audio-alc5632"; + + nvidia,model = "Compal PAZ00"; + + nvidia,audio-routing = + "Int Spk", "SPKOUT", + "Int Spk", "SPKOUTN", + "MIC1", "MICBIAS1", + "MICBIAS1", "Headset Mic", + "Headset Stereophone", "HPR", + "Headset Stereophone", "HPL"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&alc5632>; +}; diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts index 4d1bcdc..692d20c 100644 --- a/arch/arm/boot/dts/tegra-paz00.dts +++ b/arch/arm/boot/dts/tegra-paz00.dts @@ -12,6 +12,13 @@ i2c@7000c000 { clock-frequency = <400000>; + + alc5632: alc5632@1e { + compatible = "realtek,alc5632"; + reg = <0x1e>; + gpio-controller; + #gpio-cells = <2>; + }; }; i2c@7000c400 { @@ -37,16 +44,26 @@ clock-frequency = <400000>; }; - i2s@70002800 { - status = "disable"; - }; - i2s@70002a00 { status = "disable"; }; - das@70000c00 { - status = "disable"; + sound { + compatible = "nvidia,tegra-audio-alc5632-paz00", + "nvidia,tegra-audio-alc5632"; + + nvidia,model = "Compal PAZ00"; + + nvidia,audio-routing = + "Int Spk", "SPKOUT", + "Int Spk", "SPKOUTN", + "MIC1", "MICBIAS1", + "MICBIAS1", "Headset Mic", + "Headset Stereophone", "HPR", + "Headset Stereophone", "HPL"; + + nvidia,audio-codec = <&alc5632>; + nvidia,i2s-controller = <&tegra_i2s1>; }; serial@70006000 { diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 4a0e805..22348e8 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -36,6 +36,7 @@ struct tegra_alc5632 { struct tegra_asoc_utils_data util_data; + struct platform_device *pcm_dev; }; static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, @@ -163,26 +164,80 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) sizeof(struct tegra_alc5632), GFP_KERNEL); if (!alc5632) { dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err; } - ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); - if (ret) - return ret; - card->dev = &pdev->dev; platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, alc5632); + alc5632->pcm_dev = ERR_PTR(-EINVAL); + + if (!(pdev->dev.of_node)) { + dev_err(&pdev->dev, "No platform data supplied\n"); + ret = -EINVAL; + goto err; + } + + 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_alc5632_dai.codec_name = NULL; + tegra_alc5632_dai.codec_of_node = of_parse_phandle( + pdev->dev.of_node, "nvidia,audio-codec", 0); + + if (!tegra_alc5632_dai.codec_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,audio-codec' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + tegra_alc5632_dai.cpu_dai_name = NULL; + tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle( + pdev->dev.of_node, "nvidia,i2s-controller", 0); + if (!tegra_alc5632_dai.cpu_dai_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,i2s-controller' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + alc5632->pcm_dev = platform_device_register_simple( + "tegra-pcm-audio", -1, NULL, 0); + if (IS_ERR(alc5632->pcm_dev)) { + dev_err(&pdev->dev, + "Can't instantiate tegra-pcm-audio\n"); + ret = PTR_ERR(alc5632->pcm_dev); + goto err; + } + + ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); + if (ret) + goto err_unregister; + ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - tegra_asoc_utils_fini(&alc5632->util_data); - return ret; + goto err_fini_utils; } return 0; + +err_fini_utils: + tegra_asoc_utils_fini(&alc5632->util_data); +err_unregister: + if (!IS_ERR(alc5632->pcm_dev)) + platform_device_unregister(alc5632->pcm_dev); +err: + return ret; } static int __devexit tegra_alc5632_remove(struct platform_device *pdev) @@ -193,15 +248,23 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev) snd_soc_unregister_card(card); tegra_asoc_utils_fini(&alc5632->util_data); + if (!IS_ERR(alc5632->pcm_dev)) + platform_device_unregister(alc5632->pcm_dev); return 0; } +static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = { + { .compatible = "nvidia,tegra-audio-alc5632", }, + {}, +}; + static struct platform_driver tegra_alc5632_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, + .of_match_table = tegra_alc5632_of_match, }, .probe = tegra_alc5632_probe, .remove = __devexit_p(tegra_alc5632_remove), @@ -212,3 +275,4 @@ MODULE_AUTHOR("Leon Romanovsky "); MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, tegra_alc5632_of_match);