From patchwork Wed Aug 29 15:00:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 10580471 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6B9F51709 for ; Wed, 29 Aug 2018 15:20:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5AA7E2B4F4 for ; Wed, 29 Aug 2018 15:20:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4E45A2B552; Wed, 29 Aug 2018 15:20:22 +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=-2.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3CAC02B4F4 for ; Wed, 29 Aug 2018 15:20:10 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 87CE3267913; Wed, 29 Aug 2018 17:01:04 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id BFF102678FC; Wed, 29 Aug 2018 17:01:00 +0200 (CEST) Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by alsa0.perex.cz (Postfix) with ESMTP id 214C426784A for ; Wed, 29 Aug 2018 17:00:59 +0200 (CEST) Received: by mail-wr1-f65.google.com with SMTP id w11-v6so5141039wrc.5 for ; Wed, 29 Aug 2018 08:00:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Xudw7HosvH3W7S4koGFg9NQMloENC1Orc4gV4bavhXY=; b=WzIF7m75s/Y3pq01Bepd8jIX/flt5Ql76r5eKTNb7ix0v3B4cKhypNDblv71DPOzxC mWoDZOc9uRqBQ1nySXdmpNh35lFdJYaze5Cn4rPmauhGAAHz6o4KUM+blDNs3AnivSse mHKVr6bmrTejcxE3wx82N8+9i6LwmFcPuCk7RzfFtrCpeC8hSD6BD4SLgti1XT+YvJhq +3pwX5BR1Mugf2W5JZM3OAP6s174lGw1BeCY3kB3Z4pcag5m8Ojk8pNkHB+KRJDiR7Fo pDtIkYEuoddWHyvJbJXB+Ep/7DFhZXuklbDqP52cbP7NsutSrxlQspfwzMQupnKElmLv 596A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Xudw7HosvH3W7S4koGFg9NQMloENC1Orc4gV4bavhXY=; b=qDfCR3ZYi3khwhOPH9d/Ap3d7vh6KLNpmhhUu2x9dsSo/aIktE+Rhk+GfG48MBRWh9 ehaQ+v6GXIzDMBldKYWwdHr8J6upFbXrEMcCMdqMZ0JMhtaOW6yAys6oxpZYY+p6jKBN MxhrLVOgAKvPRugqwfNEU3IA98P1gs36+qBGM0LavQtrghPXar5TQd18pFK5TeJrdZd6 XnlvevLFVQO+fWN7N+TLu4xpf3nrii3SZ5ncWmWd0cwiOVBJquRdmIwyCEop88mirzcK uaX6qtMRlO+MiVwfbJcbm2e/ujgfzNkY74nHmpO1oqqKjDHQQkziMWWYkbvAIN76ZkSZ TO2g== X-Gm-Message-State: APzg51CznBHIRFKxYv30CJzahREo/+kHqo1GU0dZfXAwit58+fCWjhSC kZvWUMCel0rxaLHSNHFch8ceRw== X-Google-Smtp-Source: ANB0VdYu0IABOq04A1L8K89obmifBFQ/BUOxlH4A0vSy23FSM4sna2fWD4kj8Aq/GgjQviMod7leMA== X-Received: by 2002:adf:fe06:: with SMTP id n6-v6mr4775093wrr.171.1535554858744; Wed, 29 Aug 2018 08:00:58 -0700 (PDT) Received: from boomer.baylibre.local ([90.63.244.31]) by smtp.googlemail.com with ESMTPSA id v46-v6sm7267217wrc.63.2018.08.29.08.00.57 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 Aug 2018 08:00:58 -0700 (PDT) From: Jerome Brunet To: Mark Brown , Liam Girdwood , Kevin Hilman , Carlo Caione Date: Wed, 29 Aug 2018 17:00:48 +0200 Message-Id: <20180829150051.18190-2-jbrunet@baylibre.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180829150051.18190-1-jbrunet@baylibre.com> References: <20180829150051.18190-1-jbrunet@baylibre.com> Cc: linux-amlogic@lists.infradead.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Jerome Brunet Subject: [alsa-devel] [PATCH 1/4] ASoC: dmic: add Kconfig prompt for the generic dmic codec. X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Add Kconfig prompt for the generic digital mic to make it configurable through menuconfig Signed-off-by: Jerome Brunet --- sound/soc/codecs/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index adaf26e1989c..9989d35e0fc6 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -578,7 +578,11 @@ config SND_SOC_DA9055 tristate config SND_SOC_DMIC - tristate + tristate "Generic Digital Microphone CODEC" + depends on GPIOLIB + help + Enable support for the Generic Digital Microphone CODEC. + Select this if your sound card has DMICs. config SND_SOC_HDMI_CODEC tristate From patchwork Wed Aug 29 15:00:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 10580467 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5F4D35A4 for ; Wed, 29 Aug 2018 15:20:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4CCE42B4E7 for ; Wed, 29 Aug 2018 15:20:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3EC912B55B; Wed, 29 Aug 2018 15:20:21 +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=-2.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3B5B42B4E7 for ; Wed, 29 Aug 2018 15:20:10 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id A32DB267922; Wed, 29 Aug 2018 17:01:06 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 5C9CD2678FC; Wed, 29 Aug 2018 17:01:02 +0200 (CEST) Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by alsa0.perex.cz (Postfix) with ESMTP id 9D65726766C for ; Wed, 29 Aug 2018 17:01:00 +0200 (CEST) Received: by mail-wr1-f66.google.com with SMTP id o37-v6so5144357wrf.6 for ; Wed, 29 Aug 2018 08:01:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=uUbMF3nMXRw/+9rZqOfjCDmKj73BdEnRsLVytA1Yk6Q=; b=0qD3Raki6lB/dZdEao0Ktml94uXot/dSS2tppB4k29vIR+pPbhOxyo7/ThW4SPQRFN PbvK+G9wfCmlbu4OZKsZsk01A7I8QrqN+8t1/XrHvM0iC4IO6aS5RWGZ7APzw5E4Bgyr be7kof5G/dnfyuUXiodeJSUHC7+6ns0SVX1/Dz+9wduczCnWEO/+8Lhu21Y54dQxLEbc OOs1ntOO/mJcoMiFZNLWrFQUFi8/3ghJZrB+G0bq0pl9sIBCjv+kZHUmgfm7aBpfPK+B jpqL0GfqFexxko70eCdQCrL0KxCyysMFhG7tO1MeSUhXzFiuXmrlPBfXDk0fBJnW7UQW rghg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=uUbMF3nMXRw/+9rZqOfjCDmKj73BdEnRsLVytA1Yk6Q=; b=OmIZM+KHNwLt/Q64btA6Nd/boJmz1EWOMeSM/wm0FVBJrcLQZn/PmiX3mgLr6pAiMo ANMpR0Hm/KZjGogPBvBnTCWbJrW5gzFD0Zb7xW/aBwlQHrDw0xWpY7ps4yLGRpTlR13o 4+Gy8Rv8MxHreDnMPh7cDBGVRyfNzZDo+iI+XkuyER5jO0iCuRqIgdeAH2dtg3MqI93E pHQgaR1umrAevhxhDDwmEQ1tnN6Ipf26SZXFbTXes7RMBFhzhO7hBjBRt8iFYltUZLvY 4v+egQWi3niavt8jzTZk/6s0HgqPYfbfzaUaNfyy7i0eKouLXuLextQuHj6kuZdcWWVr vJdg== X-Gm-Message-State: APzg51CRK/0oaUIjQZBIYUvYu1hgRwgb4DkW7LveUGAbhT90W/3YbBT4 7fXMm8q/R7iJBNwFXrYQPk58yA== X-Google-Smtp-Source: ANB0VdYnfu/IKQTnk/aEzhvE9cihI8Y4ivp9rJaXlTK4WkF3+uJ+N4RZRZBevvc5j/3nVFmVhFGCmg== X-Received: by 2002:adf:9101:: with SMTP id j1-v6mr4638185wrj.3.1535554860163; Wed, 29 Aug 2018 08:01:00 -0700 (PDT) Received: from boomer.baylibre.local ([90.63.244.31]) by smtp.googlemail.com with ESMTPSA id v46-v6sm7267217wrc.63.2018.08.29.08.00.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 Aug 2018 08:00:59 -0700 (PDT) From: Jerome Brunet To: Mark Brown , Liam Girdwood , Kevin Hilman , Carlo Caione Date: Wed, 29 Aug 2018 17:00:49 +0200 Message-Id: <20180829150051.18190-3-jbrunet@baylibre.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180829150051.18190-1-jbrunet@baylibre.com> References: <20180829150051.18190-1-jbrunet@baylibre.com> Cc: linux-amlogic@lists.infradead.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Jerome Brunet Subject: [alsa-devel] [PATCH 2/4] ASoC: dmic: add DT module alias X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Before this patch the only alias provided by the dmic module is: alias: platform:dmic-codec Device instantiated from DT will not probe automatically with this After this patch, here is the new alias list: alias: platform:dmic-codec alias: of:N*T*Cdmic-codecC* alias: of:N*T*Cdmic-codec Now the dmic codec probes automatically when instantiated from DT. Signed-off-by: Jerome Brunet --- sound/soc/codecs/dmic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index 8c4926df9286..71322e0410ee 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -148,6 +148,7 @@ static const struct of_device_id dmic_dev_match[] = { {.compatible = "dmic-codec"}, {} }; +MODULE_DEVICE_TABLE(of, dmic_dev_match); static struct platform_driver dmic_driver = { .driver = { From patchwork Wed Aug 29 15:00:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 10580469 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9DF281709 for ; Wed, 29 Aug 2018 15:20:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C9E12B4FC for ; Wed, 29 Aug 2018 15:20:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8007C2B55E; Wed, 29 Aug 2018 15:20:21 +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=-2.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3CB522B4FC for ; Wed, 29 Aug 2018 15:20:10 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 6380026792C; Wed, 29 Aug 2018 17:01:08 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 6DE58267917; Wed, 29 Aug 2018 17:01:03 +0200 (CEST) Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by alsa0.perex.cz (Postfix) with ESMTP id D024826766C for ; Wed, 29 Aug 2018 17:01:01 +0200 (CEST) Received: by mail-wr1-f66.google.com with SMTP id v90-v6so5162973wrc.0 for ; Wed, 29 Aug 2018 08:01:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=M3ulMuAVOTpyiu7CM7KID8UePIh9rpVFCKWBlNIO4N4=; b=Sv/R+UkmGDOneWQ1vOl2ZQN1NkzWSxynTM5r3zgoruDAmwQ7Pzzs3Wb8Si9Br4ZiEt Ppvplkt829dOxcPSlZaPjnujJ6w/tfzBk1q6tnJpz0yVNV8n8CKWPbwf0/DuQZNbIAa2 tlhEsVKWgM4WuZNJlkLZXwScaEx1l/B1sd30KgjGcLb8OLuKGomFAys/rQI5v7A/QuVp /+5Bz6mHz3Rm0syn9nAg7cZpo59UopwLb90JC2bb4eeRmVuwJfb1u1gVLslUgJ+E+oKM ySH0XqS9NY5/DqisBghOZSITBK2aq8NcI6/CFNjVrAYJbXzRh0zHCin4jMepuH3c5y1q hiOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=M3ulMuAVOTpyiu7CM7KID8UePIh9rpVFCKWBlNIO4N4=; b=CDKp79WBbsIOpp245bLV55VDey6n54/69/+UUS+ZYIDzw5H8FGBRFSj7jDjuyHS0vC 9v3NGscBNxbzfp1Z8a6QlCh+v4faQOiXxKhI/MYjVyXaciV3DUxv2Wz+HB8R9EDTc9bm zDK6y8iu/pp5iYwWxkBCHeMrd3bxKrKGT/GVHa8oyf9qRfYAkehQohQBd0KzZFFsso6W sX8UZ+DRrBqIB0QdG7yRO5d2hwChjXSWv3eiB81maD5ydxeTws0hKvwo/oU7y1SOfAql PmQ9lTSARcCHf/+bDcpjOGdb9zYPBKCuvhv1xIINFHiQU9Vr5LY2642R/knTNaJeUtUr nqHQ== X-Gm-Message-State: APzg51AXYNWOkSPLEZUsys8k+/eeashomA5MZm2RRSUN3TI/ggfjvYcc Xch5Q2BP0DoYpA3/+p1hAiDM0g== X-Google-Smtp-Source: ANB0VdaWBD4X+xBHaPEwsm0QTym3/lgumkc6A0v/5yaNR+19pJrXakuuD882K0VxNxKjbmc3NP6HfA== X-Received: by 2002:adf:ae01:: with SMTP id x1-v6mr4565744wrc.45.1535554861409; Wed, 29 Aug 2018 08:01:01 -0700 (PDT) Received: from boomer.baylibre.local ([90.63.244.31]) by smtp.googlemail.com with ESMTPSA id v46-v6sm7267217wrc.63.2018.08.29.08.01.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 Aug 2018 08:01:00 -0700 (PDT) From: Jerome Brunet To: Mark Brown , Liam Girdwood , Kevin Hilman , Carlo Caione Date: Wed, 29 Aug 2018 17:00:50 +0200 Message-Id: <20180829150051.18190-4-jbrunet@baylibre.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180829150051.18190-1-jbrunet@baylibre.com> References: <20180829150051.18190-1-jbrunet@baylibre.com> Cc: linux-amlogic@lists.infradead.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Jerome Brunet Subject: [alsa-devel] [PATCH 3/4] ASoC: meson: add axg pdm input DT binding documentation X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Add the DT binding documentation for axg's PDM input Signed-off-by: Jerome Brunet --- .../bindings/sound/amlogic,axg-pdm.txt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/amlogic,axg-pdm.txt diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-pdm.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-pdm.txt new file mode 100644 index 000000000000..5672d0bc5b16 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/amlogic,axg-pdm.txt @@ -0,0 +1,24 @@ +* Amlogic Audio PDM input + +Required properties: +- compatible: 'amlogic,axg-pdm' +- reg: physical base address of the controller and length of memory + mapped region. +- clocks: list of clock phandle, one for each entry clock-names. +- clock-names: should contain the following: + * "pclk" : peripheral clock. + * "dclk" : pdm digital clock + * "sysclk" : dsp system clock +- #sound-dai-cells: must be 0. + +Example of PDM on the A113 SoC: + +pdm: audio-controller@ff632000 { + compatible = "amlogic,axg-pdm"; + reg = <0x0 0xff632000 0x0 0x34>; + #sound-dai-cells = <0>; + clocks = <&clkc_audio AUD_CLKID_PDM>, + <&clkc_audio AUD_CLKID_PDM_DCLK>, + <&clkc_audio AUD_CLKID_PDM_SYSCLK>; + clock-names = "pclk", "dclk", "sysclk"; +}; From patchwork Wed Aug 29 15:00:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 10580475 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0C3DC5A4 for ; Wed, 29 Aug 2018 15:20:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ED13B2B4ED for ; Wed, 29 Aug 2018 15:20:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E12082B502; Wed, 29 Aug 2018 15:20:22 +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=-2.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C9C02B4ED for ; Wed, 29 Aug 2018 15:20:10 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 12853267924; Wed, 29 Aug 2018 17:01:10 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 62C47267924; Wed, 29 Aug 2018 17:01:06 +0200 (CEST) Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by alsa0.perex.cz (Postfix) with ESMTP id A7EF326791E for ; Wed, 29 Aug 2018 17:01:03 +0200 (CEST) Received: by mail-wr1-f68.google.com with SMTP id v17-v6so5142382wrr.9 for ; Wed, 29 Aug 2018 08:01:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1D2eMoJSjTYcNYPoZVI4fezqGYd7iJJeSPowrxJTKXQ=; b=DZ2TqYvjDdKyL7RJrLlRWRJcf0aI4QAeFc7OTD8Ro7yeIv5ZkobFWNYHpODPUI/gci Od4gSVtRpOSrdJ0whYkmLJMYnf/fYz1+8PI4XsiYvnQ2TG5AG1pnXWQAAUlzZesPlRc3 FnpGwo1dmuEPDGAn4f6VoVjf17UE9A8ctj6MjGcVK1pDt3oFEJr49cykIfZiR9Z1YS3K ff2v10kLSAxS1mHV19eNxl2dgWUDU7XRKnPBnbtzkDLxKflpOKZOzBzoVKt3hLSPrH7r Fzf/InaAnD0e9nPoT6sSJQQS0davNrwQu8Y+goWRStvlEGyHu7vIzJ3ji5Y+M33iGZpq FyfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1D2eMoJSjTYcNYPoZVI4fezqGYd7iJJeSPowrxJTKXQ=; b=S2ukZ/X6pM24YT0EPvVs2CE5MvumiSM+PhCVChl5B4veNsb4O+/rhNTeR/F1SiQGQj MhXkDo4ZoO1EyvoFLGq3Ul8z/IP/26Qp7zxNTDtjEht7AY0b12wzHs1ZTCmmrgqEkJDV 2ZuaNMFVOida4et6ZG1tUjEtTnzQESeUnYGkgI8ZGfxnCwajgARLNrZjeh5sc2VFD9yA Z1TNDWOEQVIzR+3KZl1f933KP2ud5Flb5HY8gMBNjQWlFehiSKpDf/dPH8yMhe0uqsr5 QRYVkzhmnR3WYvu0rtLqO6eiN7EhntKVoDUwhQxx0SfPPQ6hoq5KCIiZRkaN9moRbnau l10A== X-Gm-Message-State: APzg51DBxStAsOGvhPGW/F/SWyS8tHq1n0Lv8y0Gld9jk6VV9JR4roYt pg7gGHvK8KlbXmhuavdAdYV01A== X-Google-Smtp-Source: ANB0VdZN1B/1q6YRy35M62hWEF0SSnVPUn2etCa5MBbMz8W4iARcoDhYbIotRxLBeRm/EwX9UVE24A== X-Received: by 2002:adf:eaca:: with SMTP id o10-v6mr4307302wrn.98.1535554862587; Wed, 29 Aug 2018 08:01:02 -0700 (PDT) Received: from boomer.baylibre.local ([90.63.244.31]) by smtp.googlemail.com with ESMTPSA id v46-v6sm7267217wrc.63.2018.08.29.08.01.01 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 Aug 2018 08:01:02 -0700 (PDT) From: Jerome Brunet To: Mark Brown , Liam Girdwood , Kevin Hilman , Carlo Caione Date: Wed, 29 Aug 2018 17:00:51 +0200 Message-Id: <20180829150051.18190-5-jbrunet@baylibre.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180829150051.18190-1-jbrunet@baylibre.com> References: <20180829150051.18190-1-jbrunet@baylibre.com> Cc: linux-amlogic@lists.infradead.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Jerome Brunet Subject: [alsa-devel] [PATCH 4/4] ASoC: meson: add axg pdm input X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Add pdm input driver for the device found on the amlogic AXG SoC family Signed-off-by: Jerome Brunet --- sound/soc/meson/Kconfig | 9 + sound/soc/meson/Makefile | 2 + sound/soc/meson/axg-pdm.c | 654 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 665 insertions(+) create mode 100644 sound/soc/meson/axg-pdm.c diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig index 2ccbadc387de..8b8426ed2363 100644 --- a/sound/soc/meson/Kconfig +++ b/sound/soc/meson/Kconfig @@ -54,6 +54,7 @@ config SND_MESON_AXG_SOUND_CARD imply SND_MESON_AXG_TDMIN imply SND_MESON_AXG_TDMOUT imply SND_MESON_AXG_SPDIFOUT + imply SND_MESON_AXG_PDM help Select Y or M to add support for the AXG SoC sound card @@ -66,4 +67,12 @@ config SND_MESON_AXG_SPDIFOUT Select Y or M to add support for SPDIF output serializer embedded in the Amlogic AXG SoC family +config SND_MESON_AXG_PDM + tristate "Amlogic AXG PDM Input Support" + imply SND_SOC_DMIC + imply COMMON_CLK_AXG_AUDIO + help + Select Y or M to add support for PDM input embedded + in the Amlogic AXG SoC family + endmenu diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile index c5e003b093db..4cd25104029d 100644 --- a/sound/soc/meson/Makefile +++ b/sound/soc/meson/Makefile @@ -9,6 +9,7 @@ snd-soc-meson-axg-tdmin-objs := axg-tdmin.o snd-soc-meson-axg-tdmout-objs := axg-tdmout.o snd-soc-meson-axg-sound-card-objs := axg-card.o snd-soc-meson-axg-spdifout-objs := axg-spdifout.o +snd-soc-meson-axg-pdm-objs := axg-pdm.o obj-$(CONFIG_SND_MESON_AXG_FIFO) += snd-soc-meson-axg-fifo.o obj-$(CONFIG_SND_MESON_AXG_FRDDR) += snd-soc-meson-axg-frddr.o @@ -19,3 +20,4 @@ obj-$(CONFIG_SND_MESON_AXG_TDMIN) += snd-soc-meson-axg-tdmin.o obj-$(CONFIG_SND_MESON_AXG_TDMOUT) += snd-soc-meson-axg-tdmout.o obj-$(CONFIG_SND_MESON_AXG_SOUND_CARD) += snd-soc-meson-axg-sound-card.o obj-$(CONFIG_SND_MESON_AXG_SPDIFOUT) += snd-soc-meson-axg-spdifout.o +obj-$(CONFIG_SND_MESON_AXG_PDM) += snd-soc-meson-axg-pdm.o diff --git a/sound/soc/meson/axg-pdm.c b/sound/soc/meson/axg-pdm.c new file mode 100644 index 000000000000..9d5684493ffc --- /dev/null +++ b/sound/soc/meson/axg-pdm.c @@ -0,0 +1,654 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +// +// Copyright (c) 2018 BayLibre, SAS. +// Author: Jerome Brunet + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PDM_CTRL 0x00 +#define PDM_CTRL_EN BIT(31) +#define PDM_CTRL_OUT_MODE BIT(29) +#define PDM_CTRL_BYPASS_MODE BIT(28) +#define PDM_CTRL_RST_FIFO BIT(16) +#define PDM_CTRL_CHAN_RSTN_MASK GENMASK(15, 8) +#define PDM_CTRL_CHAN_RSTN(x) ((x) << 8) +#define PDM_CTRL_CHAN_EN_MASK GENMASK(7, 0) +#define PDM_CTRL_CHAN_EN(x) ((x) << 0) +#define PDM_HCIC_CTRL1 0x04 +#define PDM_FILTER_EN BIT(31) +#define PDM_HCIC_CTRL1_GAIN_SFT_MASK GENMASK(29, 24) +#define PDM_HCIC_CTRL1_GAIN_SFT(x) ((x) << 24) +#define PDM_HCIC_CTRL1_GAIN_MULT_MASK GENMASK(23, 16) +#define PDM_HCIC_CTRL1_GAIN_MULT(x) ((x) << 16) +#define PDM_HCIC_CTRL1_DSR_MASK GENMASK(8, 4) +#define PDM_HCIC_CTRL1_DSR(x) ((x) << 4) +#define PDM_HCIC_CTRL1_STAGE_NUM_MASK GENMASK(3, 0) +#define PDM_HCIC_CTRL1_STAGE_NUM(x) ((x) << 0) +#define PDM_HCIC_CTRL2 0x08 +#define PDM_F1_CTRL 0x0c +#define PDM_LPF_ROUND_MODE_MASK GENMASK(17, 16) +#define PDM_LPF_ROUND_MODE(x) ((x) << 16) +#define PDM_LPF_DSR_MASK GENMASK(15, 12) +#define PDM_LPF_DSR(x) ((x) << 12) +#define PDM_LPF_STAGE_NUM_MASK GENMASK(8, 0) +#define PDM_LPF_STAGE_NUM(x) ((x) << 0) +#define PDM_LPF_MAX_STAGE 336 +#define PDM_LPF_NUM 3 +#define PDM_F2_CTRL 0x10 +#define PDM_F3_CTRL 0x14 +#define PDM_HPF_CTRL 0x18 +#define PDM_HPF_SFT_STEPS_MASK GENMASK(20, 16) +#define PDM_HPF_SFT_STEPS(x) ((x) << 16) +#define PDM_HPF_OUT_FACTOR_MASK GENMASK(15, 0) +#define PDM_HPF_OUT_FACTOR(x) ((x) << 0) +#define PDM_CHAN_CTRL 0x1c +#define PDM_CHAN_CTRL_POINTER_WIDTH 8 +#define PDM_CHAN_CTRL_POINTER_MAX ((1 << PDM_CHAN_CTRL_POINTER_WIDTH) - 1) +#define PDM_CHAN_CTRL_NUM 4 +#define PDM_CHAN_CTRL1 0x20 +#define PDM_COEFF_ADDR 0x24 +#define PDM_COEFF_DATA 0x28 +#define PDM_CLKG_CTRL 0x2c +#define PDM_STS 0x30 + +struct axg_pdm_lpf { + unsigned int ds; + unsigned int round_mode; + const unsigned int *tap; + unsigned int tap_num; +}; + +struct axg_pdm_hcic { + unsigned int shift; + unsigned int mult; + unsigned int steps; + unsigned int ds; +}; + +struct axg_pdm_hpf { + unsigned int out_factor; + unsigned int steps; +}; + +struct axg_pdm_filters { + struct axg_pdm_hcic hcic; + struct axg_pdm_hpf hpf; + struct axg_pdm_lpf lpf[PDM_LPF_NUM]; +}; + +struct axg_pdm_cfg { + const struct axg_pdm_filters *filters; + unsigned int sys_rate; +}; + +struct axg_pdm { + const struct axg_pdm_cfg *cfg; + struct regmap *map; + struct clk *dclk; + struct clk *sysclk; + struct clk *pclk; +}; + +static void axg_pdm_enable(struct regmap *map) +{ + /* Reset AFIFO */ + regmap_update_bits(map, PDM_CTRL, PDM_CTRL_RST_FIFO, PDM_CTRL_RST_FIFO); + regmap_update_bits(map, PDM_CTRL, PDM_CTRL_RST_FIFO, 0); + + /* Enable PDM */ + regmap_update_bits(map, PDM_CTRL, PDM_CTRL_EN, PDM_CTRL_EN); +} + +static void axg_pdm_disable(struct regmap *map) +{ + regmap_update_bits(map, PDM_CTRL, PDM_CTRL_EN, 0); +} + +static void axg_pdm_filters_enable(struct regmap *map, bool enable) +{ + unsigned int val = enable ? PDM_FILTER_EN : 0; + + regmap_update_bits(map, PDM_HCIC_CTRL1, PDM_FILTER_EN, val); + regmap_update_bits(map, PDM_F1_CTRL, PDM_FILTER_EN, val); + regmap_update_bits(map, PDM_F2_CTRL, PDM_FILTER_EN, val); + regmap_update_bits(map, PDM_F3_CTRL, PDM_FILTER_EN, val); + regmap_update_bits(map, PDM_HPF_CTRL, PDM_FILTER_EN, val); +} + +static int axg_pdm_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + axg_pdm_enable(priv->map); + return 0; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + axg_pdm_disable(priv->map); + return 0; + + default: + return -EINVAL; + } +} + +static unsigned int axg_pdm_get_os(struct axg_pdm *priv) +{ + const struct axg_pdm_filters *filters = priv->cfg->filters; + unsigned int os = filters->hcic.ds; + int i; + + /* + * The global oversampling factor is defined by the down sampling + * factor applied by each filter (HCIC and LPFs) + */ + + for (i = 0; i < PDM_LPF_NUM; i++) + os *= filters->lpf[i].ds; + + return os; +} + +static int axg_pdm_set_sysclk(struct axg_pdm *priv, unsigned int os, + unsigned int rate) +{ + unsigned int sys_rate = os * 2 * rate * PDM_CHAN_CTRL_POINTER_MAX; + + /* + * Set the default system clock rate unless it is too fast for + * for the requested sample rate. In this case, the sample pointer + * counter could overflow so set a lower system clock rate + */ + if (sys_rate < priv->cfg->sys_rate) + return clk_set_rate(priv->sysclk, sys_rate); + + return clk_set_rate(priv->sysclk, priv->cfg->sys_rate); +} + +static int axg_pdm_set_sample_pointer(struct axg_pdm *priv) +{ + unsigned int spmax, sp, val; + int i; + + /* Max sample counter value per half period of dclk */ + spmax = DIV_ROUND_UP_ULL((u64)clk_get_rate(priv->sysclk), + clk_get_rate(priv->dclk) * 2); + + /* Check if sysclk is not too fast - should not happen */ + if (WARN_ON(spmax > PDM_CHAN_CTRL_POINTER_MAX)) + return -EINVAL; + + /* Capture the data when we are at 75% of the half period */ + sp = spmax * 3 / 4; + + for (i = 0, val = 0; i < PDM_CHAN_CTRL_NUM; i++) + val |= sp << (PDM_CHAN_CTRL_POINTER_WIDTH * i); + + regmap_write(priv->map, PDM_CHAN_CTRL, val); + regmap_write(priv->map, PDM_CHAN_CTRL1, val); + + return 0; +} + +static void axg_pdm_set_channel_mask(struct axg_pdm *priv, + unsigned int channels) +{ + unsigned int mask = GENMASK(channels - 1, 0); + + /* Put all channel in reset */ + regmap_update_bits(priv->map, PDM_CTRL, + PDM_CTRL_CHAN_RSTN_MASK, 0); + + /* Take the necessary channels out of reset and enable them */ + regmap_update_bits(priv->map, PDM_CTRL, + PDM_CTRL_CHAN_RSTN_MASK | + PDM_CTRL_CHAN_EN_MASK, + PDM_CTRL_CHAN_RSTN(mask) | + PDM_CTRL_CHAN_EN(mask)); +} + +static int axg_pdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai); + unsigned int os = axg_pdm_get_os(priv); + unsigned int rate = params_rate(params); + unsigned int val; + int ret; + + switch (params_width(params)) { + case 24: + val = PDM_CTRL_OUT_MODE; + break; + case 32: + val = 0; + break; + default: + dev_err(dai->dev, "unsupported sample width\n"); + return -EINVAL; + } + + regmap_update_bits(priv->map, PDM_CTRL, PDM_CTRL_OUT_MODE, val); + + ret = axg_pdm_set_sysclk(priv, os, rate); + if (ret) { + dev_err(dai->dev, "failed to set system clock\n"); + return ret; + } + + ret = clk_set_rate(priv->dclk, rate * os); + if (ret) { + dev_err(dai->dev, "failed to set dclk\n"); + return ret; + } + + ret = axg_pdm_set_sample_pointer(priv); + if (ret) { + dev_err(dai->dev, "invalid clock setting\n"); + return ret; + } + + axg_pdm_set_channel_mask(priv, params_channels(params)); + + return 0; +} + +static int axg_pdm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai); + int ret; + + ret = clk_prepare_enable(priv->dclk); + if (ret) { + dev_err(dai->dev, "enabling dclk failed\n"); + return ret; + } + + /* Enable the filters */ + axg_pdm_filters_enable(priv->map, true); + + return ret; +} + +static void axg_pdm_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai); + + axg_pdm_filters_enable(priv->map, false); + clk_disable_unprepare(priv->dclk); +} + +static const struct snd_soc_dai_ops axg_pdm_dai_ops = { + .trigger = axg_pdm_trigger, + .hw_params = axg_pdm_hw_params, + .startup = axg_pdm_startup, + .shutdown = axg_pdm_shutdown, +}; + +static void axg_pdm_set_hcic_ctrl(struct axg_pdm *priv) +{ + const struct axg_pdm_hcic *hcic = &priv->cfg->filters->hcic; + unsigned int val; + + val = PDM_HCIC_CTRL1_STAGE_NUM(hcic->steps); + val |= PDM_HCIC_CTRL1_DSR(hcic->ds); + val |= PDM_HCIC_CTRL1_GAIN_MULT(hcic->mult); + val |= PDM_HCIC_CTRL1_GAIN_SFT(hcic->shift); + + regmap_update_bits(priv->map, PDM_HCIC_CTRL1, + PDM_HCIC_CTRL1_STAGE_NUM_MASK | + PDM_HCIC_CTRL1_DSR_MASK | + PDM_HCIC_CTRL1_GAIN_MULT_MASK | + PDM_HCIC_CTRL1_GAIN_SFT_MASK, + val); +} + +static void axg_pdm_set_lpf_ctrl(struct axg_pdm *priv, unsigned int index) +{ + const struct axg_pdm_lpf *lpf = &priv->cfg->filters->lpf[index]; + unsigned int offset = index * regmap_get_reg_stride(priv->map) + + PDM_F1_CTRL; + unsigned int val; + + val = PDM_LPF_STAGE_NUM(lpf->tap_num); + val |= PDM_LPF_DSR(lpf->ds); + val |= PDM_LPF_ROUND_MODE(lpf->round_mode); + + regmap_update_bits(priv->map, offset, + PDM_LPF_STAGE_NUM_MASK | + PDM_LPF_DSR_MASK | + PDM_LPF_ROUND_MODE_MASK, + val); +} + +static void axg_pdm_set_hpf_ctrl(struct axg_pdm *priv) +{ + const struct axg_pdm_hpf *hpf = &priv->cfg->filters->hpf; + unsigned int val; + + val = PDM_HPF_OUT_FACTOR(hpf->out_factor); + val |= PDM_HPF_SFT_STEPS(hpf->steps); + + regmap_update_bits(priv->map, PDM_HPF_CTRL, + PDM_HPF_OUT_FACTOR_MASK | + PDM_HPF_SFT_STEPS_MASK, + val); +} + +static int axg_pdm_set_lpf_filters(struct axg_pdm *priv) +{ + const struct axg_pdm_lpf *lpf = priv->cfg->filters->lpf; + unsigned int count = 0; + int i, j; + + for (i = 0; i < PDM_LPF_NUM; i++) + count += lpf[i].tap_num; + + /* Make sure the coeffs fit in the memory */ + if (count >= PDM_LPF_MAX_STAGE) + return -EINVAL; + + /* Set the initial APB bus register address */ + regmap_write(priv->map, PDM_COEFF_ADDR, 0); + + /* Set the tap filter values of all 3 filters */ + for (i = 0; i < PDM_LPF_NUM; i++) { + axg_pdm_set_lpf_ctrl(priv, i); + + for (j = 0; j < lpf[i].tap_num; j++) + regmap_write(priv->map, PDM_COEFF_DATA, lpf[i].tap[j]); + } + + return 0; +} + +static int axg_pdm_dai_probe(struct snd_soc_dai *dai) +{ + struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai); + int ret; + + ret = clk_prepare_enable(priv->pclk); + if (ret) { + dev_err(dai->dev, "enabling pclk failed\n"); + return ret; + } + + /* + * sysclk must be set and enabled as well to access the pdm registers + * Accessing the register w/o it will give a bus error. + */ + ret = clk_set_rate(priv->sysclk, priv->cfg->sys_rate); + if (ret) { + dev_err(dai->dev, "setting sysclk failed\n"); + goto err_pclk; + } + + ret = clk_prepare_enable(priv->sysclk); + if (ret) { + dev_err(dai->dev, "enabling sysclk failed\n"); + goto err_pclk; + } + + /* Make sure the device is initially disabled */ + axg_pdm_disable(priv->map); + + /* Make sure filter bypass is disabled */ + regmap_update_bits(priv->map, PDM_CTRL, PDM_CTRL_BYPASS_MODE, 0); + + /* Load filter settings */ + axg_pdm_set_hcic_ctrl(priv); + axg_pdm_set_hpf_ctrl(priv); + + ret = axg_pdm_set_lpf_filters(priv); + if (ret) { + dev_err(dai->dev, "invalid filter configuration\n"); + goto err_sysclk; + } + + return 0; + +err_sysclk: + clk_disable_unprepare(priv->sysclk); +err_pclk: + clk_disable_unprepare(priv->pclk); + return ret; +} + +static int axg_pdm_dai_remove(struct snd_soc_dai *dai) +{ + struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai); + + clk_disable_unprepare(priv->sysclk); + clk_disable_unprepare(priv->pclk); + + return 0; +} + +static struct snd_soc_dai_driver axg_pdm_dai_drv = { + .name = "PDM", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 5512, + .rate_max = 48000, + .formats = (SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE), + }, + .ops = &axg_pdm_dai_ops, + .probe = axg_pdm_dai_probe, + .remove = axg_pdm_dai_remove, +}; + +static const struct snd_soc_component_driver axg_pdm_component_drv = {}; + +static const struct regmap_config axg_pdm_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = PDM_STS, +}; + +static const unsigned int lpf1_default_tap[] = { + 0x000014, 0xffffb2, 0xfffed9, 0xfffdce, 0xfffd45, + 0xfffe32, 0x000147, 0x000645, 0x000b86, 0x000e21, + 0x000ae3, 0x000000, 0xffeece, 0xffdca8, 0xffd212, + 0xffd7d1, 0xfff2a7, 0x001f4c, 0x0050c2, 0x0072aa, + 0x006ff1, 0x003c32, 0xffdc4e, 0xff6a18, 0xff0fef, + 0xfefbaf, 0xff4c40, 0x000000, 0x00ebc8, 0x01c077, + 0x02209e, 0x01c1a4, 0x008e60, 0xfebe52, 0xfcd690, + 0xfb8fa5, 0xfba498, 0xfd9812, 0x0181ce, 0x06f5f3, + 0x0d112f, 0x12a958, 0x169686, 0x18000e, 0x169686, + 0x12a958, 0x0d112f, 0x06f5f3, 0x0181ce, 0xfd9812, + 0xfba498, 0xfb8fa5, 0xfcd690, 0xfebe52, 0x008e60, + 0x01c1a4, 0x02209e, 0x01c077, 0x00ebc8, 0x000000, + 0xff4c40, 0xfefbaf, 0xff0fef, 0xff6a18, 0xffdc4e, + 0x003c32, 0x006ff1, 0x0072aa, 0x0050c2, 0x001f4c, + 0xfff2a7, 0xffd7d1, 0xffd212, 0xffdca8, 0xffeece, + 0x000000, 0x000ae3, 0x000e21, 0x000b86, 0x000645, + 0x000147, 0xfffe32, 0xfffd45, 0xfffdce, 0xfffed9, + 0xffffb2, 0x000014, +}; + +static const unsigned int lpf2_default_tap[] = { + 0x00050a, 0xfff004, 0x0002c1, 0x003c12, 0xffa818, + 0xffc87d, 0x010aef, 0xff5223, 0xfebd93, 0x028f41, + 0xff5c0e, 0xfc63f8, 0x055f81, 0x000000, 0xf478a0, + 0x11c5e3, 0x2ea74d, 0x11c5e3, 0xf478a0, 0x000000, + 0x055f81, 0xfc63f8, 0xff5c0e, 0x028f41, 0xfebd93, + 0xff5223, 0x010aef, 0xffc87d, 0xffa818, 0x003c12, + 0x0002c1, 0xfff004, 0x00050a, +}; + +static const unsigned int lpf3_default_tap[] = { + 0x000000, 0x000081, 0x000000, 0xfffedb, 0x000000, + 0x00022d, 0x000000, 0xfffc46, 0x000000, 0x0005f7, + 0x000000, 0xfff6eb, 0x000000, 0x000d4e, 0x000000, + 0xffed1e, 0x000000, 0x001a1c, 0x000000, 0xffdcb0, + 0x000000, 0x002ede, 0x000000, 0xffc2d1, 0x000000, + 0x004ebe, 0x000000, 0xff9beb, 0x000000, 0x007dd7, + 0x000000, 0xff633a, 0x000000, 0x00c1d2, 0x000000, + 0xff11d5, 0x000000, 0x012368, 0x000000, 0xfe9c45, + 0x000000, 0x01b252, 0x000000, 0xfdebf6, 0x000000, + 0x0290b8, 0x000000, 0xfcca0d, 0x000000, 0x041d7c, + 0x000000, 0xfa8152, 0x000000, 0x07e9c6, 0x000000, + 0xf28fb5, 0x000000, 0x28b216, 0x3fffde, 0x28b216, + 0x000000, 0xf28fb5, 0x000000, 0x07e9c6, 0x000000, + 0xfa8152, 0x000000, 0x041d7c, 0x000000, 0xfcca0d, + 0x000000, 0x0290b8, 0x000000, 0xfdebf6, 0x000000, + 0x01b252, 0x000000, 0xfe9c45, 0x000000, 0x012368, + 0x000000, 0xff11d5, 0x000000, 0x00c1d2, 0x000000, + 0xff633a, 0x000000, 0x007dd7, 0x000000, 0xff9beb, + 0x000000, 0x004ebe, 0x000000, 0xffc2d1, 0x000000, + 0x002ede, 0x000000, 0xffdcb0, 0x000000, 0x001a1c, + 0x000000, 0xffed1e, 0x000000, 0x000d4e, 0x000000, + 0xfff6eb, 0x000000, 0x0005f7, 0x000000, 0xfffc46, + 0x000000, 0x00022d, 0x000000, 0xfffedb, 0x000000, + 0x000081, 0x000000, +}; + +/* + * These values are sane defaults for the axg platform: + * - OS = 64 + * - Latency = 38700 (?) + * + * TODO: There is a lot of different HCIC, LPFs and HPF configurations possible. + * the configuration may depend on the dmic used by the platform, the + * expected tradeoff between latency and quality, etc ... If/When other + * settings are required, we should add a fw interface to this driver to + * load new filter settings. + */ +static const struct axg_pdm_filters axg_default_filters = { + .hcic = { + .shift = 0x15, + .mult = 0x80, + .steps = 7, + .ds = 8, + }, + .hpf = { + .out_factor = 0x8000, + .steps = 13, + }, + .lpf = { + [0] = { + .ds = 2, + .round_mode = 1, + .tap = lpf1_default_tap, + .tap_num = ARRAY_SIZE(lpf1_default_tap), + }, + [1] = { + .ds = 2, + .round_mode = 0, + .tap = lpf2_default_tap, + .tap_num = ARRAY_SIZE(lpf2_default_tap), + }, + [2] = { + .ds = 2, + .round_mode = 1, + .tap = lpf3_default_tap, + .tap_num = ARRAY_SIZE(lpf3_default_tap) + }, + }, +}; + +static const struct axg_pdm_cfg axg_pdm_config = { + .filters = &axg_default_filters, + .sys_rate = 250000000, +}; + +static const struct of_device_id axg_pdm_of_match[] = { + { + .compatible = "amlogic,axg-pdm", + .data = &axg_pdm_config, + }, {} +}; +MODULE_DEVICE_TABLE(of, axg_pdm_of_match); + +static int axg_pdm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct axg_pdm *priv; + struct resource *res; + void __iomem *regs; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + platform_set_drvdata(pdev, priv); + + priv->cfg = of_device_get_match_data(dev); + if (!priv->cfg) { + dev_err(dev, "failed to match device\n"); + return -ENODEV; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + regs = devm_ioremap_resource(dev, res); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + priv->map = devm_regmap_init_mmio(dev, regs, &axg_pdm_regmap_cfg); + if (IS_ERR(priv->map)) { + dev_err(dev, "failed to init regmap: %ld\n", + PTR_ERR(priv->map)); + return PTR_ERR(priv->map); + } + + priv->pclk = devm_clk_get(dev, "pclk"); + if (IS_ERR(priv->pclk)) { + ret = PTR_ERR(priv->pclk); + if (ret != -EPROBE_DEFER) + dev_err(dev, "failed to get pclk: %d\n", ret); + return ret; + } + + priv->dclk = devm_clk_get(dev, "dclk"); + if (IS_ERR(priv->dclk)) { + ret = PTR_ERR(priv->dclk); + if (ret != -EPROBE_DEFER) + dev_err(dev, "failed to get dclk: %d\n", ret); + return ret; + } + + priv->sysclk = devm_clk_get(dev, "sysclk"); + if (IS_ERR(priv->sysclk)) { + ret = PTR_ERR(priv->sysclk); + if (ret != -EPROBE_DEFER) + dev_err(dev, "failed to get dclk: %d\n", ret); + return ret; + } + + return devm_snd_soc_register_component(dev, &axg_pdm_component_drv, + &axg_pdm_dai_drv, 1); +} + +static struct platform_driver axg_pdm_pdrv = { + .probe = axg_pdm_probe, + .driver = { + .name = "axg-pdm", + .of_match_table = axg_pdm_of_match, + }, +}; +module_platform_driver(axg_pdm_pdrv); + +MODULE_DESCRIPTION("Amlogic AXG PDM Input driver"); +MODULE_AUTHOR("Jerome Brunet "); +MODULE_LICENSE("GPL v2");