From patchwork Thu Jan 31 11:23:12 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hebbar, Gururaja" X-Patchwork-Id: 2072721 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 4AE58DF2E5 for ; Thu, 31 Jan 2013 11:26:30 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1U0sF7-0004u2-AW; Thu, 31 Jan 2013 11:23:45 +0000 Received: from bear.ext.ti.com ([192.94.94.41]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1U0sDt-0004Sq-Lc for linux-arm-kernel@lists.infradead.org; Thu, 31 Jan 2013 11:22:34 +0000 Received: from dbdp20.itg.ti.com ([172.24.170.38]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id r0VBMNk1031483; Thu, 31 Jan 2013 05:22:24 -0600 Received: from DBDE71.ent.ti.com (localhost [127.0.0.1]) by dbdp20.itg.ti.com (8.13.8/8.13.8) with ESMTP id r0VBMGk8009926; Thu, 31 Jan 2013 16:52:20 +0530 (IST) Received: from dbdp32.itg.ti.com (172.24.170.251) by DBDE71.ent.ti.com (172.24.170.149) with Microsoft SMTP Server id 14.1.323.3; Thu, 31 Jan 2013 16:52:18 +0530 Received: from ucmsshproxy.india.ext.ti.com (dbdp20.itg.ti.com [172.24.170.38]) by dbdp32.itg.ti.com (8.13.8/8.13.8) with SMTP id r0VBMI6G010463; Thu, 31 Jan 2013 16:52:18 +0530 Received: from symphony.india.ext.ti.com (unknown [192.168.247.13]) by ucmsshproxy.india.ext.ti.com (Postfix) with ESMTP id DA611158006; Thu, 31 Jan 2013 16:52:17 +0530 (IST) Received: from ubuntu-psp-linux.india.ext.ti.com (ubuntu-psp-linux [192.168.247.46]) by symphony.india.ext.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id r0VBMHR29874; Thu, 31 Jan 2013 16:52:17 +0530 (IST) From: Hebbar Gururaja To: , , , Subject: [PATCH v3 3/4] ASoC: davinci: machine: Add device tree binding Date: Thu, 31 Jan 2013 16:53:12 +0530 Message-ID: <1359631394-9511-4-git-send-email-gururaja.hebbar@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1359631394-9511-1-git-send-email-gururaja.hebbar@ti.com> References: <1359631394-9511-1-git-send-email-gururaja.hebbar@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130131_062230_170055_738C8A39 X-CRM114-Status: GOOD ( 26.57 ) X-Spam-Score: -4.6 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [192.94.94.41 listed in list.dnswl.org] 3.0 KHOP_BIG_TO_CC Sent to 10+ recipients instaed of Bcc or a list -0.0 SPF_PASS SPF: sender matches SPF record -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: lgirdwood@gmail.com, tony@atomide.com, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, nsekhar@ti.com, linux-kernel@vger.kernel.org, gururaja.hebbar@ti.com, grant.likely@secretlab.ca, rob@landley.net, perex@perex.cz X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: "Hebbar, Gururaja" Device tree support for Davinci Machine driver When the board boots with device tree, the driver will receive card, codec, dai interface details (like the card name, DAPM routing map, phandle for the audio components described in the dts file, codec mclk speed). The card will be set up based on this information. Since the routing is provided via DT we can mark the card fully routed so core can take care of disconnecting the unused pins. Signed-off-by: Hebbar, Gururaja --- Changes in v3 - New patch Changes in v2 - Remove reference to Linux & software details from DT binding :000000 100644 0000000... 92ad4c7... A Documentation/devicetree/bindings/sound/davinci-evm-audio.txt :100644 100644 484b22c... e6009a4... M sound/soc/davinci/davinci-evm.c .../bindings/sound/davinci-evm-audio.txt | 53 ++++++ sound/soc/davinci/davinci-evm.c | 179 +++++++++++++++++--- 2 files changed, 212 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt new file mode 100644 index 0000000..92ad4c7 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt @@ -0,0 +1,53 @@ +* Texas Instruments SoC audio setups with TLV320AIC3X Codec + +Required properties: +- compatible : + "ti,dm365-voice-codec-audio" : for DM365 platforms with Voice Codec + "ti,da830-evm-audio" : for DM365/DA8xx/OMAPL1x/AM33xx + +- ti,model : The user-visible name of this sound complex. +- ti,audio-codec : The phandle of the TLV320AIC3x audio codec +- ti,mcasp-controller : The phandle of the McASP controller +- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec +- ti,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 codec's pins, and the jacks on the board: + + Codec pins: + + * MIC3L + * MIC3R + * LINE1L + * LINE2L + * LINE1R + * LINE2R + + Board connectors: + + * Headphone Jack + * Line Out + * Mic Jack + + +Example: + +sound { + compatible = "ti,da830-evm-audio"; + ti,model = "DA830 EVM"; + ti,audio-codec = <&tlv320aic3x>; + ti,mcasp-controller = <&mcasp1>; + ti,codec-clock-rate = <12000000>; + ti,audio-routing = + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "MIC3L", "Mic Bias", + "MIC3R", "Mic Bias", + "Mic Bias", "Mic Jack", + "LINE1L", "Line In", + "LINE2L", "Line In", + "LINE1R", "Line In", + "LINE2R", "Line In"; +}; diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 484b22c..e6009a4 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -34,27 +35,38 @@ static int evm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_card *soc_card = codec->card; + struct device_node *np = soc_card->dev->of_node; int ret = 0; unsigned sysclk; - /* ASP1 on DM355 EVM is clocked by an external oscillator */ - if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() || - machine_is_davinci_dm365_evm()) - sysclk = 27000000; - - /* ASP0 in DM6446 EVM is clocked by U55, as configured by - * board-dm644x-evm.c using GPIOs from U18. There are six - * options; here we "know" we use a 48 KHz sample rate. - */ - else if (machine_is_davinci_evm()) - sysclk = 12288000; - - else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) - sysclk = 24576000; - - else - return -EINVAL; + if (np) { + ret = of_property_read_u32(np, "ti,codec-clock-rate", &sysclk); + if (ret < 0) + return ret; + } else { + /* ASP1 on DM355 EVM is clocked by an external oscillator */ + if (machine_is_davinci_dm355_evm() || + machine_is_davinci_dm6467_evm() || + machine_is_davinci_dm365_evm()) + sysclk = 27000000; + + /* + * ASP0 in DM6446 EVM is clocked by U55, as configured by + * board-dm644x-evm.c using GPIOs from U18. There are six + * options; here we "know" we use a 48 KHz sample rate. + */ + else if (machine_is_davinci_evm()) + sysclk = 12288000; + + else if (machine_is_davinci_da830_evm() || + machine_is_davinci_da850_evm()) + sysclk = 24576000; + + else + return -EINVAL; + } /* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT); @@ -132,13 +144,22 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; + struct device_node *np = codec->card->dev->of_node; + int ret; /* Add davinci-evm specific widgets */ snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets)); - /* Set up davinci-evm specific audio path audio_map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + if (np) { + ret = snd_soc_of_parse_audio_routing(codec->card, + "ti,audio-routing"); + if (ret) + return ret; + } else { + /* Set up davinci-evm specific audio path audio_map */ + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + } /* not connected */ snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); @@ -287,6 +308,108 @@ static struct snd_soc_card da850_snd_soc_card = { .num_links = 1, }; +#if defined(CONFIG_OF) + +enum { + MACHINE_VERSION_1 = 0, /* DM365 with Voice Codec */ + MACHINE_VERSION_2, /* DM365/DA8xx/OMAPL1x/AM33xx */ +}; + +static const struct of_device_id davinci_evm_dt_ids[] = { + { + .compatible = "ti,dm365-voice-codec-audio", + .data = (void *)MACHINE_VERSION_1, + }, + { + .compatible = "ti,da830-evm-audio", + .data = (void *)MACHINE_VERSION_2, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, davinci_mcasp_dt_ids); + +/* + * This struct is just used as place holder. It will be filled with + * data from dt node + */ +static struct snd_soc_dai_link evm_dai = { + .name = "TLV320AIC3X", + .stream_name = "AIC3X", + .codec_dai_name = "tlv320aic3x-hifi", +}; + +/* davinci evm audio machine driver */ +static struct snd_soc_card evm_soc_card = { + .owner = THIS_MODULE, + .dai_link = &evm_dai, + .num_links = 1, +}; + +static int davinci_evm_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *match = + of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev); + u32 machine_ver; + int ret = 0; + + machine_ver = (u32)match->data; + switch (machine_ver) { + case MACHINE_VERSION_1: + evm_dai.name = "Voice Codec - CQ93VC"; + evm_dai.stream_name = "CQ93"; + evm_dai.codec_dai_name = "cq93vc-hifi"; + break; + + case MACHINE_VERSION_2: + evm_dai.ops = &evm_ops; + evm_dai.init = evm_aic3x_init; + break; + } + + evm_dai.codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0); + if (!evm_dai.codec_of_node) + return -EINVAL; + + evm_dai.cpu_of_node = of_parse_phandle(np, + "ti,mcasp-controller", 0); + if (!evm_dai.cpu_of_node) + return -EINVAL; + + evm_dai.platform_of_node = evm_dai.cpu_of_node; + + evm_soc_card.dev = &pdev->dev; + ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model"); + if (ret) + return ret; + + ret = snd_soc_register_card(&evm_soc_card); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + + return ret; +} + +static int __devexit davinci_evm_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static struct platform_driver davinci_evm_driver = { + .probe = davinci_evm_probe, + .remove = __devexit_p(davinci_evm_remove), + .driver = { + .name = "davinci_evm", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(davinci_evm_dt_ids), + }, +}; +#endif + static struct platform_device *evm_snd_device; static int __init evm_init(void) @@ -295,6 +418,15 @@ static int __init evm_init(void) int index; int ret; +#if defined(CONFIG_OF) + /* + * If dtb is there, the devices will be created dynamically. + * Only register platfrom driver structure. + */ + if (of_have_populated_dt()) + return platform_driver_register(&davinci_evm_driver); +#endif + if (machine_is_davinci_evm()) { evm_snd_dev_data = &dm6446_snd_soc_card_evm; index = 0; @@ -330,6 +462,13 @@ static int __init evm_init(void) static void __exit evm_exit(void) { +#if defined(CONFIG_OF) + if (of_have_populated_dt()) { + platform_driver_unregister(&davinci_evm_driver); + return; + } +#endif + platform_device_unregister(evm_snd_device); }