From patchwork Wed Feb 19 13:36:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 11391473 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CBC01930 for ; Wed, 19 Feb 2020 13:38:42 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6311420801 for ; Wed, 19 Feb 2020 13:38:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="RIORxEVw"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="pgi+TBIf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6311420801 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B7EA01698; Wed, 19 Feb 2020 14:37:55 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B7EA01698 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1582119520; bh=GLA8XQhKkwhXaQmXQlyLvv/TIokS4AMSUAxBeZsIcXQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=RIORxEVwPoJcXtE5nokE1Bp8riGjYTt0bnynNlJZpu4nz2dRmIS+x24gOJ/2P2OHy Fnf7I48TMnxSpIf6ZkIpvk9MTwuEHwefFTUKOJJY4MsGA+rwcypD7QPOYLD6rsePAB Qiz9YdwM78TWHTMIZYPAQ98B7eNuio9qGPYhgyM4= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7B27FF80277; Wed, 19 Feb 2020 14:37:05 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id B6409F80276; Wed, 19 Feb 2020 14:37:00 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, SPF_HELO_NONE,SPF_PASS,SURBL_BLOCKED,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id BF2EDF80114 for ; Wed, 19 Feb 2020 14:36:57 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BF2EDF80114 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="pgi+TBIf" Received: by mail-wr1-x443.google.com with SMTP id c9so550079wrw.8 for ; Wed, 19 Feb 2020 05:36:57 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=idNFPyAtkmq04AJWh7a0/gnkZseJQQBbr31aSDqpxTo=; b=pgi+TBIfgcN3kTkndoro2wO8PcZFOTmypoXoT9oPvzBxZMrgOYmFREyP3GAWSdSFA9 W/vH5mTeEJe6txM2vOAQ6qcI5zMlhWbBDJBd2DseAl76AwuZqBKKQCYRDewdfbQw+GNe jmsusBY99uLMfYUT0ZBXI87iPS9HRDmepSofoFVnzq+oTg3I9o+n3eHIv7Bf0DJi1GS6 vPhREp4T+t+eKJkx9tcRWI3GlCMwIaMz0UT0dco4O68gnMIfvLVfpoSoW8iZIvblHvJp Wi6RwXWNKVFscVbHLjzE9FpD2OBeVcieFINJ3GJD1KQlakxunb2k4k1KzbE2esIPCnde LE2A== 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:mime-version:content-transfer-encoding; bh=idNFPyAtkmq04AJWh7a0/gnkZseJQQBbr31aSDqpxTo=; b=YbZTZ6YhO7h1OpOTEa74piWxD0ifqG4XQ/xZ3l8cNnKgrF5nV4IWkkjhGMniT7xLhv 1dfzqtGWkuj65NDiwqmJZiVrfA9prVLSK/tGq9E10WJcCtXrSselnBE78pxP3FFqMKjE BM7r76GO2d18T6pE8qclZ/jGiDv1SOhLKaCa22LP2zNCTVFtWCIF1XuDXPHS3zE9YI+r DFX5z29PrTZHnleoWLRP1KrawHdT3imnSAkpUtli8lzc6nKT1c9ZdcLDzz0kVq7ORC7Z wyYeSUqi0pt1zQp/AL5Wl+jiV6fIkUvHpEwEAy6ba9ftsINIw2Z5P3qhwA18ukTY+EdU ID0Q== X-Gm-Message-State: APjAAAVL5a7wRvros5C1rh7W8YIeeyTNWiEXHdPcarn5Zx6rGYQmxBO0 kT6FYWyrMj3Vv3s2++X1aLuRFVo9Rg4= X-Google-Smtp-Source: APXvYqwCdG6arwwkXKRGXknOCJ7az3kOoi5ADFVldBeUfvCD9Xrxom8biCGNQ4YGwzDvnmboPbXyrw== X-Received: by 2002:adf:dd0b:: with SMTP id a11mr37802096wrm.150.1582119416706; Wed, 19 Feb 2020 05:36:56 -0800 (PST) Received: from localhost.localdomain (cag06-3-82-243-161-21.fbx.proxad.net. [82.243.161.21]) by smtp.googlemail.com with ESMTPSA id q124sm8856480wme.2.2020.02.19.05.36.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2020 05:36:56 -0800 (PST) From: Jerome Brunet To: Mark Brown , Liam Girdwood Subject: [PATCH 1/2] ASoC: meson: add t9015 internal codec binding documentation Date: Wed, 19 Feb 2020 14:36:45 +0100 Message-Id: <20200219133646.1035506-2-jbrunet@baylibre.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200219133646.1035506-1-jbrunet@baylibre.com> References: <20200219133646.1035506-1-jbrunet@baylibre.com> MIME-Version: 1.0 X-Patchwork-Bot: notify Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org, Kevin Hilman , linux-kernel@vger.kernel.org, linux-amlogic@lists.infradead.org, Jerome Brunet X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Add the DT binding documention of the internal DAC found in the Amlogic gxl, g12a and sm1 SoC family. Signed-off-by: Jerome Brunet --- .../bindings/sound/amlogic,t9015.yaml | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/amlogic,t9015.yaml diff --git a/Documentation/devicetree/bindings/sound/amlogic,t9015.yaml b/Documentation/devicetree/bindings/sound/amlogic,t9015.yaml new file mode 100644 index 000000000000..b7c38c2b5b54 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/amlogic,t9015.yaml @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/amlogic,t9015.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic T9015 Internal Audio DAC + +maintainers: + - Jerome Brunet + +properties: + $nodename: + pattern: "^audio-controller@.*" + + "#sound-dai-cells": + const: 0 + + compatible: + items: + - const: amlogic,t9015 + + clocks: + items: + - description: Peripheral clock + + clock-names: + items: + - const: pclk + + reg: + maxItems: 1 + + resets: + maxItems: 1 + +required: + - "#sound-dai-cells" + - compatible + - reg + - clocks + - clock-names + - resets + +examples: + - | + #include + #include + + acodec: audio-controller@32000 { + compatible = "amlogic,t9015"; + reg = <0x0 0x32000 0x0 0x14>; + #sound-dai-cells = <0>; + clocks = <&clkc CLKID_AUDIO_CODEC>; + clock-names = "pclk"; + resets = <&reset RESET_AUDIO_CODEC>; + }; + From patchwork Wed Feb 19 13:36:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 11391475 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BB060159A for ; Wed, 19 Feb 2020 13:39:30 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 51B112465D for ; Wed, 19 Feb 2020 13:39:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="pRHFZ+eP"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="VHAdISWM" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 51B112465D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id D943416A1; Wed, 19 Feb 2020 14:38:42 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D943416A1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1582119567; bh=U0yXSCL2l8h18Yp3DC5mvvPHX9OSs/hCqpOqk9l6E3o=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=pRHFZ+ePPd+konwADOQocOS4EmJtc65RtIJ8H4EB2C/zX1pAZqtsvXTABY46uzW+B 605ElO+2G+MiWQ+EPGAy2aePhdUe1B7dkv8DW5T7pDQoCXtqFZ4c6iw8GAwozxah52 JI3XD1fn/gpBFRzcvHhrCrgBmZHuBGYrzCwmBZ5w= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D1838F8027C; Wed, 19 Feb 2020 14:37:06 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 67B8FF80279; Wed, 19 Feb 2020 14:37:03 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 93914F8025F for ; Wed, 19 Feb 2020 14:36:59 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 93914F8025F Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="VHAdISWM" Received: by mail-wr1-x443.google.com with SMTP id u6so620887wrt.0 for ; Wed, 19 Feb 2020 05:36:59 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=6FPAvPiCXoDi8cmgLJ1lHMdUMUKv0XX6f1mskgtrNFY=; b=VHAdISWMfathLd5IZRk9Zm7NOQA2Jr4RLaFpZqB9GMWjQts6p6VlTaznQF2kzF+8uz S4XPBtb4mQ9raZGYexfsyAuQ2nz83XyCD3eIM07WwU6NWchwh7cnm8tbvOpdua8+VzRz jpcknKAdQjkZJ6NF+PJVE4MnTpN425MuIuK0FM6aDXVb9U9KMf6bL6w94zp4Po1qSdYE t9/81v9IGC+VLKnvZVCwjX8qLVjpuNBSg5qJnG5jF994o1RIiUySdIKQgDxnsnT/BeY9 Q4bmJYgoPjaP+intj4PpueODvBDkmQE4F5/i3qKR60L+UuFsfNkJlLASmA2IUVgfYDrU HOkA== 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:mime-version:content-transfer-encoding; bh=6FPAvPiCXoDi8cmgLJ1lHMdUMUKv0XX6f1mskgtrNFY=; b=XO4u9fON/msw5zAxvG6UQARaxX8+2rJ57VgbeDiL4OHH76/n5o8vAZbfCRgINZJ2j+ vCeqRdSUqwODBSoZ+UdtHk9otq6aO6sdo/OkuIh6ziRuSwOBchZ5L6x+vA8XoMrfcoVk OAc+nCIjzxKEV/bcmTmqT09SWQmJ2A6V4jHboOubHPaVVYitAFSBltLsxVNhmg183zA6 pxEtn1S/Y6hnz1eB9CSP9e/fo51TNdFWKDjq7ncahV7D46PFUhDg3FY77pWfkAanGdvZ mPj3m4fK6xqkm6yD4ju2pl+2+O2yEsuChMnXJejRelaEjYRF/X3xC9Y0Yh+Cl/2sz++O aSvw== X-Gm-Message-State: APjAAAW1wIRgAL2GheN9GiwL3Sko0IcIT3grlvWe/4llvN7Du3snFmi0 n4VB6Dk0cmWW40SfnCVWQzMg9A== X-Google-Smtp-Source: APXvYqwoJQU6JTKcGP81SNBGUHBlm2hN2BfEOeA/oaAL5HgHjinkvgYDfnooX4+Av/3xA/iGqBUmjw== X-Received: by 2002:adf:f288:: with SMTP id k8mr38062587wro.301.1582119418954; Wed, 19 Feb 2020 05:36:58 -0800 (PST) Received: from localhost.localdomain (cag06-3-82-243-161-21.fbx.proxad.net. [82.243.161.21]) by smtp.googlemail.com with ESMTPSA id q124sm8856480wme.2.2020.02.19.05.36.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2020 05:36:57 -0800 (PST) From: Jerome Brunet To: Mark Brown , Liam Girdwood Subject: [PATCH 2/2] ASoC: meson: add t9015 internal DAC driver Date: Wed, 19 Feb 2020 14:36:46 +0100 Message-Id: <20200219133646.1035506-3-jbrunet@baylibre.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200219133646.1035506-1-jbrunet@baylibre.com> References: <20200219133646.1035506-1-jbrunet@baylibre.com> MIME-Version: 1.0 X-Patchwork-Bot: notify Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org, Kevin Hilman , linux-kernel@vger.kernel.org, linux-amlogic@lists.infradead.org, Jerome Brunet X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Add the codec driver of the internal DAC found on Amlogic gxl, g12a and sm1 family. Signed-off-by: Jerome Brunet --- sound/soc/meson/Kconfig | 8 + sound/soc/meson/Makefile | 2 + sound/soc/meson/t9015.c | 320 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+) create mode 100644 sound/soc/meson/t9015.c diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig index 22d2af75b59e..897a706dcda0 100644 --- a/sound/soc/meson/Kconfig +++ b/sound/soc/meson/Kconfig @@ -6,6 +6,7 @@ config SND_MESON_AIU tristate "Amlogic AIU" select SND_MESON_CODEC_GLUE select SND_PCM_IEC958 + imply SND_SOC_MESON_T9015 imply SND_SOC_HDMI_CODEC if DRM_MESON_DW_HDMI help Select Y or M to add support for the Audio output subsystem found @@ -116,4 +117,11 @@ config SND_MESON_G12A_TOHDMITX help Select Y or M to add support for HDMI audio on the g12a SoC family + +config SND_SOC_MESON_T9015 + tristate "Amlogic T9015 DAC" + select REGMAP_MMIO + help + Say Y or M if you want to add support for the internal DAC found + on GXL, G12 and SM1 SoC family. endmenu diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile index f9c90c391498..3c9d48846816 100644 --- a/sound/soc/meson/Makefile +++ b/sound/soc/meson/Makefile @@ -23,6 +23,7 @@ snd-soc-meson-card-utils-objs := meson-card-utils.o snd-soc-meson-codec-glue-objs := meson-codec-glue.o snd-soc-meson-gx-sound-card-objs := gx-card.o snd-soc-meson-g12a-tohdmitx-objs := g12a-tohdmitx.o +snd-soc-meson-t9015-objs := t9015.o obj-$(CONFIG_SND_MESON_AIU) += snd-soc-meson-aiu.o obj-$(CONFIG_SND_MESON_AXG_FIFO) += snd-soc-meson-axg-fifo.o @@ -40,3 +41,4 @@ obj-$(CONFIG_SND_MESON_CARD_UTILS) += snd-soc-meson-card-utils.o obj-$(CONFIG_SND_MESON_CODEC_GLUE) += snd-soc-meson-codec-glue.o obj-$(CONFIG_SND_MESON_GX_SOUND_CARD) += snd-soc-meson-gx-sound-card.o obj-$(CONFIG_SND_MESON_G12A_TOHDMITX) += snd-soc-meson-g12a-tohdmitx.o +obj-$(CONFIG_SND_SOC_MESON_T9015) += snd-soc-meson-t9015.o diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c new file mode 100644 index 000000000000..b8a003efa628 --- /dev/null +++ b/sound/soc/meson/t9015.c @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2020 BayLibre, SAS. +// Author: Jerome Brunet + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BLOCK_EN 0x00 +#define LORN_EN 0 +#define LORP_EN 1 +#define LOLN_EN 2 +#define LOLP_EN 3 +#define DACR_EN 4 +#define DACL_EN 5 +#define DACR_INV 20 +#define DACL_INV 21 +#define DACR_SRC 22 +#define DACL_SRC 23 +#define REFP_BUF_EN BIT(12) +#define BIAS_CURRENT_EN BIT(13) +#define VMID_GEN_FAST BIT(14) +#define VMID_GEN_EN BIT(15) +#define I2S_MODE BIT(30) +#define VOL_CTRL0 0x04 +#define GAIN_H 31 +#define GAIN_L 23 +#define VOL_CTRL1 0x08 +#define DAC_MONO 8 +#define RAMP_RATE 10 +#define VC_RAMP_MODE 12 +#define MUTE_MODE 13 +#define UNMUTE_MODE 14 +#define DAC_SOFT_MUTE 15 +#define DACR_VC 16 +#define DACL_VC 24 +#define LINEOUT_CFG 0x0c +#define LORN_POL 0 +#define LORP_POL 4 +#define LOLN_POL 8 +#define LOLP_POL 12 +#define POWER_CFG 0x10 + +struct t9015 { + struct clk *pclk; + struct regulator *avdd; +}; + +static int t9015_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_component *component = dai->component; + unsigned int val; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + val = I2S_MODE; + break; + + case SND_SOC_DAIFMT_CBS_CFS: + val = 0; + break; + + default: + return -EINVAL; + } + + snd_soc_component_update_bits(component, BLOCK_EN, I2S_MODE, val); + + if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) && + ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_LEFT_J)) + return -EINVAL; + + return 0; +} + +static const struct snd_soc_dai_ops t9015_dai_ops = { + .set_fmt = t9015_dai_set_fmt, +}; + +static struct snd_soc_dai_driver t9015_dai = { + .name = "t9015-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = (SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_LE | + SNDRV_PCM_FMTBIT_S24_LE), + }, + .ops = &t9015_dai_ops, +}; + +static const DECLARE_TLV_DB_MINMAX_MUTE(dac_vol_tlv, -9525, 0); + +static const char * const ramp_rate_txt[] = { "Fast", "Slow" }; +static SOC_ENUM_SINGLE_DECL(ramp_rate_enum, VOL_CTRL1, RAMP_RATE, + ramp_rate_txt); + +static const char * const dacr_in_txt[] = { "Right", "Left" }; +static SOC_ENUM_SINGLE_DECL(dacr_in_enum, BLOCK_EN, DACR_SRC, dacr_in_txt); + +static const char * const dacl_in_txt[] = { "Left", "Right" }; +static SOC_ENUM_SINGLE_DECL(dacl_in_enum, BLOCK_EN, DACL_SRC, dacl_in_txt); + +static const char * const mono_txt[] = { "Stereo", "Mono"}; +static SOC_ENUM_SINGLE_DECL(mono_enum, VOL_CTRL1, DAC_MONO, mono_txt); + +static const struct snd_kcontrol_new t9015_snd_controls[] = { + /* Volume Controls */ + SOC_SINGLE("Playback Mute", VOL_CTRL1, DAC_SOFT_MUTE, 1, 0), + SOC_DOUBLE_TLV("Playback Volume", VOL_CTRL1, DACL_VC, DACR_VC, + 0xff, 0, dac_vol_tlv), + + /* Ramp Controls */ + SOC_ENUM("Ramp Rate", ramp_rate_enum), + SOC_SINGLE("Volume Ramp Enable", VOL_CTRL1, VC_RAMP_MODE, 1, 0), + SOC_SINGLE("Mute Ramp Enable", VOL_CTRL1, MUTE_MODE, 1, 0), + SOC_SINGLE("Unmute Ramp Enable", VOL_CTRL1, UNMUTE_MODE, 1, 0), + + /* Channel Src */ + SOC_ENUM("Right DAC Source", dacr_in_enum), + SOC_ENUM("Left DAC Source", dacl_in_enum), + SOC_ENUM("Channel Mode", mono_enum), +}; + +static const struct snd_soc_dapm_widget t9015_dapm_widgets[] = { + SND_SOC_DAPM_DAC("Right DAC", NULL, BLOCK_EN, DACR_EN, 0), + SND_SOC_DAPM_DAC("Left DAC", NULL, BLOCK_EN, DACL_EN, 0), + SND_SOC_DAPM_OUT_DRV("Right- Driver", BLOCK_EN, LORN_EN, 0, + NULL, 0), + SND_SOC_DAPM_OUT_DRV("Right+ Driver", BLOCK_EN, LORP_EN, 0, + NULL, 0), + SND_SOC_DAPM_OUT_DRV("Left- Driver", BLOCK_EN, LOLN_EN, 0, + NULL, 0), + SND_SOC_DAPM_OUT_DRV("Left+ Driver", BLOCK_EN, LOLP_EN, 0, + NULL, 0), + SND_SOC_DAPM_OUTPUT("LORN"), + SND_SOC_DAPM_OUTPUT("LORP"), + SND_SOC_DAPM_OUTPUT("LOLN"), + SND_SOC_DAPM_OUTPUT("LOLP"), +}; + +static const struct snd_soc_dapm_route t9015_dapm_routes[] = { + { "Right DAC", NULL, "Playback" }, + { "Left DAC", NULL, "Playback" }, + { "Right- Driver", NULL, "Right DAC" }, + { "Right+ Driver", NULL, "Right DAC" }, + { "Left- Driver", NULL, "Left DAC" }, + { "Left+ Driver", NULL, "Left DAC" }, + { "LORN", NULL, "Right- Driver", }, + { "LORP", NULL, "Right+ Driver", }, + { "LOLN", NULL, "Left- Driver", }, + { "LOLP", NULL, "Left+ Driver", }, +}; + +static int t9015_set_bias_level(struct snd_soc_component *component, + enum snd_soc_bias_level level) +{ + struct t9015 *priv = snd_soc_component_get_drvdata(component); + enum snd_soc_bias_level now = + snd_soc_component_get_bias_level(component); + int ret; + + switch (level) { + case SND_SOC_BIAS_ON: + snd_soc_component_update_bits(component, BLOCK_EN, + BIAS_CURRENT_EN, + BIAS_CURRENT_EN); + break; + case SND_SOC_BIAS_PREPARE: + snd_soc_component_update_bits(component, BLOCK_EN, + BIAS_CURRENT_EN, + 0); + break; + case SND_SOC_BIAS_STANDBY: + ret = regulator_enable(priv->avdd); + if (ret) { + dev_err(component->dev, "AVDD enable failed\n"); + return ret; + } + + if (now == SND_SOC_BIAS_OFF) { + snd_soc_component_update_bits(component, BLOCK_EN, + VMID_GEN_EN | VMID_GEN_FAST | REFP_BUF_EN, + VMID_GEN_EN | VMID_GEN_FAST | REFP_BUF_EN); + + mdelay(200); + snd_soc_component_update_bits(component, BLOCK_EN, + VMID_GEN_FAST, + 0); + } + + break; + case SND_SOC_BIAS_OFF: + snd_soc_component_update_bits(component, BLOCK_EN, + VMID_GEN_EN | VMID_GEN_FAST | REFP_BUF_EN, + 0); + + regulator_disable(priv->avdd); + break; + } + + return 0; +} + +static const struct snd_soc_component_driver t9015_codec_driver = { + .set_bias_level = t9015_set_bias_level, + .controls = t9015_snd_controls, + .num_controls = ARRAY_SIZE(t9015_snd_controls), + .dapm_widgets = t9015_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(t9015_dapm_widgets), + .dapm_routes = t9015_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(t9015_dapm_routes), + .suspend_bias_off = 1, + .endianness = 1, + .non_legacy_dai_naming = 1, +}; + +static const struct regmap_config t9015_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = POWER_CFG, +}; + +static int t9015_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct t9015 *priv; + void __iomem *regs; + struct regmap *regmap; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + platform_set_drvdata(pdev, priv); + + priv->pclk = devm_clk_get(dev, "pclk"); + if (IS_ERR(priv->pclk)) { + if (PTR_ERR(priv->pclk) != -EPROBE_DEFER) + dev_err(dev, "failed to get core clock\n"); + return PTR_ERR(priv->pclk); + } + + priv->avdd = devm_regulator_get(dev, "AVDD"); + if (IS_ERR(priv->avdd)) { + if (PTR_ERR(priv->avdd) != -EPROBE_DEFER) + dev_err(dev, "failed to AVDD\n"); + return PTR_ERR(priv->avdd); + } + + ret = clk_prepare_enable(priv->pclk); + if (ret) { + dev_err(dev, "core clock enable failed\n"); + return ret; + } + + ret = devm_add_action_or_reset(dev, + (void(*)(void *))clk_disable_unprepare, + priv->pclk); + if (ret) + return ret; + + ret = device_reset(dev); + if (ret) { + dev_err(dev, "reset failed\n"); + return ret; + } + + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) { + dev_err(dev, "register map failed\n"); + return PTR_ERR(regs); + } + + regmap = devm_regmap_init_mmio(dev, regs, &t9015_regmap_config); + if (IS_ERR(regmap)) { + dev_err(dev, "regmap init failed\n"); + return PTR_ERR(regmap); + } + + /* + * Initialize output polarity: + * ATM the output polarity is fixed but in the future it might useful + * to add DT property to set this depending on the platform needs + */ + regmap_write(regmap, LINEOUT_CFG, 0x1111); + + return devm_snd_soc_register_component(dev, &t9015_codec_driver, + &t9015_dai, 1); +} + +static const struct of_device_id t9015_ids[] = { + { .compatible = "amlogic,t9015", }, + { } +}; +MODULE_DEVICE_TABLE(of, t9015_ids); + +static struct platform_driver t9015_driver = { + .driver = { + .name = "t9015-codec", + .of_match_table = of_match_ptr(t9015_ids), + }, + .probe = t9015_probe, +}; + +module_platform_driver(t9015_driver); + +MODULE_DESCRIPTION("ASoC Amlogic T9015 codec driver"); +MODULE_AUTHOR("Jerome Brunet "); +MODULE_LICENSE("GPL");