From patchwork Fri Apr 21 17:19:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sylwester Nawrocki/Kernel \\(PLT\\) /SRPOL/Staff Engineer/Samsung Electronics" X-Patchwork-Id: 9693431 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 51B306038D for ; Fri, 21 Apr 2017 18:34:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 46BE228654 for ; Fri, 21 Apr 2017 18:34:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3B2042865B; Fri, 21 Apr 2017 18:34:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A595628654 for ; Fri, 21 Apr 2017 18:34:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1041992AbdDUSe4 (ORCPT ); Fri, 21 Apr 2017 14:34:56 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:52269 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1041984AbdDUSeu (ORCPT ); Fri, 21 Apr 2017 14:34:50 -0400 Received: from epcas1p4.samsung.com (unknown [182.195.41.48]) by mailout3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OOR016SZS6NSH20@mailout3.samsung.com>; Sat, 22 Apr 2017 02:20:47 +0900 (KST) Received: from epsmges1p5.samsung.com (unknown [182.195.42.57]) by epcas1p4.samsung.com (KnoxPortal) with ESMTP id 20170421172046epcas1p4bb0d783eda2b7f4bc2ebe3dbb66c77da~3eV4vS5aO1162611626epcas1p4_; Fri, 21 Apr 2017 17:20:46 +0000 (GMT) Received: from epcas1p4.samsung.com ( [182.195.41.48]) by epsmges1p5.samsung.com (Symantec Messaging Gateway) with SMTP id 6E.11.03717.E6F3AF85; Sat, 22 Apr 2017 02:20:46 +0900 (KST) Received: from epcpsbgm1new.samsung.com (u26.gpu120.samsung.co.kr [203.254.230.26]) by epcas1p3.samsung.com (KnoxPortal) with ESMTP id 20170421172046epcas1p32778006ff0ddc30083d49b31497b5b5b~3eV4ae1vL2641726417epcas1p3D; Fri, 21 Apr 2017 17:20:46 +0000 (GMT) X-AuditID: b6c32a39-f790c6d000000e85-d6-58fa3f6e1d8f Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1new.samsung.com (EPCPMTA) with SMTP id 1B.59.05715.E6F3AF85; Sat, 22 Apr 2017 02:20:46 +0900 (KST) Received: from AMDC3061.digital.local ([106.116.147.40]) by mmp1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OOR00KJBS560G40@mmp1.samsung.com>; Sat, 22 Apr 2017 02:20:46 +0900 (KST) From: Sylwester Nawrocki To: linux-samsung-soc@vger.kernel.org, linux-clk@vger.kernel.org, dri-devel@lists.freedesktop.org, alsa-devel@alsa-project.org, devicetree@vger.kernel.org Cc: inki.dae@samsung.com, sw0312.kim@samsung.com, cw00.choi@samsung.com, javier@osg.samsung.com, krzk@kernel.org, jy0922.shim@samsung.com, broonie@kernel.org, robh+dt@kernel.org, b.zolnierkie@samsung.com, Sylwester Nawrocki Subject: [PATCH RFC 6/7] ASoC: samsung: Add Odroid ASoC machine driver Date: Fri, 21 Apr 2017 19:19:50 +0200 Message-id: <1492795191-31298-7-git-send-email-s.nawrocki@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1492795191-31298-1-git-send-email-s.nawrocki@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrFIsWRmVeSWpSXmKPExsWy7bCmgW6e/a8IgzXvTS2uXDzEZLFxxnpW i6kPn7BZXP/ynNVi/pFzrBZXvr5ns5h0fwKLxZu3a5gsXty7yGJx/vwGdouPPfdYLWac38dk 0br3CLvF4TftQO7kl2wO/B4bPjexeWxa1cnmcb/7OJPHlv677B59W1YxenzeJBfAFsVlk5Ka k1mWWqRvl8CVcWHHdpaCgzYVHXv9GhhnGXUxcnJICJhI3NjYwwJhi0lcuLeerYuRi0NIYAej xLJbcxkhnHYmicU3prPAdGy68IYVIrGcUeL+kZtQLb8YJRZ9Xs8EUsUmYCjRe7QPrF1EYB6j xLVtE8CqmAX+MUpMuzCZHaRKWMBNomn7azCbRUBVYvbn7WwgNi9Q/OGB91D75CROHpsMtI+D g1PAXeLiU3aQORIC29glHt94ygwSlxCQldh0gBmi3EVi1cstjBC2sMSr41vYIWxpiVX/bjFB 9PYzSpxY08wI4cxglLjTPoEJospa4vDxi6wgNrMAn8S7rz2sEAt4JTrahCBKPCQe9n6Bus1R 4uBVWCDNYpT4+nwm0wRGmQWMDKsYxVILinPTU4sNC0z1ihNzi0vz0vWS83M3MYJThJblDsZj 53wOMQpwMCrx8K5g+RUhxJpYVlyZe4hRgoNZSYTXWx8oxJuSWFmVWpQfX1Sak1p8iFGag0VJ nFd0/bUIIYH0xJLU7NTUgtQimCwTB6dUA+P5m5v6gh90//o49WbNEf89EVohF3hLZi/PeW8r /etJ4Wf124q+3hcO3X3DaMl8svS27kKL3xVyApp+ry1uWNSqOHvcu/RKu9z0n6thwC2PmLAw V33uydtLeTjPJDRtUNovzH+LbbI4w6K9C+YYvPyeFrtspmhCwCGjWVm52jdbt+bkX3p9N0WJ pTgj0VCLuag4EQBXOFxxDQMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprFIsWRmVeSWpSXmKPExsVy+t9jAd08+18RBv/vyVpcuXiIyWLjjPWs FlMfPmGzuP7lOavF/CPnWC2ufH3PZjHp/gQWizdv1zBZvLh3kcXi/PkN7BYfe+6xWsw4v4/J onXvEXaLw2/agdzJL9kc+D02fG5i89i0qpPN4373cSaPLf132T36tqxi9Pi8SS6ALcrNJiM1 MSW1SCE1Lzk/JTMv3VYpNMRN10JJIS8xN9VWKULXNyRISaEsMacUyDMyQAMOzgHuwUr6dglu GRd2bGcpOGhT0bHXr4FxllEXIyeHhICJxKYLb1ghbDGJC/fWs3UxcnEICSxllNj4ZjorhPOL UeLWrPdMIFVsAoYSvUf7GEESIgLzGCU2nFwL5jAL/GOUONbUzwJSJSzgJtG0/TU7iM0ioCox +/N2NhCbFyj+8MB7Foh9chInj00GWsHBwSngLnHxKVi5EFDJ0v7LrBMYeRcwMqxilEgtSC4o TkrPNcxLLdcrTswtLs1L10vOz93ECI6XZ1I7GA/ucj/EKMDBqMTDu4LlV4QQa2JZcWXuIUYJ DmYlEV5vfaAQb0piZVVqUX58UWlOavEhRlOguyYyS4km5wNjOa8k3tDE3MTc2MDC3NLSxEhJ nLdx9rNwIYH0xJLU7NTUgtQimD4mDk6pBsZWzj1V1rIlKz4amhpqLjk130yUIaQrT+DqyVv/ bc2E9a/MenE72cd8hcsuYYW7cet5Wnzbja7qyVWv176twe5qOrOncFFrL//jG8I/5/d9PPvJ fM/NiWckr1oZm7779VDixIyEBJMfse4WJjOY1XRc83nerlw8MSXad3d+jY/gnQzOyZcKfymx FGckGmoxFxUnAgCwv88grQIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170421172046epcas1p32778006ff0ddc30083d49b31497b5b5b X-Msg-Generator: CA X-Sender-IP: 203.254.230.26 X-Local-Sender: =?UTF-8?B?U3lsd2VzdGVyIE5hd3JvY2tpG1NSUE9MLUtlcm5lbCAoVFAp?= =?UTF-8?B?G+yCvOyEseyghOyekBtTZW5pb3IgU29mdHdhcmUgRW5naW5lZXI=?= X-Global-Sender: =?UTF-8?B?U3lsd2VzdGVyIE5hd3JvY2tpG1NSUE9MLUtlcm5lbCAoVFAp?= =?UTF-8?B?G1NhbXN1bmcgRWxlY3Ryb25pY3MbU2VuaW9yIFNvZnR3YXJlIEVuZ2luZWVy?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 101P X-HopCount: 7 X-CMS-RootMailID: 20170421172046epcas1p32778006ff0ddc30083d49b31497b5b5b X-RootMTR: 20170421172046epcas1p32778006ff0ddc30083d49b31497b5b5b References: <1492795191-31298-1-git-send-email-s.nawrocki@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This dedicated driver allows to support SoC specific clock settings and helps to ensure proper number of channels gets negotiated in multicodec system configurations. Signed-off-by: Sylwester Nawrocki --- sound/soc/samsung/Kconfig | 8 ++ sound/soc/samsung/Makefile | 2 + sound/soc/samsung/odroid.c | 219 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 sound/soc/samsung/odroid.c diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index f1f1d79..0520f5a 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -185,6 +185,14 @@ config SND_SOC_SNOW Say Y if you want to add audio support for various Snow boards based on Exynos5 series of SoCs. +config SND_SOC_ODROID + tristate "Audio support for Odroid XU3/XU4" + depends on SND_SOC_SAMSUNG && I2C + select SND_SOC_MAX98090 + select SND_SAMSUNG_I2S + help + Say Y here to enable audio support for the Odroid XU3/XU4. + config SND_SOC_ARNDALE_RT5631_ALC5631 tristate "Audio support for RT5631(ALC5631) on Arndale Board" depends on I2C diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index b5df5e2e..b6c2ee3 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -40,6 +40,7 @@ snd-soc-tobermory-objs := tobermory.o snd-soc-lowland-objs := lowland.o snd-soc-littlemill-objs := littlemill.o snd-soc-bells-objs := bells.o +snd-soc-odroid-objs := odroid.o snd-soc-arndale-rt5631-objs := arndale_rt5631.o snd-soc-tm2-wm5110-objs := tm2_wm5110.o @@ -62,5 +63,6 @@ obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o +obj-$(CONFIG_SND_SOC_ODROID) += snd-soc-odroid.o obj-$(CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631) += snd-soc-arndale-rt5631.o obj-$(CONFIG_SND_SOC_SAMSUNG_TM2_WM5110) += snd-soc-tm2-wm5110.o diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c new file mode 100644 index 0000000..0c0b00e --- /dev/null +++ b/sound/soc/samsung/odroid.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2017 Samsung Electronics Co., 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. + */ + +#include +#include +#include +#include +#include +#include +#include "i2s.h" +#include "i2s-regs.h" + +struct odroid_priv { + struct snd_soc_card card; + struct snd_soc_dai_link dai_link; + + struct clk *pll; + struct clk *rclk; +}; + +static int odroid_card_startup(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2); + return 0; +} + +static int odroid_card_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card); + unsigned int pll_freq, rclk_freq; + int ret; + + switch (params_rate(params)) { + case 32000: + case 64000: + pll_freq = 131072000U; + break; + case 44100: + case 88200: + case 176400: + pll_freq = 180633600U; + break; + case 48000: + case 96000: + case 192000: + pll_freq = 196608000U; + break; + default: + return -EINVAL; + } + + ret = clk_set_rate(priv->pll, pll_freq + 1); + if (ret < 0) + return ret; + + rclk_freq = params_rate(params) * 256 * 4; + + ret = clk_set_rate(priv->rclk, rclk_freq); + if (ret < 0) + return ret; + + if (rtd->num_codecs > 1) { + struct snd_soc_dai *codec_dai = rtd->codec_dais[1]; + + ret = snd_soc_dai_set_sysclk(codec_dai, 0, rclk_freq, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + } + + return 0; +} + +static const struct snd_soc_ops odroid_card_ops = { + .startup = odroid_card_startup, + .hw_params = odroid_card_hw_params, +}; + +static void odroid_put_codec_of_nodes(struct snd_soc_dai_link *link) +{ + struct snd_soc_dai_link_component *component = link->codecs; + int i; + + for (i = 0; i < link->num_codecs; i++, component++) { + if (!component->of_node) + break; + of_node_put(component->of_node); + } +} + +static int odroid_audio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *cpu, *codec; + struct odroid_priv *priv; + struct snd_soc_dai_link *link; + struct snd_soc_card *card; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + card = &priv->card; + card->dev = dev; + + card->owner = THIS_MODULE; + card->fully_routed = true; + + snd_soc_card_set_drvdata(card, priv); + + priv->pll = devm_clk_get(dev, "epll"); + if (IS_ERR(priv->pll)) + return PTR_ERR(priv->pll); + + priv->rclk = devm_clk_get(dev, "i2s_rclk"); + if (IS_ERR(priv->rclk)) + return PTR_ERR(priv->rclk); + + ret = snd_soc_of_parse_card_name(card, "model"); + if (ret < 0) + return ret; + + if (of_property_read_bool(dev->of_node, "samsung,audio-widgets")) { + ret = snd_soc_of_parse_audio_simple_widgets(card, + "samsung,audio-widgets"); + if (ret < 0) + return ret; + } + + if (of_property_read_bool(dev->of_node, "samsung,audio-routing")) { + ret = snd_soc_of_parse_audio_routing(card, + "samsung,audio-routing"); + if (ret < 0) + return ret; + } + + link = &priv->dai_link; + + link->ops = &odroid_card_ops; + link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS; + + card->dai_link = &priv->dai_link; + card->num_links = 1; + + cpu = of_get_child_by_name(dev->of_node, "cpu"); + codec = of_get_child_by_name(dev->of_node, "codec"); + + link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0); + if (!link->cpu_of_node) { + dev_err(dev, "Failed parsing cpu/sound-dai property\n"); + return -EINVAL; + } + + ret = snd_soc_of_get_dai_link_codecs(dev, codec, link); + if (ret < 0) + goto err_put_codec_n; + + link->platform_of_node = link->cpu_of_node; + + link->name = "Primary"; + link->stream_name = link->name; + + ret = devm_snd_soc_register_card(dev, card); + if (ret < 0) { + dev_err(dev, "snd_soc_register_card() failed: %d\n", ret); + goto err_put_i2s_n; + } + + return 0; + +err_put_i2s_n: + of_node_put(link->cpu_of_node); +err_put_codec_n: + odroid_put_codec_of_nodes(link); + return ret; +} + +static int odroid_audio_remove(struct platform_device *pdev) +{ + struct odroid_priv *priv = platform_get_drvdata(pdev); + + of_node_put(priv->dai_link.cpu_of_node); + odroid_put_codec_of_nodes(&priv->dai_link); + + return 0; +} + +static const struct of_device_id odroid_audio_of_match[] = { + { .compatible = "samsung,odroid-xu3-audio" }, + { .compatible = "samsung,odroid-xu4-audio"}, + { }, +}; +MODULE_DEVICE_TABLE(of, odroid_audio_of_match); + +static struct platform_driver odroid_audio_driver = { + .driver = { + .name = "odroid-audio", + .of_match_table = odroid_audio_of_match, + .pm = &snd_soc_pm_ops, + }, + .probe = odroid_audio_probe, + .remove = odroid_audio_remove, +}; +module_platform_driver(odroid_audio_driver); + +MODULE_AUTHOR("Sylwester Nawrocki "); +MODULE_DESCRIPTION("Odroid XU3/XU4 audio support"); +MODULE_LICENSE("GPL v2");