From patchwork Fri Apr 26 17:22:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645153 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B890DC04FFE for ; Fri, 26 Apr 2024 17:22:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 79F4E113B62; Fri, 26 Apr 2024 17:22:44 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="U0ZFvSZL"; dkim-atps=neutral Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1B4B510EB34 for ; Fri, 26 Apr 2024 17:22:40 +0000 (UTC) Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-a58c89bda70so138967466b.3 for ; Fri, 26 Apr 2024 10:22:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152158; x=1714756958; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=I46Ibjxmnn5yy081gSXZ9cudlQC/VlKWW3WhTJhSrbw=; b=U0ZFvSZLB7s2IGMVUB0gkhKdh9kaCC7ItFXF5A/7x/fSG0qOBdWQEL1NfBSpc4+Xpf K5qxXnWOieciGgkxg/7+Kh81Ml4N0ay0ioBteK9rhRu+8QDMQLng0zsuHv4td3b8ubUi 95EduHO+hqO2dy+y+3+SJ0Tj3/wrTQOtzlQ0bRY6qYqzsWZNYaBJmKIs5WlSUDuCDdx3 zLrQ4zDzMyY31pXgASU/knzfS4qLhBapJjA8BL0vWlyQbEtalLAiXhgBhxY/zhJ9nBoO T9HuS6LdBXKmBSZE1ITJ1loYBauV0Rn+T74cI9JTUlwS675NgHM9nNMLF0aNZC1KbgC1 QnHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152158; x=1714756958; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=I46Ibjxmnn5yy081gSXZ9cudlQC/VlKWW3WhTJhSrbw=; b=TLM5MGzfy/D5BIRBCkOwpV8YF8WbmZYNUIW9KbQvVDPGeDqDtQ1cOoaZpYb9J1hp98 myUinh83xXu8ouHoIEzOv2Ml+ovYgqjyBJZfN36rSMsLvGWGe2aGZx+SmDK+Gt2pB68t myoWdQhA1IgdohWT1US/iQ8x8AECdqCJUsKcZpcXKabp2E51c30bifKy9bV6ij4Emfmb lJzfGTmF7R/rrzbOrRWPABBFFPXPbQoehCe3yPAYi2YbOTaMTU4Y4aJbzQtmtaNvbbKV QJ5dwDfpmIWy8xQefspCaEPLT/9ITGWStoqRdCQjCstnQ2S32l545WQlDkfiYdu0/iNe VZkg== X-Forwarded-Encrypted: i=1; AJvYcCVY60wjX7G01Emp5Ee8N8O2hBSNLfKapE5yBZ5mgLfMN1vdpTKVKLITycfmLVi5kMsZdcAULxV1tZWrdokGTXwsERjXsY2AQM8XrtI9UChi X-Gm-Message-State: AOJu0Yxlwy9Pt4ssafuvbcoUGt8QfKov04GAyNIUF3ARN7c+i20w9ot/ lLH/F6YcbF1HwZyoW1zPJNESuRvnK6AtrshJvcQVlZFlN+QbH3SjVZ2VPsK19gI= X-Google-Smtp-Source: AGHT+IGUaKJ2bisa2YXm3HzCKI+QdDP+ZC4VvfOSJA6Lakp7bBabcfb0LXePJJPgP2PFAKWrz8G/yA== X-Received: by 2002:a17:906:6899:b0:a58:dcc3:f4b0 with SMTP id n25-20020a170906689900b00a58dcc3f4b0mr580280ejr.61.1714152158342; Fri, 26 Apr 2024 10:22:38 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:37 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:30 +0200 Subject: [PATCH v4 01/16] ASoC: dt-bindings: mediatek,mt8365-afe: Add audio afe document MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-1-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4568; i=amergnat@baylibre.com; h=from:subject:message-id; bh=XK/yaNy7n8mlOsrCzgcSHm0w5LeFndFZXd+EBLOo2Z0=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaW9P90pKeXd7l0uFbxmJvFZ+dwyCWlzTbC45l x0lgcF6JAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURVvVD/ 4jEt2v5XKDN/IjGKFFuvIq6pNGahsS7ZaCjB/2lN8OHrRy2UjymVNP3DyzTCvPidzuU8W70lRgMc9C yzaalBkExgjofRIrsj68u/deILcEPJPdsTDI/zvxVa5gJwniDWdvbQI1nt+2nP+OsNDm4Z+0LHkHrh DJxwDRXbVfajNT99ZCUGvU/pwvv4NYQjzbZFOlSpcwqJpaQ6dA19Q1GtjVBF/UYBgM7tilY6qMpshZ NqnoNktnCWyjP7o3wiq0HEAuxdf497NnfUtm6L7vEO9hPmfVCShMlbUGGiK/m99rVcbhlsksRRgAV1 i+lrUcB6gVXT1ZEuJTRvZWmSr8Fs5YnAZHJyHysRsGrOAjSZWTv53rfUDs4e9H7XxOiGEcaLx8uiEB xQBsREGu8uiffWcapfGZuP3ex17ptsLSqgTMgXfFCakTPXK2XciSh4AwUMMgbAgqQeVgQstL0bv+Dp 1/QOs47jAwCSHx6BUb4xXxdjGZyMRoPaWzf8rmNgzd2hs4pH6kYyE7sqEpAHqYfnFZS/vTn/158G1H W/AZhb9UmDgrAxwrFbCGwtz781w2XI32H5tdVpG2KJPmv6v2tmk2hnLU7+Ah8WWfIZiUqWT9DyLvth RqBSA+8CCZIew6/xjw6F+xmAWJsbojdBIh86RPIYlZBr/Vp/ufiri5OU3y6Q== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add MT8365 audio front-end bindings Signed-off-by: Alexandre Mergnat Reviewed-by: Krzysztof Kozlowski --- .../bindings/sound/mediatek,mt8365-afe.yaml | 130 +++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8365-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8365-afe.yaml new file mode 100644 index 000000000000..45ad56d37234 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8365-afe.yaml @@ -0,0 +1,130 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt8365-afe.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek Audio Front End PCM controller for MT8365 + +maintainers: + - Alexandre Mergnat + +properties: + compatible: + const: mediatek,mt8365-afe-pcm + + reg: + maxItems: 1 + + "#sound-dai-cells": + const: 0 + + clocks: + items: + - description: 26M clock + - description: mux for audio clock + - description: audio i2s0 mck + - description: audio i2s1 mck + - description: audio i2s2 mck + - description: audio i2s3 mck + - description: engen 1 clock + - description: engen 2 clock + - description: audio 1 clock + - description: audio 2 clock + - description: mux for i2s0 + - description: mux for i2s1 + - description: mux for i2s2 + - description: mux for i2s3 + + clock-names: + items: + - const: top_clk26m_clk + - const: top_audio_sel + - const: audio_i2s0_m + - const: audio_i2s1_m + - const: audio_i2s2_m + - const: audio_i2s3_m + - const: engen1 + - const: engen2 + - const: aud1 + - const: aud2 + - const: i2s0_m_sel + - const: i2s1_m_sel + - const: i2s2_m_sel + - const: i2s3_m_sel + + interrupts: + maxItems: 1 + + power-domains: + maxItems: 1 + + mediatek,dmic-mode: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Indicates how many data pins are used to transmit two channels of PDM + signal. 1 means two wires, 0 means one wire. Default value is 0. + enum: + - 0 # one wire + - 1 # two wires + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - power-domains + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + audio-controller@11220000 { + compatible = "mediatek,mt8365-afe-pcm"; + reg = <0 0x11220000 0 0x1000>; + #sound-dai-cells = <0>; + clocks = <&clk26m>, + <&topckgen CLK_TOP_AUDIO_SEL>, + <&topckgen CLK_TOP_AUD_I2S0_M>, + <&topckgen CLK_TOP_AUD_I2S1_M>, + <&topckgen CLK_TOP_AUD_I2S2_M>, + <&topckgen CLK_TOP_AUD_I2S3_M>, + <&topckgen CLK_TOP_AUD_ENGEN1_SEL>, + <&topckgen CLK_TOP_AUD_ENGEN2_SEL>, + <&topckgen CLK_TOP_AUD_1_SEL>, + <&topckgen CLK_TOP_AUD_2_SEL>, + <&topckgen CLK_TOP_APLL_I2S0_SEL>, + <&topckgen CLK_TOP_APLL_I2S1_SEL>, + <&topckgen CLK_TOP_APLL_I2S2_SEL>, + <&topckgen CLK_TOP_APLL_I2S3_SEL>; + clock-names = "top_clk26m_clk", + "top_audio_sel", + "audio_i2s0_m", + "audio_i2s1_m", + "audio_i2s2_m", + "audio_i2s3_m", + "engen1", + "engen2", + "aud1", + "aud2", + "i2s0_m_sel", + "i2s1_m_sel", + "i2s2_m_sel", + "i2s3_m_sel"; + interrupts = ; + power-domains = <&spm MT8365_POWER_DOMAIN_AUDIO>; + mediatek,dmic-mode = <1>; + }; + }; + +... From patchwork Fri Apr 26 17:22:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645152 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D80ABC4345F for ; Fri, 26 Apr 2024 17:22:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4BBFB11252D; Fri, 26 Apr 2024 17:22:44 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="LKQwoqsv"; dkim-atps=neutral Received: from mail-ej1-f42.google.com (mail-ej1-f42.google.com [209.85.218.42]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0238E10EF50 for ; Fri, 26 Apr 2024 17:22:41 +0000 (UTC) Received: by mail-ej1-f42.google.com with SMTP id a640c23a62f3a-a58c09e2187so218575966b.3 for ; Fri, 26 Apr 2024 10:22:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152160; x=1714756960; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=4TU43dOQH6UMfjQS6G859NG2HaMeSGxyH5T3QTnjRnY=; b=LKQwoqsv/kgfroR7ezwGwveWwfyQmIuQ7qprJDV8y0YMH7mRa6Oa3uHFj8hYPj+GMk AH/5P9CMaEe8lVluIUkbpDSmIEtqMNb+z2S9315JaGZoB2TKCu7dQxbPQ+MSIpdghzXz oLgi7e7g2AmF/6ez9JACW6pEgz8S7Lom9ODehxs0MbVSU3VZALRCSGldIHYqGbVVYxaT lr7HH6/gNzEn7VwZBjET+qMyR2TO9Jhuaygfmc6bCHnOiWwmm0ysa8iFFyBHveljgo3j zyWncg8jEDBAReRvImP58+v7bPDCaZ9FDeh3pgyipEnjRKCnJp2OO76O6jKQ+4dyhsf9 tO7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152160; x=1714756960; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4TU43dOQH6UMfjQS6G859NG2HaMeSGxyH5T3QTnjRnY=; b=PRPeiQIz1sM/UXk/zYPmZniPdMYzQ5qbsHNC+fX0xSKKm2jXBjGVM6+TqZI/M2EV0J EU+6oTtqpFZkyMqVjZVD/mofBCIMXAWlU9wSJ9msmimWdAjfxPEIT+FaNgQ79jCj0Bne apCtDRG8FcTElbRDDolTCxC7uliG+hVevSRyIhgBJMYGE1beFxpE68+FE9012bCqn9Pw sjTuEaaDacjpK4+2K6uP6VHJr5UXF+1X14efBVMVssSIzbPM0nEW9jKCKphqiVuVAvG/ p+35Kr94DuRJ4719r4N/XzJxhLI0SLFv+Z2ue+UaJUchoKi5mCGnoYai12IubdkXUyWd W8EQ== X-Forwarded-Encrypted: i=1; AJvYcCWkPPbDGYcBNubY749Tn0w2+aW6vcBpOFKfUwCZBz8biGcyUfZ9V/xOC/cn4RfRAFPB+gnPWrnyrWOnZGKqYFplGYedRYeuYjC3caBxluX8 X-Gm-Message-State: AOJu0Yzxj9mc9CxHLasIwSOX0ygxKA/HBUMDfWR6mtSTFm9uWdO3fZmh lo8Se3FHYRKUL98TKvvR3RQF2ZI5XHlWjmTa7ygCY8HWaUrPOVQx3o4d1kgK0sI= X-Google-Smtp-Source: AGHT+IHcBmX2GHh34oFPQvGPIaePMc8392KtBItCgcwB4NvhhucWlDZ3EAw/bb4ovkR1+MLNq0adww== X-Received: by 2002:a17:906:c288:b0:a58:7283:f587 with SMTP id r8-20020a170906c28800b00a587283f587mr2140675ejz.33.1714152159933; Fri, 26 Apr 2024 10:22:39 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:39 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:31 +0200 Subject: [PATCH v4 02/16] ASoC: dt-bindings: mediatek,mt8365-mt6357: Add audio sound card document MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-2-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3263; i=amergnat@baylibre.com; h=from:subject:message-id; bh=RfcGWh4J4Ru+vCmoaCssck50D44laU1fHfw1FIxcYyA=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaS/TeL9lgDhsOUZkB6fGKdDfM1W9MWsbPfEMi JmdJbfKJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURUymEA CNNp4DesNUeM0GUuDt/1G0pbD4jz4uHrL7JeY0bqC+GS59MxGwPSYDsmHoHACfSv4Auy7Mr6AI/lCZ eeXcrfAg3jGsLq5nDOLFW2YyqcKs2qvOvG9RpMGF1E/wmT67od51GEjhsbpTb36vjAi0fxcm3BKCm+ DpW18Cq1LhI9Y9ZU66I3WaBcrXlVHRnkEIZeB5yop2GKPBii9g335yPsuoh22bIBH0raZGWiSiqAwd hKwCfsgHJtLO5wzTELCojIwEEn4N06TOk5GNSaihM875N7w1zaVYNte+wgcnALZJdRDXkbHL9aeQ19 zJ8793FsDW8jCjldeIdQO2LKbFejGNT7FUSJU3pKTZUh0M9pQjxi/9mk3OeBTVdCy1+fiauYHLWcwl xDZzjUtyxaykzBuf3jD1/VWlOGLa2gj6Ks5F7CzvMRM58kzZIgqlxPEG0+3hlaHXLSguDTThAfAxdb /JzwzQRxVhd4RyTRjGlFjWaati4BOFMtSpzeTn4wWF8y0xig/3+US5yuIVRD3c73+AxRGQ1dWmsXH1 nRIIcapVKL3KCjh+OlxcOV5kON4yPMVq0Dm2sPXnyhlWYq8I5oBQ8pM9zMSDrRXbSpiw0XvKYR73M3 FnWVbmFMca+bUJ5NXumQ/E9Edev7275CsD60sYOS7BYPnfZ/wvs1w8kOqAzg== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add soundcard bindings for the MT8365 SoC with the MT6357 audio codec. Signed-off-by: Alexandre Mergnat Reviewed-by: Krzysztof Kozlowski --- .../bindings/sound/mediatek,mt8365-mt6357.yaml | 107 +++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8365-mt6357.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8365-mt6357.yaml new file mode 100644 index 000000000000..f68883da1bb8 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8365-mt6357.yaml @@ -0,0 +1,107 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt8365-mt6357.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT8365 ASoC sound card + +maintainers: + - Alexandre Mergnat + +properties: + compatible: + const: mediatek,mt8365-mt6357 + + pinctrl-names: + minItems: 1 + items: + - const: default + - const: dmic + - const: miso_off + - const: miso_on + - const: mosi_off + - const: mosi_on + + mediatek,platform: + $ref: /schemas/types.yaml#/definitions/phandle + description: The phandle of MT8365 ASoC platform. + +patternProperties: + "^dai-link-[0-9]+$": + type: object + description: + Container for dai-link level properties and CODEC sub-nodes. + + properties: + codec: + type: object + description: Holds subnode which indicates codec dai. + + properties: + sound-dai: + maxItems: 1 + description: phandle of the codec DAI + + additionalProperties: false + + link-name: + description: Indicates dai-link name and PCM stream name + enum: + - I2S_IN_BE + - I2S_OUT_BE + - PCM1_BE + - PDM1_BE + - PDM2_BE + - PDM3_BE + - PDM4_BE + - SPDIF_IN_BE + - SPDIF_OUT_BE + - TDM_IN_BE + - TDM_OUT_BE + + sound-dai: + maxItems: 1 + description: phandle of the CPU DAI + + required: + - link-name + - sound-dai + + additionalProperties: false + +required: + - compatible + - pinctrl-names + - mediatek,platform + +additionalProperties: false + +examples: + - | + sound { + compatible = "mediatek,mt8365-mt6357"; + pinctrl-names = "default", + "dmic", + "miso_off", + "miso_on", + "mosi_off", + "mosi_on"; + pinctrl-0 = <&aud_default_pins>; + pinctrl-1 = <&aud_dmic_pins>; + pinctrl-2 = <&aud_miso_off_pins>; + pinctrl-3 = <&aud_miso_on_pins>; + pinctrl-4 = <&aud_mosi_off_pins>; + pinctrl-5 = <&aud_mosi_on_pins>; + mediatek,platform = <&afe>; + + /* hdmi interface */ + dai-link-0 { + link-name = "I2S_OUT_BE"; + sound-dai = <&afe>; + + codec { + sound-dai = <&it66121hdmitx>; + }; + }; + }; From patchwork Fri Apr 26 17:22:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645151 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 206EEC4345F for ; Fri, 26 Apr 2024 17:22:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0FDA8113A1C; Fri, 26 Apr 2024 17:22:44 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="o+QGx49x"; dkim-atps=neutral Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.52]) by gabe.freedesktop.org (Postfix) with ESMTPS id 515F511252E for ; Fri, 26 Apr 2024 17:22:43 +0000 (UTC) Received: by mail-ed1-f52.google.com with SMTP id 4fb4d7f45d1cf-5708d8beec6so3010541a12.0 for ; Fri, 26 Apr 2024 10:22:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152161; x=1714756961; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=M5h1cKb9Wd4tygVd4523MaRapeEHkSuSBrFUYOzLXOs=; b=o+QGx49xB1PG89LiPdvrfdoIpRodGIxut1uExUcqipT0OEQpXqmqnx9TdvR+Iqy9Rt xhAkT2VF4UCfOR2fYy327YkZki5S52NB1KqQESzUp1RvLLO37XFNf/pZkjCQJO0eL1QP 1AEREZsjJK+msTNDIAPPwvhzW8OhN0o+mVDjs9+yDBn1LHrSxu6pO+yzm9XpidT1lnom pKjmNbzM2W4OrUIvt9JkSohPmUy02labF1jsyt6E20oXzijfcR/9RT2vqKwCdPSIRY2q fx5j2+YUdtJvVUnbUO6E+4hvTyO0elxuNsETx6wNQKFpWZP3RvQ93W6gUZosyleEwACT 9tVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152161; x=1714756961; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=M5h1cKb9Wd4tygVd4523MaRapeEHkSuSBrFUYOzLXOs=; b=jHvvSxQC6viUrj3NVoFDZSphJIvQxQrvzTzk/Tl2WoosXa1UwePdhH3ayVBnSIppcP I5H2Ya1tY7qvse8tltsfU/QF3W8CCe0ktFVA9HnbYxKebnLEEKmsU6vTJGUCv+oG5GkP 3pmHcLJuEO7E1OFlcQKlikkNrQknjnQwu7MkjwlhpdksrLOlq9RGpB7SI1wQl1ODHmoi 5RNnxXHy73BytWQfOarZOmzvrUzo2pVsq602Hln0SGZXd+9j4MtEq3gZhFzQRiNZJb2q w0uGbpRx7coxtwWBgmwtNQ0gKvKfux4GEtjuYB7Di/Gp6uIM49F8y6+3/QY5cRZ7gd/m dDLw== X-Forwarded-Encrypted: i=1; AJvYcCWsED9ugOqK2Szfi+1KD9NRGlhclE8lXThbos7d29sHpzoAPYBgynulovAw0aQdMIX9U+URmSx1b1brWa+HhEZeMYDrtlN8st/NSXHDz0cM X-Gm-Message-State: AOJu0YwmgQ0nXi3p7ubdkJSnPv6XnmMb6PxU5B5MVmTBYqwuX1wjK8wt AkMmWAJreI1EsVWz2n2vkULBBdzXiKS/SUn4hCdytZwf4ZpXGfbAvm8QJnNVtb8= X-Google-Smtp-Source: AGHT+IEn/eMoitApgBUgg8pUEzJGdQivGCLI6Ph+rcC2EpA3138fG0ZSzfIhKnaXEIqhtSXOiOuDMg== X-Received: by 2002:a17:906:dc91:b0:a52:2e08:207e with SMTP id cs17-20020a170906dc9100b00a522e08207emr3002872ejc.77.1714152161629; Fri, 26 Apr 2024 10:22:41 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:41 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:32 +0200 Subject: [PATCH v4 03/16] dt-bindings: mfd: mediatek: Add codec property for MT6357 PMIC MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-3-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2270; i=amergnat@baylibre.com; h=from:subject:message-id; bh=hb4Sc+m6+KqrDRmnsqru9xwwm6vpFvEeTj8R76uZXcI=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaLpQM5c95jo6O7Mo+/ZZ15lOssjMuNjGmsrwq VNAKjCOJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURUkqD/ 9szNNvPScpI+ZPCLaKq2JhlSvxl7NubkybaxFDnbZZN5rZuWJjf3Io2EMZp7xgPg9qvwuCSnjf0O3t t6KJTT62Cv8K2HaAZEKUmTxf94dY9Mb/mpJm99n5WWjRIOt/aUxqpILst9spy3IDLNJZoX2wLyDUaG Ss8Uz+FKMTtzzZ8tK9/7ZXmGWjbHGLeUGXz34zmBWK5+rIuudOEwNNX/9xhxv77tVzD56pVjb7ubcl baF6fdn+n7IIQUccQVCnNHxAMrqCQuz4jzLWBYbhAD+EoIoe0y36ZCQwPsV2v5vDXwm92uhpAhic3X 6oV/VYIluV6Ygg8FzWGuC08vXaJ5hASpczPT2S6ch3wLq4ExegtWFXHv79MIyW8N2griJ0/iSwCNZU 2eeDx7Y3gqi/wHeQ5n8tIMIHIsVZsDRdIWXnT4VtYIpMyrbzj7QsETPB9zYm1xZgzxu/ElYmitgrtp ZoJMP9sj+fAVVZBWeucdazDEgK8G2IgL9s49TRsF+PXDGL1lePzQd5/9qynOZY1lUdzQxXqYgumIgd jwTnvGuoD9VvOwCwzYdLWm9d0YyigwuzHOxDI6Lk3CTQCcyc6kMBbNKEdnLW2PjT389M+pivjq9YYR l7TvJ7oZDeI74NRSKU4Az7sXeN0HebsBq8sfnBReTVZqRJGxs0bWpZWik0Tg== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add the audio codec sub-device. This sub-device is used to set required and optional voltage needed according to the hardware. The properties are: - phandle of the required power supply. - Setup of microphone bias voltage. - Setup of the speaker pin pull-down. Signed-off-by: Alexandre Mergnat --- .../devicetree/bindings/mfd/mediatek,mt6357.yaml | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml index 37423c2e0fdf..30234f13a810 100644 --- a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml +++ b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml @@ -37,6 +37,34 @@ properties: "#interrupt-cells": const: 2 + audio-codec: + type: object + properties: + vaud28-supply: + description: 2.8 volt supply phandle for the audio codec + + mediatek,hp-pull-down: + description: + Earphone driver positive output stage short to + the audio reference ground. + type: boolean + + mediatek,micbias0-microvolt: + description: Selects MIC Bias 0 output voltage. + enum: [1700000, 1800000, 1900000, 2000000, + 2100000, 2500000, 2600000, 2700000] + default: 1700000 + + mediatek,micbias1-microvolt: + description: Selects MIC Bias 1 output voltage. + enum: [1700000, 1800000, 1900000, 2000000, + 2100000, 2500000, 2600000, 2700000] + default: 1700000 + + required: + - vaud28-supply + unevaluatedProperties: false + regulators: type: object $ref: /schemas/regulator/mediatek,mt6357-regulator.yaml @@ -83,6 +111,12 @@ examples: interrupt-controller; #interrupt-cells = <2>; + audio-codec { + mediatek,micbias0-microvolt = <1700000>; + mediatek,micbias1-microvolt = <1700000>; + vaud28-supply = <&mt6357_vaud28_reg>; + }; + regulators { mt6357_vproc_reg: buck-vproc { regulator-name = "vproc"; From patchwork Fri Apr 26 17:22:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645157 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ADE77C4345F for ; Fri, 26 Apr 2024 17:22:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4D1DB10F1CE; Fri, 26 Apr 2024 17:22:53 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="HAJED+Qu"; dkim-atps=neutral Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5802C10F887 for ; Fri, 26 Apr 2024 17:22:45 +0000 (UTC) Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-5724f26b8c9so2395870a12.1 for ; Fri, 26 Apr 2024 10:22:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152163; x=1714756963; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=jAOSUHPpOI437DuBEDokZB8X/c18KNLVUPwKPKsfSf8=; b=HAJED+QuToeuCNbTlM/f1Zk80vonVrv3Ezvh+0aWy/hRGgUihE25sUthxral7A8Vvz IhdI3icl/FMYyIfxuNyjA8UU9+AHkEEXc0cY96RTyjvUPOWYBFAmMw+hgSOQ+l2+KM9c Rmxeds9VJTrzwd3vhKrImEDQpNIavVAW1CB7swSXQEErTMt61kCfOBBiHm8eTr0EQy9l w6YHBFlvD061CJ1u1GgzOTQ+vyEnW0wdIODibJvlrYZsvyEObKc3iG4W7FONd/13pmcX iuD3vQfbDmef9Ilqp61n0l43+7b++Nq7nhKsM+dPx2uMYfiBl625XzmVuFRZ9gn0hJK5 NO6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152163; x=1714756963; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jAOSUHPpOI437DuBEDokZB8X/c18KNLVUPwKPKsfSf8=; b=Is6i26Pt3WMD3PtO4gV2t4A6lY6t+alPWbue5Av96piZoX6fyiJtxQcVRSvitzoeA3 wGnmYaahU+JHdbnsKtDJze5j3QzB2wXZQEwQ12TicfXrsHKC5xTc1+fadoy/+3Cc4MfD Agbhpxa3mZEsfvgDN7A8LZTxFRleF52dmVbosoeuJ55m0osQmOQoSa0EJhKoC3g4dKfl Xypa21V2RunYF0cNeTr7uN2pFw2gJGLuqR84HbLXP6rh95/cHMg9tx0ma5C8x3J//uIl H41Jrw/ipfsHTdmaI/WgMAzF582qxBwZa2njbbeSAUs7bF+ETN41FafQ/v/hQ1gND3Yd QtCg== X-Forwarded-Encrypted: i=1; AJvYcCVqFsDZlcU8C6tXD7XSYeo2CuEkfvZSg+r9Fyluv40/MLJjgeDJJX+FOWYMOKEhE5D52k7buvrGTqVzmrPGkxiXmMrcqr7FKReeSIlZGcki X-Gm-Message-State: AOJu0Yx2JaGCFY4VwFb2swpVjfr54U77yqT+a6HTKxuoFDdErUtyUgJw HmesPlzXjNwCNGspoKTK0+2Jh6egy+g8O8nllrISl2gGiXR/FrNW9wh6QUnYLHQ= X-Google-Smtp-Source: AGHT+IF02tINfpNMXuiDforlPWAmp+shfC/T4XWg3D1Qwasfg2+Ln+c9xCJ9xmdqgYhpjcssG6mM3w== X-Received: by 2002:a17:906:1950:b0:a58:9899:89ab with SMTP id b16-20020a170906195000b00a58989989abmr2842485eje.22.1714152163443; Fri, 26 Apr 2024 10:22:43 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:42 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:33 +0200 Subject: [PATCH v4 04/16] ASoC: mediatek: mt8365: Add common header MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-4-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=51608; i=amergnat@baylibre.com; h=from:subject:message-id; bh=DH9bdMsUhvBoSaMPtaGV5zufNn9i3LR4MExSJEpvGKE=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaLcs7lBY2D1e/DWW9RlgG9WAq4eJHbRN1TkoX EWvmSVmJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURejXD/ 0X/kVfzYz9PSrC4go/eFsmwPqPTPWt8WgfP4AtEk/E0jYXHsSsuWWl9oGtazfq70bHT6q5x2Hq3641 nCJQ/OLNfuEQw5UI27orJNzkPOCWfU0wkaDFt0MK5dOAgFNKAsjZt6oFEfDLDS/yBaeEvru76lIyc4 Csa6ZTPn5ajmu4r6qcBcS4G3beAluQ33omPAR1Uxvp2fZ7q9OfiQaDXQHXbt1b5gWL1dc4YprSqaAX 3abeb5nRLanMjLLYA2mRI1PW/8kUzk/qGtKYwxkP/Qr0PiC3DmQ/hujxoIwlphU/GWgUDXkQoEtjIk N+RZTzXqx0oTgPzIJKx79acyXW1dZtDkK9ms0EsG0HXAQFuMaHeGIkKXhd+KBCSEf3xHV35Jsqb0zD od72xfWjWx+Fs4sqpBQnVZmiJLBOXHZEpRAC66YJphz5nUNBqwqlFQjponLGjJxcLtKNKe/LyaOrEY RQTa27NgSdSi0dsaeZhG6D/qtffcUnXY3VB8IxjNj6n2i/Q8Ru8kMaQEQjtE1o+1iB6wfjXM9uIcC4 haMU3bdkEDQqOyPV2k0cIk2dZUZ2lKOqy1wuet1D3A60xAbIbEnylDis3lzptf6K/we//WOge5exEz ska8XpfGVpW1ULcyvGUeWtlWtaiTfSziKpCrQWslVcT+kMzzCMl7VjKg5ZDw== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add header files for register definition and structure. Signed-off-by: Alexandre Mergnat --- sound/soc/mediatek/mt8365/mt8365-afe-common.h | 491 +++++++++++++ sound/soc/mediatek/mt8365/mt8365-reg.h | 991 ++++++++++++++++++++++++++ 2 files changed, 1482 insertions(+) diff --git a/sound/soc/mediatek/mt8365/mt8365-afe-common.h b/sound/soc/mediatek/mt8365/mt8365-afe-common.h new file mode 100644 index 000000000000..4d8f8c4b19e3 --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-afe-common.h @@ -0,0 +1,491 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Mediatek 8365 audio driver common definitions + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Jia Zeng + * Alexandre Mergnat + */ + +#ifndef _MT8365_AFE_COMMON_H_ +#define _MT8365_AFE_COMMON_H_ + +#define COMMON_CLOCK_FRAMEWORK_API +#define IDLE_TASK_DRIVER_API +#define ENABLE_AFE_APLL_TUNER + +#include +#include +#include +#include +#include +#include "../common/mtk-base-afe.h" +#include "mt8365-reg.h" + +#define ENUM_TO_STR(enum) #enum + +#define snd_soc_dai_stream_active_playback(dai) \ + snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK) +#define snd_soc_dai_stream_active_capture(dai) \ + snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE) + +enum { + MT8365_AFE_MEMIF_DL1, + MT8365_AFE_MEMIF_DL2, + MT8365_AFE_MEMIF_TDM_OUT, + /* + * MT8365_AFE_MEMIF_SPDIF_OUT, + */ + MT8365_AFE_MEMIF_AWB, + MT8365_AFE_MEMIF_VUL, + MT8365_AFE_MEMIF_VUL2, + MT8365_AFE_MEMIF_VUL3, + MT8365_AFE_MEMIF_TDM_IN, + /* + * MT8365_AFE_MEMIF_SPDIF_IN, + */ + MT8365_AFE_MEMIF_NUM, + MT8365_AFE_BACKEND_BASE = MT8365_AFE_MEMIF_NUM, + MT8365_AFE_IO_TDM_OUT = MT8365_AFE_BACKEND_BASE, + MT8365_AFE_IO_TDM_IN, + MT8365_AFE_IO_I2S, + MT8365_AFE_IO_2ND_I2S, + MT8365_AFE_IO_PCM1, + MT8365_AFE_IO_VIRTUAL_DL_SRC, + MT8365_AFE_IO_VIRTUAL_TDM_OUT_SRC, + MT8365_AFE_IO_VIRTUAL_FM, + MT8365_AFE_IO_DMIC, + MT8365_AFE_IO_INT_ADDA, + MT8365_AFE_IO_GASRC1, + MT8365_AFE_IO_GASRC2, + MT8365_AFE_IO_TDM_ASRC, + MT8365_AFE_IO_HW_GAIN1, + MT8365_AFE_IO_HW_GAIN2, + MT8365_AFE_BACKEND_END, + MT8365_AFE_BACKEND_NUM = (MT8365_AFE_BACKEND_END - + MT8365_AFE_BACKEND_BASE), +}; + +enum { + MT8365_AFE_IRQ1, + MT8365_AFE_IRQ2, + MT8365_AFE_IRQ3, + MT8365_AFE_IRQ4, + MT8365_AFE_IRQ5, + MT8365_AFE_IRQ6, + MT8365_AFE_IRQ7, + MT8365_AFE_IRQ8, + MT8365_AFE_IRQ9, + MT8365_AFE_IRQ10, + MT8365_AFE_IRQ_NUM, +}; + +enum { + MT8365_TOP_CG_AFE, + MT8365_TOP_CG_I2S_IN, + MT8365_TOP_CG_22M, + MT8365_TOP_CG_24M, + MT8365_TOP_CG_INTDIR_CK, + MT8365_TOP_CG_APLL2_TUNER, + MT8365_TOP_CG_APLL_TUNER, + MT8365_TOP_CG_SPDIF, + MT8365_TOP_CG_TDM_OUT, + MT8365_TOP_CG_TDM_IN, + MT8365_TOP_CG_ADC, + MT8365_TOP_CG_DAC, + MT8365_TOP_CG_DAC_PREDIS, + MT8365_TOP_CG_TML, + MT8365_TOP_CG_I2S1_BCLK, + MT8365_TOP_CG_I2S2_BCLK, + MT8365_TOP_CG_I2S3_BCLK, + MT8365_TOP_CG_I2S4_BCLK, + MT8365_TOP_CG_DMIC0_ADC, + MT8365_TOP_CG_DMIC1_ADC, + MT8365_TOP_CG_DMIC2_ADC, + MT8365_TOP_CG_DMIC3_ADC, + MT8365_TOP_CG_CONNSYS_I2S_ASRC, + MT8365_TOP_CG_GENERAL1_ASRC, + MT8365_TOP_CG_GENERAL2_ASRC, + MT8365_TOP_CG_TDM_ASRC, + MT8365_TOP_CG_NUM +}; + +enum { + MT8365_CLK_TOP_AUD_SEL, + MT8365_CLK_AUD_I2S0_M, + MT8365_CLK_AUD_I2S1_M, + MT8365_CLK_AUD_I2S2_M, + MT8365_CLK_AUD_I2S3_M, + MT8365_CLK_ENGEN1, + MT8365_CLK_ENGEN2, + MT8365_CLK_AUD1, + MT8365_CLK_AUD2, + MT8365_CLK_I2S0_M_SEL, + MT8365_CLK_I2S1_M_SEL, + MT8365_CLK_I2S2_M_SEL, + MT8365_CLK_I2S3_M_SEL, + MT8365_CLK_CLK26M, + MT8365_CLK_NUM +}; + +enum { + MT8365_AFE_APLL1 = 0, + MT8365_AFE_APLL2, + MT8365_AFE_APLL_NUM, +}; + +enum { + MT8365_AFE_1ST_I2S = 0, + MT8365_AFE_2ND_I2S, + MT8365_AFE_I2S_SETS, +}; + +enum { + MT8365_AFE_I2S_SEPARATE_CLOCK = 0, + MT8365_AFE_I2S_SHARED_CLOCK, +}; + +enum { + MT8365_AFE_TDM_OUT_I2S = 0, + MT8365_AFE_TDM_OUT_TDM, + MT8365_AFE_TDM_OUT_I2S_32BITS, +}; + +enum mt8365_afe_tdm_ch_start { + AFE_TDM_CH_START_O28_O29 = 0, + AFE_TDM_CH_START_O30_O31, + AFE_TDM_CH_START_O32_O33, + AFE_TDM_CH_START_O34_O35, + AFE_TDM_CH_ZERO, +}; + +enum { + MT8365_PCM_FORMAT_I2S = 0, + MT8365_PCM_FORMAT_EIAJ, + MT8365_PCM_FORMAT_PCMA, + MT8365_PCM_FORMAT_PCMB, +}; + +enum { + MT8365_FS_8K = 0, + MT8365_FS_11D025K, + MT8365_FS_12K, + MT8365_FS_384K, + MT8365_FS_16K, + MT8365_FS_22D05K, + MT8365_FS_24K, + MT8365_FS_130K, + MT8365_FS_32K, + MT8365_FS_44D1K, + MT8365_FS_48K, + MT8365_FS_88D2K, + MT8365_FS_96K, + MT8365_FS_176D4K, + MT8365_FS_192K, +}; + +enum { + FS_8000HZ = 0, /* 0000b */ + FS_11025HZ = 1, /* 0001b */ + FS_12000HZ = 2, /* 0010b */ + FS_384000HZ = 3, /* 0011b */ + FS_16000HZ = 4, /* 0100b */ + FS_22050HZ = 5, /* 0101b */ + FS_24000HZ = 6, /* 0110b */ + FS_130000HZ = 7, /* 0111b */ + FS_32000HZ = 8, /* 1000b */ + FS_44100HZ = 9, /* 1001b */ + FS_48000HZ = 10, /* 1010b */ + FS_88200HZ = 11, /* 1011b */ + FS_96000HZ = 12, /* 1100b */ + FS_176400HZ = 13, /* 1101b */ + FS_192000HZ = 14, /* 1110b */ + FS_260000HZ = 15, /* 1111b */ +}; + +enum { + MT8365_AFE_DEBUGFS_AFE, + MT8365_AFE_DEBUGFS_MEMIF, + MT8365_AFE_DEBUGFS_IRQ, + MT8365_AFE_DEBUGFS_CONN, + MT8365_AFE_DEBUGFS_DBG, + MT8365_AFE_DEBUGFS_NUM, +}; + +enum { + MT8365_AFE_IRQ_DIR_MCU = 0, + MT8365_AFE_IRQ_DIR_DSP, + MT8365_AFE_IRQ_DIR_BOTH, +}; + +/* MCLK */ +enum { + MT8365_I2S0_MCK = 0, + MT8365_I2S3_MCK, + MT8365_MCK_NUM, +}; + +struct mt8365_fe_dai_data { + bool use_sram; + unsigned int sram_phy_addr; + void __iomem *sram_vir_addr; + unsigned int sram_size; +}; + +struct mt8365_be_dai_data { + bool prepared[SNDRV_PCM_STREAM_LAST + 1]; + unsigned int fmt_mode; +}; + +#define MT8365_CLK_26M 26000000 +#define MT8365_CLK_24M 24000000 +#define MT8365_CLK_22M 22000000 +#define MT8365_CM_UPDATA_CNT_SET 8 + +enum mt8365_cm_num { + MT8365_CM1 = 0, + MT8365_CM2, + MT8365_CM_NUM, +}; + +enum mt8365_cm2_mux_in { + MT8365_FROM_GASRC1 = 1, + MT8365_FROM_GASRC2, + MT8365_FROM_TDM_ASRC, + MT8365_CM_MUX_NUM, +}; + +enum cm2_mux_conn_in { + GENERAL2_ASRC_OUT_LCH = 0, + GENERAL2_ASRC_OUT_RCH = 1, + TDM_IN_CH0 = 2, + TDM_IN_CH1 = 3, + TDM_IN_CH2 = 4, + TDM_IN_CH3 = 5, + TDM_IN_CH4 = 6, + TDM_IN_CH5 = 7, + TDM_IN_CH6 = 8, + TDM_IN_CH7 = 9, + GENERAL1_ASRC_OUT_LCH = 10, + GENERAL1_ASRC_OUT_RCH = 11, + TDM_OUT_ASRC_CH0 = 12, + TDM_OUT_ASRC_CH1 = 13, + TDM_OUT_ASRC_CH2 = 14, + TDM_OUT_ASRC_CH3 = 15, + TDM_OUT_ASRC_CH4 = 16, + TDM_OUT_ASRC_CH5 = 17, + TDM_OUT_ASRC_CH6 = 18, + TDM_OUT_ASRC_CH7 = 19 +}; + +struct mt8365_cm_ctrl_reg { + unsigned int con0; + unsigned int con1; + unsigned int con2; + unsigned int con3; + unsigned int con4; +}; + +struct mt8365_control_data { + bool bypass_cm1; + bool bypass_cm2; + unsigned int loopback_type; +}; + +enum dmic_input_mode { + DMIC_MODE_3P25M = 0, + DMIC_MODE_1P625M, + DMIC_MODE_812P5K, + DMIC_MODE_406P25K, +}; + +enum iir_mode { + IIR_MODE0 = 0, + IIR_MODE1, + IIR_MODE2, + IIR_MODE3, + IIR_MODE4, + IIR_MODE5, +}; + +enum { + MT8365_GASRC1 = 0, + MT8365_GASRC2, + MT8365_GASRC_NUM, + MT8365_TDM_ASRC1 = MT8365_GASRC_NUM, + MT8365_TDM_ASRC2, + MT8365_TDM_ASRC3, + MT8365_TDM_ASRC4, + MT8365_TDM_ASRC_NUM, +}; + +struct mt8365_gasrc_ctrl_reg { + unsigned int con0; + unsigned int con2; + unsigned int con3; + unsigned int con4; + unsigned int con5; + unsigned int con6; + unsigned int con9; + unsigned int con10; + unsigned int con12; + unsigned int con13; +}; + +struct mt8365_gasrc_data { + bool duplex; + bool tx_mode; + bool cali_on; + bool tdm_asrc_out_cm2; + bool iir_on; +}; + +#ifdef CONFIG_MTK_HIFIXDSP_SUPPORT +struct mt8365_adsp_data { + /* information adsp supply */ + bool adsp_on; + int (*hostless_active)(void); + /* information afe supply */ + int (*set_afe_memif)(struct mtk_base_afe *afe, + int memif_id, + unsigned int rate, + unsigned int channels, + snd_pcm_format_t format); + int (*set_afe_memif_enable)(struct mtk_base_afe *afe, + int memif_id, + unsigned int rate, + unsigned int period_size, + int enable); + void (*get_afe_memif_sram)(struct mtk_base_afe *afe, + int memif_id, + unsigned int *paddr, + unsigned int *size); + void (*set_afe_init)(struct mtk_base_afe *afe); + void (*set_afe_uninit)(struct mtk_base_afe *afe); +}; +#endif + +struct mt8365_afe_private { + struct clk *clocks[MT8365_CLK_NUM]; + struct regmap *topckgen; + struct mt8365_fe_dai_data fe_data[MT8365_AFE_MEMIF_NUM]; + struct mt8365_be_dai_data be_data[MT8365_AFE_BACKEND_NUM]; + struct mt8365_control_data ctrl_data; + struct mt8365_gasrc_data gasrc_data[MT8365_TDM_ASRC_NUM]; +#ifdef CONFIG_MTK_HIFIXDSP_SUPPORT + struct mt8365_adsp_data adsp_data; +#endif + int afe_on_ref_cnt; + int top_cg_ref_cnt[MT8365_TOP_CG_NUM]; + void __iomem *afe_sram_vir_addr; + unsigned int afe_sram_phy_addr; + unsigned int afe_sram_size; + /* locks */ + spinlock_t afe_ctrl_lock; + struct mutex afe_clk_mutex; /* Protect & sync APLL TUNER registers access*/ +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_dentry[MT8365_AFE_DEBUGFS_NUM]; +#endif + int apll_tuner_ref_cnt[MT8365_AFE_APLL_NUM]; + unsigned int tdm_out_mode; + unsigned int cm2_mux_input; + + /* dai */ + bool dai_on[MT8365_AFE_BACKEND_END]; + void *dai_priv[MT8365_AFE_BACKEND_END]; +}; + +static inline u32 rx_frequency_palette(unsigned int fs) +{ + /* * + * A = (26M / fs) * 64 + * B = 8125 / A + * return = DEC2HEX(B * 2^23) + */ + switch (fs) { + case FS_8000HZ: return 0x050000; + case FS_11025HZ: return 0x06E400; + case FS_12000HZ: return 0x078000; + case FS_16000HZ: return 0x0A0000; + case FS_22050HZ: return 0x0DC800; + case FS_24000HZ: return 0x0F0000; + case FS_32000HZ: return 0x140000; + case FS_44100HZ: return 0x1B9000; + case FS_48000HZ: return 0x1E0000; + case FS_88200HZ: return 0x372000; + case FS_96000HZ: return 0x3C0000; + case FS_176400HZ: return 0x6E4000; + case FS_192000HZ: return 0x780000; + default: return 0x0; + } +} + +static inline u32 AutoRstThHi(unsigned int fs) +{ + switch (fs) { + case FS_8000HZ: return 0x36000; + case FS_11025HZ: return 0x27000; + case FS_12000HZ: return 0x24000; + case FS_16000HZ: return 0x1B000; + case FS_22050HZ: return 0x14000; + case FS_24000HZ: return 0x12000; + case FS_32000HZ: return 0x0D800; + case FS_44100HZ: return 0x09D00; + case FS_48000HZ: return 0x08E00; + case FS_88200HZ: return 0x04E00; + case FS_96000HZ: return 0x04800; + case FS_176400HZ: return 0x02700; + case FS_192000HZ: return 0x02400; + default: return 0x0; + } +} + +static inline u32 AutoRstThLo(unsigned int fs) +{ + switch (fs) { + case FS_8000HZ: return 0x30000; + case FS_11025HZ: return 0x23000; + case FS_12000HZ: return 0x20000; + case FS_16000HZ: return 0x18000; + case FS_22050HZ: return 0x11000; + case FS_24000HZ: return 0x0FE00; + case FS_32000HZ: return 0x0BE00; + case FS_44100HZ: return 0x08A00; + case FS_48000HZ: return 0x07F00; + case FS_88200HZ: return 0x04500; + case FS_96000HZ: return 0x04000; + case FS_176400HZ: return 0x02300; + case FS_192000HZ: return 0x02000; + default: return 0x0; + } +} + +bool mt8365_afe_clk_group_48k(int sample_rate); +bool mt8365_afe_rate_supported(unsigned int rate, unsigned int id); +bool mt8365_afe_channel_supported(unsigned int channel, unsigned int id); +#ifdef CONFIG_MTK_HIFIXDSP_SUPPORT +struct mtk_base_afe *mt8365_afe_pcm_get_info(void); +#endif + +int mt8365_dai_i2s_register(struct mtk_base_afe *afe); +int mt8365_dai_set_priv(struct mtk_base_afe *afe, + int id, + int priv_size, + const void *priv_data); + +int mt8365_afe_fs_timing(unsigned int rate); + +void mt8365_afe_set_i2s_out_enable(struct mtk_base_afe *afe, bool enable); +int mt8365_afe_set_i2s_out(struct mtk_base_afe *afe, unsigned int rate, int bit_width); + +int mt8365_dai_adda_register(struct mtk_base_afe *afe); +int mt8365_dai_enable_adda_on(struct mtk_base_afe *afe); +int mt8365_dai_disable_adda_on(struct mtk_base_afe *afe); + +int mt8365_dai_dmic_register(struct mtk_base_afe *afe); + +int mt8365_dai_pcm_register(struct mtk_base_afe *afe); + +int mt8365_dai_tdm_register(struct mtk_base_afe *afe); + +#endif diff --git a/sound/soc/mediatek/mt8365/mt8365-reg.h b/sound/soc/mediatek/mt8365/mt8365-reg.h new file mode 100644 index 000000000000..f79ae78b5c1e --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-reg.h @@ -0,0 +1,991 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Mediatek 8365 audio driver reg definition + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Jia Zeng + * Alexandre Mergnat + */ + +#ifndef _MT8365_REG_H_ +#define _MT8365_REG_H_ + +#define AUDIO_TOP_CON0 (0x0000) +#define AUDIO_TOP_CON1 (0x0004) +#define AUDIO_TOP_CON2 (0x0008) +#define AUDIO_TOP_CON3 (0x000c) + +#define AFE_DAC_CON0 (0x0010) +#define AFE_DAC_CON1 (0x0014) +#define AFE_I2S_CON (0x0018) +#define AFE_CONN0 (0x0020) +#define AFE_CONN1 (0x0024) +#define AFE_CONN2 (0x0028) +#define AFE_CONN3 (0x002c) +#define AFE_CONN4 (0x0030) +#define AFE_I2S_CON1 (0x0034) +#define AFE_I2S_CON2 (0x0038) +#define AFE_MRGIF_CON (0x003c) +#define AFE_DL1_BASE (0x0040) +#define AFE_DL1_CUR (0x0044) +#define AFE_DL1_END (0x0048) +#define AFE_I2S_CON3 (0x004c) +#define AFE_DL2_BASE (0x0050) +#define AFE_DL2_CUR (0x0054) +#define AFE_DL2_END (0x0058) +#define AFE_CONN5 (0x005c) +#define AFE_AWB_BASE (0x0070) +#define AFE_AWB_END (0x0078) +#define AFE_AWB_CUR (0x007c) +#define AFE_VUL_BASE (0x0080) +#define AFE_VUL_END (0x0088) +#define AFE_VUL_CUR (0x008c) +#define AFE_CONN6 (0x00bc) +#define AFE_MEMIF_MSB (0x00cc) +#define AFE_MEMIF_MON0 (0x00d0) +#define AFE_MEMIF_MON1 (0x00d4) +#define AFE_MEMIF_MON2 (0x00d8) +#define AFE_MEMIF_MON3 (0x00dc) +#define AFE_MEMIF_MON4 (0x00e0) +#define AFE_MEMIF_MON5 (0x00e4) +#define AFE_MEMIF_MON6 (0x00e8) +#define AFE_MEMIF_MON7 (0x00ec) +#define AFE_MEMIF_MON8 (0x00f0) +#define AFE_MEMIF_MON9 (0x00f4) +#define AFE_MEMIF_MON10 (0x00f8) +#define AFE_MEMIF_MON11 (0x00fc) +#define AFE_ADDA_DL_SRC2_CON0 (0x0108) +#define AFE_ADDA_DL_SRC2_CON1 (0x010c) +#define AFE_ADDA_UL_SRC_CON0 (0x0114) +#define AFE_ADDA_UL_SRC_CON1 (0x0118) +#define AFE_ADDA_TOP_CON0 (0x0120) +#define AFE_ADDA_UL_DL_CON0 (0x0124) +#define AFE_ADDA_SRC_DEBUG (0x012c) +#define AFE_ADDA_SRC_DEBUG_MON0 (0x0130) +#define AFE_ADDA_SRC_DEBUG_MON1 (0x0134) +#define AFE_ADDA_UL_SRC_MON0 (0x0148) +#define AFE_ADDA_UL_SRC_MON1 (0x014c) +#define AFE_SRAM_BOUND (0x0170) +#define AFE_SECURE_CON (0x0174) +#define AFE_SECURE_CONN0 (0x0178) +#define AFE_SIDETONE_DEBUG (0x01d0) +#define AFE_SIDETONE_MON (0x01d4) +#define AFE_SIDETONE_CON0 (0x01e0) +#define AFE_SIDETONE_COEFF (0x01e4) +#define AFE_SIDETONE_CON1 (0x01e8) +#define AFE_SIDETONE_GAIN (0x01ec) +#define AFE_SGEN_CON0 (0x01f0) +#define AFE_SINEGEN_CON_TDM (0x01f8) +#define AFE_SINEGEN_CON_TDM_IN (0x01fc) +#define AFE_TOP_CON0 (0x0200) +#define AFE_BUS_CFG (0x0240) +#define AFE_BUS_MON0 (0x0244) +#define AFE_ADDA_PREDIS_CON0 (0x0260) +#define AFE_ADDA_PREDIS_CON1 (0x0264) +#define AFE_CONN_MON0 (0x0280) +#define AFE_CONN_MON1 (0x0284) +#define AFE_CONN_MON2 (0x0288) +#define AFE_CONN_MON3 (0x028c) +#define AFE_ADDA_IIR_COEF_02_01 (0x0290) +#define AFE_ADDA_IIR_COEF_04_03 (0x0294) +#define AFE_ADDA_IIR_COEF_06_05 (0x0298) +#define AFE_ADDA_IIR_COEF_08_07 (0x029c) +#define AFE_ADDA_IIR_COEF_10_09 (0x02a0) +#define AFE_VUL_D2_BASE (0x0350) +#define AFE_VUL_D2_END (0x0358) +#define AFE_VUL_D2_CUR (0x035c) +#define AFE_HDMI_OUT_CON0 (0x0370) +#define AFE_HDMI_OUT_BASE (0x0374) +#define AFE_HDMI_OUT_CUR (0x0378) +#define AFE_HDMI_OUT_END (0x037c) +#define AFE_SPDIF_OUT_CON0 (0x0380) +#define AFE_SPDIF_OUT_BASE (0x0384) +#define AFE_SPDIF_OUT_CUR (0x0388) +#define AFE_SPDIF_OUT_END (0x038c) +#define AFE_HDMI_CONN0 (0x0390) +#define AFE_HDMI_CONN1 (0x0398) +#define AFE_CONN_TDMIN_CON (0x039c) +#define AFE_IRQ_MCU_CON (0x03a0) +#define AFE_IRQ_MCU_STATUS (0x03a4) +#define AFE_IRQ_MCU_CLR (0x03a8) +#define AFE_IRQ_MCU_CNT1 (0x03ac) +#define AFE_IRQ_MCU_CNT2 (0x03b0) +#define AFE_IRQ_MCU_EN (0x03b4) +#define AFE_IRQ_MCU_MON2 (0x03b8) +#define AFE_IRQ_MCU_CNT5 (0x03bc) +#define AFE_IRQ1_MCU_CNT_MON (0x03c0) +#define AFE_IRQ2_MCU_CNT_MON (0x03c4) +#define AFE_IRQ1_MCU_EN_CNT_MON (0x03c8) +#define AFE_IRQ5_MCU_CNT_MON (0x03cc) +#define AFE_MEMIF_MINLEN (0x03d0) +#define AFE_MEMIF_MAXLEN (0x03d4) +#define AFE_MEMIF_PBUF_SIZE (0x03d8) +#define AFE_IRQ_MCU_CNT7 (0x03dc) +#define AFE_IRQ7_MCU_CNT_MON (0x03e0) +#define AFE_MEMIF_PBUF2_SIZE (0x03ec) +#define AFE_APLL_TUNER_CFG (0x03f0) +#define AFE_APLL_TUNER_CFG1 (0x03f4) +#define AFE_IRQ_MCU_CON2 (0x03f8) +#define IRQ13_MCU_CNT (0x0408) +#define IRQ13_MCU_CNT_MON (0x040c) +#define AFE_GAIN1_CON0 (0x0410) +#define AFE_GAIN1_CON1 (0x0414) +#define AFE_GAIN1_CON2 (0x0418) +#define AFE_GAIN1_CON3 (0x041c) +#define AFE_GAIN2_CON0 (0x0428) +#define AFE_GAIN2_CON1 (0x042c) +#define AFE_GAIN2_CON2 (0x0430) +#define AFE_GAIN2_CON3 (0x0434) +#define AFE_GAIN2_CUR (0x043c) +#define AFE_CONN11 (0x0448) +#define AFE_CONN12 (0x044c) +#define AFE_CONN13 (0x0450) +#define AFE_CONN14 (0x0454) +#define AFE_CONN15 (0x0458) +#define AFE_CONN16 (0x045c) +#define AFE_CONN7 (0x0460) +#define AFE_CONN8 (0x0464) +#define AFE_CONN9 (0x0468) +#define AFE_CONN10 (0x046c) +#define AFE_CONN21 (0x0470) +#define AFE_CONN22 (0x0474) +#define AFE_CONN23 (0x0478) +#define AFE_CONN24 (0x047c) +#define AFE_IEC_CFG (0x0480) +#define AFE_IEC_NSNUM (0x0484) +#define AFE_IEC_BURST_INFO (0x0488) +#define AFE_IEC_BURST_LEN (0x048c) +#define AFE_IEC_NSADR (0x0490) +#define AFE_CONN_RS (0x0494) +#define AFE_CONN_DI (0x0498) +#define AFE_IEC_CHL_STAT0 (0x04a0) +#define AFE_IEC_CHL_STAT1 (0x04a4) +#define AFE_IEC_CHR_STAT0 (0x04a8) +#define AFE_IEC_CHR_STAT1 (0x04ac) +#define AFE_CONN25 (0x04b0) +#define AFE_CONN26 (0x04b4) +#define FPGA_CFG2 (0x04b8) +#define FPGA_CFG3 (0x04bc) +#define FPGA_CFG0 (0x04c0) +#define FPGA_CFG1 (0x04c4) +#define AFE_SRAM_DELSEL_CON0 (0x04f0) +#define AFE_SRAM_DELSEL_CON1 (0x04f4) +#define AFE_SRAM_DELSEL_CON2 (0x04f8) +#define FPGA_CFG4 (0x04fc) +#define AFE_TDM_GASRC4_ASRC_2CH_CON0 (0x0500) +#define AFE_TDM_GASRC4_ASRC_2CH_CON1 (0x0504) +#define AFE_TDM_GASRC4_ASRC_2CH_CON2 (0x0508) +#define AFE_TDM_GASRC4_ASRC_2CH_CON3 (0x050c) +#define AFE_TDM_GASRC4_ASRC_2CH_CON4 (0x0510) +#define AFE_TDM_GASRC4_ASRC_2CH_CON5 (0x0514) +#define AFE_TDM_GASRC4_ASRC_2CH_CON6 (0x0518) +#define AFE_TDM_GASRC4_ASRC_2CH_CON7 (0x051c) +#define AFE_TDM_GASRC4_ASRC_2CH_CON8 (0x0520) +#define AFE_TDM_GASRC4_ASRC_2CH_CON9 (0x0524) +#define AFE_TDM_GASRC4_ASRC_2CH_CON10 (0x0528) +#define AFE_TDM_GASRC4_ASRC_2CH_CON12 (0x0530) +#define AFE_TDM_GASRC4_ASRC_2CH_CON13 (0x0534) +#define PCM_INTF_CON2 (0x0538) +#define PCM2_INTF_CON (0x053c) +#define AFE_APB_MON (0x0540) +#define AFE_CONN34 (0x0544) +#define AFE_TDM_CON1 (0x0548) +#define AFE_TDM_CON2 (0x054c) +#define PCM_INTF_CON1 (0x0550) +#define AFE_SECURE_MASK_CONN47_1 (0x0554) +#define AFE_SECURE_MASK_CONN48_1 (0x0558) +#define AFE_SECURE_MASK_CONN49_1 (0x055c) +#define AFE_SECURE_MASK_CONN50_1 (0x0560) +#define AFE_SECURE_MASK_CONN51_1 (0x0564) +#define AFE_SECURE_MASK_CONN52_1 (0x0568) +#define AFE_SECURE_MASK_CONN53_1 (0x056c) +#define AFE_SE_SECURE_CON (0x0570) +#define AFE_TDM_IN_CON1 (0x0588) +#define AFE_TDM_IN_CON2 (0x058c) +#define AFE_TDM_IN_MON1 (0x0590) +#define AFE_TDM_IN_MON2 (0x0594) +#define AFE_TDM_IN_MON3 (0x0598) +#define AFE_DMIC0_UL_SRC_CON0 (0x05b4) +#define AFE_DMIC0_UL_SRC_CON1 (0x05b8) +#define AFE_DMIC0_SRC_DEBUG (0x05bc) +#define AFE_DMIC0_SRC_DEBUG_MON0 (0x05c0) +#define AFE_DMIC0_UL_SRC_MON0 (0x05c8) +#define AFE_DMIC0_UL_SRC_MON1 (0x05cc) +#define AFE_DMIC0_IIR_COEF_02_01 (0x05d0) +#define AFE_DMIC0_IIR_COEF_04_03 (0x05d4) +#define AFE_DMIC0_IIR_COEF_06_05 (0x05d8) +#define AFE_DMIC0_IIR_COEF_08_07 (0x05dc) +#define AFE_DMIC0_IIR_COEF_10_09 (0x05e0) +#define AFE_DMIC1_UL_SRC_CON0 (0x0620) +#define AFE_DMIC1_UL_SRC_CON1 (0x0624) +#define AFE_DMIC1_SRC_DEBUG (0x0628) +#define AFE_DMIC1_SRC_DEBUG_MON0 (0x062c) +#define AFE_DMIC1_UL_SRC_MON0 (0x0634) +#define AFE_DMIC1_UL_SRC_MON1 (0x0638) +#define AFE_DMIC1_IIR_COEF_02_01 (0x063c) +#define AFE_DMIC1_IIR_COEF_04_03 (0x0640) +#define AFE_DMIC1_IIR_COEF_06_05 (0x0644) +#define AFE_DMIC1_IIR_COEF_08_07 (0x0648) +#define AFE_DMIC1_IIR_COEF_10_09 (0x064c) +#define AFE_SECURE_MASK_CONN39_1 (0x068c) +#define AFE_SECURE_MASK_CONN40_1 (0x0690) +#define AFE_SECURE_MASK_CONN41_1 (0x0694) +#define AFE_SECURE_MASK_CONN42_1 (0x0698) +#define AFE_SECURE_MASK_CONN43_1 (0x069c) +#define AFE_SECURE_MASK_CONN44_1 (0x06a0) +#define AFE_SECURE_MASK_CONN45_1 (0x06a4) +#define AFE_SECURE_MASK_CONN46_1 (0x06a8) +#define AFE_TDM_GASRC1_ASRC_2CH_CON0 (0x06c0) +#define AFE_TDM_GASRC1_ASRC_2CH_CON1 (0x06c4) +#define AFE_TDM_GASRC1_ASRC_2CH_CON2 (0x06c8) +#define AFE_TDM_GASRC1_ASRC_2CH_CON3 (0x06cc) +#define AFE_TDM_GASRC1_ASRC_2CH_CON4 (0x06d0) +#define AFE_TDM_GASRC1_ASRC_2CH_CON5 (0x06d4) +#define AFE_TDM_GASRC1_ASRC_2CH_CON6 (0x06d8) +#define AFE_TDM_GASRC1_ASRC_2CH_CON7 (0x06dc) +#define AFE_TDM_GASRC1_ASRC_2CH_CON8 (0x06e0) +#define AFE_TDM_GASRC1_ASRC_2CH_CON9 (0x06e4) +#define AFE_TDM_GASRC1_ASRC_2CH_CON10 (0x06e8) +#define AFE_TDM_GASRC1_ASRC_2CH_CON12 (0x06f0) +#define AFE_TDM_GASRC1_ASRC_2CH_CON13 (0x06f4) +#define AFE_TDM_ASRC_CON0 (0x06f8) +#define AFE_TDM_GASRC2_ASRC_2CH_CON0 (0x0700) +#define AFE_TDM_GASRC2_ASRC_2CH_CON1 (0x0704) +#define AFE_TDM_GASRC2_ASRC_2CH_CON2 (0x0708) +#define AFE_TDM_GASRC2_ASRC_2CH_CON3 (0x070c) +#define AFE_TDM_GASRC2_ASRC_2CH_CON4 (0x0710) +#define AFE_TDM_GASRC2_ASRC_2CH_CON5 (0x0714) +#define AFE_TDM_GASRC2_ASRC_2CH_CON6 (0x0718) +#define AFE_TDM_GASRC2_ASRC_2CH_CON7 (0x071c) +#define AFE_TDM_GASRC2_ASRC_2CH_CON8 (0x0720) +#define AFE_TDM_GASRC2_ASRC_2CH_CON9 (0x0724) +#define AFE_TDM_GASRC2_ASRC_2CH_CON10 (0x0728) +#define AFE_TDM_GASRC2_ASRC_2CH_CON12 (0x0730) +#define AFE_TDM_GASRC2_ASRC_2CH_CON13 (0x0734) +#define AFE_TDM_GASRC3_ASRC_2CH_CON0 (0x0740) +#define AFE_TDM_GASRC3_ASRC_2CH_CON1 (0x0744) +#define AFE_TDM_GASRC3_ASRC_2CH_CON2 (0x0748) +#define AFE_TDM_GASRC3_ASRC_2CH_CON3 (0x074c) +#define AFE_TDM_GASRC3_ASRC_2CH_CON4 (0x0750) +#define AFE_TDM_GASRC3_ASRC_2CH_CON5 (0x0754) +#define AFE_TDM_GASRC3_ASRC_2CH_CON6 (0x0758) +#define AFE_TDM_GASRC3_ASRC_2CH_CON7 (0x075c) +#define AFE_TDM_GASRC3_ASRC_2CH_CON8 (0x0760) +#define AFE_TDM_GASRC3_ASRC_2CH_CON9 (0x0764) +#define AFE_TDM_GASRC3_ASRC_2CH_CON10 (0x0768) +#define AFE_TDM_GASRC3_ASRC_2CH_CON12 (0x0770) +#define AFE_TDM_GASRC3_ASRC_2CH_CON13 (0x0774) +#define AFE_DMIC2_UL_SRC_CON0 (0x0780) +#define AFE_DMIC2_UL_SRC_CON1 (0x0784) +#define AFE_DMIC2_SRC_DEBUG (0x0788) +#define AFE_DMIC2_SRC_DEBUG_MON0 (0x078c) +#define AFE_DMIC2_UL_SRC_MON0 (0x0794) +#define AFE_DMIC2_UL_SRC_MON1 (0x0798) +#define AFE_DMIC2_IIR_COEF_02_01 (0x079c) +#define AFE_DMIC2_IIR_COEF_04_03 (0x07a0) +#define AFE_DMIC2_IIR_COEF_06_05 (0x07a4) +#define AFE_DMIC2_IIR_COEF_08_07 (0x07a8) +#define AFE_DMIC2_IIR_COEF_10_09 (0x07ac) +#define AFE_DMIC3_UL_SRC_CON0 (0x07ec) +#define AFE_DMIC3_UL_SRC_CON1 (0x07f0) +#define AFE_DMIC3_SRC_DEBUG (0x07f4) +#define AFE_DMIC3_SRC_DEBUG_MON0 (0x07f8) +#define AFE_DMIC3_UL_SRC_MON0 (0x0800) +#define AFE_DMIC3_UL_SRC_MON1 (0x0804) +#define AFE_DMIC3_IIR_COEF_02_01 (0x0808) +#define AFE_DMIC3_IIR_COEF_04_03 (0x080c) +#define AFE_DMIC3_IIR_COEF_06_05 (0x0810) +#define AFE_DMIC3_IIR_COEF_08_07 (0x0814) +#define AFE_DMIC3_IIR_COEF_10_09 (0x0818) +#define AFE_SECURE_MASK_CONN25_1 (0x0858) +#define AFE_SECURE_MASK_CONN26_1 (0x085c) +#define AFE_SECURE_MASK_CONN27_1 (0x0860) +#define AFE_SECURE_MASK_CONN28_1 (0x0864) +#define AFE_SECURE_MASK_CONN29_1 (0x0868) +#define AFE_SECURE_MASK_CONN30_1 (0x086c) +#define AFE_SECURE_MASK_CONN31_1 (0x0870) +#define AFE_SECURE_MASK_CONN32_1 (0x0874) +#define AFE_SECURE_MASK_CONN33_1 (0x0878) +#define AFE_SECURE_MASK_CONN34_1 (0x087c) +#define AFE_SECURE_MASK_CONN35_1 (0x0880) +#define AFE_SECURE_MASK_CONN36_1 (0x0884) +#define AFE_SECURE_MASK_CONN37_1 (0x0888) +#define AFE_SECURE_MASK_CONN38_1 (0x088c) +#define AFE_IRQ_MCU_SCP_EN (0x0890) +#define AFE_IRQ_MCU_DSP_EN (0x0894) +#define AFE_IRQ3_MCU_CNT_MON (0x0898) +#define AFE_IRQ4_MCU_CNT_MON (0x089c) +#define AFE_IRQ8_MCU_CNT_MON (0x08a0) +#define AFE_IRQ_MCU_CNT3 (0x08a4) +#define AFE_IRQ_MCU_CNT4 (0x08a8) +#define AFE_IRQ_MCU_CNT8 (0x08ac) +#define AFE_IRQ_MCU_CNT11 (0x08b0) +#define AFE_IRQ_MCU_CNT12 (0x08b4) +#define AFE_IRQ11_MCU_CNT_MON (0x08b8) +#define AFE_IRQ12_MCU_CNT_MON (0x08bc) +#define AFE_VUL3_BASE (0x08c0) +#define AFE_VUL3_CUR (0x08c4) +#define AFE_VUL3_END (0x08c8) +#define AFE_VUL3_BASE_MSB (0x08d0) +#define AFE_VUL3_END_MSB (0x08d4) +#define AFE_IRQ10_MCU_CNT_MON (0x08d8) +#define AFE_IRQ_MCU_CNT10 (0x08dc) +#define AFE_IRQ_ACC1_CNT (0x08e0) +#define AFE_IRQ_ACC2_CNT (0x08e4) +#define AFE_IRQ_ACC1_CNT_MON1 (0x08e8) +#define AFE_IRQ_ACC2_CNT_MON (0x08ec) +#define AFE_TSF_CON (0x08f0) +#define AFE_TSF_MON (0x08f4) +#define AFE_IRQ_ACC1_CNT_MON2 (0x08f8) +#define AFE_SPDIFIN_CFG0 (0x0900) +#define AFE_SPDIFIN_CFG1 (0x0904) +#define AFE_SPDIFIN_CHSTS1 (0x0908) +#define AFE_SPDIFIN_CHSTS2 (0x090c) +#define AFE_SPDIFIN_CHSTS3 (0x0910) +#define AFE_SPDIFIN_CHSTS4 (0x0914) +#define AFE_SPDIFIN_CHSTS5 (0x0918) +#define AFE_SPDIFIN_CHSTS6 (0x091c) +#define AFE_SPDIFIN_DEBUG1 (0x0920) +#define AFE_SPDIFIN_DEBUG2 (0x0924) +#define AFE_SPDIFIN_DEBUG3 (0x0928) +#define AFE_SPDIFIN_DEBUG4 (0x092c) +#define AFE_SPDIFIN_EC (0x0930) +#define AFE_SPDIFIN_CKLOCK_CFG (0x0934) +#define AFE_SPDIFIN_BR (0x093c) +#define AFE_SPDIFIN_BR_DBG1 (0x0940) +#define AFE_SPDIFIN_INT_EXT (0x0948) +#define AFE_SPDIFIN_INT_EXT2 (0x094c) +#define SPDIFIN_FREQ_INFO (0x0950) +#define SPDIFIN_FREQ_INFO_2 (0x0954) +#define SPDIFIN_FREQ_INFO_3 (0x0958) +#define SPDIFIN_FREQ_STATUS (0x095c) +#define SPDIFIN_USERCODE1 (0x0960) +#define SPDIFIN_USERCODE2 (0x0964) +#define SPDIFIN_USERCODE3 (0x0968) +#define SPDIFIN_USERCODE4 (0x096c) +#define SPDIFIN_USERCODE5 (0x0970) +#define SPDIFIN_USERCODE6 (0x0974) +#define SPDIFIN_USERCODE7 (0x0978) +#define SPDIFIN_USERCODE8 (0x097c) +#define SPDIFIN_USERCODE9 (0x0980) +#define SPDIFIN_USERCODE10 (0x0984) +#define SPDIFIN_USERCODE11 (0x0988) +#define SPDIFIN_USERCODE12 (0x098c) +#define SPDIFIN_MEMIF_CON0 (0x0990) +#define SPDIFIN_BASE_ADR (0x0994) +#define SPDIFIN_END_ADR (0x0998) +#define SPDIFIN_APLL_TUNER_CFG (0x09a0) +#define SPDIFIN_APLL_TUNER_CFG1 (0x09a4) +#define SPDIFIN_APLL2_TUNER_CFG (0x09a8) +#define SPDIFIN_APLL2_TUNER_CFG1 (0x09ac) +#define SPDIFIN_TYPE_DET (0x09b0) +#define MPHONE_MULTI_CON0 (0x09b4) +#define SPDIFIN_CUR_ADR (0x09b8) +#define AFE_SINEGEN_CON_SPDIFIN (0x09bc) +#define AFE_HDMI_IN_2CH_CON0 (0x09c0) +#define AFE_HDMI_IN_2CH_BASE (0x09c4) +#define AFE_HDMI_IN_2CH_END (0x09c8) +#define AFE_HDMI_IN_2CH_CUR (0x09cc) +#define AFE_MEMIF_BUF_MON0 (0x09d0) +#define AFE_MEMIF_BUF_MON1 (0x09d4) +#define AFE_MEMIF_BUF_MON2 (0x09d8) +#define AFE_MEMIF_BUF_MON3 (0x09dc) +#define AFE_MEMIF_BUF_MON6 (0x09e8) +#define AFE_MEMIF_BUF_MON7 (0x09ec) +#define AFE_MEMIF_BUF_MON8 (0x09f0) +#define AFE_MEMIF_BUF_MON10 (0x09f8) +#define AFE_MEMIF_BUF_MON11 (0x09fc) +#define SYSTOP_STC_CONFIG (0x0a00) +#define AUDIO_STC_STATUS (0x0a04) +#define SYSTOP_W_STC_H (0x0a08) +#define SYSTOP_W_STC_L (0x0a0c) +#define SYSTOP_R_STC_H (0x0a10) +#define SYSTOP_R_STC_L (0x0a14) +#define AUDIO_W_STC_H (0x0a18) +#define AUDIO_W_STC_L (0x0a1c) +#define AUDIO_R_STC_H (0x0a20) +#define AUDIO_R_STC_L (0x0a24) +#define SYSTOP_W_STC2_H (0x0a28) +#define SYSTOP_W_STC2_L (0x0a2c) +#define SYSTOP_R_STC2_H (0x0a30) +#define SYSTOP_R_STC2_L (0x0a34) +#define AUDIO_W_STC2_H (0x0a38) +#define AUDIO_W_STC2_L (0x0a3c) +#define AUDIO_R_STC2_H (0x0a40) +#define AUDIO_R_STC2_L (0x0a44) + +#define AFE_CONN17 (0x0a48) +#define AFE_CONN18 (0x0a4c) +#define AFE_CONN19 (0x0a50) +#define AFE_CONN20 (0x0a54) +#define AFE_CONN27 (0x0a58) +#define AFE_CONN28 (0x0a5c) +#define AFE_CONN29 (0x0a60) +#define AFE_CONN30 (0x0a64) +#define AFE_CONN31 (0x0a68) +#define AFE_CONN32 (0x0a6c) +#define AFE_CONN33 (0x0a70) +#define AFE_CONN35 (0x0a74) +#define AFE_CONN36 (0x0a78) +#define AFE_CONN37 (0x0a7c) +#define AFE_CONN38 (0x0a80) +#define AFE_CONN39 (0x0a84) +#define AFE_CONN40 (0x0a88) +#define AFE_CONN41 (0x0a8c) +#define AFE_CONN42 (0x0a90) +#define AFE_CONN44 (0x0a94) +#define AFE_CONN45 (0x0a98) +#define AFE_CONN46 (0x0a9c) +#define AFE_CONN47 (0x0aa0) +#define AFE_CONN_24BIT (0x0aa4) +#define AFE_CONN0_1 (0x0aa8) +#define AFE_CONN1_1 (0x0aac) +#define AFE_CONN2_1 (0x0ab0) +#define AFE_CONN3_1 (0x0ab4) +#define AFE_CONN4_1 (0x0ab8) +#define AFE_CONN5_1 (0x0abc) +#define AFE_CONN6_1 (0x0ac0) +#define AFE_CONN7_1 (0x0ac4) +#define AFE_CONN8_1 (0x0ac8) +#define AFE_CONN9_1 (0x0acc) +#define AFE_CONN10_1 (0x0ad0) +#define AFE_CONN11_1 (0x0ad4) +#define AFE_CONN12_1 (0x0ad8) +#define AFE_CONN13_1 (0x0adc) +#define AFE_CONN14_1 (0x0ae0) +#define AFE_CONN15_1 (0x0ae4) +#define AFE_CONN16_1 (0x0ae8) +#define AFE_CONN17_1 (0x0aec) +#define AFE_CONN18_1 (0x0af0) +#define AFE_CONN19_1 (0x0af4) +#define AFE_CONN43 (0x0af8) +#define AFE_CONN43_1 (0x0afc) +#define AFE_CONN21_1 (0x0b00) +#define AFE_CONN22_1 (0x0b04) +#define AFE_CONN23_1 (0x0b08) +#define AFE_CONN24_1 (0x0b0c) +#define AFE_CONN25_1 (0x0b10) +#define AFE_CONN26_1 (0x0b14) +#define AFE_CONN27_1 (0x0b18) +#define AFE_CONN28_1 (0x0b1c) +#define AFE_CONN29_1 (0x0b20) +#define AFE_CONN30_1 (0x0b24) +#define AFE_CONN31_1 (0x0b28) +#define AFE_CONN32_1 (0x0b2c) +#define AFE_CONN33_1 (0x0b30) +#define AFE_CONN34_1 (0x0b34) +#define AFE_CONN35_1 (0x0b38) +#define AFE_CONN36_1 (0x0b3c) +#define AFE_CONN37_1 (0x0b40) +#define AFE_CONN38_1 (0x0b44) +#define AFE_CONN39_1 (0x0b48) +#define AFE_CONN40_1 (0x0b4c) +#define AFE_CONN41_1 (0x0b50) +#define AFE_CONN42_1 (0x0b54) +#define AFE_CONN44_1 (0x0b58) +#define AFE_CONN45_1 (0x0b5c) +#define AFE_CONN46_1 (0x0b60) +#define AFE_CONN47_1 (0x0b64) +#define AFE_CONN_RS_1 (0x0b68) +#define AFE_CONN_DI_1 (0x0b6c) +#define AFE_CONN_24BIT_1 (0x0b70) +#define AFE_GAIN1_CUR (0x0b78) +#define AFE_CONN20_1 (0x0b7c) +#define AFE_DL1_BASE_MSB (0x0b80) +#define AFE_DL1_END_MSB (0x0b84) +#define AFE_DL2_BASE_MSB (0x0b88) +#define AFE_DL2_END_MSB (0x0b8c) +#define AFE_AWB_BASE_MSB (0x0b90) +#define AFE_AWB_END_MSB (0x0b94) +#define AFE_VUL_BASE_MSB (0x0ba0) +#define AFE_VUL_END_MSB (0x0ba4) +#define AFE_VUL_D2_BASE_MSB (0x0ba8) +#define AFE_VUL_D2_END_MSB (0x0bac) +#define AFE_HDMI_OUT_BASE_MSB (0x0bb8) +#define AFE_HDMI_OUT_END_MSB (0x0bbc) +#define AFE_HDMI_IN_2CH_BASE_MSB (0x0bc0) +#define AFE_HDMI_IN_2CH_END_MSB (0x0bc4) +#define AFE_SPDIF_OUT_BASE_MSB (0x0bc8) +#define AFE_SPDIF_OUT_END_MSB (0x0bcc) +#define SPDIFIN_BASE_MSB (0x0bd0) +#define SPDIFIN_END_MSB (0x0bd4) +#define AFE_DL1_CUR_MSB (0x0bd8) +#define AFE_DL2_CUR_MSB (0x0bdc) +#define AFE_AWB_CUR_MSB (0x0be8) +#define AFE_VUL_CUR_MSB (0x0bf8) +#define AFE_VUL_D2_CUR_MSB (0x0c04) +#define AFE_HDMI_OUT_CUR_MSB (0x0c0c) +#define AFE_HDMI_IN_2CH_CUR_MSB (0x0c10) +#define AFE_SPDIF_OUT_CUR_MSB (0x0c14) +#define SPDIFIN_CUR_MSB (0x0c18) +#define AFE_CONN_REG (0x0c20) +#define AFE_SECURE_MASK_CONN14_1 (0x0c24) +#define AFE_SECURE_MASK_CONN15_1 (0x0c28) +#define AFE_SECURE_MASK_CONN16_1 (0x0c2c) +#define AFE_SECURE_MASK_CONN17_1 (0x0c30) +#define AFE_SECURE_MASK_CONN18_1 (0x0c34) +#define AFE_SECURE_MASK_CONN19_1 (0x0c38) +#define AFE_SECURE_MASK_CONN20_1 (0x0c3c) +#define AFE_SECURE_MASK_CONN21_1 (0x0c40) +#define AFE_SECURE_MASK_CONN22_1 (0x0c44) +#define AFE_SECURE_MASK_CONN23_1 (0x0c48) +#define AFE_SECURE_MASK_CONN24_1 (0x0c4c) +#define AFE_ADDA_DL_SDM_DCCOMP_CON (0x0c50) +#define AFE_ADDA_DL_SDM_TEST (0x0c54) +#define AFE_ADDA_DL_DC_COMP_CFG0 (0x0c58) +#define AFE_ADDA_DL_DC_COMP_CFG1 (0x0c5c) +#define AFE_ADDA_DL_SDM_FIFO_MON (0x0c60) +#define AFE_ADDA_DL_SRC_LCH_MON (0x0c64) +#define AFE_ADDA_DL_SRC_RCH_MON (0x0c68) +#define AFE_ADDA_DL_SDM_OUT_MON (0x0c6c) +#define AFE_ADDA_DL_SDM_DITHER_CON (0x0c70) + +#define AFE_VUL3_CUR_MSB (0x0c78) +#define AFE_ASRC_2CH_CON0 (0x0c80) +#define AFE_ASRC_2CH_CON1 (0x0c84) +#define AFE_ASRC_2CH_CON2 (0x0c88) +#define AFE_ASRC_2CH_CON3 (0x0c8c) +#define AFE_ASRC_2CH_CON4 (0x0c90) +#define AFE_ASRC_2CH_CON5 (0x0c94) +#define AFE_ASRC_2CH_CON6 (0x0c98) +#define AFE_ASRC_2CH_CON7 (0x0c9c) +#define AFE_ASRC_2CH_CON8 (0x0ca0) +#define AFE_ASRC_2CH_CON9 (0x0ca4) +#define AFE_ASRC_2CH_CON10 (0x0ca8) +#define AFE_ASRC_2CH_CON12 (0x0cb0) +#define AFE_ASRC_2CH_CON13 (0x0cb4) + +#define AFE_PCM_TX_ASRC_2CH_CON0 (0x0cc0) +#define AFE_PCM_TX_ASRC_2CH_CON1 (0x0cc4) +#define AFE_PCM_TX_ASRC_2CH_CON2 (0x0cc8) +#define AFE_PCM_TX_ASRC_2CH_CON3 (0x0ccc) +#define AFE_PCM_TX_ASRC_2CH_CON4 (0x0cd0) +#define AFE_PCM_TX_ASRC_2CH_CON5 (0x0cd4) +#define AFE_PCM_TX_ASRC_2CH_CON6 (0x0cd8) +#define AFE_PCM_TX_ASRC_2CH_CON7 (0x0cdc) +#define AFE_PCM_TX_ASRC_2CH_CON8 (0x0ce0) +#define AFE_PCM_TX_ASRC_2CH_CON9 (0x0ce4) +#define AFE_PCM_TX_ASRC_2CH_CON10 (0x0ce8) +#define AFE_PCM_TX_ASRC_2CH_CON12 (0x0cf0) +#define AFE_PCM_TX_ASRC_2CH_CON13 (0x0cf4) +#define AFE_PCM_RX_ASRC_2CH_CON0 (0x0d00) +#define AFE_PCM_RX_ASRC_2CH_CON1 (0x0d04) +#define AFE_PCM_RX_ASRC_2CH_CON2 (0x0d08) +#define AFE_PCM_RX_ASRC_2CH_CON3 (0x0d0c) +#define AFE_PCM_RX_ASRC_2CH_CON4 (0x0d10) +#define AFE_PCM_RX_ASRC_2CH_CON5 (0x0d14) +#define AFE_PCM_RX_ASRC_2CH_CON6 (0x0d18) +#define AFE_PCM_RX_ASRC_2CH_CON7 (0x0d1c) +#define AFE_PCM_RX_ASRC_2CH_CON8 (0x0d20) +#define AFE_PCM_RX_ASRC_2CH_CON9 (0x0d24) +#define AFE_PCM_RX_ASRC_2CH_CON10 (0x0d28) +#define AFE_PCM_RX_ASRC_2CH_CON12 (0x0d30) +#define AFE_PCM_RX_ASRC_2CH_CON13 (0x0d34) + +#define AFE_ADDA_PREDIS_CON2 (0x0d40) +#define AFE_ADDA_PREDIS_CON3 (0x0d44) +#define AFE_SECURE_MASK_CONN4_1 (0x0d48) +#define AFE_SECURE_MASK_CONN5_1 (0x0d4c) +#define AFE_SECURE_MASK_CONN6_1 (0x0d50) +#define AFE_SECURE_MASK_CONN7_1 (0x0d54) +#define AFE_SECURE_MASK_CONN8_1 (0x0d58) +#define AFE_SECURE_MASK_CONN9_1 (0x0d5c) +#define AFE_SECURE_MASK_CONN10_1 (0x0d60) +#define AFE_SECURE_MASK_CONN11_1 (0x0d64) +#define AFE_SECURE_MASK_CONN12_1 (0x0d68) +#define AFE_SECURE_MASK_CONN13_1 (0x0d6c) +#define AFE_MEMIF_MON12 (0x0d70) +#define AFE_MEMIF_MON13 (0x0d74) +#define AFE_MEMIF_MON14 (0x0d78) +#define AFE_MEMIF_MON15 (0x0d7c) +#define AFE_SECURE_MASK_CONN42 (0x0dbc) +#define AFE_SECURE_MASK_CONN43 (0x0dc0) +#define AFE_SECURE_MASK_CONN44 (0x0dc4) +#define AFE_SECURE_MASK_CONN45 (0x0dc8) +#define AFE_SECURE_MASK_CONN46 (0x0dcc) +#define AFE_HD_ENGEN_ENABLE (0x0dd0) +#define AFE_SECURE_MASK_CONN47 (0x0dd4) +#define AFE_SECURE_MASK_CONN48 (0x0dd8) +#define AFE_SECURE_MASK_CONN49 (0x0ddc) +#define AFE_SECURE_MASK_CONN50 (0x0de0) +#define AFE_SECURE_MASK_CONN51 (0x0de4) +#define AFE_SECURE_MASK_CONN52 (0x0de8) +#define AFE_SECURE_MASK_CONN53 (0x0dec) +#define AFE_SECURE_MASK_CONN0_1 (0x0df0) +#define AFE_SECURE_MASK_CONN1_1 (0x0df4) +#define AFE_SECURE_MASK_CONN2_1 (0x0df8) +#define AFE_SECURE_MASK_CONN3_1 (0x0dfc) + +#define AFE_ADDA_MTKAIF_CFG0 (0x0e00) +#define AFE_ADDA_MTKAIF_SYNCWORD_CFG (0x0e14) +#define AFE_ADDA_MTKAIF_RX_CFG0 (0x0e20) +#define AFE_ADDA_MTKAIF_RX_CFG1 (0x0e24) +#define AFE_ADDA_MTKAIF_RX_CFG2 (0x0e28) +#define AFE_ADDA_MTKAIF_MON0 (0x0e34) +#define AFE_ADDA_MTKAIF_MON1 (0x0e38) +#define AFE_AUD_PAD_TOP (0x0e40) + +#define AFE_CM1_CON4 (0x0e48) +#define AFE_CM2_CON4 (0x0e4c) +#define AFE_CM1_CON0 (0x0e50) +#define AFE_CM1_CON1 (0x0e54) +#define AFE_CM1_CON2 (0x0e58) +#define AFE_CM1_CON3 (0x0e5c) +#define AFE_CM2_CON0 (0x0e60) +#define AFE_CM2_CON1 (0x0e64) +#define AFE_CM2_CON2 (0x0e68) +#define AFE_CM2_CON3 (0x0e6c) +#define AFE_CM2_CONN0 (0x0e70) +#define AFE_CM2_CONN1 (0x0e74) +#define AFE_CM2_CONN2 (0x0e78) + +#define AFE_GENERAL1_ASRC_2CH_CON0 (0x0e80) +#define AFE_GENERAL1_ASRC_2CH_CON1 (0x0e84) +#define AFE_GENERAL1_ASRC_2CH_CON2 (0x0e88) +#define AFE_GENERAL1_ASRC_2CH_CON3 (0x0e8c) +#define AFE_GENERAL1_ASRC_2CH_CON4 (0x0e90) +#define AFE_GENERAL1_ASRC_2CH_CON5 (0x0e94) +#define AFE_GENERAL1_ASRC_2CH_CON6 (0x0e98) +#define AFE_GENERAL1_ASRC_2CH_CON7 (0x0e9c) +#define AFE_GENERAL1_ASRC_2CH_CON8 (0x0ea0) +#define AFE_GENERAL1_ASRC_2CH_CON9 (0x0ea4) +#define AFE_GENERAL1_ASRC_2CH_CON10 (0x0ea8) +#define AFE_GENERAL1_ASRC_2CH_CON12 (0x0eb0) +#define AFE_GENERAL1_ASRC_2CH_CON13 (0x0eb4) +#define GENERAL_ASRC_MODE (0x0eb8) +#define GENERAL_ASRC_EN_ON (0x0ebc) + +#define AFE_CONN48 (0x0ec0) +#define AFE_CONN49 (0x0ec4) +#define AFE_CONN50 (0x0ec8) +#define AFE_CONN51 (0x0ecc) +#define AFE_CONN52 (0x0ed0) +#define AFE_CONN53 (0x0ed4) +#define AFE_CONN48_1 (0x0ee0) +#define AFE_CONN49_1 (0x0ee4) +#define AFE_CONN50_1 (0x0ee8) +#define AFE_CONN51_1 (0x0eec) +#define AFE_CONN52_1 (0x0ef0) +#define AFE_CONN53_1 (0x0ef4) + +#define AFE_GENERAL2_ASRC_2CH_CON0 (0x0f00) +#define AFE_GENERAL2_ASRC_2CH_CON1 (0x0f04) +#define AFE_GENERAL2_ASRC_2CH_CON2 (0x0f08) +#define AFE_GENERAL2_ASRC_2CH_CON3 (0x0f0c) +#define AFE_GENERAL2_ASRC_2CH_CON4 (0x0f10) +#define AFE_GENERAL2_ASRC_2CH_CON5 (0x0f14) +#define AFE_GENERAL2_ASRC_2CH_CON6 (0x0f18) +#define AFE_GENERAL2_ASRC_2CH_CON7 (0x0f1c) +#define AFE_GENERAL2_ASRC_2CH_CON8 (0x0f20) +#define AFE_GENERAL2_ASRC_2CH_CON9 (0x0f24) +#define AFE_GENERAL2_ASRC_2CH_CON10 (0x0f28) +#define AFE_GENERAL2_ASRC_2CH_CON12 (0x0f30) +#define AFE_GENERAL2_ASRC_2CH_CON13 (0x0f34) + +#define AFE_SECURE_MASK_CONN28 (0x0f48) +#define AFE_SECURE_MASK_CONN29 (0x0f4c) +#define AFE_SECURE_MASK_CONN30 (0x0f50) +#define AFE_SECURE_MASK_CONN31 (0x0f54) +#define AFE_SECURE_MASK_CONN32 (0x0f58) +#define AFE_SECURE_MASK_CONN33 (0x0f5c) +#define AFE_SECURE_MASK_CONN34 (0x0f60) +#define AFE_SECURE_MASK_CONN35 (0x0f64) +#define AFE_SECURE_MASK_CONN36 (0x0f68) +#define AFE_SECURE_MASK_CONN37 (0x0f6c) +#define AFE_SECURE_MASK_CONN38 (0x0f70) +#define AFE_SECURE_MASK_CONN39 (0x0f74) +#define AFE_SECURE_MASK_CONN40 (0x0f78) +#define AFE_SECURE_MASK_CONN41 (0x0f7c) +#define AFE_SIDEBAND0 (0x0f80) +#define AFE_SIDEBAND1 (0x0f84) +#define AFE_SECURE_SIDEBAND0 (0x0f88) +#define AFE_SECURE_SIDEBAND1 (0x0f8c) +#define AFE_SECURE_MASK_CONN0 (0x0f90) +#define AFE_SECURE_MASK_CONN1 (0x0f94) +#define AFE_SECURE_MASK_CONN2 (0x0f98) +#define AFE_SECURE_MASK_CONN3 (0x0f9c) +#define AFE_SECURE_MASK_CONN4 (0x0fa0) +#define AFE_SECURE_MASK_CONN5 (0x0fa4) +#define AFE_SECURE_MASK_CONN6 (0x0fa8) +#define AFE_SECURE_MASK_CONN7 (0x0fac) +#define AFE_SECURE_MASK_CONN8 (0x0fb0) +#define AFE_SECURE_MASK_CONN9 (0x0fb4) +#define AFE_SECURE_MASK_CONN10 (0x0fb8) +#define AFE_SECURE_MASK_CONN11 (0x0fbc) +#define AFE_SECURE_MASK_CONN12 (0x0fc0) +#define AFE_SECURE_MASK_CONN13 (0x0fc4) +#define AFE_SECURE_MASK_CONN14 (0x0fc8) +#define AFE_SECURE_MASK_CONN15 (0x0fcc) +#define AFE_SECURE_MASK_CONN16 (0x0fd0) +#define AFE_SECURE_MASK_CONN17 (0x0fd4) +#define AFE_SECURE_MASK_CONN18 (0x0fd8) +#define AFE_SECURE_MASK_CONN19 (0x0fdc) +#define AFE_SECURE_MASK_CONN20 (0x0fe0) +#define AFE_SECURE_MASK_CONN21 (0x0fe4) +#define AFE_SECURE_MASK_CONN22 (0x0fe8) +#define AFE_SECURE_MASK_CONN23 (0x0fec) +#define AFE_SECURE_MASK_CONN24 (0x0ff0) +#define AFE_SECURE_MASK_CONN25 (0x0ff4) +#define AFE_SECURE_MASK_CONN26 (0x0ff8) +#define AFE_SECURE_MASK_CONN27 (0x0ffc) + +#define MAX_REGISTER AFE_SECURE_MASK_CONN27 + +#define AFE_IRQ_STATUS_BITS 0x3ff + +/* AUDIO_TOP_CON0 (0x0000) */ +#define AUD_TCON0_PDN_TML BIT(27) +#define AUD_TCON0_PDN_DAC_PREDIS BIT(26) +#define AUD_TCON0_PDN_DAC BIT(25) +#define AUD_TCON0_PDN_ADC BIT(24) +#define AUD_TCON0_PDN_TDM_IN BIT(23) +#define AUD_TCON0_PDN_TDM_OUT BIT(22) +#define AUD_TCON0_PDN_SPDIF BIT(21) +#define AUD_TCON0_PDN_APLL_TUNER BIT(19) +#define AUD_TCON0_PDN_APLL2_TUNER BIT(18) +#define AUD_TCON0_PDN_INTDIR BIT(15) +#define AUD_TCON0_PDN_24M BIT(9) +#define AUD_TCON0_PDN_22M BIT(8) +#define AUD_TCON0_PDN_I2S_IN BIT(6) +#define AUD_TCON0_PDN_AFE BIT(2) + +/* AUDIO_TOP_CON1 (0x0004) */ +#define AUD_TCON1_PDN_TDM_ASRC BIT(15) +#define AUD_TCON1_PDN_GENERAL2_ASRC BIT(14) +#define AUD_TCON1_PDN_GENERAL1_ASRC BIT(13) +#define AUD_TCON1_PDN_CONNSYS_I2S_ASRC BIT(12) +#define AUD_TCON1_PDN_DMIC3_ADC BIT(11) +#define AUD_TCON1_PDN_DMIC2_ADC BIT(10) +#define AUD_TCON1_PDN_DMIC1_ADC BIT(9) +#define AUD_TCON1_PDN_DMIC0_ADC BIT(8) +#define AUD_TCON1_PDN_I2S4_BCLK BIT(7) +#define AUD_TCON1_PDN_I2S3_BCLK BIT(6) +#define AUD_TCON1_PDN_I2S2_BCLK BIT(5) +#define AUD_TCON1_PDN_I2S1_BCLK BIT(4) + +/* AUDIO_TOP_CON3 (0x000C) */ +#define AUD_TCON3_HDMI_BCK_INV BIT(3) + +/* AFE_I2S_CON (0x0018) */ +#define AFE_I2S_CON_PHASE_SHIFT_FIX BIT(31) +#define AFE_I2S_CON_FROM_IO_MUX BIT(28) +#define AFE_I2S_CON_LOW_JITTER_CLK BIT(12) +#define AFE_I2S_CON_RATE_MASK GENMASK(11, 8) +#define AFE_I2S_CON_FORMAT_I2S BIT(3) +#define AFE_I2S_CON_SRC_SLAVE BIT(2) + +/* AFE_ASRC_2CH_CON0 */ +#define ONE_HEART BIT(31) +#define CHSET_STR_CLR BIT(4) +#define COEFF_SRAM_CTRL BIT(1) +#define ASM_ON BIT(0) + +/* CON2 */ +#define O16BIT BIT(19) +#define CLR_IIR_HISTORY BIT(17) +#define IS_MONO BIT(16) +#define IIR_EN BIT(11) +#define IIR_STAGE_MASK GENMASK(10, 8) + +/* CON5 */ +#define CALI_CYCLE_MASK GENMASK(31, 16) +#define CALI_64_CYCLE FIELD_PREP(CALI_CYCLE_MASK, 0x3F) +#define CALI_96_CYCLE FIELD_PREP(CALI_CYCLE_MASK, 0x5F) +#define CALI_441_CYCLE FIELD_PREP(CALI_CYCLE_MASK, 0x1B8) + +#define CALI_AUTORST BIT(15) +#define AUTO_TUNE_FREQ5 BIT(12) +#define COMP_FREQ_RES BIT(11) + +#define CALI_SEL_MASK GENMASK(9, 8) +#define CALI_SEL_00 FIELD_PREP(CALI_SEL_MASK, 0) +#define CALI_SEL_01 FIELD_PREP(CALI_SEL_MASK, 1) + +#define CALI_BP_DGL BIT(7) /* Bypass the deglitch circuit */ +#define AUTO_TUNE_FREQ4 BIT(3) +#define CALI_AUTO_RESTART BIT(2) +#define CALI_USE_FREQ_OUT BIT(1) +#define CALI_ON BIT(0) + +#define AFE_I2S_CON_WLEN_32BIT BIT(1) +#define AFE_I2S_CON_EN BIT(0) + +#define AFE_CONN3_I03_O03_S BIT(3) +#define AFE_CONN4_I04_O04_S BIT(4) +#define AFE_CONN4_I03_O04_S BIT(3) + +/* AFE_I2S_CON1 (0x0034) */ +#define AFE_I2S_CON1_I2S2_TO_PAD BIT(18) +#define AFE_I2S_CON1_TDMOUT_TO_PAD (0 << 18) +#define AFE_I2S_CON1_RATE GENMASK(11, 8) +#define AFE_I2S_CON1_FORMAT_I2S BIT(3) +#define AFE_I2S_CON1_WLEN_32BIT BIT(1) +#define AFE_I2S_CON1_EN BIT(0) + +/* AFE_I2S_CON2 (0x0038) */ +#define AFE_I2S_CON2_LOW_JITTER_CLK BIT(12) +#define AFE_I2S_CON2_RATE GENMASK(11, 8) +#define AFE_I2S_CON2_FORMAT_I2S BIT(3) +#define AFE_I2S_CON2_WLEN_32BIT BIT(1) +#define AFE_I2S_CON2_EN BIT(0) + +/* AFE_I2S_CON3 (0x004C) */ +#define AFE_I2S_CON3_LOW_JITTER_CLK BIT(12) +#define AFE_I2S_CON3_RATE GENMASK(11, 8) +#define AFE_I2S_CON3_FORMAT_I2S BIT(3) +#define AFE_I2S_CON3_WLEN_32BIT BIT(1) +#define AFE_I2S_CON3_EN BIT(0) + +/* AFE_ADDA_DL_SRC2_CON0 (0x0108) */ +#define AFE_ADDA_DL_SAMPLING_RATE GENMASK(31, 28) +#define AFE_ADDA_DL_8X_UPSAMPLE GENMASK(25, 24) +#define AFE_ADDA_DL_MUTE_OFF_CH1 BIT(12) +#define AFE_ADDA_DL_MUTE_OFF_CH2 BIT(11) +#define AFE_ADDA_DL_VOICE_DATA BIT(5) +#define AFE_ADDA_DL_DEGRADE_GAIN BIT(1) + +/* AFE_ADDA_UL_SRC_CON0 (0x0114) */ +#define AFE_ADDA_UL_SAMPLING_RATE GENMASK(19, 17) + +/* AFE_ADDA_UL_DL_CON0 */ +#define AFE_ADDA_UL_DL_ADDA_AFE_ON BIT(0) +#define AFE_ADDA_UL_DL_DMIC_CLKDIV_ON BIT(1) + +/* AFE_APLL_TUNER_CFG (0x03f0) */ +#define AFE_APLL_TUNER_CFG_MASK GENMASK(15, 1) +#define AFE_APLL_TUNER_CFG_EN_MASK BIT(0) + +/* AFE_APLL_TUNER_CFG1 (0x03f4) */ +#define AFE_APLL_TUNER_CFG1_MASK GENMASK(15, 1) +#define AFE_APLL_TUNER_CFG1_EN_MASK BIT(0) + +/* PCM_INTF_CON1 (0x0550) */ +#define PCM_INTF_CON1_EXT_MODEM BIT(17) +#define PCM_INTF_CON1_16BIT (0 << 16) +#define PCM_INTF_CON1_24BIT BIT(16) +#define PCM_INTF_CON1_32BCK (0 << 14) +#define PCM_INTF_CON1_64BCK BIT(14) +#define PCM_INTF_CON1_MASTER_MODE (0 << 5) +#define PCM_INTF_CON1_SLAVE_MODE BIT(5) +#define PCM_INTF_CON1_FS_MASK GENMASK(4, 3) +#define PCM_INTF_CON1_FS_8K FIELD_PREP(PCM_INTF_CON1_FS_MASK, 0) +#define PCM_INTF_CON1_FS_16K FIELD_PREP(PCM_INTF_CON1_FS_MASK, 1) +#define PCM_INTF_CON1_FS_32K FIELD_PREP(PCM_INTF_CON1_FS_MASK, 2) +#define PCM_INTF_CON1_FS_48K FIELD_PREP(PCM_INTF_CON1_FS_MASK, 3) +#define PCM_INTF_CON1_SYNC_LEN_MASK GENMASK(13, 9) +#define PCM_INTF_CON1_SYNC_LEN(x) FIELD_PREP(PCM_INTF_CON1_SYNC_LEN_MASK, ((x) - 1)) +#define PCM_INTF_CON1_FORMAT_MASK GENMASK(2, 1) +#define PCM_INTF_CON1_SYNC_OUT_INV BIT(23) +#define PCM_INTF_CON1_BCLK_OUT_INV BIT(22) +#define PCM_INTF_CON1_SYNC_IN_INV BIT(21) +#define PCM_INTF_CON1_BCLK_IN_INV BIT(20) +#define PCM_INTF_CON1_BYPASS_ASRC BIT(6) +#define PCM_INTF_CON1_EN BIT(0) +#define PCM_INTF_CON1_CONFIG_MASK (0xf3fffe) + +/* AFE_DMIC0_UL_SRC_CON0 (0x05b4) + * AFE_DMIC1_UL_SRC_CON0 (0x0620) + * AFE_DMIC2_UL_SRC_CON0 (0x0780) + * AFE_DMIC3_UL_SRC_CON0 (0x07ec) + */ +#define DMIC_TOP_CON_CK_PHASE_SEL_CH1 GENMASK(29, 27) +#define DMIC_TOP_CON_CK_PHASE_SEL_CH2 GENMASK(26, 24) +#define DMIC_TOP_CON_TWO_WIRE_MODE BIT(23) +#define DMIC_TOP_CON_CH2_ON BIT(22) +#define DMIC_TOP_CON_CH1_ON BIT(21) +#define DMIC_TOP_CON_VOICE_MODE_MASK GENMASK(19, 17) +#define DMIC_TOP_CON_VOICE_MODE_8K FIELD_PREP(DMIC_TOP_CON_VOICE_MODE_MASK, 0) +#define DMIC_TOP_CON_VOICE_MODE_16K FIELD_PREP(DMIC_TOP_CON_VOICE_MODE_MASK, 1) +#define DMIC_TOP_CON_VOICE_MODE_32K FIELD_PREP(DMIC_TOP_CON_VOICE_MODE_MASK, 2) +#define DMIC_TOP_CON_VOICE_MODE_48K FIELD_PREP(DMIC_TOP_CON_VOICE_MODE_MASK, 3) +#define DMIC_TOP_CON_LOW_POWER_MODE_MASK GENMASK(15, 14) +#define DMIC_TOP_CON_LOW_POWER_MODE(x) FIELD_PREP(DMIC_TOP_CON_LOW_POWER_MODE_MASK, (x)) +#define DMIC_TOP_CON_IIR_ON BIT(10) +#define DMIC_TOP_CON_IIR_MODE GENMASK(9, 7) +#define DMIC_TOP_CON_INPUT_MODE BIT(5) +#define DMIC_TOP_CON_SDM3_LEVEL_MODE BIT(1) +#define DMIC_TOP_CON_SRC_ON BIT(0) +#define DMIC_TOP_CON_SDM3_DE_SELECT (0 << 1) +#define DMIC_TOP_CON_CONFIG_MASK (0x3f8ed7a6) + +/* AFE_CONN_24BIT (0x0AA4) */ +#define AFE_CONN_24BIT_O10 BIT(10) +#define AFE_CONN_24BIT_O09 BIT(9) +#define AFE_CONN_24BIT_O06 BIT(6) +#define AFE_CONN_24BIT_O05 BIT(5) +#define AFE_CONN_24BIT_O04 BIT(4) +#define AFE_CONN_24BIT_O03 BIT(3) +#define AFE_CONN_24BIT_O02 BIT(2) +#define AFE_CONN_24BIT_O01 BIT(1) +#define AFE_CONN_24BIT_O00 BIT(0) + +/* AFE_HD_ENGEN_ENABLE */ +#define AFE_22M_PLL_EN BIT(0) +#define AFE_24M_PLL_EN BIT(1) + +/* AFE_GAIN1_CON0 (0x0410) */ +#define AFE_GAIN1_CON0_EN_MASK GENMASK(0, 0) +#define AFE_GAIN1_CON0_MODE_MASK GENMASK(7, 4) +#define AFE_GAIN1_CON0_SAMPLE_PER_STEP_MASK GENMASK(15, 8) + +/* AFE_GAIN1_CON1 (0x0414) */ +#define AFE_GAIN1_CON1_MASK GENMASK(19, 0) + +/* AFE_GAIN1_CUR (0x0B78) */ +#define AFE_GAIN1_CUR_MASK GENMASK(19, 0) + +/* AFE_CM1_CON0 (0x0e50) */ +/* AFE_CM2_CON0 (0x0e60) */ +#define CM_AFE_CM_CH_NUM_MASK GENMASK(3, 0) +#define CM_AFE_CM_CH_NUM(x) FIELD_PREP(CM_AFE_CM_CH_NUM_MASK, ((x) - 1)) +#define CM_AFE_CM_ON BIT(4) +#define CM_AFE_CM_START_DATA_MASK GENMASK(11, 8) + +#define CM_AFE_CM1_VUL_SEL BIT(12) +#define CM_AFE_CM1_IN_MODE_MASK GENMASK(19, 16) +#define CM_AFE_CM2_TDM_SEL BIT(12) +#define CM_AFE_CM2_CLK_SEL BIT(13) +#define CM_AFE_CM2_GASRC1_OUT_SEL BIT(17) +#define CM_AFE_CM2_GASRC2_OUT_SEL BIT(16) + +/* AFE_CM2_CONN* */ +#define CM2_AFE_CM2_CONN_CFG1(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG1_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG1_MASK GENMASK(4, 0) +#define CM2_AFE_CM2_CONN_CFG2(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG2_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG2_MASK GENMASK(9, 5) +#define CM2_AFE_CM2_CONN_CFG3(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG3_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG3_MASK GENMASK(14, 10) +#define CM2_AFE_CM2_CONN_CFG4(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG4_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG4_MASK GENMASK(19, 15) +#define CM2_AFE_CM2_CONN_CFG5(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG5_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG5_MASK GENMASK(24, 20) +#define CM2_AFE_CM2_CONN_CFG6(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG6_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG6_MASK GENMASK(29, 25) +#define CM2_AFE_CM2_CONN_CFG7(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG7_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG7_MASK GENMASK(4, 0) +#define CM2_AFE_CM2_CONN_CFG8(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG8_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG8_MASK GENMASK(9, 5) +#define CM2_AFE_CM2_CONN_CFG9(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG9_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG9_MASK GENMASK(14, 10) +#define CM2_AFE_CM2_CONN_CFG10(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG10_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG10_MASK GENMASK(19, 15) +#define CM2_AFE_CM2_CONN_CFG11(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG11_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG11_MASK GENMASK(24, 20) +#define CM2_AFE_CM2_CONN_CFG12(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG12_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG12_MASK GENMASK(29, 25) +#define CM2_AFE_CM2_CONN_CFG13(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG13_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG13_MASK GENMASK(4, 0) +#define CM2_AFE_CM2_CONN_CFG14(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG14_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG14_MASK GENMASK(9, 5) +#define CM2_AFE_CM2_CONN_CFG15(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG15_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG15_MASK GENMASK(14, 10) +#define CM2_AFE_CM2_CONN_CFG16(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG16_MASK, (x)) +#define CM2_AFE_CM2_CONN_CFG16_MASK GENMASK(19, 15) + +/* AFE_CM1_CON* */ +#define CM_AFE_CM_UPDATE_CNT1_MASK GENMASK(15, 0) +#define CM_AFE_CM_UPDATE_CNT1(x) FIELD_PREP(CM_AFE_CM_UPDATE_CNT1_MASK, (x)) +#define CM_AFE_CM_UPDATE_CNT2_MASK GENMASK(31, 16) +#define CM_AFE_CM_UPDATE_CNT2(x) FIELD_PREP(CM_AFE_CM_UPDATE_CNT2_MASK, (x)) + +#endif From patchwork Fri Apr 26 17:22:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645156 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4A1D9C25B5C for ; Fri, 26 Apr 2024 17:22:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5FFFA10F1FC; Fri, 26 Apr 2024 17:22:53 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="JpRpfRCj"; dkim-atps=neutral Received: from mail-ej1-f48.google.com (mail-ej1-f48.google.com [209.85.218.48]) by gabe.freedesktop.org (Postfix) with ESMTPS id E70E210F1B0 for ; Fri, 26 Apr 2024 17:22:46 +0000 (UTC) Received: by mail-ej1-f48.google.com with SMTP id a640c23a62f3a-a5883518135so279541866b.3 for ; Fri, 26 Apr 2024 10:22:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152165; x=1714756965; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=7RgW8794hN60MILI/kljVur+gnpfRmnQ67qOV8Uh/Cg=; b=JpRpfRCjhs+J0ZW7S8yoRbPNyHBnNS9nWeg/My4K98AfR8XwhlaC/6HC49QR0IYBOK Y0PEanyZoRXsOeVUVShosscG29Y8kyRMKPQsIQSQI9XhJfkT1MloepRL8PWSYfN2H8rC hyHhsuVnhxKjQEhAp/ibCm72KbjL9wK4oZ+gnBJ9xjXSSSzhp3f+slMvov/A2cHbzv3f Dckcl9xyIPULk6Fym+DiGYZDOojXHUlb1OmUloMNmNxF2EmHuDpHZ07cAvEWnuUlRwFS /IpfwUz//E2L/SAhC+Dgug91yareM9dwNXO+kELbu5A9Nxf7F9ny7X2tFnq7mV2Bq7BX 9dow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152165; x=1714756965; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7RgW8794hN60MILI/kljVur+gnpfRmnQ67qOV8Uh/Cg=; b=WxD24cisqNlxryFOgFM+oFTulaYrCVFq6kTNW0g3bFvCemVRD1m27f8xvztupUw0RJ pDx+88y78I3Kw5qNqMth62M9aKbLSJvoR5L6T4ALfhWZYpbi6cAdc1g8gIJTW6S3qd05 HqzhCHPGJ2cjslqwkk1t4hF7ypC2Ir4AH5r+TESpyW3yVy9cBewkTr1iavGWeZdnwcwU BDYHa0LHZ6JiCdGTuz2doc9uK/oRMAlxEioI4U/u6Q5KRBOVqIdL01283wQq9u6d7nl6 +ybIc3na8ANHB4XyBsY+lNAKQK3jf6ioiSFPYY+4cZgR1G3bqzDlQkQvJVskEifkii96 CLkw== X-Forwarded-Encrypted: i=1; AJvYcCUmS/XKNFfGe97yBi2Sc0ArKUnUPnBxMlVqf+p+kjA39f8TajVBoAaZCWW+Ufzj0ZE8nEzOfEGM3LG81O+jJQJbfF9sWh+sJk1yVZCf08rb X-Gm-Message-State: AOJu0YwLs1yz1jJboB2tsl4V5LlCjmBQK+SSo/53q0sTewfmRJrnQHdF 62ubORqO5JT98NjHk0O5GbrTSoQF6KksQWOYFv9c0ZyvHnVGj5qHsvGAMB/xNEY= X-Google-Smtp-Source: AGHT+IGJTg6BllHqneBqq6nsjWsMfp9LBW2zggr5YJIRlFGIO495GuWcky6KYjV5PL4y1jJ2x/BRRg== X-Received: by 2002:a17:906:6895:b0:a58:c0e2:9792 with SMTP id n21-20020a170906689500b00a58c0e29792mr140945ejr.61.1714152165289; Fri, 26 Apr 2024 10:22:45 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:44 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:34 +0200 Subject: [PATCH v4 05/16] SoC: mediatek: mt8365: support audio clock control MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-5-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=15161; i=amergnat@baylibre.com; h=from:subject:message-id; bh=QPkoelXm9AubLbrSKR0yXXVmXp9ic4MwuyG0tg4fC30=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+Las65x6Cj98N6celvxNRPWSqVWhCNsmU2Nloin hBtc+/mJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURSdFEA CxHdeGKfeWg57UktXwet0g7dJP8DC9Amr3nymvW7hGNfNUZ8cQqWTUm7VZXxLemnLHyt4rs+5i/eJ0 Q65iKRv/JM/JTOaHHzmpjqUOpXepX1p/HbCUlDBn/hbGW1Y9+EjnNBi60g9ClEH4tHiLvQCdWVbytP 9+sAJrDI9xTmkf8Bt5F8dGwBsbLEacnIPMCIuQLfLEjZ5qNVpkH15JzHqZyDN+lQMDUM6IIphRX7rH nT1+GAuktlKn39DQXhO3sQiaqMwK1WLK30+3N8AohM09tAYZXTRfHMUe/p/B4f1eYuRo3tMv0vwnQO a3TmYvZuTUzjUL8orBM9gAgQXlZYpoqKTxiqHaem4utnmmhnVvBClRmSBP37UdNgME0qNsmD7Rv8KR IkAOU7GEHBFwDMszE8wGntqDbCN6JmT9K+CSB7JEvQ6ezf1t26YpVDEb0eaPHIYPxtQfe+Gpu0xFk6 4UNzlW/0udoylFD5+fDgjefzvT/vQkAJtkii/FJRcfVyCj70CjnzjNLb2grEDmFvpAWdtbty7dlP92 YF43xdxFoDItT9PCk/VEFeUuXDBHMeeu/w1Scn3JE5q35ig/h5J6pasEvct0ya/OgCyDPmV/h0gVQ5 jgQnIBPwTAFIgaFSTJ06Fs3y6eKRBXp9QrN+sIRVLYT1h4nlJuwR+TYQzSXg== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add audio clock wrapper and audio tuner control. Signed-off-by: Alexandre Mergnat --- sound/soc/mediatek/mt8365/mt8365-afe-clk.c | 443 +++++++++++++++++++++++++++++ sound/soc/mediatek/mt8365/mt8365-afe-clk.h | 49 ++++ 2 files changed, 492 insertions(+) diff --git a/sound/soc/mediatek/mt8365/mt8365-afe-clk.c b/sound/soc/mediatek/mt8365/mt8365-afe-clk.c new file mode 100644 index 000000000000..3a525dae857c --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-afe-clk.c @@ -0,0 +1,443 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek 8365 AFE clock control + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Jia Zeng + * Alexandre Mergnat + */ + +#include "mt8365-afe-clk.h" +#include "mt8365-afe-common.h" +#include "mt8365-reg.h" +#include "../common/mtk-base-afe.h" +#include +#include + +static const char *aud_clks[MT8365_CLK_NUM] = { + [MT8365_CLK_TOP_AUD_SEL] = "top_audio_sel", + [MT8365_CLK_AUD_I2S0_M] = "audio_i2s0_m", + [MT8365_CLK_AUD_I2S1_M] = "audio_i2s1_m", + [MT8365_CLK_AUD_I2S2_M] = "audio_i2s2_m", + [MT8365_CLK_AUD_I2S3_M] = "audio_i2s3_m", + [MT8365_CLK_ENGEN1] = "engen1", + [MT8365_CLK_ENGEN2] = "engen2", + [MT8365_CLK_AUD1] = "aud1", + [MT8365_CLK_AUD2] = "aud2", + [MT8365_CLK_I2S0_M_SEL] = "i2s0_m_sel", + [MT8365_CLK_I2S1_M_SEL] = "i2s1_m_sel", + [MT8365_CLK_I2S2_M_SEL] = "i2s2_m_sel", + [MT8365_CLK_I2S3_M_SEL] = "i2s3_m_sel", + [MT8365_CLK_CLK26M] = "top_clk26m_clk", +}; + +int mt8365_afe_init_audio_clk(struct mtk_base_afe *afe) +{ + size_t i; + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + for (i = 0; i < ARRAY_SIZE(aud_clks); i++) { + afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]); + if (IS_ERR(afe_priv->clocks[i])) { + dev_err(afe->dev, "%s devm_clk_get %s fail\n", + __func__, aud_clks[i]); + return PTR_ERR(afe_priv->clocks[i]); + } + } + return 0; +} + +int mt8365_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk) +{ + int ret; + + if (clk) { + ret = clk_prepare_enable(clk); + if (ret) { + dev_err(afe->dev, "Failed to enable clk\n"); + return ret; + } + } + return 0; +} + +void mt8365_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk) +{ + if (clk) + clk_disable_unprepare(clk); +} + +int mt8365_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk, + unsigned int rate) +{ + int ret; + + if (clk) { + ret = clk_set_rate(clk, rate); + if (ret) { + dev_err(afe->dev, "Failed to set rate\n"); + return ret; + } + } + return 0; +} + +int mt8365_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk, + struct clk *parent) +{ + int ret; + + if (clk && parent) { + ret = clk_set_parent(clk, parent); + if (ret) { + dev_err(afe->dev, "Failed to set parent\n"); + return ret; + } + } + return 0; +} + +static unsigned int get_top_cg_reg(unsigned int cg_type) +{ + switch (cg_type) { + case MT8365_TOP_CG_AFE: + case MT8365_TOP_CG_I2S_IN: + case MT8365_TOP_CG_22M: + case MT8365_TOP_CG_24M: + case MT8365_TOP_CG_INTDIR_CK: + case MT8365_TOP_CG_APLL2_TUNER: + case MT8365_TOP_CG_APLL_TUNER: + case MT8365_TOP_CG_SPDIF: + case MT8365_TOP_CG_TDM_OUT: + case MT8365_TOP_CG_TDM_IN: + case MT8365_TOP_CG_ADC: + case MT8365_TOP_CG_DAC: + case MT8365_TOP_CG_DAC_PREDIS: + case MT8365_TOP_CG_TML: + return AUDIO_TOP_CON0; + case MT8365_TOP_CG_I2S1_BCLK: + case MT8365_TOP_CG_I2S2_BCLK: + case MT8365_TOP_CG_I2S3_BCLK: + case MT8365_TOP_CG_I2S4_BCLK: + case MT8365_TOP_CG_DMIC0_ADC: + case MT8365_TOP_CG_DMIC1_ADC: + case MT8365_TOP_CG_DMIC2_ADC: + case MT8365_TOP_CG_DMIC3_ADC: + case MT8365_TOP_CG_CONNSYS_I2S_ASRC: + case MT8365_TOP_CG_GENERAL1_ASRC: + case MT8365_TOP_CG_GENERAL2_ASRC: + case MT8365_TOP_CG_TDM_ASRC: + return AUDIO_TOP_CON1; + default: + return 0; + } +} + +static unsigned int get_top_cg_mask(unsigned int cg_type) +{ + switch (cg_type) { + case MT8365_TOP_CG_AFE: + return AUD_TCON0_PDN_AFE; + case MT8365_TOP_CG_I2S_IN: + return AUD_TCON0_PDN_I2S_IN; + case MT8365_TOP_CG_22M: + return AUD_TCON0_PDN_22M; + case MT8365_TOP_CG_24M: + return AUD_TCON0_PDN_24M; + case MT8365_TOP_CG_INTDIR_CK: + return AUD_TCON0_PDN_INTDIR; + case MT8365_TOP_CG_APLL2_TUNER: + return AUD_TCON0_PDN_APLL2_TUNER; + case MT8365_TOP_CG_APLL_TUNER: + return AUD_TCON0_PDN_APLL_TUNER; + case MT8365_TOP_CG_SPDIF: + return AUD_TCON0_PDN_SPDIF; + case MT8365_TOP_CG_TDM_OUT: + return AUD_TCON0_PDN_TDM_OUT; + case MT8365_TOP_CG_TDM_IN: + return AUD_TCON0_PDN_TDM_IN; + case MT8365_TOP_CG_ADC: + return AUD_TCON0_PDN_ADC; + case MT8365_TOP_CG_DAC: + return AUD_TCON0_PDN_DAC; + case MT8365_TOP_CG_DAC_PREDIS: + return AUD_TCON0_PDN_DAC_PREDIS; + case MT8365_TOP_CG_TML: + return AUD_TCON0_PDN_TML; + case MT8365_TOP_CG_I2S1_BCLK: + return AUD_TCON1_PDN_I2S1_BCLK; + case MT8365_TOP_CG_I2S2_BCLK: + return AUD_TCON1_PDN_I2S2_BCLK; + case MT8365_TOP_CG_I2S3_BCLK: + return AUD_TCON1_PDN_I2S3_BCLK; + case MT8365_TOP_CG_I2S4_BCLK: + return AUD_TCON1_PDN_I2S4_BCLK; + case MT8365_TOP_CG_DMIC0_ADC: + return AUD_TCON1_PDN_DMIC0_ADC; + case MT8365_TOP_CG_DMIC1_ADC: + return AUD_TCON1_PDN_DMIC1_ADC; + case MT8365_TOP_CG_DMIC2_ADC: + return AUD_TCON1_PDN_DMIC2_ADC; + case MT8365_TOP_CG_DMIC3_ADC: + return AUD_TCON1_PDN_DMIC3_ADC; + case MT8365_TOP_CG_CONNSYS_I2S_ASRC: + return AUD_TCON1_PDN_CONNSYS_I2S_ASRC; + case MT8365_TOP_CG_GENERAL1_ASRC: + return AUD_TCON1_PDN_GENERAL1_ASRC; + case MT8365_TOP_CG_GENERAL2_ASRC: + return AUD_TCON1_PDN_GENERAL2_ASRC; + case MT8365_TOP_CG_TDM_ASRC: + return AUD_TCON1_PDN_TDM_ASRC; + default: + return 0; + } +} + +static unsigned int get_top_cg_on_val(unsigned int cg_type) +{ + return 0; +} + +static unsigned int get_top_cg_off_val(unsigned int cg_type) +{ + return get_top_cg_mask(cg_type); +} + +int mt8365_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + unsigned int reg = get_top_cg_reg(cg_type); + unsigned int mask = get_top_cg_mask(cg_type); + unsigned int val = get_top_cg_on_val(cg_type); + unsigned long flags; + + spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); + + afe_priv->top_cg_ref_cnt[cg_type]++; + if (afe_priv->top_cg_ref_cnt[cg_type] == 1) + regmap_update_bits(afe->regmap, reg, mask, val); + + spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); + + return 0; +} + +int mt8365_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + unsigned int reg = get_top_cg_reg(cg_type); + unsigned int mask = get_top_cg_mask(cg_type); + unsigned int val = get_top_cg_off_val(cg_type); + unsigned long flags; + + spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); + + afe_priv->top_cg_ref_cnt[cg_type]--; + if (afe_priv->top_cg_ref_cnt[cg_type] == 0) + regmap_update_bits(afe->regmap, reg, mask, val); + else if (afe_priv->top_cg_ref_cnt[cg_type] < 0) + afe_priv->top_cg_ref_cnt[cg_type] = 0; + + spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); + + return 0; +} + +int mt8365_afe_enable_main_clk(struct mtk_base_afe *afe) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + mt8365_afe_enable_clk(afe, afe_priv->clocks[MT8365_CLK_TOP_AUD_SEL]); + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_AFE); + mt8365_afe_enable_afe_on(afe); + + return 0; +} + +int mt8365_afe_disable_main_clk(struct mtk_base_afe *afe) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + mt8365_afe_disable_afe_on(afe); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_AFE); + mt8365_afe_disable_clk(afe, afe_priv->clocks[MT8365_CLK_TOP_AUD_SEL]); + + return 0; +} + +int mt8365_afe_emi_clk_on(struct mtk_base_afe *afe) +{ + return 0; +} + +int mt8365_afe_emi_clk_off(struct mtk_base_afe *afe) +{ + return 0; +} + +int mt8365_afe_enable_afe_on(struct mtk_base_afe *afe) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + unsigned long flags; + + spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); + + afe_priv->afe_on_ref_cnt++; + if (afe_priv->afe_on_ref_cnt == 1) + regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1); + + spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); + + return 0; +} + +int mt8365_afe_disable_afe_on(struct mtk_base_afe *afe) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + unsigned long flags; + + spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); + + afe_priv->afe_on_ref_cnt--; + if (afe_priv->afe_on_ref_cnt == 0) + regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x0); + else if (afe_priv->afe_on_ref_cnt < 0) + afe_priv->afe_on_ref_cnt = 0; + + spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); + + return 0; +} + +int mt8365_afe_hd_engen_enable(struct mtk_base_afe *afe, bool apll1) +{ + if (apll1) + regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE, + AFE_22M_PLL_EN, AFE_22M_PLL_EN); + else + regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE, + AFE_24M_PLL_EN, AFE_24M_PLL_EN); + + return 0; +} + +int mt8365_afe_hd_engen_disable(struct mtk_base_afe *afe, bool apll1) +{ + if (apll1) + regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE, + AFE_22M_PLL_EN, ~AFE_22M_PLL_EN); + else + regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE, + AFE_24M_PLL_EN, ~AFE_24M_PLL_EN); + + return 0; +} + +int mt8365_afe_enable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + mutex_lock(&afe_priv->afe_clk_mutex); + + afe_priv->apll_tuner_ref_cnt[apll]++; + if (afe_priv->apll_tuner_ref_cnt[apll] != 1) { + mutex_unlock(&afe_priv->afe_clk_mutex); + return 0; + } + + if (apll == MT8365_AFE_APLL1) { + regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG, + AFE_APLL_TUNER_CFG_MASK, 0x432); + regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG, + AFE_APLL_TUNER_CFG_EN_MASK, 0x1); + } else { + regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG1, + AFE_APLL_TUNER_CFG1_MASK, 0x434); + regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG1, + AFE_APLL_TUNER_CFG1_EN_MASK, 0x1); + } + + mutex_unlock(&afe_priv->afe_clk_mutex); + return 0; +} + +int mt8365_afe_disable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + mutex_lock(&afe_priv->afe_clk_mutex); + + afe_priv->apll_tuner_ref_cnt[apll]--; + if (afe_priv->apll_tuner_ref_cnt[apll] == 0) { + if (apll == MT8365_AFE_APLL1) + regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG, + AFE_APLL_TUNER_CFG_EN_MASK, 0x0); + else + regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG1, + AFE_APLL_TUNER_CFG1_EN_MASK, 0x0); + + } else if (afe_priv->apll_tuner_ref_cnt[apll] < 0) { + afe_priv->apll_tuner_ref_cnt[apll] = 0; + } + + mutex_unlock(&afe_priv->afe_clk_mutex); + return 0; +} + +int mt8365_afe_enable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + if (apll == MT8365_AFE_APLL1) { + if (clk_prepare_enable(afe_priv->clocks[MT8365_CLK_ENGEN1])) { + dev_info(afe->dev, "%s Failed to enable ENGEN1 clk\n", + __func__); + return 0; + } + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_22M); + mt8365_afe_hd_engen_enable(afe, true); +#ifdef ENABLE_AFE_APLL_TUNER + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_APLL_TUNER); + mt8365_afe_enable_apll_tuner_cfg(afe, MT8365_AFE_APLL1); +#endif + } else { + if (clk_prepare_enable(afe_priv->clocks[MT8365_CLK_ENGEN2])) { + dev_info(afe->dev, "%s Failed to enable ENGEN2 clk\n", + __func__); + return 0; + } + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_24M); + mt8365_afe_hd_engen_enable(afe, false); +#ifdef ENABLE_AFE_APLL_TUNER + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_APLL2_TUNER); + mt8365_afe_enable_apll_tuner_cfg(afe, MT8365_AFE_APLL2); +#endif + } + + return 0; +} + +int mt8365_afe_disable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + if (apll == MT8365_AFE_APLL1) { +#ifdef ENABLE_AFE_APLL_TUNER + mt8365_afe_disable_apll_tuner_cfg(afe, MT8365_AFE_APLL1); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_APLL_TUNER); +#endif + mt8365_afe_hd_engen_disable(afe, true); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_22M); + clk_disable_unprepare(afe_priv->clocks[MT8365_CLK_ENGEN1]); + } else { +#ifdef ENABLE_AFE_APLL_TUNER + mt8365_afe_disable_apll_tuner_cfg(afe, MT8365_AFE_APLL2); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_APLL2_TUNER); +#endif + mt8365_afe_hd_engen_disable(afe, false); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_24M); + clk_disable_unprepare(afe_priv->clocks[MT8365_CLK_ENGEN2]); + } + + return 0; +} diff --git a/sound/soc/mediatek/mt8365/mt8365-afe-clk.h b/sound/soc/mediatek/mt8365/mt8365-afe-clk.h new file mode 100644 index 000000000000..14fca6ae2641 --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-afe-clk.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Mediatek 8365 AFE clock control definitions + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Jia Zeng + * Alexandre Mergnat + */ + +#ifndef _MT8365_AFE_UTILS_H_ +#define _MT8365_AFE_UTILS_H_ + +struct mtk_base_afe; +struct clk; + +int mt8365_afe_init_audio_clk(struct mtk_base_afe *afe); + +int mt8365_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk); + +void mt8365_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk); + +int mt8365_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk, unsigned int rate); + +int mt8365_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk, struct clk *parent); + +int mt8365_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type); + +int mt8365_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type); + +int mt8365_afe_enable_main_clk(struct mtk_base_afe *afe); + +int mt8365_afe_disable_main_clk(struct mtk_base_afe *afe); + +int mt8365_afe_emi_clk_on(struct mtk_base_afe *afe); + +int mt8365_afe_emi_clk_off(struct mtk_base_afe *afe); + +int mt8365_afe_enable_afe_on(struct mtk_base_afe *afe); + +int mt8365_afe_disable_afe_on(struct mtk_base_afe *afe); + +int mt8365_afe_enable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll); + +int mt8365_afe_disable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll); + +int mt8365_afe_enable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll); + +int mt8365_afe_disable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll); +#endif From patchwork Fri Apr 26 17:22:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645154 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8BEFDC4345F for ; Fri, 26 Apr 2024 17:22:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 64DDC10F1B0; Fri, 26 Apr 2024 17:22:52 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="HZQe4RMA"; dkim-atps=neutral Received: from mail-lj1-f169.google.com (mail-lj1-f169.google.com [209.85.208.169]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2986310F1CE for ; Fri, 26 Apr 2024 17:22:49 +0000 (UTC) Received: by mail-lj1-f169.google.com with SMTP id 38308e7fff4ca-2def8e58471so33580961fa.0 for ; Fri, 26 Apr 2024 10:22:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152167; x=1714756967; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=dRV21odMDlex1rg2VPTTIxBGhyXnDTdo0QEnA7Bs1Ys=; b=HZQe4RMAlXa7Gx8Z0xKzqU1NUi4fKIKQowXteS4rf+RiZJTshndGg8DLSeEcSqp/Bu R/XephnBB7nRO7Ty9luSAIezwmGXmXbCRUovvdMEmZ7fsHiGo42nTHK/g0hKBPW1Ppqt fN8Z8gdqgyXSyUFfczvSbT1CS+YEVILWBbj6wpQN6L+rxE2vrVag0rHTBXeX61GfRd20 GKZsdC4M5vXvA6nV6XLKpWRUJYz2gw9VZGqeh4YveuZutfIv6PbjoylYxRsDqAqzeDKa Rw+gcSxc0VY2AUiFJQU1GJYhJRQCfqUHLNFmoH5Rbvdvn/mTQZ4CI6wKvrAC3ebFN4CW t+vA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152167; x=1714756967; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dRV21odMDlex1rg2VPTTIxBGhyXnDTdo0QEnA7Bs1Ys=; b=mFFxefB8z2B2/EqyPHfPM8O9JbEASF94N+RWYdNihlIaWmjTlffUcGWIr/dBVIfjnN Qmgu4pnAuVwZSavo7GXfV0sXdJ2bULVCIEqVvYWV8XaeDL2A4tp+Qm05Ti27LggtKUUk 1ZhT5/f56o91WeLwqxMtnsVHYaZ0J+b0up/Z1XM5XtaXGNHCRD//05lf5/033Qpiv1hC 9HOcWw7MWnvDuuXUu2E017gDDZPg/DUqgaO7CVyDtipGCtkCxCjs9VKhwCL85mUB14aR sx3HltJXSS7cHOc1QZfVV5lR9Zk+50raOCtW12iiPi6iTx2mSTFyygA8DVbJhA5zcg3C ZjtQ== X-Forwarded-Encrypted: i=1; AJvYcCWQffn7aYxokRzbYyHjcBHDb/ltbVORveYSFiYc8L4eGFnJx1TWOZbugBqzG6FgScyutWjM0aGxul/yLCuCY6Sli1lFsjVYQUXS4rGkd7FY X-Gm-Message-State: AOJu0YygUMbi6WzqZlcBbUlvycbFK3+G/rXjQf25wxxVSK0/aWZK/bpc 6/fKfxp7iyih0vVsdibS9bcuXfFVE+O2R5srGLr/E3C0J14b4noeMSvXYfxPPiw= X-Google-Smtp-Source: AGHT+IFFpvyQNYtYQfqWi9RqrisK6suVcQr2aTfA/bC+hDQ3J5sqQ5UWNfahKIlEP0TVjs5UPBCDrA== X-Received: by 2002:a2e:2c18:0:b0:2d8:7d1a:1118 with SMTP id s24-20020a2e2c18000000b002d87d1a1118mr2780015ljs.23.1714152167048; Fri, 26 Apr 2024 10:22:47 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:46 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:35 +0200 Subject: [PATCH v4 06/16] ASoC: mediatek: mt8365: Add I2S DAI support MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-6-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=27760; i=amergnat@baylibre.com; h=from:subject:message-id; bh=uIUEQbX74BjpBT6arp9xgmz0PSMZGSl08X+sKXtOPS4=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaGdBByU7hk17Q6PV9vlnxV+KVFln9iyyBYlaG n9PKK8yJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURdyXD/ 9lL6mjDytImznemCPJj3ih3ZqjmAnzCHfjgLOYNDNAJkDyysA7NWdh/Bfj9TuTpPNO0ZFN7gkLsD6n IDyx1RQTN+IYYetBUzz0AZ7EuLZfQ7TJb6y/kZMvAVOZIybvCf3LwYu2D/pH+k7bqk+j1XjvVAEX7x tcteeynHP4DpbcTMJYNyIsSXTQG1Pot7Luh4zfqttRkqP9X5AO6QonwhuzbzNarqBW3uPR9hJrsujC RX0fvb72UhbwsnhxKSpX/nCz3Efo3U9l+IQ+Sl8n6Mk1PqwtgEKd+/09WhXEUGhPLqhTJ7wJMuuy1L 5p+JRTig6hwJA4WIxxSwgpErNYTg/RKhJsgPGId9yuRSh4WtSa5LDPsFTwoigwBaKKhFhDO4Teb6SU +Z4nQIAdrjLiVaeB/F3H/xv/3xM44UA/hnyB3WrcePgznFRqdBtyoAFA1ssBTJSXhXs+/WtxfgIhou hOsdYWAU5kg7BRTNwNqn23hwO+rJHRM3l1iZy8hNwaQfO7ehWdqwwruSr1LyLqn6CQGHVnm9sDLAHm jpN76XsDvjEHI/IsOKbXbXDjODiAHcOMPFf8Dy3lynlh0N9PfjEVvC+hZwPpD3YFx3cJ5vdfEjlwMu //XKYTP2KpWdJnaKxD/2bRRIALspjwWa+LEoSQ9ZbLmKmBSngn/Vj9L9PzgA== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add I2S Device Audio Interface support for MT8365 SoC. Signed-off-by: Alexandre Mergnat --- sound/soc/mediatek/mt8365/mt8365-dai-i2s.c | 854 +++++++++++++++++++++++++++++ 1 file changed, 854 insertions(+) diff --git a/sound/soc/mediatek/mt8365/mt8365-dai-i2s.c b/sound/soc/mediatek/mt8365/mt8365-dai-i2s.c new file mode 100644 index 000000000000..c12d75dfe215 --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-dai-i2s.c @@ -0,0 +1,854 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek 8365 ALSA SoC Audio DAI I2S Control + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Jia Zeng + * Alexandre Mergnat + */ + +#include +#include +#include +#include "mt8365-afe-clk.h" +#include "mt8365-afe-common.h" + +struct mtk_afe_i2s_priv { + bool adda_link; + int i2s_out_on_ref_cnt; + int id; + int low_jitter_en; + int mclk_id; + int share_i2s_id; + unsigned int clk_id_in; + unsigned int clk_id_in_m_sel; + unsigned int clk_id_out; + unsigned int clk_id_out_m_sel; + unsigned int clk_in_mult; + unsigned int clk_out_mult; + unsigned int config_val_in; + unsigned int config_val_out; + unsigned int dynamic_bck; + unsigned int reg_off_in; + unsigned int reg_off_out; +}; + +/* This enum is merely for mtk_afe_i2s_priv declare */ +enum { + DAI_I2S0 = 0, + DAI_I2S3, + DAI_I2S_NUM, +}; + +static const struct mtk_afe_i2s_priv mt8365_i2s_priv[DAI_I2S_NUM] = { + [DAI_I2S0] = { + .id = MT8365_AFE_IO_I2S, + .mclk_id = MT8365_I2S0_MCK, + .share_i2s_id = -1, + .clk_id_in = MT8365_CLK_AUD_I2S2_M, + .clk_id_out = MT8365_CLK_AUD_I2S1_M, + .clk_id_in_m_sel = MT8365_CLK_I2S2_M_SEL, + .clk_id_out_m_sel = MT8365_CLK_I2S1_M_SEL, + .clk_in_mult = 256, + .clk_out_mult = 256, + .adda_link = true, + .config_val_out = AFE_I2S_CON1_I2S2_TO_PAD, + .reg_off_in = AFE_I2S_CON2, + .reg_off_out = AFE_I2S_CON1, + }, + [DAI_I2S3] = { + .id = MT8365_AFE_IO_2ND_I2S, + .mclk_id = MT8365_I2S3_MCK, + .share_i2s_id = -1, + .clk_id_in = MT8365_CLK_AUD_I2S0_M, + .clk_id_out = MT8365_CLK_AUD_I2S3_M, + .clk_id_in_m_sel = MT8365_CLK_I2S0_M_SEL, + .clk_id_out_m_sel = MT8365_CLK_I2S3_M_SEL, + .clk_in_mult = 256, + .clk_out_mult = 256, + .adda_link = false, + .config_val_in = AFE_I2S_CON_FROM_IO_MUX, + .reg_off_in = AFE_I2S_CON, + .reg_off_out = AFE_I2S_CON3, + }, +}; + +static const u32 *get_iir_coef(unsigned int input_fs, + unsigned int output_fs, unsigned int *count) +{ +#define RATIOVER 9 +#define INV_COEF 10 +#define NO_NEED 11 + + static const u32 IIR_COEF_48_TO_44p1[30] = { + 0x061fb0, 0x0bd256, 0x061fb0, 0xe3a3e6, 0xf0a300, 0x000003, + 0x0e416d, 0x1bb577, 0x0e416d, 0xe59178, 0xf23637, 0x000003, + 0x0c7d72, 0x189060, 0x0c7d72, 0xe96f09, 0xf505b2, 0x000003, + 0x126054, 0x249143, 0x126054, 0xe1fc0c, 0xf4b20a, 0x000002, + 0x000000, 0x323c85, 0x323c85, 0xf76d4e, 0x000000, 0x000002, + }; + + static const u32 IIR_COEF_44p1_TO_32[42] = { + 0x0a6074, 0x0d237a, 0x0a6074, 0xdd8d6c, 0xe0b3f6, 0x000002, + 0x0e41f8, 0x128d48, 0x0e41f8, 0xefc14e, 0xf12d7a, 0x000003, + 0x0cfa60, 0x11e89c, 0x0cfa60, 0xf1b09e, 0xf27205, 0x000003, + 0x15b69c, 0x20e7e4, 0x15b69c, 0xea799a, 0xe9314a, 0x000002, + 0x0f79e2, 0x1a7064, 0x0f79e2, 0xf65e4a, 0xf03d8e, 0x000002, + 0x10c34f, 0x1ffe4b, 0x10c34f, 0x0bbecb, 0xf2bc4b, 0x000001, + 0x000000, 0x23b063, 0x23b063, 0x07335f, 0x000000, 0x000002, + }; + + static const u32 IIR_COEF_48_TO_32[42] = { + 0x0a2a9b, 0x0a2f05, 0x0a2a9b, 0xe73873, 0xe0c525, 0x000002, + 0x0dd4ad, 0x0e765a, 0x0dd4ad, 0xf49808, 0xf14844, 0x000003, + 0x18a8cd, 0x1c40d0, 0x18a8cd, 0xed2aab, 0xe542ec, 0x000002, + 0x13e044, 0x1a47c4, 0x13e044, 0xf44aed, 0xe9acc7, 0x000002, + 0x1abd9c, 0x2a5429, 0x1abd9c, 0xff3441, 0xe0fc5f, 0x000001, + 0x0d86db, 0x193e2e, 0x0d86db, 0x1a6f15, 0xf14507, 0x000001, + 0x000000, 0x1f820c, 0x1f820c, 0x0a1b1f, 0x000000, 0x000002, + }; + + static const u32 IIR_COEF_32_TO_16[48] = { + 0x122893, 0xffadd4, 0x122893, 0x0bc205, 0xc0ee1c, 0x000001, + 0x1bab8a, 0x00750d, 0x1bab8a, 0x06a983, 0xe18a5c, 0x000002, + 0x18f68e, 0x02706f, 0x18f68e, 0x0886a9, 0xe31bcb, 0x000002, + 0x149c05, 0x054487, 0x149c05, 0x0bec31, 0xe5973e, 0x000002, + 0x0ea303, 0x07f24a, 0x0ea303, 0x115ff9, 0xe967b6, 0x000002, + 0x0823fd, 0x085531, 0x0823fd, 0x18d5b4, 0xee8d21, 0x000002, + 0x06888e, 0x0acbbb, 0x06888e, 0x40b55c, 0xe76dce, 0x000001, + 0x000000, 0x2d31a9, 0x2d31a9, 0x23ba4f, 0x000000, 0x000001, + }; + + static const u32 IIR_COEF_96_TO_44p1[48] = { + 0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002, + 0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002, + 0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002, + 0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002, + 0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002, + 0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002, + 0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001, + 0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001, + }; + + static const u32 IIR_COEF_44p1_TO_16[48] = { + 0x0998fb, 0xf7f925, 0x0998fb, 0x1e54a0, 0xe06605, 0x000002, + 0x0d828e, 0xf50f97, 0x0d828e, 0x0f41b5, 0xf0a999, 0x000003, + 0x17ebeb, 0xee30d8, 0x17ebeb, 0x1f48ca, 0xe2ae88, 0x000002, + 0x12fab5, 0xf46ddc, 0x12fab5, 0x20cc51, 0xe4d068, 0x000002, + 0x0c7ac6, 0xfbd00e, 0x0c7ac6, 0x2337da, 0xe8028c, 0x000002, + 0x060ddc, 0x015b3e, 0x060ddc, 0x266754, 0xec21b6, 0x000002, + 0x0407b5, 0x04f827, 0x0407b5, 0x52e3d0, 0xe0149f, 0x000001, + 0x000000, 0x1f9521, 0x1f9521, 0x2ac116, 0x000000, 0x000001, + }; + + static const u32 IIR_COEF_48_TO_16[48] = { + 0x0955ff, 0xf6544a, 0x0955ff, 0x2474e5, 0xe062e6, 0x000002, + 0x0d4180, 0xf297f4, 0x0d4180, 0x12415b, 0xf0a3b0, 0x000003, + 0x0ba079, 0xf4f0b0, 0x0ba079, 0x1285d3, 0xf1488b, 0x000003, + 0x12247c, 0xf1033c, 0x12247c, 0x2625be, 0xe48e0d, 0x000002, + 0x0b98e0, 0xf96d1a, 0x0b98e0, 0x27e79c, 0xe7798a, 0x000002, + 0x055e3b, 0xffed09, 0x055e3b, 0x2a2e2d, 0xeb2854, 0x000002, + 0x01a934, 0x01ca03, 0x01a934, 0x2c4fea, 0xee93ab, 0x000002, + 0x000000, 0x1c46c5, 0x1c46c5, 0x2d37dc, 0x000000, 0x000001, + }; + + static const u32 IIR_COEF_96_TO_16[48] = { + 0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002, + 0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003, + 0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003, + 0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003, + 0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002, + 0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002, + 0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002, + 0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001, + }; + + static const struct { + const u32 *coef; + unsigned int cnt; + } iir_coef_tbl_list[8] = { + /* 0: 0.9188 */ + { IIR_COEF_48_TO_44p1, ARRAY_SIZE(IIR_COEF_48_TO_44p1) }, + /* 1: 0.7256 */ + { IIR_COEF_44p1_TO_32, ARRAY_SIZE(IIR_COEF_44p1_TO_32) }, + /* 2: 0.6667 */ + { IIR_COEF_48_TO_32, ARRAY_SIZE(IIR_COEF_48_TO_32) }, + /* 3: 0.5 */ + { IIR_COEF_32_TO_16, ARRAY_SIZE(IIR_COEF_32_TO_16) }, + /* 4: 0.4594 */ + { IIR_COEF_96_TO_44p1, ARRAY_SIZE(IIR_COEF_96_TO_44p1) }, + /* 5: 0.3628 */ + { IIR_COEF_44p1_TO_16, ARRAY_SIZE(IIR_COEF_44p1_TO_16) }, + /* 6: 0.3333 */ + { IIR_COEF_48_TO_16, ARRAY_SIZE(IIR_COEF_48_TO_16) }, + /* 7: 0.1667 */ + { IIR_COEF_96_TO_16, ARRAY_SIZE(IIR_COEF_96_TO_16) }, + }; + + static const u32 freq_new_index[16] = { + 0, 1, 2, 99, 3, 4, 5, 99, 6, 7, 8, 9, 10, 11, 12, 99 + }; + + static const u32 iir_coef_tbl_matrix[13][13] = { + {/*0*/ + NO_NEED, NO_NEED, NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED + }, + {/*1*/ + 1, NO_NEED, NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, NO_NEED + }, + {/*2*/ + 2, 0, NO_NEED, NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED + }, + {/*3*/ + 3, INV_COEF, INV_COEF, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, NO_NEED + }, + {/*4*/ + 5, 3, INV_COEF, 2, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, NO_NEED + }, + {/*5*/ + 6, 4, 3, 2, 0, NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED + }, + {/*6*/ + INV_COEF, INV_COEF, INV_COEF, 3, INV_COEF, + INV_COEF, NO_NEED, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED + }, + {/*7*/ + INV_COEF, INV_COEF, INV_COEF, 5, 3, + INV_COEF, 1, NO_NEED, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, NO_NEED + }, + {/*8*/ + 7, INV_COEF, INV_COEF, 6, 4, 3, 2, 0, NO_NEED, + NO_NEED, NO_NEED, NO_NEED, NO_NEED + }, + {/*9*/ + INV_COEF, INV_COEF, INV_COEF, INV_COEF, + INV_COEF, INV_COEF, 5, 3, INV_COEF, + NO_NEED, NO_NEED, NO_NEED, NO_NEED + }, + {/*10*/ + INV_COEF, INV_COEF, INV_COEF, 7, INV_COEF, + INV_COEF, 6, 4, 3, 0, + NO_NEED, NO_NEED, NO_NEED + }, + { /*11*/ + RATIOVER, INV_COEF, INV_COEF, INV_COEF, + INV_COEF, INV_COEF, INV_COEF, INV_COEF, + INV_COEF, 3, INV_COEF, NO_NEED, NO_NEED + }, + {/*12*/ + RATIOVER, RATIOVER, INV_COEF, INV_COEF, + INV_COEF, INV_COEF, 7, INV_COEF, + INV_COEF, 4, 3, 0, NO_NEED + }, + }; + + const u32 *coef = NULL; + unsigned int cnt = 0; + u32 i = freq_new_index[input_fs]; + u32 j = freq_new_index[output_fs]; + + if (i >= 13 || j >= 13) { + } else { + u32 k = iir_coef_tbl_matrix[i][j]; + + if (k >= NO_NEED) { + } else if (k == RATIOVER) { + } else if (k == INV_COEF) { + } else { + coef = iir_coef_tbl_list[k].coef; + cnt = iir_coef_tbl_list[k].cnt; + } + } + *count = cnt; + return coef; +} + +static int mt8365_dai_set_config(struct mtk_base_afe *afe, + struct mtk_afe_i2s_priv *i2s_data, + bool is_input, unsigned int rate, + int bit_width) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_be_dai_data *be = + &afe_priv->be_data[i2s_data->id - MT8365_AFE_BACKEND_BASE]; + unsigned int val, reg_off; + int fs = mt8365_afe_fs_timing(rate); + + if (fs < 0) + return -EINVAL; + + val = AFE_I2S_CON_LOW_JITTER_CLK | + FIELD_PREP(AFE_I2S_CON_RATE_MASK, fs) | + AFE_I2S_CON_FORMAT_I2S; + + if (is_input) { + reg_off = i2s_data->reg_off_in; + if (i2s_data->adda_link) + val |= i2s_data->config_val_in; + } else { + reg_off = i2s_data->reg_off_out; + val |= i2s_data->config_val_in; + } + + /* 1:bck=32lrck(16bit) or bck=64lrck(32bit) 0:fix bck=64lrck */ + if (i2s_data->dynamic_bck) { + if (bit_width > 16) + val |= AFE_I2S_CON_WLEN_32BIT; + else + val &= ~(u32)AFE_I2S_CON_WLEN_32BIT; + } else { + val |= AFE_I2S_CON_WLEN_32BIT; + } + + if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == + SND_SOC_DAIFMT_CBM_CFM) { + val |= AFE_I2S_CON_SRC_SLAVE; + val &= ~(u32)AFE_I2S_CON_FROM_IO_MUX;//from consys + } + + regmap_update_bits(afe->regmap, reg_off, ~(u32)AFE_I2S_CON_EN, val); + + if (i2s_data->adda_link && is_input) + regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, 0x1, 0x1); + + return 0; +} + +int mt8365_afe_set_i2s_out(struct mtk_base_afe *afe, + unsigned int rate, int bit_width) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_data = + afe_priv->dai_priv[MT8365_AFE_IO_I2S]; + + return mt8365_dai_set_config(afe, i2s_data, false, rate, bit_width); +} + +static int mt8365_afe_set_2nd_i2s_asrc(struct mtk_base_afe *afe, + unsigned int rate_in, + unsigned int rate_out, + unsigned int width, + unsigned int mono, + int o16bit, int tracking) +{ + int ifs, ofs = 0; + unsigned int val = 0; + unsigned int mask = 0; + const u32 *coef; + u32 iir_stage; + unsigned int coef_count = 0; + + ifs = mt8365_afe_fs_timing(rate_in); + + if (ifs < 0) + return -EINVAL; + + ofs = mt8365_afe_fs_timing(rate_out); + + if (ofs < 0) + return -EINVAL; + + val = FIELD_PREP(O16BIT, o16bit) | FIELD_PREP(IS_MONO, mono); + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2, + O16BIT | IS_MONO, val); + + coef = get_iir_coef(ifs, ofs, &coef_count); + iir_stage = ((u32)coef_count / 6) - 1; + + if (coef) { + unsigned int i; + + /* CPU control IIR coeff SRAM */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, + COEFF_SRAM_CTRL, COEFF_SRAM_CTRL); + + /* set to 0, IIR coeff SRAM addr */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON13, + 0xffffffff, 0x0); + + for (i = 0; i < coef_count; ++i) + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON12, + 0xffffffff, coef[i]); + + /* disable IIR coeff SRAM access */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, + COEFF_SRAM_CTRL, + (unsigned long)~COEFF_SRAM_CTRL); + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2, + CLR_IIR_HISTORY | IIR_EN | IIR_STAGE_MASK, + CLR_IIR_HISTORY | IIR_EN | + FIELD_PREP(IIR_STAGE_MASK, iir_stage)); + } else { + /* disable IIR */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2, + IIR_EN, (unsigned long)~IIR_EN); + } + + /* CON3 setting (RX OFS) */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON3, + 0x00FFFFFF, rx_frequency_palette(ofs)); + /* CON4 setting (RX IFS) */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON4, + 0x00FFFFFF, rx_frequency_palette(ifs)); + + /* CON5 setting */ + if (tracking) { + val = CALI_64_CYCLE | + CALI_AUTORST | + AUTO_TUNE_FREQ5 | + COMP_FREQ_RES | + CALI_BP_DGL | + CALI_AUTO_RESTART | + CALI_USE_FREQ_OUT | + CALI_SEL_01; + + mask = CALI_CYCLE_MASK | + CALI_AUTORST | + AUTO_TUNE_FREQ5 | + COMP_FREQ_RES | + CALI_SEL_MASK | + CALI_BP_DGL | + AUTO_TUNE_FREQ4 | + CALI_AUTO_RESTART | + CALI_USE_FREQ_OUT | + CALI_ON; + + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5, + mask, val); + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5, + CALI_ON, CALI_ON); + } else { + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5, + 0xffffffff, 0x0); + } + /* CON6 setting fix 8125 */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON6, + 0x0000ffff, 0x1FBD); + /* CON9 setting (RX IFS) */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON9, + 0x000fffff, AutoRstThHi(ifs)); + /* CON10 setting (RX IFS) */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON10, + 0x000fffff, AutoRstThLo(ifs)); + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, + CHSET_STR_CLR, CHSET_STR_CLR); + + return 0; +} + +static int mt8365_afe_set_2nd_i2s_asrc_enable(struct mtk_base_afe *afe, + bool enable) +{ + if (enable) + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, + ASM_ON, ASM_ON); + else + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, + ASM_ON, (unsigned long)~ASM_ON); + return 0; +} + +void mt8365_afe_set_i2s_out_enable(struct mtk_base_afe *afe, bool enable) +{ + int i; + unsigned long flags; + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_data; + + for (i = 0; i < DAI_I2S_NUM; i++) { + if (mt8365_i2s_priv[i].adda_link) + i2s_data = afe_priv->dai_priv[mt8365_i2s_priv[i].id]; + } + + spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); + + if (enable) { + i2s_data->i2s_out_on_ref_cnt++; + if (i2s_data->i2s_out_on_ref_cnt == 1) + regmap_update_bits(afe->regmap, AFE_I2S_CON1, + 0x1, enable); + } else { + i2s_data->i2s_out_on_ref_cnt--; + if (i2s_data->i2s_out_on_ref_cnt == 0) + regmap_update_bits(afe->regmap, AFE_I2S_CON1, + 0x1, enable); + else if (i2s_data->i2s_out_on_ref_cnt < 0) + i2s_data->i2s_out_on_ref_cnt = 0; + } + + spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); +} + +static void mt8365_dai_set_enable(struct mtk_base_afe *afe, + struct mtk_afe_i2s_priv *i2s_data, + bool is_input, bool enable) +{ + unsigned int reg_off; + + if (is_input) { + reg_off = i2s_data->reg_off_in; + } else { + if (i2s_data->adda_link) { + mt8365_afe_set_i2s_out_enable(afe, enable); + return; + } + reg_off = i2s_data->reg_off_out; + } + regmap_update_bits(afe->regmap, reg_off, + 0x1, enable); +} + +static int mt8365_dai_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id]; + struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; + bool i2s_in_slave = + (substream->stream == SNDRV_PCM_STREAM_CAPTURE) && + ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == + SND_SOC_DAIFMT_CBM_CFM); + + mt8365_afe_enable_main_clk(afe); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + mt8365_afe_enable_clk(afe, + afe_priv->clocks[i2s_data->clk_id_out]); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && !i2s_in_slave) + mt8365_afe_enable_clk(afe, + afe_priv->clocks[i2s_data->clk_id_in]); + + if (i2s_in_slave) + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_I2S_IN); + + return 0; +} + +static void mt8365_dai_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id]; + struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; + bool reset_i2s_out_change = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + bool reset_i2s_in_change = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + bool i2s_in_slave = + (substream->stream == SNDRV_PCM_STREAM_CAPTURE) && + ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == + SND_SOC_DAIFMT_CBM_CFM); + + if (be->prepared[substream->stream]) { + if (reset_i2s_out_change) + mt8365_dai_set_enable(afe, i2s_data, false, false); + + if (reset_i2s_in_change) + mt8365_dai_set_enable(afe, i2s_data, true, false); + + if (substream->runtime->rate % 8000) + mt8365_afe_disable_apll_associated_cfg(afe, MT8365_AFE_APLL1); + else + mt8365_afe_disable_apll_associated_cfg(afe, MT8365_AFE_APLL2); + + if (reset_i2s_out_change) + be->prepared[SNDRV_PCM_STREAM_PLAYBACK] = false; + + if (reset_i2s_in_change) + be->prepared[SNDRV_PCM_STREAM_CAPTURE] = false; + } + + if (reset_i2s_out_change) + mt8365_afe_disable_clk(afe, + afe_priv->clocks[i2s_data->clk_id_out]); + + if (reset_i2s_in_change && !i2s_in_slave) + mt8365_afe_disable_clk(afe, + afe_priv->clocks[i2s_data->clk_id_in]); + + if (i2s_in_slave) + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_I2S_IN); + + mt8365_afe_disable_main_clk(afe); +} + +static int mt8365_dai_i2s_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id]; + struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; + bool apply_i2s_out_change = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + bool apply_i2s_in_change = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + unsigned int rate = substream->runtime->rate; + int bit_width = snd_pcm_format_width(substream->runtime->format); + int ret; + + if (be->prepared[substream->stream]) { + dev_info(afe->dev, "%s '%s' prepared already\n", + __func__, snd_pcm_stream_str(substream)); + return 0; + } + + if (apply_i2s_out_change) { + ret = mt8365_dai_set_config(afe, i2s_data, false, rate, bit_width); + if (ret) + return ret; + } + + if (apply_i2s_in_change) { + if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) + == SND_SOC_DAIFMT_CBM_CFM) { + ret = mt8365_afe_set_2nd_i2s_asrc(afe, 32000, rate, + (unsigned int)bit_width, + 0, 0, 1); + if (ret < 0) + return ret; + } + ret = mt8365_dai_set_config(afe, i2s_data, true, rate, bit_width); + if (ret) + return ret; + } + + if (rate % 8000) + mt8365_afe_enable_apll_associated_cfg(afe, MT8365_AFE_APLL1); + else + mt8365_afe_enable_apll_associated_cfg(afe, MT8365_AFE_APLL2); + + if (apply_i2s_out_change) { + mt8365_afe_set_clk_parent(afe, + afe_priv->clocks[i2s_data->clk_id_out_m_sel], + ((rate % 8000) ? + afe_priv->clocks[MT8365_CLK_AUD1] : + afe_priv->clocks[MT8365_CLK_AUD2])); + + mt8365_afe_set_clk_rate(afe, + afe_priv->clocks[i2s_data->clk_id_out], + rate * i2s_data->clk_out_mult); + + mt8365_dai_set_enable(afe, i2s_data, false, true); + be->prepared[SNDRV_PCM_STREAM_PLAYBACK] = true; + } + + if (apply_i2s_in_change) { + mt8365_afe_set_clk_parent(afe, + afe_priv->clocks[i2s_data->clk_id_in_m_sel], + ((rate % 8000) ? + afe_priv->clocks[MT8365_CLK_AUD1] : + afe_priv->clocks[MT8365_CLK_AUD2])); + + mt8365_afe_set_clk_rate(afe, + afe_priv->clocks[i2s_data->clk_id_in], + rate * i2s_data->clk_in_mult); + + mt8365_dai_set_enable(afe, i2s_data, true, true); + + if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) + == SND_SOC_DAIFMT_CBM_CFM) + mt8365_afe_set_2nd_i2s_asrc_enable(afe, true); + + be->prepared[SNDRV_PCM_STREAM_CAPTURE] = true; + } + return 0; +} + +static int mt8365_afe_2nd_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + unsigned int width_val = params_width(params) > 16 ? + (AFE_CONN_24BIT_O00 | AFE_CONN_24BIT_O01) : 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + regmap_update_bits(afe->regmap, AFE_CONN_24BIT, + AFE_CONN_24BIT_O00 | AFE_CONN_24BIT_O01, width_val); + + return 0; +} + +static int mt8365_afe_2nd_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; + + be->fmt_mode = 0; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + be->fmt_mode |= SND_SOC_DAIFMT_I2S; + break; + case SND_SOC_DAIFMT_LEFT_J: + be->fmt_mode |= SND_SOC_DAIFMT_LEFT_J; + break; + default: + dev_info(afe->dev, "invalid audio format for 2nd i2s!\n"); + return -EINVAL; + } + + if (((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) && + ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_IF) && + ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_IB_NF) && + ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_IB_IF)) { + dev_info(afe->dev, "invalid audio format for 2nd i2s!\n"); + return -EINVAL; + } + + be->fmt_mode |= (fmt & SND_SOC_DAIFMT_INV_MASK); + + if (((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)) + be->fmt_mode |= (fmt & SND_SOC_DAIFMT_MASTER_MASK); + + return 0; +} + +static const struct snd_soc_dai_ops mt8365_afe_i2s_ops = { + .startup = mt8365_dai_i2s_startup, + .shutdown = mt8365_dai_i2s_shutdown, + .prepare = mt8365_dai_i2s_prepare, +}; + +static const struct snd_soc_dai_ops mt8365_afe_2nd_i2s_ops = { + .startup = mt8365_dai_i2s_startup, + .shutdown = mt8365_dai_i2s_shutdown, + .hw_params = mt8365_afe_2nd_i2s_hw_params, + .prepare = mt8365_dai_i2s_prepare, + .set_fmt = mt8365_afe_2nd_i2s_set_fmt, +}; + +static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = { + { + .name = "I2S", + .id = MT8365_AFE_IO_I2S, + .playback = { + .stream_name = "I2S Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "I2S Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_i2s_ops, + }, { + .name = "2ND I2S", + .id = MT8365_AFE_IO_2ND_I2S, + .playback = { + .stream_name = "2ND I2S Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "2ND I2S Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_2nd_i2s_ops, + } +}; + +/* low jitter control */ +static const char * const mt8365_i2s_hd_str[] = { + "Normal", "Low_Jitter" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(mt8365_i2s_enum, mt8365_i2s_hd_str); + +static const char * const fmi2sin_text[] = { + "OPEN", "FM_2ND_I2S_IN" +}; + +static SOC_ENUM_SINGLE_VIRT_DECL(fmi2sin_enum, fmi2sin_text); + +static const struct snd_kcontrol_new fmi2sin_mux = + SOC_DAPM_ENUM("FM 2ND I2S Source", fmi2sin_enum); + +static const struct snd_kcontrol_new i2s_o03_o04_enable_ctl = + SOC_DAPM_SINGLE_VIRT("Switch", 1); + +static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = { + SND_SOC_DAPM_SWITCH("I2S O03_O04", SND_SOC_NOPM, 0, 0, + &i2s_o03_o04_enable_ctl), + SND_SOC_DAPM_MUX("FM 2ND I2S Mux", SND_SOC_NOPM, 0, 0, &fmi2sin_mux), + SND_SOC_DAPM_INPUT("2ND I2S In"), +}; + +static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { + {"I2S O03_O04", "Switch", "O03"}, + {"I2S O03_O04", "Switch", "O04"}, + {"I2S Playback", NULL, "I2S O03_O04"}, + {"2ND I2S Playback", NULL, "O00"}, + {"2ND I2S Playback", NULL, "O01"}, + {"2ND I2S Capture", NULL, "2ND I2S In"}, + {"FM 2ND I2S Mux", "FM_2ND_I2S_IN", "2ND I2S Capture"}, +}; + +static int mt8365_dai_i2s_set_priv(struct mtk_base_afe *afe) +{ + int i, ret; + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + for (i = 0; i < DAI_I2S_NUM; i++) { + ret = mt8365_dai_set_priv(afe, mt8365_i2s_priv[i].id, + sizeof(*afe_priv), + &mt8365_i2s_priv[i]); + if (ret) + return ret; + } + return 0; +} + +int mt8365_dai_i2s_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_i2s_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver); + dai->dapm_widgets = mtk_dai_i2s_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets); + dai->dapm_routes = mtk_dai_i2s_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes); + + /* set all dai i2s private data */ + return mt8365_dai_i2s_set_priv(afe); +} From patchwork Fri Apr 26 17:22:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645155 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9B31BC04FFE for ; Fri, 26 Apr 2024 17:22:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F0A2D10EF50; Fri, 26 Apr 2024 17:22:52 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="T39H0sSA"; dkim-atps=neutral Received: from mail-lj1-f171.google.com (mail-lj1-f171.google.com [209.85.208.171]) by gabe.freedesktop.org (Postfix) with ESMTPS id C41B210ECC4 for ; Fri, 26 Apr 2024 17:22:50 +0000 (UTC) Received: by mail-lj1-f171.google.com with SMTP id 38308e7fff4ca-2def8e58471so33581371fa.0 for ; Fri, 26 Apr 2024 10:22:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152169; x=1714756969; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=GTSY1ko++/wb2lPvySWoKOwaimob916R/fGD0IssuIQ=; b=T39H0sSAOdHOpraPrHWMiWoQCUVEu1ltvop8vE/YFOVKXvF/pgWjvlIzahHrU2prAl 9tXbGdjFKkQXZGLs+0KfSdAwzhNRDYy/89ygLJdl5ApGIbVm71FOtsjzuYR+KBxNhpit oEY9Ab5WDOYeY6rnXdyJ/kpui77B4qzmy0K9WymJKsjYDT2NWwSekwlJ5JJg20HLPRsF TcncMwmdwEwaJPZnwy41c5tzhdw1Einj1lAlduUliEgROO4fdyyct5XIvxKpRPayhe4t jTSUQiNf1Wjwvo3U6ODUY7Xq55tkwj04RAoossTjh7WI8AaoAQ5jwqDR/s0rQUQ46Elg qOCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152169; x=1714756969; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GTSY1ko++/wb2lPvySWoKOwaimob916R/fGD0IssuIQ=; b=PL2yax7E7M8G87Kul3QNvShjxvRCi8pF/8qcJPnILWvpyXLRIc5ql4EtFxx4c7o5cU eYNn/DsZYGqlN9so7tCluDfQZMgrWKLp0nWs7CzAlqtMHQl9OVzEMhPSthpRvHnFZBdj pKx1F2hGoQ+BrOQJHeOr0VwA9o5pI7ZlOgn2pJaAMjyx0ffdJoeC2kyVis9CTqe0uOcv YED244IMoCpzDGc0dHAzA2QM88fkkkUA3q4mNW1Fr5ZPSvcCadatTWCQUnUObWWpuV14 xMHePWwrZ39GFdCmWdwHOpl6/fM5EZ9nHI9h8IqfAslX3aVsPMwBpXh8w2SHOdiqHTlz tlOg== X-Forwarded-Encrypted: i=1; AJvYcCWnvEgOcX4OT48TlsRpFwB3Go/3F1gOPgNH4CDODCMM2lKfy6MAUpaiOo0oyNQ/2pznP37PYgSz64xD95XU5R1S3a2wT/Uj5i9eRTxxsYqw X-Gm-Message-State: AOJu0YwDKrLmhcq8yu+ZftGnmt9EMHWZri0uxJq3N2Kh6l/se1KaC0Df oZtSht0cwoD+t8E2i+NXFzZzEA4Wd8vtVg6Bd/umSpTiQoBBMj71DsO6Mi6jVJk= X-Google-Smtp-Source: AGHT+IGyMCQcv8a5p539hpb7XhCWiEvacxq9uLmPO1I7UnIGZY4NrK6ZNB1ydrCeSWxn7frNx8OGXA== X-Received: by 2002:a2e:9008:0:b0:2db:a9c9:4c5e with SMTP id h8-20020a2e9008000000b002dba9c94c5emr2761461ljg.21.1714152168954; Fri, 26 Apr 2024 10:22:48 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:48 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:36 +0200 Subject: [PATCH v4 07/16] ASoC: mediatek: mt8365: Add ADDA DAI support MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-7-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10092; i=amergnat@baylibre.com; h=from:subject:message-id; bh=rupMHCo4ov9trVUAGySMN2xWWd+DYicdRaX3eev6dnk=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LahayLRRrw5KpN0IzsLZFXqXJXCy2x3zCZRu7J OBlVJVeJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURTlLEA CkdHIBfbblpCMNJxcA7OiP3KWN1HNUv9oe9aS32DJqQdGAE5AbHWe1u4fQGUoCM/w7XWvsWAApygh/ haiNmvg76c0NYuEjfhj/PSU5p5KBjiE7EpMFZ3xZqus8lxbyzPTKHdjnANlhr7jOLgN1C52+2cg1M6 IOSYZ+i3o+gO00bI7+HNGLXMFXuZ6xLM+zWEAj0/bK7FORrSoE2MTG/m1zmysCA4fcXh9/wpPZQHbC 8malyJJ/PUakYcQ7WsK0FBi9n/HwNiWxdXUG067ZOPUDc6NRhyhFb0egedNlbBWe+UIWJBI/VoPTN/ LSKXk120eDpmbaiUqRxEJKVPX4ZngJjW5aFj0z7qdfymFdS2+9L8eSLtlBpn4ZiO3FCvl09hjuZe5L jmDkhVYKw8SGROtEpbMwltN/wk7+W7DadzTGdZcOZj+mlJRO1Y12sxuItOirpaASWwTp6iwzz07eGu YOXwRKCUqV0HsuTca1pK2dSH04CfyqH8Ld6nTZDkrbExXGwoLH4BvFkwOxsegE5/kuWsqTpBSDLrat F8Vn7T/a13BHmovVj+RTlVSoGSpjdoxROjdnxRw+IEEm5BtwWGwsABD5WtRx1pcBcxogNOr2nLTkt4 43fu9p1m2wmzyhbHC18u5j0KRjBuIVFQFt4WfO7VuJj6AZL9q6rf8PAXJ4tA== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add ADDA Device Audio Interface support for MT8365 SoC. Signed-off-by: Alexandre Mergnat --- sound/soc/mediatek/mt8365/mt8365-dai-adda.c | 315 ++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) diff --git a/sound/soc/mediatek/mt8365/mt8365-dai-adda.c b/sound/soc/mediatek/mt8365/mt8365-dai-adda.c new file mode 100644 index 000000000000..65d45010ac90 --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-dai-adda.c @@ -0,0 +1,315 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek 8365 ALSA SoC Audio DAI ADDA Control + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Jia Zeng + * Alexandre Mergnat + */ + +#include +#include +#include +#include "mt8365-afe-clk.h" +#include "mt8365-afe-common.h" +#include "../common/mtk-dai-adda-common.h" + +static int adda_afe_on_ref_cnt; + +/* DAI Drivers */ + +static int mt8365_dai_set_adda_out(struct mtk_base_afe *afe, unsigned int rate) +{ + unsigned int val; + + switch (rate) { + case 8000: + val = AFE_ADDA_DL_VOICE_DATA; + break; + case 16000: + val = AFE_ADDA_DL_VOICE_DATA; + break; + default: + val = 0; + } + + val |= FIELD_PREP(AFE_ADDA_DL_SAMPLING_RATE, + mtk_adda_dl_rate_transform(afe, rate)); + val |= AFE_ADDA_DL_8X_UPSAMPLE | + AFE_ADDA_DL_MUTE_OFF_CH1 | + AFE_ADDA_DL_MUTE_OFF_CH2 | + AFE_ADDA_DL_DEGRADE_GAIN; + + regmap_update_bits(afe->regmap, AFE_ADDA_PREDIS_CON0, 0xffffffff, 0); + regmap_update_bits(afe->regmap, AFE_ADDA_PREDIS_CON1, 0xffffffff, 0); + regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, 0xffffffff, val); + /* SA suggest apply -0.3db to audio/speech path */ + regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON1, + 0xffffffff, 0xf74f0000); + /* SA suggest use default value for sdm */ + regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, + 0xffffffff, 0x0700701e); + + return 0; +} + +static int mt8365_dai_set_adda_in(struct mtk_base_afe *afe, unsigned int rate) +{ + unsigned int val; + + val = FIELD_PREP(AFE_ADDA_UL_SAMPLING_RATE, + mtk_adda_ul_rate_transform(afe, rate)); + regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, + AFE_ADDA_UL_SAMPLING_RATE, val); + /* Using Internal ADC */ + regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, 0x1, 0x0); + + return 0; +} + +int mt8365_dai_enable_adda_on(struct mtk_base_afe *afe) +{ + unsigned long flags; + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); + + adda_afe_on_ref_cnt++; + if (adda_afe_on_ref_cnt == 1) + regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0, + AFE_ADDA_UL_DL_ADDA_AFE_ON, + AFE_ADDA_UL_DL_ADDA_AFE_ON); + + spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); + + return 0; +} + +int mt8365_dai_disable_adda_on(struct mtk_base_afe *afe) +{ + unsigned long flags; + struct mt8365_afe_private *afe_priv = afe->platform_priv; + + spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); + + adda_afe_on_ref_cnt--; + if (adda_afe_on_ref_cnt == 0) + regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0, + AFE_ADDA_UL_DL_ADDA_AFE_ON, + ~AFE_ADDA_UL_DL_ADDA_AFE_ON); + else if (adda_afe_on_ref_cnt < 0) + adda_afe_on_ref_cnt = 0; + + spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); + + return 0; +} + +static void mt8365_dai_set_adda_out_enable(struct mtk_base_afe *afe, + bool enable) +{ + regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, 0x1, enable); + + if (enable) + mt8365_dai_enable_adda_on(afe); + else + mt8365_dai_disable_adda_on(afe); +} + +static void mt8365_dai_set_adda_in_enable(struct mtk_base_afe *afe, bool enable) +{ + if (enable) { + regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 0x1, 0x1); + mt8365_dai_enable_adda_on(afe); + /* enable aud_pad_top fifo */ + regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, + 0xffffffff, 0x31); + } else { + /* disable aud_pad_top fifo */ + regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, + 0xffffffff, 0x30); + regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 0x1, 0x0); + /* de suggest disable ADDA_UL_SRC at least wait 125us */ + usleep_range(150, 300); + mt8365_dai_disable_adda_on(afe); + } +} + +static int mt8365_dai_int_adda_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + unsigned int stream = substream->stream; + + mt8365_afe_enable_main_clk(afe); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DAC); + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DAC_PREDIS); + } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_ADC); + } + + return 0; +} + +static void mt8365_dai_int_adda_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_be_dai_data *be = + &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; + unsigned int stream = substream->stream; + + if (be->prepared[stream]) { + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + mt8365_dai_set_adda_out_enable(afe, false); + mt8365_afe_set_i2s_out_enable(afe, false); + } else { + mt8365_dai_set_adda_in_enable(afe, false); + } + be->prepared[stream] = false; + } + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DAC_PREDIS); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DAC); + } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_ADC); + } + + mt8365_afe_disable_main_clk(afe); +} + +static int mt8365_dai_int_adda_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_be_dai_data *be = + &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; + unsigned int rate = substream->runtime->rate; + int bit_width = snd_pcm_format_width(substream->runtime->format); + int ret; + + dev_info(afe->dev, "%s '%s' rate = %u\n", __func__, + snd_pcm_stream_str(substream), rate); + + if (be->prepared[substream->stream]) { + dev_info(afe->dev, "%s '%s' prepared already\n", + __func__, snd_pcm_stream_str(substream)); + return 0; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = mt8365_dai_set_adda_out(afe, rate); + if (ret) + return ret; + + ret = mt8365_afe_set_i2s_out(afe, rate, bit_width); + if (ret) + return ret; + + mt8365_dai_set_adda_out_enable(afe, true); + mt8365_afe_set_i2s_out_enable(afe, true); + } else { + ret = mt8365_dai_set_adda_in(afe, rate); + if (ret) + return ret; + + mt8365_dai_set_adda_in_enable(afe, true); + } + be->prepared[substream->stream] = true; + return 0; +} + +static const struct snd_soc_dai_ops mt8365_afe_int_adda_ops = { + .startup = mt8365_dai_int_adda_startup, + .shutdown = mt8365_dai_int_adda_shutdown, + .prepare = mt8365_dai_int_adda_prepare, +}; + +static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { + { + .name = "INT ADDA", + .id = MT8365_AFE_IO_INT_ADDA, + .playback = { + .stream_name = "INT ADDA Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .stream_name = "INT ADDA Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_int_adda_ops, + } +}; + +/* DAI Controls */ + +static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN3, + 10, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN4, + 11, 1, 0), +}; + +static const struct snd_kcontrol_new int_adda_o03_o04_enable_ctl = + SOC_DAPM_SINGLE_VIRT("Switch", 1); + +/* DAI widget */ + +static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { + SND_SOC_DAPM_SWITCH("INT ADDA O03_O04", SND_SOC_NOPM, 0, 0, + &int_adda_o03_o04_enable_ctl), + /* inter-connections */ + SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch1_mix, + ARRAY_SIZE(mtk_adda_dl_ch1_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch2_mix, + ARRAY_SIZE(mtk_adda_dl_ch2_mix)), +}; + +/* DAI route */ + +static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { + {"INT ADDA O03_O04", "Switch", "O03"}, + {"INT ADDA O03_O04", "Switch", "O04"}, + {"INT ADDA Playback", NULL, "INT ADDA O03_O04"}, + {"INT ADDA Playback", NULL, "ADDA_DL_CH1"}, + {"INT ADDA Playback", NULL, "ADDA_DL_CH2"}, + {"AIN Mux", "INT ADC", "INT ADDA Capture"}, + {"ADDA_DL_CH1", "GAIN1_OUT_CH1", "Hostless FM DL"}, + {"ADDA_DL_CH2", "GAIN1_OUT_CH2", "Hostless FM DL"}, +}; + +int mt8365_dai_adda_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + list_add(&dai->list, &afe->sub_dais); + dai->dai_drivers = mtk_dai_adda_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); + dai->dapm_widgets = mtk_dai_adda_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); + dai->dapm_routes = mtk_dai_adda_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); + return 0; +} From patchwork Fri Apr 26 17:22:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645162 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BFCC8C04FFE for ; Fri, 26 Apr 2024 17:23:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7CE4311252E; Fri, 26 Apr 2024 17:23:24 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="yOZxZyQi"; dkim-atps=neutral Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6292610EF50 for ; Fri, 26 Apr 2024 17:22:52 +0000 (UTC) Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-a58989cd1f8so314686066b.1 for ; Fri, 26 Apr 2024 10:22:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152171; x=1714756971; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=HRoWVbb+97QwHrxPYSUdLG6n9gcD28au02QPhJHqhYE=; b=yOZxZyQiHnIz1HNfuMihqRXLzHnMhOhRFcYcXblDLC31tark/7Ee3+AcpFMfyi4TH9 hf3fCpd2aauMEa0zu8S+vIN/m6xkaFxsy1tQTgxcB8H7Aw/oQHAtP2cGmPeX/N4RFDyO ZXZr9jhXiWNwg7n9QtIbiBor2/h/XroGzXoTEqj+C98MOea5Kjc47aCwzkMWAwozUj23 AQDpGe7YULCjN3VRADvNTY2oTNAp1zudCDjIlRpZHLs5/WMTN9YJq1QO/Srq1EEN0bwd cJHi5fzknVyCv5xDFXs45hzWcXiao3Ps6RDo0d1PF2kvL2fczlxZnaZlGKrwZi+PYhvg BA7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152171; x=1714756971; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=HRoWVbb+97QwHrxPYSUdLG6n9gcD28au02QPhJHqhYE=; b=wZP1db6mVYlQa29SZjOnIeQYAuIvfUxegJH2j8daXhKRl/Yjuj0s890Y+IrAZ2YSxH FuLP2/9RWVtPnh7roaYUUMQ++Ym/Naig3oa24sDtgd1/q93q/xDPwjWe1DcoR6Y/vaX1 s+5ikvhgDOtukhskiDugGj4Duq3MEesksrPN/cFe1SxF8E3zD7qRvqPeI2NpAv9Cyp+C dxIEsIZD9akew2dsntHsFUNXBjaqw+n5YCLcBrFCXHrZn/ckK0+ak2jPZjD8JnXzcIs1 DPPp39kkA6KhREohJtD5uLXEEeAhPvcg0ok314lOWvy8rplBay0D+Quwy0Msl/lFmaPK Z4qw== X-Forwarded-Encrypted: i=1; AJvYcCWFWM1cboK6NwxERNNpia9VaR67EONyW+y4VrGrkrYEIcSFb/ob/2TXzgPBdIBcvZyK2Rzrk7yN8aGc7BUn22fkHYx8uRmCqvC1EWmgKo0U X-Gm-Message-State: AOJu0YwclJCnUX8kcmaO3feWi3bdhAr/A+Hwdc9+fdt9judPWR+jl7Dc ML6+Eb8s3zxvADl6AZORDDIV0g7ZO21xsbWJYPYOKJyRipskueaCeOr27LFV/q1eqm5Gff/Ahl/ e24Y= X-Google-Smtp-Source: AGHT+IHXGhRsF05KEI9rSFyobyZeQNjkPgaiZbJ/Gg5SCUJ8/lhsG9no5TytbJqKAAbZTzh0C9tdQA== X-Received: by 2002:a17:906:1d12:b0:a55:5541:7484 with SMTP id n18-20020a1709061d1200b00a5555417484mr134733ejh.33.1714152170742; Fri, 26 Apr 2024 10:22:50 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:50 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:37 +0200 Subject: [PATCH v4 08/16] ASoC: mediatek: mt8365: Add DMIC DAI support MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-8-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10633; i=amergnat@baylibre.com; h=from:subject:message-id; bh=ikaRpZ9zp5N+GSVqpBpZ6Q+x32qpr9yZKVqFLm31Mf4=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+La39p7NVeCECOvhepzHpq9tL3ak5hblHmrxbFg T2gmIvmJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURV6rD/ 9yiMjfzB9mS9O6DUJZR6kGkvxWtBvZ2fb8K8Ad3J0yXeb5gfz4/ByRZ9wmcXO/WQ/09AT0ViK4YgET hdG1aO9UIM+mFA4eKiSMDo8t2CXw2RTD6GppJ9+nrB7TVpYaAtGGX6HDLm1/MjxxbTcxpuw9qlTsEo RKRT54gNw6BU1XvPc99V6aEu8/V0X2VJgKG0AJdnAuN+/6mIwJ/r6ARV31JLZ3O39jxlbwCi7WGwO/ xFGcOMwjcSRSxui9jGgGa7ZZ1ue+FtbJp/G8bwbWUnJu4ejUD91H5rWgM+cNGAgDt1MJ0BAyWoh1qJ vOGiSgfVOPaq2e5RKh1A5lud53JoYeWt0sUAzFtnEu/FADfg27/0KMbiE+TEg0cTTPfvrtC9sSHSco QOqtTGRPnVGVCK7SF53guG+nqOcp36sVlW0FPz62she9duZZPWkf5yXNjxv3pI1ol/98oNG2ofUwkw iewHlTbTc8YFpeS2cmhJpTRcRNzh2OW3juFvT0NDECWm8fy0NuL98bNOCao/2CDvaksreu1IPXGOfA KGYPYHP+3stxnQSCG9UiuUjBdlIF/de2U9sw232YDf0pQxw+t8J6OgsEl2aO+FatGYI0J68Aa2nfbK 3xlIhlx6bhVmPRFn8c0/yLmQQao+z6ao+vwjGIt8Bt56Ym1VtudiCQksbcbQ== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add Digital Micro Device Audio Interface support for MT8365 SoC. Signed-off-by: Alexandre Mergnat --- sound/soc/mediatek/mt8365/mt8365-dai-dmic.c | 347 ++++++++++++++++++++++++++++ 1 file changed, 347 insertions(+) diff --git a/sound/soc/mediatek/mt8365/mt8365-dai-dmic.c b/sound/soc/mediatek/mt8365/mt8365-dai-dmic.c new file mode 100644 index 000000000000..0dd606274d8e --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-dai-dmic.c @@ -0,0 +1,347 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek 8365 ALSA SoC Audio DAI DMIC Control + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Jia Zeng + * Alexandre Mergnat + */ + +#include +#include +#include +#include "mt8365-afe-clk.h" +#include "mt8365-afe-common.h" + +struct mt8365_dmic_data { + bool two_wire_mode; + unsigned int clk_phase_sel_ch1; + unsigned int clk_phase_sel_ch2; + bool iir_on; + unsigned int irr_mode; + unsigned int dmic_mode; + unsigned int dmic_channel; +}; + +static int get_chan_reg(unsigned int channel) +{ + switch (channel) { + case 8: + fallthrough; + case 7: + return AFE_DMIC3_UL_SRC_CON0; + case 6: + fallthrough; + case 5: + return AFE_DMIC2_UL_SRC_CON0; + case 4: + fallthrough; + case 3: + return AFE_DMIC1_UL_SRC_CON0; + case 2: + fallthrough; + case 1: + return AFE_DMIC0_UL_SRC_CON0; + default: + return -EINVAL; + } +} + +/* DAI Drivers */ + +static void audio_dmic_adda_enable(struct mtk_base_afe *afe) +{ + mt8365_dai_enable_adda_on(afe); + regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0, + AFE_ADDA_UL_DL_DMIC_CLKDIV_ON, + AFE_ADDA_UL_DL_DMIC_CLKDIV_ON); +} + +static void audio_dmic_adda_disable(struct mtk_base_afe *afe) +{ + regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0, + AFE_ADDA_UL_DL_DMIC_CLKDIV_ON, + ~AFE_ADDA_UL_DL_DMIC_CLKDIV_ON); + mt8365_dai_disable_adda_on(afe); +} + +static void mt8365_dai_enable_dmic(struct mtk_base_afe *afe, + struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC]; + unsigned int val_mask; + int reg = get_chan_reg(dmic_data->dmic_channel); + + if (reg < 0) + return; + + /* val and mask will be always same to enable */ + val_mask = DMIC_TOP_CON_CH1_ON | + DMIC_TOP_CON_CH2_ON | + DMIC_TOP_CON_SRC_ON; + + regmap_update_bits(afe->regmap, reg, val_mask, val_mask); +} + +static void mt8365_dai_disable_dmic(struct mtk_base_afe *afe, + struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC]; + unsigned int mask; + int reg = get_chan_reg(dmic_data->dmic_channel); + + if (reg < 0) + return; + + dev_info(afe->dev, "%s dmic_channel %d\n", + __func__, dmic_data->dmic_channel); + + mask = DMIC_TOP_CON_CH1_ON | + DMIC_TOP_CON_CH2_ON | + DMIC_TOP_CON_SRC_ON | + DMIC_TOP_CON_SDM3_LEVEL_MODE; + + /* Set all masked values to 0 */ + regmap_update_bits(afe->regmap, reg, mask, 0); +} + +static const struct reg_sequence mt8365_dmic_iir_coeff[] = { + { AFE_DMIC0_IIR_COEF_02_01, 0x00000000 }, + { AFE_DMIC0_IIR_COEF_04_03, 0x00003FB8 }, + { AFE_DMIC0_IIR_COEF_06_05, 0x3FB80000 }, + { AFE_DMIC0_IIR_COEF_08_07, 0x3FB80000 }, + { AFE_DMIC0_IIR_COEF_10_09, 0x0000C048 }, + { AFE_DMIC1_IIR_COEF_02_01, 0x00000000 }, + { AFE_DMIC1_IIR_COEF_04_03, 0x00003FB8 }, + { AFE_DMIC1_IIR_COEF_06_05, 0x3FB80000 }, + { AFE_DMIC1_IIR_COEF_08_07, 0x3FB80000 }, + { AFE_DMIC1_IIR_COEF_10_09, 0x0000C048 }, + { AFE_DMIC2_IIR_COEF_02_01, 0x00000000 }, + { AFE_DMIC2_IIR_COEF_04_03, 0x00003FB8 }, + { AFE_DMIC2_IIR_COEF_06_05, 0x3FB80000 }, + { AFE_DMIC2_IIR_COEF_08_07, 0x3FB80000 }, + { AFE_DMIC2_IIR_COEF_10_09, 0x0000C048 }, + { AFE_DMIC3_IIR_COEF_02_01, 0x00000000 }, + { AFE_DMIC3_IIR_COEF_04_03, 0x00003FB8 }, + { AFE_DMIC3_IIR_COEF_06_05, 0x3FB80000 }, + { AFE_DMIC3_IIR_COEF_08_07, 0x3FB80000 }, + { AFE_DMIC3_IIR_COEF_10_09, 0x0000C048 }, +}; + +static int mt8365_dai_load_dmic_iir_coeff_table(struct mtk_base_afe *afe) +{ + return regmap_multi_reg_write(afe->regmap, + mt8365_dmic_iir_coeff, + ARRAY_SIZE(mt8365_dmic_iir_coeff)); +} + +static int mt8365_dai_configure_dmic(struct mtk_base_afe *afe, + struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC]; + bool two_wire_mode = dmic_data->two_wire_mode; + unsigned int clk_phase_sel_ch1 = dmic_data->clk_phase_sel_ch1; + unsigned int clk_phase_sel_ch2 = dmic_data->clk_phase_sel_ch2; + unsigned int val = 0; + unsigned int mask = 0; + unsigned int rate = dai->rate; + int reg = get_chan_reg(dai->channels); + + if (reg < 0) + return -EINVAL; + + dmic_data->dmic_channel = dai->channels; + + val |= DMIC_TOP_CON_SDM3_LEVEL_MODE; + mask |= DMIC_TOP_CON_SDM3_LEVEL_MODE; + + if (two_wire_mode) { + val |= DMIC_TOP_CON_TWO_WIRE_MODE; + mask |= DMIC_TOP_CON_TWO_WIRE_MODE; + } else { + val |= FIELD_PREP(DMIC_TOP_CON_CK_PHASE_SEL_CH1, + clk_phase_sel_ch1); + val |= FIELD_PREP(DMIC_TOP_CON_CK_PHASE_SEL_CH2, + clk_phase_sel_ch2); + mask |= DMIC_TOP_CON_CK_PHASE_SEL_CH1; + mask |= DMIC_TOP_CON_CK_PHASE_SEL_CH2; + } + + switch (rate) { + case 48000: + val |= DMIC_TOP_CON_VOICE_MODE_48K; + break; + case 32000: + val |= DMIC_TOP_CON_VOICE_MODE_32K; + break; + case 16000: + val |= DMIC_TOP_CON_VOICE_MODE_16K; + break; + case 8000: + val |= DMIC_TOP_CON_VOICE_MODE_8K; + break; + default: + return -EINVAL; + } + mask |= DMIC_TOP_CON_VOICE_MODE_MASK; + + regmap_update_bits(afe->regmap, reg, DMIC_TOP_CON_CONFIG_MASK, val); + + return 0; +} + +static int mt8365_dai_dmic_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + mt8365_afe_enable_main_clk(afe); + + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC0_ADC); + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC1_ADC); + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC2_ADC); + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC3_ADC); + + audio_dmic_adda_enable(afe); + + return 0; +} + +static void mt8365_dai_dmic_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + mt8365_dai_disable_dmic(afe, substream, dai); + audio_dmic_adda_disable(afe); + /* HW Request delay 125us before CG off */ + usleep_range(125, 300); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC3_ADC); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC2_ADC); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC1_ADC); + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC0_ADC); + + mt8365_afe_disable_main_clk(afe); +} + +static int mt8365_dai_dmic_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + mt8365_dai_configure_dmic(afe, substream, dai); + mt8365_dai_enable_dmic(afe, substream, dai); + + return 0; +} + +static const struct snd_soc_dai_ops mt8365_afe_dmic_ops = { + .startup = mt8365_dai_dmic_startup, + .shutdown = mt8365_dai_dmic_shutdown, + .prepare = mt8365_dai_dmic_prepare, +}; + +static struct snd_soc_dai_driver mtk_dai_dmic_driver[] = { + { + .name = "DMIC", + .id = MT8365_AFE_IO_DMIC, + .capture = { + .stream_name = "DMIC Capture", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_dmic_ops, + } +}; + +/* DAI Controls */ + +/* Values for 48kHz mode */ +static const char * const iir_mode_src[] = { + "SW custom", "5Hz", "10Hz", "25Hz", "50Hz", "65Hz" +}; + +static SOC_ENUM_SINGLE_DECL(iir_mode, AFE_DMIC0_UL_SRC_CON0, 7, iir_mode_src); + +static const struct snd_kcontrol_new mtk_dai_dmic_controls[] = { + SOC_SINGLE("DMIC IIR Switch", AFE_DMIC0_UL_SRC_CON0, DMIC_TOP_CON_IIR_ON, 1, 0), + SOC_ENUM("DMIC IIR Mode", iir_mode), +}; + +/* DAI widget */ + +static const struct snd_soc_dapm_widget mtk_dai_dmic_widgets[] = { + SND_SOC_DAPM_INPUT("DMIC In"), +}; + +/* DAI route */ + +static const struct snd_soc_dapm_route mtk_dai_dmic_routes[] = { + {"I14", NULL, "DMIC Capture"}, + {"I15", NULL, "DMIC Capture"}, + {"I16", NULL, "DMIC Capture"}, + {"I17", NULL, "DMIC Capture"}, + {"I18", NULL, "DMIC Capture"}, + {"I19", NULL, "DMIC Capture"}, + {"I20", NULL, "DMIC Capture"}, + {"I21", NULL, "DMIC Capture"}, + {"DMIC Capture", NULL, "DMIC In"}, +}; + +static int init_dmic_priv_data(struct mtk_base_afe *afe) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_dmic_data *dmic_priv; + struct device_node *np = afe->dev->of_node; + unsigned int temps[4]; + int ret; + + dmic_priv = devm_kzalloc(afe->dev, sizeof(*dmic_priv), GFP_KERNEL); + if (!dmic_priv) + return -ENOMEM; + + ret = of_property_read_u32_array(np, "mediatek,dmic-mode", + &temps[0], + 1); + if (ret == 0) + dmic_priv->two_wire_mode = !!temps[0]; + + if (!dmic_priv->two_wire_mode) { + dmic_priv->clk_phase_sel_ch1 = 0; + dmic_priv->clk_phase_sel_ch2 = 4; + } + + afe_priv->dai_priv[MT8365_AFE_IO_DMIC] = dmic_priv; + return 0; +} + +int mt8365_dai_dmic_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + dai->dai_drivers = mtk_dai_dmic_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_dmic_driver); + dai->controls = mtk_dai_dmic_controls; + dai->num_controls = ARRAY_SIZE(mtk_dai_dmic_controls); + dai->dapm_widgets = mtk_dai_dmic_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_dmic_widgets); + dai->dapm_routes = mtk_dai_dmic_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_dmic_routes); + return init_dmic_priv_data(afe); +} From patchwork Fri Apr 26 17:22:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645165 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 71478C25B5C for ; Fri, 26 Apr 2024 17:23:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 005B4113977; Fri, 26 Apr 2024 17:23:32 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="ClCzHwVp"; dkim-atps=neutral Received: from mail-ej1-f43.google.com (mail-ej1-f43.google.com [209.85.218.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 30A2910ECC4 for ; Fri, 26 Apr 2024 17:22:54 +0000 (UTC) Received: by mail-ej1-f43.google.com with SMTP id a640c23a62f3a-a58bd410f92so265465666b.0 for ; Fri, 26 Apr 2024 10:22:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152172; x=1714756972; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=7NcmXEnrMpeqj5XdDn0TZRLtlA98rvyn+21w0bXYsqc=; b=ClCzHwVpKzqBpwKcEoLwQ5lGAPHxR51nMMv4bkMXxC5yHKZC+aKPX3U+FTcE9UKMez OQmrZ1a7gBzplBrrYxflmlNEwr/gKye+1weCgVIbPnEiFDRCsmHt8uM4V0C0SBbewIuP Jht5mN5OTz1UUkFGPlXpq1wImiiUwxHHe8kq2JRB0XosopnyxMxhlX79ZqEq+ZDnIqd6 KFesP5VFW7jtwHZGWihkCdeRmXAzP90t7yULjzjPWD6aRNMBxUpShw/fQbZswO/zOANI K/HIZphuy/yeHESxzB9WU3FHN62ViLvf8b1OC+ETKoe9M6CcKblZlmHsk4T2py0Dx0Ki HzUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152172; x=1714756972; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7NcmXEnrMpeqj5XdDn0TZRLtlA98rvyn+21w0bXYsqc=; b=DhYZvG5yBkSBq1FCNhXMQJA8hpcEVbWuzk43ZGucUpeiM5/pIWrmSjbQyeDnym7Cvx iJNxcCCwZTlfETLEepnKaTjWiHJ83Bgxl6NIC8owCsAAHjk40HJyr+Ei7LBGAxfkMBbJ e2rkIrgTMyCWqqXrtk3ysXFrs7yvWN1Qbp6yCyG7pB/xUmuuI6HApx5cSdqFUvxOxC1o lAHFts2QQpPo49QWzJyuL4YaIMcspe8BKyRm5duv8t4bp2UFUaep8iMuBqkwbz0JMH65 13zum/gkjMDoRdwbqdPNdpKg7nWvsl+QcEPYMDdDIYD9wtAtc8W2Z5nImwQx3lB8pjtx m9CA== X-Forwarded-Encrypted: i=1; AJvYcCXJ0EmEXhqjaGbrImJv1rReCRz65X5GyPDRoJRzG3i/7IqFDwiAASfxuRVdcWVmBckg6LNmB7LFJG2lwZy44eOhu/yQ9DmCdR6Q8DpvWb6W X-Gm-Message-State: AOJu0Yzy/g3I61nhapu7rpQXKALFHjlY1Xc7bDPviEL7mmrItiKSB3z6 /XoybEWQyusBy9LW2+wJIwgSMLKBXJsD2QP9Zpo+lbgyU030iAigsy6p0TOOpGQ= X-Google-Smtp-Source: AGHT+IHlR5BwUf5YJjzVk5aFAhbuby3MlJwdbx2RI8Fe95j9s4xq8KzuwbuaiYfvEhHe/s9pVvTdwQ== X-Received: by 2002:a17:906:ecf8:b0:a58:878c:a09e with SMTP id qt24-20020a170906ecf800b00a58878ca09emr2279786ejb.56.1714152172461; Fri, 26 Apr 2024 10:22:52 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:51 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:38 +0200 Subject: [PATCH v4 09/16] ASoC: mediatek: mt8365: Add PCM DAI support MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-9-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=8166; i=amergnat@baylibre.com; h=from:subject:message-id; bh=ZWQsTQOXgV6ywBnpOyoYdC9ond5oUki1yr+VbuWucdg=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+La6Kx7C0eQDgmntZx2aVtD65oyeAJAz0L/t4LH 8+6WCMiJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURfMsD/ 9Fh2HhIJjUBJGXjTOzHLw5SqVMshgEDUg9T1Lgw/6/SZ+jOJFpZkzuUZjn+i9np0fibMcytm9gmJQ/ cZXZ3XexnoXeLbYoRbhFB3LG9sGwigm42s03olMDveuShTxrNP6M98i631eMJD/SrU/eZStXgL+wAo cybemXwtWr6lBG3FpJQFWrpCe8vH8KcFpjSlrIs8BPmqcQtJwJ+J4PZ3l97WLvx2hZ1AQWm0W6uoeY S7zCygAs+BGISWVDyR+jnbOji49egEQ/KSChk/5N9cS1Yn3YPTmTcF+4fAwe0hRgqko7MdSrrbMxZw zqPLRFEzsOBk/pb/KcE0ZILWq0SGhgtcOLXc1NphoOhheRNs4l4UN2hD6HqgRKNGLeQm53lwixdizk 7sNjNi2BQVTEd8u8ANPOgGlGcGezwrY/lu8G0EOfLeCAzlgtUDOhB+95Ava8Se1jR4HIebTPQbg/Yk cXdc8KdFv4nwKV4bqVyGBEapQ8/SBLxkx3dgzGtHHMZegi3DK5ANiYRVPE/Ne+pzczac2YsBbpnkyk u7sjLtL/sxF9CE/kD1pK/vNJ8ZvoS7L0RW80hk7YI5W54dxUPun7Ol1A53z8Eos+7dT6a536FjeuIA 1LWpCkQg0Bug75rb+vMhRoM5NFgbHwwd1Bu5Z20KDJ2e09sluqM4ZcbFvO9Q== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add Pulse Code Modulation Device Audio Interface support for MT8365 SoC. Signed-off-by: Alexandre Mergnat Reviewed-by: AngeloGioacchino Del Regno --- sound/soc/mediatek/mt8365/mt8365-dai-pcm.c | 293 +++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) diff --git a/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c b/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c new file mode 100644 index 000000000000..a5de47c69620 --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek 8365 ALSA SoC Audio DAI PCM Control + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Jia Zeng + * Alexandre Mergnat + */ + +#include +#include +#include +#include "mt8365-afe-clk.h" +#include "mt8365-afe-common.h" + +struct mt8365_pcm_intf_data { + bool slave_mode; + bool lrck_inv; + bool bck_inv; + unsigned int format; +}; + +/* DAI Drivers */ + +static void mt8365_dai_enable_pcm1(struct mtk_base_afe *afe) +{ + regmap_update_bits(afe->regmap, PCM_INTF_CON1, + PCM_INTF_CON1_EN, PCM_INTF_CON1_EN); +} + +static void mt8365_dai_disable_pcm1(struct mtk_base_afe *afe) +{ + regmap_update_bits(afe->regmap, PCM_INTF_CON1, + PCM_INTF_CON1_EN, 0x0); +} + +static int mt8365_dai_configure_pcm1(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_pcm_intf_data *pcm_priv = afe_priv->dai_priv[MT8365_AFE_IO_PCM1]; + bool slave_mode = pcm_priv->slave_mode; + bool lrck_inv = pcm_priv->lrck_inv; + bool bck_inv = pcm_priv->bck_inv; + unsigned int fmt = pcm_priv->format; + unsigned int bit_width = dai->sample_bits; + unsigned int val = 0; + + if (!slave_mode) { + val |= PCM_INTF_CON1_MASTER_MODE | + PCM_INTF_CON1_BYPASS_ASRC; + + if (lrck_inv) + val |= PCM_INTF_CON1_SYNC_OUT_INV; + if (bck_inv) + val |= PCM_INTF_CON1_BCLK_OUT_INV; + } else { + val |= PCM_INTF_CON1_SLAVE_MODE; + + if (lrck_inv) + val |= PCM_INTF_CON1_SYNC_IN_INV; + if (bck_inv) + val |= PCM_INTF_CON1_BCLK_IN_INV; + + // TODO: add asrc setting + } + + val |= FIELD_PREP(PCM_INTF_CON1_FORMAT_MASK, fmt); + + if (fmt == MT8365_PCM_FORMAT_PCMA || + fmt == MT8365_PCM_FORMAT_PCMB) + val |= PCM_INTF_CON1_SYNC_LEN(1); + else + val |= PCM_INTF_CON1_SYNC_LEN(bit_width); + + switch (substream->runtime->rate) { + case 48000: + val |= PCM_INTF_CON1_FS_48K; + break; + case 32000: + val |= PCM_INTF_CON1_FS_32K; + break; + case 16000: + val |= PCM_INTF_CON1_FS_16K; + break; + case 8000: + val |= PCM_INTF_CON1_FS_8K; + break; + default: + return -EINVAL; + } + + if (bit_width > 16) + val |= PCM_INTF_CON1_24BIT | PCM_INTF_CON1_64BCK; + else + val |= PCM_INTF_CON1_16BIT | PCM_INTF_CON1_32BCK; + + val |= PCM_INTF_CON1_EXT_MODEM; + + regmap_update_bits(afe->regmap, PCM_INTF_CON1, + PCM_INTF_CON1_CONFIG_MASK, val); + + return 0; +} + +static int mt8365_dai_pcm1_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + if (snd_soc_dai_active(dai)) + return 0; + + mt8365_afe_enable_main_clk(afe); + + return 0; +} + +static void mt8365_dai_pcm1_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + if (snd_soc_dai_active(dai)) + return; + + mt8365_dai_disable_pcm1(afe); + mt8365_afe_disable_main_clk(afe); +} + +static int mt8365_dai_pcm1_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int ret; + + if ((snd_soc_dai_stream_active_playback(dai) + + snd_soc_dai_stream_active_capture(dai)) > 1) { + dev_info(afe->dev, "%s '%s' active(%u-%u) already\n", + __func__, snd_pcm_stream_str(substream), + snd_soc_dai_stream_active_playback(dai), + snd_soc_dai_stream_active_capture(dai)); + return 0; + } + + ret = mt8365_dai_configure_pcm1(substream, dai); + if (ret) + return ret; + + mt8365_dai_enable_pcm1(afe); + + return 0; +} + +static int mt8365_dai_pcm1_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_pcm_intf_data *pcm_priv = afe_priv->dai_priv[MT8365_AFE_IO_PCM1]; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + pcm_priv->format = MT8365_PCM_FORMAT_I2S; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + pcm_priv->bck_inv = false; + pcm_priv->lrck_inv = false; + break; + case SND_SOC_DAIFMT_NB_IF: + pcm_priv->bck_inv = false; + pcm_priv->lrck_inv = true; + break; + case SND_SOC_DAIFMT_IB_NF: + pcm_priv->bck_inv = true; + pcm_priv->lrck_inv = false; + break; + case SND_SOC_DAIFMT_IB_IF: + pcm_priv->bck_inv = true; + pcm_priv->lrck_inv = true; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + pcm_priv->slave_mode = true; + break; + case SND_SOC_DAIFMT_CBS_CFS: + pcm_priv->slave_mode = false; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_dai_ops mt8365_dai_pcm1_ops = { + .startup = mt8365_dai_pcm1_startup, + .shutdown = mt8365_dai_pcm1_shutdown, + .prepare = mt8365_dai_pcm1_prepare, + .set_fmt = mt8365_dai_pcm1_set_fmt, +}; + +static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { + { + .name = "PCM1", + .id = MT8365_AFE_IO_PCM1, + .playback = { + .stream_name = "PCM1 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "PCM1 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_dai_pcm1_ops, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, + } +}; + +/* DAI widget */ + +static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = { + SND_SOC_DAPM_OUTPUT("PCM1 Out"), + SND_SOC_DAPM_INPUT("PCM1 In"), +}; + +/* DAI route */ + +static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = { + {"PCM1 Playback", NULL, "O07"}, + {"PCM1 Playback", NULL, "O08"}, + {"PCM1 Out", NULL, "PCM1 Playback"}, + + {"I09", NULL, "PCM1 Capture"}, + {"I22", NULL, "PCM1 Capture"}, + {"PCM1 Capture", NULL, "PCM1 In"}, +}; + +static int init_pcmif_priv_data(struct mtk_base_afe *afe) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_pcm_intf_data *pcmif_priv; + + pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mt8365_pcm_intf_data), + GFP_KERNEL); + if (!pcmif_priv) + return -ENOMEM; + + afe_priv->dai_priv[MT8365_AFE_IO_PCM1] = pcmif_priv; + return 0; +} + +int mt8365_dai_pcm_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + dai->dai_drivers = mtk_dai_pcm_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver); + dai->dapm_widgets = mtk_dai_pcm_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets); + dai->dapm_routes = mtk_dai_pcm_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes); + return init_pcmif_priv_data(afe); +} From patchwork Fri Apr 26 17:22:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645158 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C5647C4345F for ; Fri, 26 Apr 2024 17:23:13 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8E6C510EAD3; Fri, 26 Apr 2024 17:23:12 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="OicFOEJM"; dkim-atps=neutral Received: from mail-lj1-f177.google.com (mail-lj1-f177.google.com [209.85.208.177]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2133710ECC4 for ; Fri, 26 Apr 2024 17:22:56 +0000 (UTC) Received: by mail-lj1-f177.google.com with SMTP id 38308e7fff4ca-2db2f6cb312so37410451fa.2 for ; Fri, 26 Apr 2024 10:22:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152174; x=1714756974; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=GUTru9dNvbOZnap79Kg3Bs9o0ntjZ8kzNc6IEqec/oQ=; b=OicFOEJM1ZhkO+uEO516LTscEVkmce0Zmn1fFQgrHc/CdmUNZFAGGnWmWP/ZiDZyvB Lr600MyuVhVHE4E92i9yG/C+x9ITlcWYCtsxdA8olFNIpWuQ4+vDwUL3I8pt+mjVK3T1 PA/W7tfB/kGPe1rQMLCOXAKk7vJuXNBVe5huIocMJ8m2iRILL9WJVdON1/bjnxpfKDyz eXmsmH5u5X5rJQIM9yoWtLF03fjoGU4pW+ms9fYT6YwMDMLeB3J9I+sXLv7YAInafJ+j S+vI1GOB+rNYTLUf4eeLu7rqAABQ/SCZa7zZ0UUa7HVRS3mfQpzVtWmgKpA6bQ4R/4pV is+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152174; x=1714756974; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GUTru9dNvbOZnap79Kg3Bs9o0ntjZ8kzNc6IEqec/oQ=; b=Ms6ivjil7eeBNvmtD/oHARCkEIzItjHQs2lguH7tVem0bx6/AD9azcNhipmJrlGIGV UXJUwn9ZgXmB063NaD+GqK4C0zpIKAdA0F55a6HF9Tr631J2jeXygcgYT7xcSnzqkLBL R77jIeiPYyKWSihz45u4y3zq7KR6ggnlmfWZn/M7b8MlnEhGJGaemEbePGAOLHYvvHxs wdNbi5feV8jrtAvYcsf7Kw1YyW4JynVmQx6q6UZ+ABrmC0k9krAHFP7viMxjnFdsLcdA CJl0lhYSpdd1zj0Jkubjpm9KOd1deIiciUQLtmKo5Zj4dPfz19Y92b3U0suodWW4lA5a Y8XA== X-Forwarded-Encrypted: i=1; AJvYcCV9rdfQdpnkdw0hKcN6FhYvPD9xdo+LXNIKSj1tyjdaHmsHPtH/4UhS6VddT2cx6hp1wsECQAw9/fivq7qCcHDEx709Ui0j1du7ratPV4JX X-Gm-Message-State: AOJu0Yzl7Ynh/R0htuuNv4uBWtYeK08XSdVpxv/HFu2TAnzmxCHkyqK7 qp9qAIHaTygh3TIqzJfC9f7jlSE0FJ+mKp1NA4Fmn+RnUqmxflA420ez1Er1HY8= X-Google-Smtp-Source: AGHT+IE9Quwpp+FijGTfbiWDErxuCbULqiEH0XE97aZl1m+CkKfz3I7b0B2fblJfORGtiH2amWMFmw== X-Received: by 2002:a2e:240c:0:b0:2da:7934:768e with SMTP id k12-20020a2e240c000000b002da7934768emr2603827ljk.36.1714152174199; Fri, 26 Apr 2024 10:22:54 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:53 -0700 (PDT) From: amergnat@baylibre.com Date: Fri, 26 Apr 2024 19:22:39 +0200 Subject: [PATCH v4 10/16] ASoc: mediatek: mt8365: Add a specific soundcard for EVK MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-10-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat , Nicolas Belin X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10412; i=amergnat@baylibre.com; h=from:subject:message-id; bh=0UPcZkgr308KuygIWUDkwBxgLyTPcSFCeyaFlNvD8aw=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaZm4+fKYL2jgxyCW+j7vR8Wp/wfh720tHw+mq tnYFJ5eJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURS3rD/ sF/dxL32T+Agesz7v2ESjvQ/2Yvx2D82rwYUQZunaSXcrkqsATwnEVEe/GdD1TIkIb//d6bpforZj2 KVln7Vaoh2Ikgz1mvtYf9dYjNErv2muEqArqLUUkoreldsZmwqeNFyW0XzzOPrhRP63y0wz4QYCTI4 wPI44eOQeXzCb2kQdPl4uVN4OOfqy9lxzr7AAkFLU06oAHmzAGzMPXyakh2yzQ9G5sNgAy4CGFmyPn XYcSeg++p6xLOm3bzwO54NEH3SG/wHH4SB7lhehU26c+qV5XWeIu6CPcAOEWtAMaHPbH2sfOePkmkJ Yl1EurGIgh2iC5MRupsNMmnkvrkI/nL5IXFqggBgxLGNI/gvY/sUkzGtHG2Ay2kcjdjrMTL9H/jPjc G4Yo/OQqghqI85Gq2sp187e9zebMHqDBuz+mAHG8guQSXMswE9Igm/k6Eaq3OSJtexcZiR1z6w4mqk 1E2t95nJm75nKEW2wHQI0AJOs980r4R0wDz8iqFqk9ZScJ9wC503i0RraHjkGxzpIRv5uxuiDW87Oh gsn8Kny0eec5VoKk9f/1mNs7XYFQTjkMwLtoCnXji5SVARBG0mFwKfOSGfa3LRaws8uvgHZ44BCIvH Sw+2xqOCzbhkoZuFrur2a65XMn15WXxVKjUXvQLG4TPJqFCEIDmXMg0678qg== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Nicolas Belin Add a specific soundcard for mt8365-evk. It supports audio jack in/out, dmics, the amic and lineout. Signed-off-by: Nicolas Belin Signed-off-by: Alexandre Mergnat Reviewed-by: AngeloGioacchino Del Regno --- sound/soc/mediatek/mt8365/mt8365-mt6357.c | 348 ++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) diff --git a/sound/soc/mediatek/mt8365/mt8365-mt6357.c b/sound/soc/mediatek/mt8365/mt8365-mt6357.c new file mode 100644 index 000000000000..a65f668103da --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-mt6357.c @@ -0,0 +1,348 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek MT8365 Sound Card driver + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Nicolas Belin + */ + +#include +#include +#include +#include +#include "mt8365-afe-common.h" +#include +#include "../common/mtk-soc-card.h" +#include "../common/mtk-soundcard-driver.h" + +enum pinctrl_pin_state { + PIN_STATE_DEFAULT, + PIN_STATE_DMIC, + PIN_STATE_MISO_OFF, + PIN_STATE_MISO_ON, + PIN_STATE_MOSI_OFF, + PIN_STATE_MOSI_ON, + PIN_STATE_MAX +}; + +static const char * const mt8365_mt6357_pin_str[PIN_STATE_MAX] = { + "default", + "dmic", + "miso_off", + "miso_on", + "mosi_off", + "mosi_on", +}; + +struct mt8365_mt6357_priv { + struct pinctrl *pinctrl; + struct pinctrl_state *pin_states[PIN_STATE_MAX]; +}; + +enum { + /* FE */ + DAI_LINK_DL1_PLAYBACK = 0, + DAI_LINK_DL2_PLAYBACK, + DAI_LINK_AWB_CAPTURE, + DAI_LINK_VUL_CAPTURE, + /* BE */ + DAI_LINK_2ND_I2S_INTF, + DAI_LINK_DMIC, + DAI_LINK_INT_ADDA, + DAI_LINK_NUM +}; + +static const struct snd_soc_dapm_widget mt8365_mt6357_widgets[] = { + SND_SOC_DAPM_OUTPUT("HDMI Out"), +}; + +static const struct snd_soc_dapm_route mt8365_mt6357_routes[] = { + {"HDMI Out", NULL, "2ND I2S Playback"}, + {"DMIC In", NULL, "MICBIAS0"}, +}; + +static int mt8365_mt6357_int_adda_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct mt8365_mt6357_priv *priv = snd_soc_card_get_drvdata(rtd->card); + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (IS_ERR(priv->pin_states[PIN_STATE_MOSI_ON])) + return ret; + + ret = pinctrl_select_state(priv->pinctrl, + priv->pin_states[PIN_STATE_MOSI_ON]); + if (ret) + dev_err(rtd->card->dev, "%s failed to select state %d\n", + __func__, ret); + } + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (IS_ERR(priv->pin_states[PIN_STATE_MISO_ON])) + return ret; + + ret = pinctrl_select_state(priv->pinctrl, + priv->pin_states[PIN_STATE_MISO_ON]); + if (ret) + dev_err(rtd->card->dev, "%s failed to select state %d\n", + __func__, ret); + } + + return 0; +} + +static void mt8365_mt6357_int_adda_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct mt8365_mt6357_priv *priv = snd_soc_card_get_drvdata(rtd->card); + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (IS_ERR(priv->pin_states[PIN_STATE_MOSI_OFF])) + return; + + ret = pinctrl_select_state(priv->pinctrl, + priv->pin_states[PIN_STATE_MOSI_OFF]); + if (ret) + dev_err(rtd->card->dev, "%s failed to select state %d\n", + __func__, ret); + } + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (IS_ERR(priv->pin_states[PIN_STATE_MISO_OFF])) + return; + + ret = pinctrl_select_state(priv->pinctrl, + priv->pin_states[PIN_STATE_MISO_OFF]); + if (ret) + dev_err(rtd->card->dev, "%s failed to select state %d\n", + __func__, ret); + } +} + +static const struct snd_soc_ops mt8365_mt6357_int_adda_ops = { + .startup = mt8365_mt6357_int_adda_startup, + .shutdown = mt8365_mt6357_int_adda_shutdown, +}; + +SND_SOC_DAILINK_DEFS(playback1, + DAILINK_COMP_ARRAY(COMP_CPU("DL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback2, + DAILINK_COMP_ARRAY(COMP_CPU("DL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(awb_capture, + DAILINK_COMP_ARRAY(COMP_CPU("AWB")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(vul, + DAILINK_COMP_ARRAY(COMP_CPU("VUL")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(i2s3, + DAILINK_COMP_ARRAY(COMP_CPU("2ND I2S")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(dmic, + DAILINK_COMP_ARRAY(COMP_CPU("DMIC")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(primary_codec, + DAILINK_COMP_ARRAY(COMP_CPU("INT ADDA")), + DAILINK_COMP_ARRAY(COMP_CODEC("mt6357-sound", "mt6357-snd-codec-aif1")), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link mt8365_mt6357_dais[] = { + /* Front End DAI links */ + [DAI_LINK_DL1_PLAYBACK] = { + .name = "DL1_FE", + .stream_name = "MultiMedia1_PLayback", + .id = DAI_LINK_DL1_PLAYBACK, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST + }, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_merged_rate = 1, + SND_SOC_DAILINK_REG(playback1), + }, + [DAI_LINK_DL2_PLAYBACK] = { + .name = "DL2_FE", + .stream_name = "MultiMedia2_PLayback", + .id = DAI_LINK_DL2_PLAYBACK, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST + }, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_merged_rate = 1, + SND_SOC_DAILINK_REG(playback2), + }, + [DAI_LINK_AWB_CAPTURE] = { + .name = "AWB_FE", + .stream_name = "DL1_AWB_Record", + .id = DAI_LINK_AWB_CAPTURE, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST + }, + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_merged_rate = 1, + SND_SOC_DAILINK_REG(awb_capture), + }, + [DAI_LINK_VUL_CAPTURE] = { + .name = "VUL_FE", + .stream_name = "MultiMedia1_Capture", + .id = DAI_LINK_VUL_CAPTURE, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST + }, + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_merged_rate = 1, + SND_SOC_DAILINK_REG(vul), + }, + /* Back End DAI links */ + [DAI_LINK_2ND_I2S_INTF] = { + .name = "I2S_OUT_BE", + .no_pcm = 1, + .id = DAI_LINK_2ND_I2S_INTF, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .dpcm_playback = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(i2s3), + }, + [DAI_LINK_DMIC] = { + .name = "DMIC_BE", + .no_pcm = 1, + .id = DAI_LINK_DMIC, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(dmic), + }, + [DAI_LINK_INT_ADDA] = { + .name = "MTK_Codec", + .no_pcm = 1, + .id = DAI_LINK_INT_ADDA, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &mt8365_mt6357_int_adda_ops, + SND_SOC_DAILINK_REG(primary_codec), + }, +}; + +static int mt8365_mt6357_gpio_probe(struct snd_soc_card *card) +{ + struct mt8365_mt6357_priv *priv = snd_soc_card_get_drvdata(card); + int ret, i; + + priv->pinctrl = devm_pinctrl_get(card->dev); + if (IS_ERR(priv->pinctrl)) { + ret = PTR_ERR(priv->pinctrl); + return dev_err_probe(card->dev, ret, + "Failed to get pinctrl\n"); + } + + for (i = PIN_STATE_DEFAULT ; i < PIN_STATE_MAX ; i++) { + priv->pin_states[i] = pinctrl_lookup_state(priv->pinctrl, + mt8365_mt6357_pin_str[i]); + if (IS_ERR(priv->pin_states[i])) { + ret = PTR_ERR(priv->pin_states[i]); + dev_warn(card->dev, "No pin state for %s\n", + mt8365_mt6357_pin_str[i]); + } else { + ret = pinctrl_select_state(priv->pinctrl, + priv->pin_states[i]); + if (ret) { + dev_err_probe(card->dev, ret, + "Failed to select pin state %s\n", + mt8365_mt6357_pin_str[i]); + return ret; + } + } + } + return 0; +} + +static struct snd_soc_card mt8365_mt6357_soc_card = { + .name = "mt8365-evk", + .owner = THIS_MODULE, + .dai_link = mt8365_mt6357_dais, + .num_links = ARRAY_SIZE(mt8365_mt6357_dais), + .dapm_widgets = mt8365_mt6357_widgets, + .num_dapm_widgets = ARRAY_SIZE(mt8365_mt6357_widgets), + .dapm_routes = mt8365_mt6357_routes, + .num_dapm_routes = ARRAY_SIZE(mt8365_mt6357_routes), +}; + +static int mt8365_mt6357_dev_probe(struct mtk_soc_card_data *soc_card_data, bool legacy) +{ + struct mtk_platform_card_data *card_data = soc_card_data->card_data; + struct snd_soc_card *card = card_data->card; + struct device *dev = card->dev; + struct device_node *platform_node; + struct mt8365_mt6357_priv *mach_priv; + int i, ret; + + card->dev = dev; + ret = parse_dai_link_info(card); + if (ret) + goto err; + + mach_priv = devm_kzalloc(dev, sizeof(*mach_priv), + GFP_KERNEL); + if (!mach_priv) + return -ENOMEM; + soc_card_data->mach_priv = mach_priv; + snd_soc_card_set_drvdata(card, soc_card_data); + mt8365_mt6357_gpio_probe(card); + return 0; + +err: + clean_card_reference(card); + return ret; +} + +static const struct mtk_soundcard_pdata mt8365_mt6357_card = { + .card_name = "mt8365-mt6357", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8365_mt6357_soc_card, + }, + .soc_probe = mt8365_mt6357_dev_probe +}; + +static const struct of_device_id mt8365_mt6357_dt_match[] = { + { + .compatible = "mediatek,mt8365-mt6357", + .data = &mt8365_mt6357_card, + }, + { } +}; +MODULE_DEVICE_TABLE(of, mt8365_mt6357_dt_match); + +static struct platform_driver mt8365_mt6357_driver = { + .driver = { + .name = "mt8365_mt6357", + .of_match_table = mt8365_mt6357_dt_match, + .pm = &snd_soc_pm_ops, + }, + .probe = mtk_soundcard_common_probe, +}; + +module_platform_driver(mt8365_mt6357_driver); + +/* Module information */ +MODULE_DESCRIPTION("MT8365 EVK SoC machine driver"); +MODULE_AUTHOR("Nicolas Belin "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform: mt8365_mt6357"); From patchwork Fri Apr 26 17:22:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645160 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3F148C04FFE for ; Fri, 26 Apr 2024 17:23:15 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E55B510F887; Fri, 26 Apr 2024 17:23:12 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="xB3LRh4V"; dkim-atps=neutral Received: from mail-ej1-f42.google.com (mail-ej1-f42.google.com [209.85.218.42]) by gabe.freedesktop.org (Postfix) with ESMTPS id E2AE110ECC4 for ; Fri, 26 Apr 2024 17:22:57 +0000 (UTC) Received: by mail-ej1-f42.google.com with SMTP id a640c23a62f3a-a5872b74c44so283013266b.3 for ; Fri, 26 Apr 2024 10:22:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152176; x=1714756976; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=P+J+i804wlEe2vVXF+/fWpZaqhveTqz2nQ9x4otbBKQ=; b=xB3LRh4VDnuI8j1O8uxHunF08DeTv3IY9aeooA/Y7qHw2G3w59w5z1bW13Xqdg/dXk JraHMNatEHGWQcxN3Cy/mJFxVRiOeJAnwM8Dc8Fg3S5kzUAco5k2IzCECTjQ58uXR3oB jexn/16ZRZdl/aEsoDnWf54C5jdI9hQSpPuXLNSYy/lLC6RINBnwrrPKvNlL9Emm9A3y Y08HMTxcdqJp8feR4jSFBFjkAi+Rpr+OjsbtCyvT0SM7v8+ihpfVY06PVZyBbGGU935b 8ahhFHDyCp4aX869pTLVnk0/11ewH0E3ocMS51+IYtQPXjpueZkvpbxnFeo367t6dtFM 1I9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152176; x=1714756976; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=P+J+i804wlEe2vVXF+/fWpZaqhveTqz2nQ9x4otbBKQ=; b=XzXHzZcJf/xCmwvJ1NfRMy7wDzsfBEaLoQPWeL8NNX0xFtQhMfRTR1vVu5/oXMyvdk TV/rS9fuJx7e5agAq7QFlfrOlS93VBTc5GeQeLlvdgYeSxF795wDZxlcVJHHUzbOYVFU Vhle2BDB+2c/Mm4tc+/ZEah/SK6oTyFqcqECS0XlR5zSzcnV5EyZU15cEN6h2rB4Bo74 FEaA6PJB/xbwnR9GK2yMjgVJFKNqE2WhA2edMO505qlZaGdzCFqefnw82nroGQlOB7WL I6EMwbDqGGjneQ5ayOZ1A4KCCYdO00k5GGuHRXd8koSA5oKxNi6lkwAkbt4FqsiYvjrv mddg== X-Forwarded-Encrypted: i=1; AJvYcCWxtMhiuGCapXyaWUjXL2Zdm3ixwhavv7tpmDTBK6Wko+5qPHVXLVzJzAzdo3HscrqplSokoafyWKXbqwM8DnoSGwvBQQXCOvdrzCuNzqGP X-Gm-Message-State: AOJu0Yx3C4P0c/uxoN4afU+sXznUjCynd4Tjm1FgtoWJ2qmN9SDjbUMo bS8/vF7TJr1MOWvDl76Sy/Y3ObE8YxRGJmjx0oK0yj9PU4qMIOC9oq2mkUCg3uo= X-Google-Smtp-Source: AGHT+IEw3J0NdE6KdJ8dwVxPsjjXHL9jOFlOB6KOVTNo7v4stgf5CirJHYiZk0JTqiS7Wu0m4mWzyA== X-Received: by 2002:a17:906:b00a:b0:a58:dd06:b8bb with SMTP id v10-20020a170906b00a00b00a58dd06b8bbmr576727ejy.70.1714152176110; Fri, 26 Apr 2024 10:22:56 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:55 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:40 +0200 Subject: [PATCH v4 11/16] ASoC: mediatek: mt8365: Add platform driver MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-11-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=73212; i=amergnat@baylibre.com; h=from:subject:message-id; bh=xiv2meHAbcRhFNsbysJTY5ZFLMpnboY1NF3n/hlRaAI=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LalXW6n9FOubN+4brqlfkyKXaFtBPfXUzyPg3a geli3MyJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURSXyEA CeoAx1cPHTjxGfnOLEbRfO6EVpADPuN/WJhWl6hTN2oWyu9qeBJq62UdyGoqBdJ1BeX6RD3W1fSu0d ybcSZwvvtpJge/lY0Hzx7Jh3JUH3pu/CmV4HFJMTOluqZg+wR/Nrt8YUwntlgK7AQ1fxSDCH5CGKbI mwHSo4fOq81q+AMaigHajm5szyGUsIMayxvbBK639RfE6Ll6+xPkF0ghBQr7vFKkSoWqamf905mF6w BZfYrQbVNRPSuTxQW/8F6N4fr9IDtdEc+3/8qLA+JWz8Ib7k+4+W66hDZ2x2JtK3oYFDe9jj3+Ooua JtqV1uTbfdRhMBaVDuLwMttbn4DxLSfH/6ljjdSwgr+jzV7MvzHqe+XevE7/eA/gNb8aNhgZJ6n+JU kpQT5EG1IUjVlaCLuVWqWfb0rT7AuG7UvuUkeEMTV9j/V8Jjw/ratKshjW7jS6QBRjcBWBnk1UxLRm 98AzZYTLV6bjntuEPE1zeoPgoMxCSORKd7FvlYha8RbBCTev+MpNwPU8iUgQ2uHZIttfIhRQBZyV6Y 02cFMbXlqQl9uWc34KvgSoWOSEqUVUWbX6ewteS8Yh8Xgnt++4nfAibvPxc4i5SUXdScv1h0ZhQ9pz xhgEM3dxjogbdPIiGj6fA8YU/jo+RBXtvsu2nke2HRoczBzm7mEfJTRRZwCQ== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add mt8365 platform driver. Signed-off-by: Alexandre Mergnat Reviewed-by: AngeloGioacchino Del Regno --- sound/soc/mediatek/mt8365/mt8365-afe-pcm.c | 2275 ++++++++++++++++++++++++++++ 1 file changed, 2275 insertions(+) diff --git a/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c b/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c new file mode 100644 index 000000000000..ae99f8bdd251 --- /dev/null +++ b/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c @@ -0,0 +1,2275 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek 8365 ALSA SoC AFE platform driver + * + * Copyright (c) 2024 MediaTek Inc. + * Authors: Jia Zeng + * Alexandre Mergnat + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mt8365-afe-common.h" +#include "mt8365-afe-clk.h" +#include "mt8365-reg.h" +#include "../common/mtk-base-afe.h" +#include "../common/mtk-afe-platform-driver.h" +#include "../common/mtk-afe-fe-dai.h" + +#define AFE_BASE_END_OFFSET 8 + +static unsigned int mCM2Input; + +static const unsigned int mt8365_afe_backup_list[] = { + AUDIO_TOP_CON0, + AFE_CONN0, + AFE_CONN1, + AFE_CONN3, + AFE_CONN4, + AFE_CONN5, + AFE_CONN6, + AFE_CONN7, + AFE_CONN8, + AFE_CONN9, + AFE_CONN10, + AFE_CONN11, + AFE_CONN12, + AFE_CONN13, + AFE_CONN14, + AFE_CONN15, + AFE_CONN16, + AFE_CONN17, + AFE_CONN18, + AFE_CONN19, + AFE_CONN20, + AFE_CONN21, + AFE_CONN26, + AFE_CONN27, + AFE_CONN28, + AFE_CONN29, + AFE_CONN30, + AFE_CONN31, + AFE_CONN32, + AFE_CONN33, + AFE_CONN34, + AFE_CONN35, + AFE_CONN36, + AFE_CONN_24BIT, + AFE_CONN_24BIT_1, + AFE_DAC_CON0, + AFE_DAC_CON1, + AFE_DL1_BASE, + AFE_DL1_END, + AFE_DL2_BASE, + AFE_DL2_END, + AFE_VUL_BASE, + AFE_VUL_END, + AFE_AWB_BASE, + AFE_AWB_END, + AFE_VUL3_BASE, + AFE_VUL3_END, + AFE_HDMI_OUT_BASE, + AFE_HDMI_OUT_END, + AFE_HDMI_IN_2CH_BASE, + AFE_HDMI_IN_2CH_END, + AFE_ADDA_UL_DL_CON0, + AFE_ADDA_DL_SRC2_CON0, + AFE_ADDA_DL_SRC2_CON1, + AFE_I2S_CON, + AFE_I2S_CON1, + AFE_I2S_CON2, + AFE_I2S_CON3, + AFE_ADDA_UL_SRC_CON0, + AFE_AUD_PAD_TOP, + AFE_HD_ENGEN_ENABLE, +}; + +static const struct snd_pcm_hardware mt8365_afe_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .buffer_bytes_max = 256 * 1024, + .period_bytes_min = 512, + .period_bytes_max = 128 * 1024, + .periods_min = 2, + .periods_max = 256, + .fifo_size = 0, +}; + +struct mt8365_afe_rate { + unsigned int rate; + unsigned int reg_val; +}; + +static const struct mt8365_afe_rate mt8365_afe_fs_rates[] = { + { .rate = 8000, .reg_val = MT8365_FS_8K }, + { .rate = 11025, .reg_val = MT8365_FS_11D025K }, + { .rate = 12000, .reg_val = MT8365_FS_12K }, + { .rate = 16000, .reg_val = MT8365_FS_16K }, + { .rate = 22050, .reg_val = MT8365_FS_22D05K }, + { .rate = 24000, .reg_val = MT8365_FS_24K }, + { .rate = 32000, .reg_val = MT8365_FS_32K }, + { .rate = 44100, .reg_val = MT8365_FS_44D1K }, + { .rate = 48000, .reg_val = MT8365_FS_48K }, + { .rate = 88200, .reg_val = MT8365_FS_88D2K }, + { .rate = 96000, .reg_val = MT8365_FS_96K }, + { .rate = 176400, .reg_val = MT8365_FS_176D4K }, + { .rate = 192000, .reg_val = MT8365_FS_192K }, +}; + +int mt8365_afe_fs_timing(unsigned int rate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mt8365_afe_fs_rates); i++) + if (mt8365_afe_fs_rates[i].rate == rate) + return mt8365_afe_fs_rates[i].reg_val; + + return -EINVAL; +} + +bool mt8365_afe_rate_supported(unsigned int rate, unsigned int id) +{ + switch (id) { + case MT8365_AFE_IO_TDM_IN: + if (rate >= 8000 && rate <= 192000) + return true; + break; + case MT8365_AFE_IO_DMIC: + if (rate >= 8000 && rate <= 48000) + return true; + break; + default: + break; + } + + return false; +} + +bool mt8365_afe_channel_supported(unsigned int channel, unsigned int id) +{ + switch (id) { + case MT8365_AFE_IO_TDM_IN: + if (channel >= 1 && channel <= 8) + return true; + break; + case MT8365_AFE_IO_DMIC: + if (channel >= 1 && channel <= 8) + return true; + break; + default: + break; + } + + return false; +} + +bool mt8365_afe_clk_group_44k(int sample_rate) +{ + if (sample_rate == 11025 || + sample_rate == 22050 || + sample_rate == 44100 || + sample_rate == 88200 || + sample_rate == 176400) + return true; + else + return false; +} + +bool mt8365_afe_clk_group_48k(int sample_rate) +{ + return (!mt8365_afe_clk_group_44k(sample_rate)); +} + +int mt8365_dai_set_priv(struct mtk_base_afe *afe, int id, + int priv_size, const void *priv_data) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + void *temp_data; + + temp_data = devm_kzalloc(afe->dev, priv_size, GFP_KERNEL); + if (!temp_data) + return -ENOMEM; + + if (priv_data) + memcpy(temp_data, priv_data, priv_size); + + afe_priv->dai_priv[id] = temp_data; + + return 0; +} + +static int mt8365_afe_irq_direction_enable(struct mtk_base_afe *afe, + int irq_id, int direction) +{ + struct mtk_base_afe_irq *irq; + + if (irq_id >= MT8365_AFE_IRQ_NUM) + return -1; + + irq = &afe->irqs[irq_id]; + + if (direction == MT8365_AFE_IRQ_DIR_MCU) { + regmap_update_bits(afe->regmap, AFE_IRQ_MCU_DSP_EN, + (1 << irq->irq_data->irq_clr_shift), + 0); + regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, + (1 << irq->irq_data->irq_clr_shift), + (1 << irq->irq_data->irq_clr_shift)); + } else if (direction == MT8365_AFE_IRQ_DIR_DSP) { + regmap_update_bits(afe->regmap, AFE_IRQ_MCU_DSP_EN, + (1 << irq->irq_data->irq_clr_shift), + (1 << irq->irq_data->irq_clr_shift)); + regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, + (1 << irq->irq_data->irq_clr_shift), + 0); + } else { + regmap_update_bits(afe->regmap, AFE_IRQ_MCU_DSP_EN, + (1 << irq->irq_data->irq_clr_shift), + (1 << irq->irq_data->irq_clr_shift)); + regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, + (1 << irq->irq_data->irq_clr_shift), + (1 << irq->irq_data->irq_clr_shift)); + } + return 0; +} + +static int mt8365_memif_fs(struct snd_pcm_substream *substream, + unsigned int rate) +{ + return mt8365_afe_fs_timing(rate); +} + +static int mt8365_irq_fs(struct snd_pcm_substream *substream, + unsigned int rate) +{ + return mt8365_memif_fs(substream, rate); +} + +static const struct mt8365_cm_ctrl_reg cm_ctrl_reg[MT8365_CM_NUM] = { + [MT8365_CM1] = { + .con0 = AFE_CM1_CON0, + .con1 = AFE_CM1_CON1, + .con2 = AFE_CM1_CON2, + .con3 = AFE_CM1_CON3, + .con4 = AFE_CM1_CON4, + }, + [MT8365_CM2] = { + .con0 = AFE_CM2_CON0, + .con1 = AFE_CM2_CON1, + .con2 = AFE_CM2_CON2, + .con3 = AFE_CM2_CON3, + .con4 = AFE_CM2_CON4, + } +}; + +static int mt8365_afe_cm2_mux_conn(struct mtk_base_afe *afe) +{ + struct mt8365_afe_private *afe_priv = afe->platform_priv; + unsigned int input = afe_priv->cm2_mux_input; + + /* TDM_IN interconnect to CM2 */ + regmap_update_bits(afe->regmap, AFE_CM2_CONN0, + CM2_AFE_CM2_CONN_CFG1_MASK, + CM2_AFE_CM2_CONN_CFG1(TDM_IN_CH0)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN0, + CM2_AFE_CM2_CONN_CFG2_MASK, + CM2_AFE_CM2_CONN_CFG2(TDM_IN_CH1)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN0, + CM2_AFE_CM2_CONN_CFG3_MASK, + CM2_AFE_CM2_CONN_CFG3(TDM_IN_CH2)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN0, + CM2_AFE_CM2_CONN_CFG4_MASK, + CM2_AFE_CM2_CONN_CFG4(TDM_IN_CH3)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN0, + CM2_AFE_CM2_CONN_CFG5_MASK, + CM2_AFE_CM2_CONN_CFG5(TDM_IN_CH4)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN0, + CM2_AFE_CM2_CONN_CFG6_MASK, + CM2_AFE_CM2_CONN_CFG6(TDM_IN_CH5)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG7_MASK, + CM2_AFE_CM2_CONN_CFG7(TDM_IN_CH6)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG8_MASK, + CM2_AFE_CM2_CONN_CFG8(TDM_IN_CH7)); + + /* ref data interconnect to CM2 */ + if (input == MT8365_FROM_GASRC1) { + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG9_MASK, + CM2_AFE_CM2_CONN_CFG9(GENERAL1_ASRC_OUT_LCH)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG10_MASK, + CM2_AFE_CM2_CONN_CFG10(GENERAL1_ASRC_OUT_RCH)); + } else if (input == MT8365_FROM_GASRC2) { + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG9_MASK, + CM2_AFE_CM2_CONN_CFG9(GENERAL2_ASRC_OUT_LCH)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG10_MASK, + CM2_AFE_CM2_CONN_CFG10(GENERAL2_ASRC_OUT_RCH)); + } else if (input == MT8365_FROM_TDM_ASRC) { + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG9_MASK, + CM2_AFE_CM2_CONN_CFG9(TDM_OUT_ASRC_CH0)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG10_MASK, + CM2_AFE_CM2_CONN_CFG10(TDM_OUT_ASRC_CH1)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG11_MASK, + CM2_AFE_CM2_CONN_CFG11(TDM_OUT_ASRC_CH2)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN1, + CM2_AFE_CM2_CONN_CFG12_MASK, + CM2_AFE_CM2_CONN_CFG12(TDM_OUT_ASRC_CH3)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN2, + CM2_AFE_CM2_CONN_CFG13_MASK, + CM2_AFE_CM2_CONN_CFG13(TDM_OUT_ASRC_CH4)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN2, + CM2_AFE_CM2_CONN_CFG14_MASK, + CM2_AFE_CM2_CONN_CFG14(TDM_OUT_ASRC_CH5)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN2, + CM2_AFE_CM2_CONN_CFG15_MASK, + CM2_AFE_CM2_CONN_CFG15(TDM_OUT_ASRC_CH6)); + regmap_update_bits(afe->regmap, AFE_CM2_CONN2, + CM2_AFE_CM2_CONN_CFG16_MASK, + CM2_AFE_CM2_CONN_CFG16(TDM_OUT_ASRC_CH7)); + } else { + dev_err(afe->dev, "%s wrong CM2 input %d\n", __func__, input); + return -1; + } + + return 0; +} + +static int mt8365_afe_get_cm_update_cnt(struct mtk_base_afe *afe, + enum mt8365_cm_num cmNum, + unsigned int rate, unsigned int channel) +{ + unsigned int total_cnt, div_cnt, ch_pair, best_cnt; + unsigned int ch_update_cnt[MT8365_CM_UPDATA_CNT_SET]; + int i; + + /* calculate cm update cnt + * total_cnt = clk / fs, clk is 26m or 24m or 22m + * div_cnt = total_cnt / ch_pair, max ch 16ch ,2ch is a set + * best_cnt < div_cnt ,we set best_cnt = div_cnt -10 + * ch01 = best_cnt, ch23 = 2* ch01_up_cnt + * ch45 = 3* ch01_up_cnt ...ch1415 = 8* ch01_up_cnt + */ + + if (cmNum == MT8365_CM1) { + total_cnt = MT8365_CLK_26M / rate; + } else if (cmNum == MT8365_CM2) { + if (mt8365_afe_clk_group_48k(rate)) + total_cnt = MT8365_CLK_24M / rate; + else + total_cnt = MT8365_CLK_22M / rate; + } else { + return -1; + } + + if (channel % 2) + ch_pair = (channel / 2) + 1; + else + ch_pair = channel / 2; + + div_cnt = total_cnt / ch_pair; + best_cnt = div_cnt - 10; + + if (best_cnt <= 0) + return -1; + + for (i = 0; i < ch_pair; i++) + ch_update_cnt[i] = (i + 1) * best_cnt; + + switch (channel) { + case 16: + fallthrough; + case 15: + regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con4, + CM_AFE_CM_UPDATE_CNT2_MASK, + CM_AFE_CM_UPDATE_CNT2(ch_update_cnt[7])); + fallthrough; + case 14: + fallthrough; + case 13: + regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con4, + CM_AFE_CM_UPDATE_CNT1_MASK, + CM_AFE_CM_UPDATE_CNT1(ch_update_cnt[6])); + fallthrough; + case 12: + fallthrough; + case 11: + regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con3, + CM_AFE_CM_UPDATE_CNT2_MASK, + CM_AFE_CM_UPDATE_CNT2(ch_update_cnt[5])); + fallthrough; + case 10: + fallthrough; + case 9: + regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con3, + CM_AFE_CM_UPDATE_CNT1_MASK, + CM_AFE_CM_UPDATE_CNT1(ch_update_cnt[4])); + fallthrough; + case 8: + fallthrough; + case 7: + regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con2, + CM_AFE_CM_UPDATE_CNT2_MASK, + CM_AFE_CM_UPDATE_CNT2(ch_update_cnt[3])); + fallthrough; + case 6: + fallthrough; + case 5: + regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con2, + CM_AFE_CM_UPDATE_CNT1_MASK, + CM_AFE_CM_UPDATE_CNT1(ch_update_cnt[2])); + fallthrough; + case 4: + fallthrough; + case 3: + regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con1, + CM_AFE_CM_UPDATE_CNT2_MASK, + CM_AFE_CM_UPDATE_CNT2(ch_update_cnt[1])); + fallthrough; + case 2: + fallthrough; + case 1: + regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con1, + CM_AFE_CM_UPDATE_CNT1_MASK, + CM_AFE_CM_UPDATE_CNT1(ch_update_cnt[0])); + break; + default: + return -1; + } + + return 0; +} + +static int mt8365_afe_configure_cm(struct mtk_base_afe *afe, + enum mt8365_cm_num cmNum, + unsigned int channels, + unsigned int rate) +{ + unsigned int val, mask; + unsigned int fs = mt8365_afe_fs_timing(rate); + + val = FIELD_PREP(CM_AFE_CM_CH_NUM_MASK, (channels - 1)) | + FIELD_PREP(CM_AFE_CM_START_DATA_MASK, 0); + + mask = CM_AFE_CM_CH_NUM_MASK | + CM_AFE_CM_START_DATA_MASK; + + if (cmNum == MT8365_CM1) { + val |= FIELD_PREP(CM_AFE_CM1_IN_MODE_MASK, fs); + + mask |= CM_AFE_CM1_VUL_SEL | + CM_AFE_CM1_IN_MODE_MASK; + } else if (cmNum == MT8365_CM2) { + if (mt8365_afe_clk_group_48k(rate)) + val |= FIELD_PREP(CM_AFE_CM2_CLK_SEL, 0); + else + val |= FIELD_PREP(CM_AFE_CM2_CLK_SEL, 1); + + val |= FIELD_PREP(CM_AFE_CM2_TDM_SEL, 1); + + mask |= CM_AFE_CM2_TDM_SEL | + CM_AFE_CM1_IN_MODE_MASK | + CM_AFE_CM2_CLK_SEL; + + mt8365_afe_cm2_mux_conn(afe); + } else { + return -1; + } + + regmap_update_bits(afe->regmap, cm_ctrl_reg[cmNum].con0, mask, val); + + mt8365_afe_get_cm_update_cnt(afe, cmNum, rate, channels); + + return 0; +} + +int mt8365_afe_fe_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct snd_pcm_runtime *runtime = substream->runtime; + int memif_num = snd_soc_rtd_to_cpu(rtd, 0)->id; + struct mtk_base_afe_memif *memif = &afe->memif[memif_num]; + int ret; + + memif->substream = substream; + + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16); + + snd_soc_set_runtime_hwparams(substream, afe->mtk_afe_hardware); + + ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n"); + + mt8365_afe_enable_main_clk(afe); + return ret; +} + +static void mt8365_afe_fe_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int memif_num = snd_soc_rtd_to_cpu(rtd, 0)->id; + struct mtk_base_afe_memif *memif = &afe->memif[memif_num]; + + memif->substream = NULL; + + mt8365_afe_disable_main_clk(afe); +} + +static int mt8365_afe_fe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_control_data *ctrl_data = &afe_priv->ctrl_data; + int dai_id = snd_soc_rtd_to_cpu(rtd, 0)->id; + struct mtk_base_afe_memif *memif = &afe->memif[dai_id]; + struct mt8365_fe_dai_data *fe_data = &afe_priv->fe_data[dai_id]; + size_t request_size = params_buffer_bytes(params); + unsigned int channels = params_channels(params); + unsigned int rate = params_rate(params); + unsigned int base_end_offset = 8; + int ret, fs; + + dev_info(afe->dev, "%s %s period = %d rate = %d channels = %d\n", + __func__, memif->data->name, params_period_size(params), + rate, channels); + + if (dai_id == MT8365_AFE_MEMIF_VUL2) { + if (!ctrl_data->bypass_cm1) + /* configure cm1 */ + mt8365_afe_configure_cm(afe, MT8365_CM1, + channels, rate); + else + regmap_update_bits(afe->regmap, AFE_CM1_CON0, + CM_AFE_CM1_VUL_SEL, + CM_AFE_CM1_VUL_SEL); + } else if (dai_id == MT8365_AFE_MEMIF_TDM_IN) { + if (!ctrl_data->bypass_cm2) + /* configure cm2 */ + mt8365_afe_configure_cm(afe, MT8365_CM2, + channels, rate); + else + regmap_update_bits(afe->regmap, AFE_CM2_CON0, + CM_AFE_CM2_TDM_SEL, + ~CM_AFE_CM2_TDM_SEL); + + base_end_offset = 4; + } + + if (request_size > fe_data->sram_size) { + ret = snd_pcm_lib_malloc_pages(substream, request_size); + if (ret < 0) { + dev_err(afe->dev, + "%s %s malloc pages %zu bytes failed %d\n", + __func__, memif->data->name, request_size, ret); + return ret; + } + + fe_data->use_sram = false; + + mt8365_afe_emi_clk_on(afe); + } else { + struct snd_dma_buffer *dma_buf = &substream->dma_buffer; + + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf->dev.dev = substream->pcm->card->dev; + dma_buf->area = (unsigned char *)fe_data->sram_vir_addr; + dma_buf->addr = fe_data->sram_phy_addr; + dma_buf->bytes = request_size; + snd_pcm_set_runtime_buffer(substream, dma_buf); + + fe_data->use_sram = true; + } + + memif->phys_buf_addr = lower_32_bits(substream->runtime->dma_addr); + memif->buffer_size = substream->runtime->dma_bytes; + + /* start */ + regmap_write(afe->regmap, memif->data->reg_ofs_base, + memif->phys_buf_addr); + /* end */ + regmap_write(afe->regmap, + memif->data->reg_ofs_base + base_end_offset, + memif->phys_buf_addr + memif->buffer_size - 1); + + /* set channel */ + if (memif->data->mono_shift >= 0) { + unsigned int mono = (params_channels(params) == 1) ? 1 : 0; + + if (memif->data->mono_reg < 0) + dev_info(afe->dev, "%s mono_reg is NULL\n", __func__); + else + regmap_update_bits(afe->regmap, memif->data->mono_reg, + 1 << memif->data->mono_shift, + mono << memif->data->mono_shift); + } + + /* set rate */ + if (memif->data->fs_shift < 0) + return 0; + + fs = afe->memif_fs(substream, params_rate(params)); + + if (fs < 0) + return -EINVAL; + + if (memif->data->fs_reg < 0) + dev_info(afe->dev, "%s fs_reg is NULL\n", __func__); + else + regmap_update_bits(afe->regmap, memif->data->fs_reg, + memif->data->fs_maskbit << memif->data->fs_shift, + fs << memif->data->fs_shift); + + return 0; +} + +static int mt8365_afe_fe_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + int dai_id = snd_soc_rtd_to_cpu(rtd, 0)->id; + struct mtk_base_afe_memif *memif = &afe->memif[dai_id]; + struct mt8365_fe_dai_data *fe_data = &afe_priv->fe_data[dai_id]; + int ret = 0; + + if (fe_data->use_sram) { + snd_pcm_set_runtime_buffer(substream, NULL); + } else { + ret = snd_pcm_lib_free_pages(substream); + + mt8365_afe_emi_clk_off(afe); + } + + return ret; +} + +static int mt8365_afe_fe_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int dai_id = snd_soc_rtd_to_cpu(rtd, 0)->id; + struct mtk_base_afe_memif *memif = &afe->memif[dai_id]; + + /* set format */ + if (memif->data->hd_reg >= 0) { + switch (substream->runtime->format) { + case SNDRV_PCM_FORMAT_S16_LE: + regmap_update_bits(afe->regmap, memif->data->hd_reg, + 3 << memif->data->hd_shift, + 0 << memif->data->hd_shift); + break; + case SNDRV_PCM_FORMAT_S32_LE: + regmap_update_bits(afe->regmap, memif->data->hd_reg, + 3 << memif->data->hd_shift, + 3 << memif->data->hd_shift); + + if (dai_id == MT8365_AFE_MEMIF_TDM_IN) { + regmap_update_bits(afe->regmap, + memif->data->hd_reg, + 3 << memif->data->hd_shift, + 1 << memif->data->hd_shift); + regmap_update_bits(afe->regmap, + memif->data->hd_reg, + 1 << memif->data->hd_align_mshift, + 1 << memif->data->hd_align_mshift); + } + break; + case SNDRV_PCM_FORMAT_S24_LE: + regmap_update_bits(afe->regmap, memif->data->hd_reg, + 3 << memif->data->hd_shift, + 1 << memif->data->hd_shift); + break; + default: + return -EINVAL; + } + } + + mt8365_afe_irq_direction_enable(afe, memif->irq_usage, + MT8365_AFE_IRQ_DIR_MCU); + + return 0; +} + +int mt8365_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + int dai_id = snd_soc_rtd_to_cpu(rtd, 0)->id; + struct mt8365_control_data *ctrl_data = &afe_priv->ctrl_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + /* enable channel merge */ + if (dai_id == MT8365_AFE_MEMIF_VUL2 && + !ctrl_data->bypass_cm1) { + regmap_update_bits(afe->regmap, AFE_CM1_CON0, + CM_AFE_CM_ON, CM_AFE_CM_ON); + } else if (dai_id == MT8365_AFE_MEMIF_TDM_IN && + !ctrl_data->bypass_cm2) { + regmap_update_bits(afe->regmap, AFE_CM2_CON0, + CM_AFE_CM_ON, CM_AFE_CM_ON); + } + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + /* disable channel merge */ + if (dai_id == MT8365_AFE_MEMIF_VUL2 && + !ctrl_data->bypass_cm1) { + regmap_update_bits(afe->regmap, AFE_CM1_CON0, + CM_AFE_CM_ON, ~CM_AFE_CM_ON); + } else if (dai_id == MT8365_AFE_MEMIF_TDM_IN && + !ctrl_data->bypass_cm2) { + regmap_update_bits(afe->regmap, AFE_CM2_CON0, + CM_AFE_CM_ON, ~CM_AFE_CM_ON); + } + break; + default: + break; + } + + return mtk_afe_fe_trigger(substream, cmd, dai); +} + +static int mt8365_afe_hw_gain1_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + mt8365_afe_enable_main_clk(afe); + return 0; +} + +static void mt8365_afe_hw_gain1_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_be_dai_data *be = + &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; + + if (be->prepared[substream->stream]) { + regmap_update_bits(afe->regmap, AFE_GAIN1_CON0, + AFE_GAIN1_CON0_EN_MASK, 0); + be->prepared[substream->stream] = false; + } + mt8365_afe_disable_main_clk(afe); +} + +static int mt8365_afe_hw_gain1_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + struct mt8365_be_dai_data *be = + &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; + + int fs; + unsigned int val1 = 0, val2 = 0; + + if (be->prepared[substream->stream]) { + dev_info(afe->dev, "%s prepared already\n", __func__); + return 0; + } + + fs = mt8365_afe_fs_timing(substream->runtime->rate); + regmap_update_bits(afe->regmap, AFE_GAIN1_CON0, + AFE_GAIN1_CON0_MODE_MASK, (unsigned int)fs << 4); + + regmap_read(afe->regmap, AFE_GAIN1_CON1, &val1); + regmap_read(afe->regmap, AFE_GAIN1_CUR, &val2); + if ((val1 & AFE_GAIN1_CON1_MASK) != (val2 & AFE_GAIN1_CUR_MASK)) + regmap_update_bits(afe->regmap, AFE_GAIN1_CUR, + AFE_GAIN1_CUR_MASK, val1); + + regmap_update_bits(afe->regmap, AFE_GAIN1_CON0, + AFE_GAIN1_CON0_EN_MASK, 1); + be->prepared[substream->stream] = true; + + return 0; +} + +static const struct snd_pcm_hardware mt8365_hostless_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .period_bytes_min = 256, + .period_bytes_max = 4 * 48 * 1024, + .periods_min = 2, + .periods_max = 256, + .buffer_bytes_max = 8 * 48 * 1024, + .fifo_size = 0, +}; + +/* dai ops */ +static int mtk_dai_hostless_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct snd_pcm_runtime *runtime = substream->runtime; + int ret; + + snd_soc_set_runtime_hwparams(substream, &mt8365_hostless_hardware); + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n"); + return ret; +} + +/* FE DAIs */ +static const struct snd_soc_dai_ops mt8365_afe_fe_dai_ops = { + .startup = mt8365_afe_fe_startup, + .shutdown = mt8365_afe_fe_shutdown, + .hw_params = mt8365_afe_fe_hw_params, + .hw_free = mt8365_afe_fe_hw_free, + .prepare = mt8365_afe_fe_prepare, + .trigger = mt8365_afe_fe_trigger, +}; + +static const struct snd_soc_dai_ops mt8365_dai_hostless_ops = { + .startup = mtk_dai_hostless_startup, +}; + +static const struct snd_soc_dai_ops mt8365_afe_hw_gain1_ops = { + .startup = mt8365_afe_hw_gain1_startup, + .shutdown = mt8365_afe_hw_gain1_shutdown, + .prepare = mt8365_afe_hw_gain1_prepare, +}; + +static struct snd_soc_dai_driver mt8365_memif_dai_driver[] = { + /* FE DAIs: memory intefaces to CPU */ + { + .name = "DL1", + .id = MT8365_AFE_MEMIF_DL1, + .playback = { + .stream_name = "DL1", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_fe_dai_ops, + }, { + .name = "DL2", + .id = MT8365_AFE_MEMIF_DL2, + .playback = { + .stream_name = "DL2", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_fe_dai_ops, + }, { + .name = "TDM_OUT", + .id = MT8365_AFE_MEMIF_TDM_OUT, + .playback = { + .stream_name = "TDM_OUT", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_fe_dai_ops, + }, { + .name = "AWB", + .id = MT8365_AFE_MEMIF_AWB, + .capture = { + .stream_name = "AWB", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_fe_dai_ops, + }, { + .name = "VUL", + .id = MT8365_AFE_MEMIF_VUL, + .capture = { + .stream_name = "VUL", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_fe_dai_ops, + }, { + .name = "VUL2", + .id = MT8365_AFE_MEMIF_VUL2, + .capture = { + .stream_name = "VUL2", + .channels_min = 1, + .channels_max = 16, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_fe_dai_ops, + }, { + .name = "VUL3", + .id = MT8365_AFE_MEMIF_VUL3, + .capture = { + .stream_name = "VUL3", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_fe_dai_ops, + }, { + .name = "TDM_IN", + .id = MT8365_AFE_MEMIF_TDM_IN, + .capture = { + .stream_name = "TDM_IN", + .channels_min = 1, + .channels_max = 16, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_fe_dai_ops, + }, { + .name = "Hostless FM DAI", + .id = MT8365_AFE_IO_VIRTUAL_FM, + .playback = { + .stream_name = "Hostless FM DL", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "Hostless FM UL", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_dai_hostless_ops, + }, { + .name = "HW_GAIN1", + .id = MT8365_AFE_IO_HW_GAIN1, + .playback = { + .stream_name = "HW Gain 1 In", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "HW Gain 1 Out", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &mt8365_afe_hw_gain1_ops, + .symmetric_rate = 1, + .symmetric_channels = 1, + .symmetric_sample_bits = 1, + }, +}; + +static const struct snd_kcontrol_new mt8365_afe_o00_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN0, 5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN0, 7, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o01_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN1, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN1, 8, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o03_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN3, 5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN3, 7, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN3, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I10 Switch", AFE_CONN3, 10, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o04_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN4, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN4, 8, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN4, 1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I11 Switch", AFE_CONN4, 11, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o05_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN5, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN5, 3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN5, 5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN5, 7, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I09 Switch", AFE_CONN5, 9, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN5, 14, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN5, 16, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN5, 18, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN5, 20, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN5, 23, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I10L Switch", AFE_CONN5, 10, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o06_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN6, 1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN6, 4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN6, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN6, 8, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I22 Switch", AFE_CONN6, 22, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN6, 15, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN6, 17, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN6, 19, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN6, 21, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN6, 24, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I11L Switch", AFE_CONN6, 11, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o07_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN7, 5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN7, 7, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o08_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN8, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN8, 8, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o09_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN9, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN9, 3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I09 Switch", AFE_CONN9, 9, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN9, 14, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN9, 16, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN9, 18, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN9, 20, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o10_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN10, 1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN10, 4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I22 Switch", AFE_CONN10, 22, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN10, 15, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN10, 17, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN10, 19, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN10, 21, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o11_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN11, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN11, 3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I09 Switch", AFE_CONN11, 9, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN11, 14, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN11, 16, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN11, 18, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN11, 20, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o12_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN12, 1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN12, 4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I22 Switch", AFE_CONN12, 22, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN12, 15, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN12, 17, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN12, 19, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN12, 21, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o13_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN13, 0, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o14_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN14, 1, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o15_mix[] = { +}; + +static const struct snd_kcontrol_new mt8365_afe_o16_mix[] = { +}; + +static const struct snd_kcontrol_new mt8365_afe_o17_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN17, 3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN17, 14, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o18_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN18, 4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN18, 15, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN18, 23, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN18, 25, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o19_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN19, 4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN19, 16, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN19, 23, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN19, 24, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN19, 25, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN19, 26, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o20_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN20, 17, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN20, 24, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN20, 26, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o21_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN21, 18, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN21, 23, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN21, 25, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o22_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN22, 24, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN22, 26, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o23_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN23, 20, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN23, 23, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN23, 25, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o24_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN24, 21, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN24, 24, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN24, 26, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN24, 23, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN24, 25, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o25_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I27 Switch", AFE_CONN25, 27, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I23 Switch", AFE_CONN25, 23, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I25 Switch", AFE_CONN25, 25, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o26_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I28 Switch", AFE_CONN26, 28, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I24 Switch", AFE_CONN26, 24, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN26, 26, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o27_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN27, 5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN27, 7, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o28_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN28, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN28, 8, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o29_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN29, 5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I07 Switch", AFE_CONN29, 7, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o30_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN30, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I08 Switch", AFE_CONN30, 8, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o31_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I29 Switch", AFE_CONN31, 29, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o32_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I30 Switch", AFE_CONN32, 30, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o33_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I31 Switch", AFE_CONN33, 31, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o34_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I32 Switch", AFE_CONN34_1, 0, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o35_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I33 Switch", AFE_CONN35_1, 1, 1, 0), +}; + +static const struct snd_kcontrol_new mt8365_afe_o36_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I34 Switch", AFE_CONN36_1, 2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_hw_gain1_in_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH1 Switch", AFE_CONN13, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_hw_gain1_in_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH2 Switch", AFE_CONN14, + 1, 1, 0), +}; + +static int mt8365_afe_cm2_io_input_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = mCM2Input; + + return 0; +} + +static int mt8365_afe_cm2_io_input_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_context *dapm = + snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *comp = snd_soc_dapm_to_component(dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(comp); + struct mt8365_afe_private *afe_priv = afe->platform_priv; + int ret; + + mCM2Input = ucontrol->value.enumerated.item[0]; + + afe_priv->cm2_mux_input = mCM2Input; + ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); + + return ret; +} + +static const char * const fmhwgain_text[] = { + "OPEN", "FM_HW_GAIN_IO" +}; + +static const char * const ain_text[] = { + "INT ADC", "EXT ADC", +}; + +static const char * const vul2_in_input_text[] = { + "VUL2_IN_FROM_O17O18", "VUL2_IN_FROM_CM1", +}; + +static const char * const mt8365_afe_cm2_mux_text[] = { + "OPEN", "FROM_GASRC1_OUT", "FROM_GASRC2_OUT", "FROM_TDM_ASRC_OUT", +}; + +static SOC_ENUM_SINGLE_VIRT_DECL(fmhwgain_enum, fmhwgain_text); +static SOC_ENUM_SINGLE_DECL(ain_enum, AFE_ADDA_TOP_CON0, 0, ain_text); +static SOC_ENUM_SINGLE_VIRT_DECL(vul2_in_input_enum, vul2_in_input_text); +static SOC_ENUM_SINGLE_VIRT_DECL(mt8365_afe_cm2_mux_input_enum, + mt8365_afe_cm2_mux_text); + +static const struct snd_kcontrol_new fmhwgain_mux = + SOC_DAPM_ENUM("FM HW Gain Source", fmhwgain_enum); + +static const struct snd_kcontrol_new ain_mux = + SOC_DAPM_ENUM("AIN Source", ain_enum); + +static const struct snd_kcontrol_new vul2_in_input_mux = + SOC_DAPM_ENUM("VUL2 Input", vul2_in_input_enum); + +static const struct snd_kcontrol_new mt8365_afe_cm2_mux_input_mux = + SOC_DAPM_ENUM_EXT("CM2_MUX Source", mt8365_afe_cm2_mux_input_enum, + mt8365_afe_cm2_io_input_mux_get, + mt8365_afe_cm2_io_input_mux_put); + +static const struct snd_soc_dapm_widget mt8365_memif_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I01", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I04", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I07", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I08", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I05L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I06L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I07L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I08L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I09", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I10", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I11", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I10L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I11L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I12", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I13", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I14", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I15", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I16", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I19", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I20", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I21", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I22", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I23", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I24", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I25", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I26", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I27", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I28", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I29", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I30", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I31", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I32", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I33", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I34", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("O00", SND_SOC_NOPM, 0, 0, + mt8365_afe_o00_mix, ARRAY_SIZE(mt8365_afe_o00_mix)), + SND_SOC_DAPM_MIXER("O01", SND_SOC_NOPM, 0, 0, + mt8365_afe_o01_mix, ARRAY_SIZE(mt8365_afe_o01_mix)), + SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, + mt8365_afe_o03_mix, ARRAY_SIZE(mt8365_afe_o03_mix)), + SND_SOC_DAPM_MIXER("O04", SND_SOC_NOPM, 0, 0, + mt8365_afe_o04_mix, ARRAY_SIZE(mt8365_afe_o04_mix)), + SND_SOC_DAPM_MIXER("O05", SND_SOC_NOPM, 0, 0, + mt8365_afe_o05_mix, ARRAY_SIZE(mt8365_afe_o05_mix)), + SND_SOC_DAPM_MIXER("O06", SND_SOC_NOPM, 0, 0, + mt8365_afe_o06_mix, ARRAY_SIZE(mt8365_afe_o06_mix)), + SND_SOC_DAPM_MIXER("O07", SND_SOC_NOPM, 0, 0, + mt8365_afe_o07_mix, ARRAY_SIZE(mt8365_afe_o07_mix)), + SND_SOC_DAPM_MIXER("O08", SND_SOC_NOPM, 0, 0, + mt8365_afe_o08_mix, ARRAY_SIZE(mt8365_afe_o08_mix)), + SND_SOC_DAPM_MIXER("O09", SND_SOC_NOPM, 0, 0, + mt8365_afe_o09_mix, ARRAY_SIZE(mt8365_afe_o09_mix)), + SND_SOC_DAPM_MIXER("O10", SND_SOC_NOPM, 0, 0, + mt8365_afe_o10_mix, ARRAY_SIZE(mt8365_afe_o10_mix)), + SND_SOC_DAPM_MIXER("O11", SND_SOC_NOPM, 0, 0, + mt8365_afe_o11_mix, ARRAY_SIZE(mt8365_afe_o11_mix)), + SND_SOC_DAPM_MIXER("O12", SND_SOC_NOPM, 0, 0, + mt8365_afe_o12_mix, ARRAY_SIZE(mt8365_afe_o12_mix)), + SND_SOC_DAPM_MIXER("O13", SND_SOC_NOPM, 0, 0, + mt8365_afe_o13_mix, ARRAY_SIZE(mt8365_afe_o13_mix)), + SND_SOC_DAPM_MIXER("O14", SND_SOC_NOPM, 0, 0, + mt8365_afe_o14_mix, ARRAY_SIZE(mt8365_afe_o14_mix)), + SND_SOC_DAPM_MIXER("O15", SND_SOC_NOPM, 0, 0, + mt8365_afe_o15_mix, ARRAY_SIZE(mt8365_afe_o15_mix)), + SND_SOC_DAPM_MIXER("O16", SND_SOC_NOPM, 0, 0, + mt8365_afe_o16_mix, ARRAY_SIZE(mt8365_afe_o16_mix)), + SND_SOC_DAPM_MIXER("O17", SND_SOC_NOPM, 0, 0, + mt8365_afe_o17_mix, ARRAY_SIZE(mt8365_afe_o17_mix)), + SND_SOC_DAPM_MIXER("O18", SND_SOC_NOPM, 0, 0, + mt8365_afe_o18_mix, ARRAY_SIZE(mt8365_afe_o18_mix)), + SND_SOC_DAPM_MIXER("O19", SND_SOC_NOPM, 0, 0, + mt8365_afe_o19_mix, ARRAY_SIZE(mt8365_afe_o19_mix)), + SND_SOC_DAPM_MIXER("O20", SND_SOC_NOPM, 0, 0, + mt8365_afe_o20_mix, ARRAY_SIZE(mt8365_afe_o20_mix)), + SND_SOC_DAPM_MIXER("O21", SND_SOC_NOPM, 0, 0, + mt8365_afe_o21_mix, ARRAY_SIZE(mt8365_afe_o21_mix)), + SND_SOC_DAPM_MIXER("O22", SND_SOC_NOPM, 0, 0, + mt8365_afe_o22_mix, ARRAY_SIZE(mt8365_afe_o22_mix)), + SND_SOC_DAPM_MIXER("O23", SND_SOC_NOPM, 0, 0, + mt8365_afe_o23_mix, ARRAY_SIZE(mt8365_afe_o23_mix)), + SND_SOC_DAPM_MIXER("O24", SND_SOC_NOPM, 0, 0, + mt8365_afe_o24_mix, ARRAY_SIZE(mt8365_afe_o24_mix)), + SND_SOC_DAPM_MIXER("O25", SND_SOC_NOPM, 0, 0, + mt8365_afe_o25_mix, ARRAY_SIZE(mt8365_afe_o25_mix)), + SND_SOC_DAPM_MIXER("O26", SND_SOC_NOPM, 0, 0, + mt8365_afe_o26_mix, ARRAY_SIZE(mt8365_afe_o26_mix)), + SND_SOC_DAPM_MIXER("O27", SND_SOC_NOPM, 0, 0, + mt8365_afe_o27_mix, ARRAY_SIZE(mt8365_afe_o27_mix)), + SND_SOC_DAPM_MIXER("O28", SND_SOC_NOPM, 0, 0, + mt8365_afe_o28_mix, ARRAY_SIZE(mt8365_afe_o28_mix)), + SND_SOC_DAPM_MIXER("O29", SND_SOC_NOPM, 0, 0, + mt8365_afe_o29_mix, ARRAY_SIZE(mt8365_afe_o29_mix)), + SND_SOC_DAPM_MIXER("O30", SND_SOC_NOPM, 0, 0, + mt8365_afe_o30_mix, ARRAY_SIZE(mt8365_afe_o30_mix)), + SND_SOC_DAPM_MIXER("O31", SND_SOC_NOPM, 0, 0, + mt8365_afe_o31_mix, ARRAY_SIZE(mt8365_afe_o31_mix)), + SND_SOC_DAPM_MIXER("O32", SND_SOC_NOPM, 0, 0, + mt8365_afe_o32_mix, ARRAY_SIZE(mt8365_afe_o32_mix)), + SND_SOC_DAPM_MIXER("O33", SND_SOC_NOPM, 0, 0, + mt8365_afe_o33_mix, ARRAY_SIZE(mt8365_afe_o33_mix)), + SND_SOC_DAPM_MIXER("O34", SND_SOC_NOPM, 0, 0, + mt8365_afe_o34_mix, ARRAY_SIZE(mt8365_afe_o34_mix)), + SND_SOC_DAPM_MIXER("O35", SND_SOC_NOPM, 0, 0, + mt8365_afe_o35_mix, ARRAY_SIZE(mt8365_afe_o35_mix)), + SND_SOC_DAPM_MIXER("O36", SND_SOC_NOPM, 0, 0, + mt8365_afe_o36_mix, ARRAY_SIZE(mt8365_afe_o36_mix)), + SND_SOC_DAPM_MIXER("CM2_Mux IO", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("CM1_IO", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("O17O18", SND_SOC_NOPM, 0, 0, NULL, 0), + /* inter-connections */ + SND_SOC_DAPM_MIXER("HW_GAIN1_IN_CH1", SND_SOC_NOPM, 0, 0, + mtk_hw_gain1_in_ch1_mix, + ARRAY_SIZE(mtk_hw_gain1_in_ch1_mix)), + SND_SOC_DAPM_MIXER("HW_GAIN1_IN_CH2", SND_SOC_NOPM, 0, 0, + mtk_hw_gain1_in_ch2_mix, + ARRAY_SIZE(mtk_hw_gain1_in_ch2_mix)), + + SND_SOC_DAPM_INPUT("DL Source"), + + SND_SOC_DAPM_MUX("CM2_Mux_IO Input Mux", SND_SOC_NOPM, 0, 0, + &mt8365_afe_cm2_mux_input_mux), + + SND_SOC_DAPM_MUX("AIN Mux", SND_SOC_NOPM, 0, 0, &ain_mux), + SND_SOC_DAPM_MUX("VUL2 Input Mux", SND_SOC_NOPM, 0, 0, + &vul2_in_input_mux), + + SND_SOC_DAPM_MUX("FM HW Gain Mux", SND_SOC_NOPM, 0, 0, &fmhwgain_mux), + + SND_SOC_DAPM_INPUT("HW Gain 1 Out Endpoint"), + SND_SOC_DAPM_OUTPUT("HW Gain 1 In Endpoint"), +}; + +static const struct snd_soc_dapm_route mt8365_memif_routes[] = { + /* downlink */ + {"I00", NULL, "2ND I2S Capture"}, + {"I01", NULL, "2ND I2S Capture"}, + {"I05", NULL, "DL1"}, + {"I06", NULL, "DL1"}, + {"I07", NULL, "DL2"}, + {"I08", NULL, "DL2"}, + + {"O03", "I05 Switch", "I05"}, + {"O04", "I06 Switch", "I06"}, + {"O00", "I05 Switch", "I05"}, + {"O01", "I06 Switch", "I06"}, + {"O07", "I05 Switch", "I05"}, + {"O08", "I06 Switch", "I06"}, + {"O27", "I05 Switch", "I05"}, + {"O28", "I06 Switch", "I06"}, + {"O29", "I05 Switch", "I05"}, + {"O30", "I06 Switch", "I06"}, + + {"O03", "I07 Switch", "I07"}, + {"O04", "I08 Switch", "I08"}, + {"O00", "I07 Switch", "I07"}, + {"O01", "I08 Switch", "I08"}, + {"O07", "I07 Switch", "I07"}, + {"O08", "I08 Switch", "I08"}, + + /* uplink */ + {"AWB", NULL, "O05"}, + {"AWB", NULL, "O06"}, + {"VUL", NULL, "O09"}, + {"VUL", NULL, "O10"}, + {"VUL3", NULL, "O11"}, + {"VUL3", NULL, "O12"}, + + {"AIN Mux", "EXT ADC", "I2S Capture"}, + {"I03", NULL, "AIN Mux"}, + {"I04", NULL, "AIN Mux"}, + + {"HW_GAIN1_IN_CH1", "CONNSYS_I2S_CH1", "Hostless FM DL"}, + {"HW_GAIN1_IN_CH2", "CONNSYS_I2S_CH2", "Hostless FM DL"}, + + {"HW Gain 1 In Endpoint", NULL, "HW Gain 1 In"}, + {"HW Gain 1 Out", NULL, "HW Gain 1 Out Endpoint"}, + {"HW Gain 1 In", NULL, "HW_GAIN1_IN_CH1"}, + {"HW Gain 1 In", NULL, "HW_GAIN1_IN_CH2"}, + + {"FM HW Gain Mux", "FM_HW_GAIN_IO", "HW Gain 1 Out"}, + {"Hostless FM UL", NULL, "FM HW Gain Mux"}, + {"Hostless FM UL", NULL, "FM 2ND I2S Mux"}, + + {"O05", "I05 Switch", "I05L"}, + {"O06", "I06 Switch", "I06L"}, + {"O05", "I07 Switch", "I07L"}, + {"O06", "I08 Switch", "I08L"}, + + {"O05", "I03 Switch", "I03"}, + {"O06", "I04 Switch", "I04"}, + {"O05", "I00 Switch", "I00"}, + {"O06", "I01 Switch", "I01"}, + {"O05", "I09 Switch", "I09"}, + {"O06", "I22 Switch", "I22"}, + {"O05", "I14 Switch", "I14"}, + {"O06", "I15 Switch", "I15"}, + {"O05", "I16 Switch", "I16"}, + {"O06", "I17 Switch", "I17"}, + {"O05", "I18 Switch", "I18"}, + {"O06", "I19 Switch", "I19"}, + {"O05", "I20 Switch", "I20"}, + {"O06", "I21 Switch", "I21"}, + {"O05", "I23 Switch", "I23"}, + {"O06", "I24 Switch", "I24"}, + + {"O09", "I03 Switch", "I03"}, + {"O10", "I04 Switch", "I04"}, + {"O09", "I00 Switch", "I00"}, + {"O10", "I01 Switch", "I01"}, + {"O09", "I09 Switch", "I09"}, + {"O10", "I22 Switch", "I22"}, + {"O09", "I14 Switch", "I14"}, + {"O10", "I15 Switch", "I15"}, + {"O09", "I16 Switch", "I16"}, + {"O10", "I17 Switch", "I17"}, + {"O09", "I18 Switch", "I18"}, + {"O10", "I19 Switch", "I19"}, + {"O09", "I20 Switch", "I20"}, + {"O10", "I21 Switch", "I21"}, + + {"O11", "I03 Switch", "I03"}, + {"O12", "I04 Switch", "I04"}, + {"O11", "I00 Switch", "I00"}, + {"O12", "I01 Switch", "I01"}, + {"O11", "I09 Switch", "I09"}, + {"O12", "I22 Switch", "I22"}, + {"O11", "I14 Switch", "I14"}, + {"O12", "I15 Switch", "I15"}, + {"O11", "I16 Switch", "I16"}, + {"O12", "I17 Switch", "I17"}, + {"O11", "I18 Switch", "I18"}, + {"O12", "I19 Switch", "I19"}, + {"O11", "I20 Switch", "I20"}, + {"O12", "I21 Switch", "I21"}, + + /* CM2_Mux*/ + {"CM2_Mux IO", NULL, "CM2_Mux_IO Input Mux"}, + + /* VUL2 */ + {"VUL2", NULL, "VUL2 Input Mux"}, + {"VUL2 Input Mux", "VUL2_IN_FROM_O17O18", "O17O18"}, + {"VUL2 Input Mux", "VUL2_IN_FROM_CM1", "CM1_IO"}, + + {"O17O18", NULL, "O17"}, + {"O17O18", NULL, "O18"}, + {"CM1_IO", NULL, "O17"}, + {"CM1_IO", NULL, "O18"}, + {"CM1_IO", NULL, "O19"}, + {"CM1_IO", NULL, "O20"}, + {"CM1_IO", NULL, "O21"}, + {"CM1_IO", NULL, "O22"}, + {"CM1_IO", NULL, "O23"}, + {"CM1_IO", NULL, "O24"}, + {"CM1_IO", NULL, "O25"}, + {"CM1_IO", NULL, "O26"}, + {"CM1_IO", NULL, "O31"}, + {"CM1_IO", NULL, "O32"}, + {"CM1_IO", NULL, "O33"}, + {"CM1_IO", NULL, "O34"}, + {"CM1_IO", NULL, "O35"}, + {"CM1_IO", NULL, "O36"}, + + {"O17", "I14 Switch", "I14"}, + {"O18", "I15 Switch", "I15"}, + {"O19", "I16 Switch", "I16"}, + {"O20", "I17 Switch", "I17"}, + {"O21", "I18 Switch", "I18"}, + {"O22", "I19 Switch", "I19"}, + {"O23", "I20 Switch", "I20"}, + {"O24", "I21 Switch", "I21"}, + {"O25", "I23 Switch", "I23"}, + {"O26", "I24 Switch", "I24"}, + {"O25", "I25 Switch", "I25"}, + {"O26", "I26 Switch", "I26"}, + + {"O17", "I03 Switch", "I03"}, + {"O18", "I04 Switch", "I04"}, + {"O18", "I23 Switch", "I23"}, + {"O18", "I25 Switch", "I25"}, + {"O19", "I04 Switch", "I04"}, + {"O19", "I23 Switch", "I23"}, + {"O19", "I24 Switch", "I24"}, + {"O19", "I25 Switch", "I25"}, + {"O19", "I26 Switch", "I26"}, + {"O20", "I24 Switch", "I24"}, + {"O20", "I26 Switch", "I26"}, + {"O21", "I23 Switch", "I23"}, + {"O21", "I25 Switch", "I25"}, + {"O22", "I24 Switch", "I24"}, + {"O22", "I26 Switch", "I26"}, + + {"O23", "I23 Switch", "I23"}, + {"O23", "I25 Switch", "I25"}, + {"O24", "I24 Switch", "I24"}, + {"O24", "I26 Switch", "I26"}, + {"O24", "I23 Switch", "I23"}, + {"O24", "I25 Switch", "I25"}, + {"O13", "I00 Switch", "I00"}, + {"O14", "I01 Switch", "I01"}, + {"O03", "I10 Switch", "I10"}, + {"O04", "I11 Switch", "I11"}, +}; + +static const struct mtk_base_memif_data memif_data[MT8365_AFE_MEMIF_NUM] = { + { + .name = "DL1", + .id = MT8365_AFE_MEMIF_DL1, + .reg_ofs_base = AFE_DL1_BASE, + .reg_ofs_cur = AFE_DL1_CUR, + .fs_reg = AFE_DAC_CON1, + .fs_shift = 0, + .fs_maskbit = 0xf, + .mono_reg = AFE_DAC_CON1, + .mono_shift = 21, + .hd_reg = AFE_MEMIF_PBUF_SIZE, + .hd_shift = 16, + .enable_reg = AFE_DAC_CON0, + .enable_shift = 1, + .msb_reg = -1, + .msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + }, { + .name = "DL2", + .id = MT8365_AFE_MEMIF_DL2, + .reg_ofs_base = AFE_DL2_BASE, + .reg_ofs_cur = AFE_DL2_CUR, + .fs_reg = AFE_DAC_CON1, + .fs_shift = 4, + .fs_maskbit = 0xf, + .mono_reg = AFE_DAC_CON1, + .mono_shift = 22, + .hd_reg = AFE_MEMIF_PBUF_SIZE, + .hd_shift = 18, + .enable_reg = AFE_DAC_CON0, + .enable_shift = 2, + .msb_reg = -1, + .msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + }, { + .name = "TDM OUT", + .id = MT8365_AFE_MEMIF_TDM_OUT, + .reg_ofs_base = AFE_HDMI_OUT_BASE, + .reg_ofs_cur = AFE_HDMI_OUT_CUR, + .fs_reg = -1, + .fs_shift = -1, + .fs_maskbit = -1, + .mono_reg = -1, + .mono_shift = -1, + .hd_reg = AFE_MEMIF_PBUF_SIZE, + .hd_shift = 28, + .enable_reg = AFE_HDMI_OUT_CON0, + .enable_shift = 0, + .msb_reg = -1, + .msb_shift = -1, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + }, { + .name = "AWB", + .id = MT8365_AFE_MEMIF_AWB, + .reg_ofs_base = AFE_AWB_BASE, + .reg_ofs_cur = AFE_AWB_CUR, + .fs_reg = AFE_DAC_CON1, + .fs_shift = 12, + .fs_maskbit = 0xf, + .mono_reg = AFE_DAC_CON1, + .mono_shift = 24, + .hd_reg = AFE_MEMIF_PBUF_SIZE, + .hd_shift = 20, + .enable_reg = AFE_DAC_CON0, + .enable_shift = 6, + .msb_reg = AFE_MEMIF_MSB, + .msb_shift = 17, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + }, { + .name = "VUL", + .id = MT8365_AFE_MEMIF_VUL, + .reg_ofs_base = AFE_VUL_BASE, + .reg_ofs_cur = AFE_VUL_CUR, + .fs_reg = AFE_DAC_CON1, + .fs_shift = 16, + .fs_maskbit = 0xf, + .mono_reg = AFE_DAC_CON1, + .mono_shift = 27, + .hd_reg = AFE_MEMIF_PBUF_SIZE, + .hd_shift = 22, + .enable_reg = AFE_DAC_CON0, + .enable_shift = 3, + .msb_reg = AFE_MEMIF_MSB, + .msb_shift = 20, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + }, { + .name = "VUL2", + .id = MT8365_AFE_MEMIF_VUL2, + .reg_ofs_base = AFE_VUL_D2_BASE, + .reg_ofs_cur = AFE_VUL_D2_CUR, + .fs_reg = AFE_DAC_CON0, + .fs_shift = 20, + .fs_maskbit = 0xf, + .mono_reg = -1, + .mono_shift = -1, + .hd_reg = AFE_MEMIF_PBUF_SIZE, + .hd_shift = 14, + .enable_reg = AFE_DAC_CON0, + .enable_shift = 9, + .msb_reg = AFE_MEMIF_MSB, + .msb_shift = 21, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + }, { + .name = "VUL3", + .id = MT8365_AFE_MEMIF_VUL3, + .reg_ofs_base = AFE_VUL3_BASE, + .reg_ofs_cur = AFE_VUL3_CUR, + .fs_reg = AFE_DAC_CON1, + .fs_shift = 8, + .fs_maskbit = 0xf, + .mono_reg = AFE_DAC_CON0, + .mono_shift = 13, + .hd_reg = AFE_MEMIF_PBUF2_SIZE, + .hd_shift = 10, + .enable_reg = AFE_DAC_CON0, + .enable_shift = 12, + .msb_reg = AFE_MEMIF_MSB, + .msb_shift = 27, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + }, { + .name = "TDM IN", + .id = MT8365_AFE_MEMIF_TDM_IN, + .reg_ofs_base = AFE_HDMI_IN_2CH_BASE, + .reg_ofs_cur = AFE_HDMI_IN_2CH_CUR, + .fs_reg = -1, + .fs_shift = -1, + .fs_maskbit = -1, + .mono_reg = AFE_HDMI_IN_2CH_CON0, + .mono_shift = 1, + .hd_reg = AFE_MEMIF_PBUF2_SIZE, + .hd_shift = 8, + .hd_align_mshift = 5, + .enable_reg = AFE_HDMI_IN_2CH_CON0, + .enable_shift = 0, + .msb_reg = AFE_MEMIF_MSB, + .msb_shift = 28, + .agent_disable_reg = -1, + .agent_disable_shift = -1, + }, +}; + +static const struct mtk_base_irq_data irq_data[MT8365_AFE_IRQ_NUM] = { + { + .id = MT8365_AFE_IRQ1, + .irq_cnt_reg = AFE_IRQ_MCU_CNT1, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x3ffff, + .irq_en_reg = AFE_IRQ_MCU_CON, + .irq_en_shift = 0, + .irq_fs_reg = AFE_IRQ_MCU_CON, + .irq_fs_shift = 4, + .irq_fs_maskbit = 0xf, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 0, + }, { + .id = MT8365_AFE_IRQ2, + .irq_cnt_reg = AFE_IRQ_MCU_CNT2, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x3ffff, + .irq_en_reg = AFE_IRQ_MCU_CON, + .irq_en_shift = 1, + .irq_fs_reg = AFE_IRQ_MCU_CON, + .irq_fs_shift = 8, + .irq_fs_maskbit = 0xf, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 1, + }, { + .id = MT8365_AFE_IRQ3, + .irq_cnt_reg = AFE_IRQ_MCU_CNT3, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x3ffff, + .irq_en_reg = AFE_IRQ_MCU_CON, + .irq_en_shift = 2, + .irq_fs_reg = AFE_IRQ_MCU_CON, + .irq_fs_shift = 16, + .irq_fs_maskbit = 0xf, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 2, + }, { + .id = MT8365_AFE_IRQ4, + .irq_cnt_reg = AFE_IRQ_MCU_CNT4, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x3ffff, + .irq_en_reg = AFE_IRQ_MCU_CON, + .irq_en_shift = 3, + .irq_fs_reg = AFE_IRQ_MCU_CON, + .irq_fs_shift = 20, + .irq_fs_maskbit = 0xf, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 3, + }, { + .id = MT8365_AFE_IRQ5, + .irq_cnt_reg = AFE_IRQ_MCU_CNT5, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x3ffff, + .irq_en_reg = AFE_IRQ_MCU_CON2, + .irq_en_shift = 3, + .irq_fs_reg = -1, + .irq_fs_shift = 0, + .irq_fs_maskbit = 0x0, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 4, + }, { + .id = MT8365_AFE_IRQ6, + .irq_cnt_reg = -1, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x0, + .irq_en_reg = AFE_IRQ_MCU_CON, + .irq_en_shift = 13, + .irq_fs_reg = -1, + .irq_fs_shift = 0, + .irq_fs_maskbit = 0x0, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 5, + }, { + .id = MT8365_AFE_IRQ7, + .irq_cnt_reg = AFE_IRQ_MCU_CNT7, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x3ffff, + .irq_en_reg = AFE_IRQ_MCU_CON, + .irq_en_shift = 14, + .irq_fs_reg = AFE_IRQ_MCU_CON, + .irq_fs_shift = 24, + .irq_fs_maskbit = 0xf, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 6, + }, { + .id = MT8365_AFE_IRQ8, + .irq_cnt_reg = AFE_IRQ_MCU_CNT8, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x3ffff, + .irq_en_reg = AFE_IRQ_MCU_CON, + .irq_en_shift = 15, + .irq_fs_reg = AFE_IRQ_MCU_CON, + .irq_fs_shift = 28, + .irq_fs_maskbit = 0xf, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 7, + }, { + .id = MT8365_AFE_IRQ9, + .irq_cnt_reg = -1, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x0, + .irq_en_reg = AFE_IRQ_MCU_CON2, + .irq_en_shift = 2, + .irq_fs_reg = -1, + .irq_fs_shift = 0, + .irq_fs_maskbit = 0x0, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 8, + }, { + .id = MT8365_AFE_IRQ10, + .irq_cnt_reg = AFE_IRQ_MCU_CNT10, + .irq_cnt_shift = 0, + .irq_cnt_maskbit = 0x3ffff, + .irq_en_reg = AFE_IRQ_MCU_CON2, + .irq_en_shift = 4, + .irq_fs_reg = -1, + .irq_fs_shift = 0, + .irq_fs_maskbit = 0x0, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = 9, + }, +}; + +static int memif_specified_irqs[MT8365_AFE_MEMIF_NUM] = { + [MT8365_AFE_MEMIF_DL1] = MT8365_AFE_IRQ1, + [MT8365_AFE_MEMIF_DL2] = MT8365_AFE_IRQ2, + [MT8365_AFE_MEMIF_TDM_OUT] = MT8365_AFE_IRQ5, + [MT8365_AFE_MEMIF_AWB] = MT8365_AFE_IRQ3, + [MT8365_AFE_MEMIF_VUL] = MT8365_AFE_IRQ4, + [MT8365_AFE_MEMIF_VUL2] = MT8365_AFE_IRQ7, + [MT8365_AFE_MEMIF_VUL3] = MT8365_AFE_IRQ8, + [MT8365_AFE_MEMIF_TDM_IN] = MT8365_AFE_IRQ10, +}; + +static const struct regmap_config mt8365_afe_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = MAX_REGISTER, + .cache_type = REGCACHE_NONE, +}; + +static irqreturn_t mt8365_afe_irq_handler(int irq, void *dev_id) +{ + struct mtk_base_afe *afe = dev_id; + unsigned int reg_value; + unsigned int mcu_irq_mask; + int i, ret; + + ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, ®_value); + if (ret) { + dev_err_ratelimited(afe->dev, "%s irq status err\n", __func__); + reg_value = AFE_IRQ_STATUS_BITS; + goto err_irq; + } + + ret = regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_irq_mask); + if (ret) { + dev_err_ratelimited(afe->dev, "%s irq mcu_en err\n", __func__); + reg_value = AFE_IRQ_STATUS_BITS; + goto err_irq; + } + + /* only clr cpu irq */ + reg_value &= mcu_irq_mask; + + for (i = 0; i < MT8365_AFE_MEMIF_NUM; i++) { + struct mtk_base_afe_memif *memif = &afe->memif[i]; + struct mtk_base_afe_irq *mcu_irq; + + if (memif->irq_usage < 0) + continue; + + mcu_irq = &afe->irqs[memif->irq_usage]; + + if (!(reg_value & (1 << mcu_irq->irq_data->irq_clr_shift))) + continue; + + snd_pcm_period_elapsed(memif->substream); + } + +err_irq: + /* clear irq */ + regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, + reg_value & AFE_IRQ_STATUS_BITS); + + return IRQ_HANDLED; +} + +static int __maybe_unused mt8365_afe_runtime_suspend(struct device *dev) +{ + return 0; +} + +static int mt8365_afe_runtime_resume(struct device *dev) +{ + return 0; +} + +static int __maybe_unused mt8365_afe_suspend(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + struct regmap *regmap = afe->regmap; + int i; + + mt8365_afe_enable_main_clk(afe); + + if (!afe->reg_back_up) + afe->reg_back_up = + devm_kcalloc(dev, afe->reg_back_up_list_num, + sizeof(unsigned int), GFP_KERNEL); + + for (i = 0; i < afe->reg_back_up_list_num; i++) + regmap_read(regmap, afe->reg_back_up_list[i], + &afe->reg_back_up[i]); + + mt8365_afe_disable_main_clk(afe); + + return 0; +} + +static int __maybe_unused mt8365_afe_resume(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + struct regmap *regmap = afe->regmap; + int i = 0; + + if (!afe->reg_back_up) + return 0; + + mt8365_afe_enable_main_clk(afe); + + for (i = 0; i < afe->reg_back_up_list_num; i++) + regmap_write(regmap, afe->reg_back_up_list[i], + afe->reg_back_up[i]); + + mt8365_afe_disable_main_clk(afe); + + return 0; +} + +static int __maybe_unused mt8365_afe_dev_runtime_suspend(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + + if (pm_runtime_status_suspended(dev) || afe->suspended) + return 0; + + mt8365_afe_suspend(dev); + afe->suspended = true; + return 0; +} + +static int __maybe_unused mt8365_afe_dev_runtime_resume(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + + if (pm_runtime_status_suspended(dev) || !afe->suspended) + return 0; + + mt8365_afe_resume(dev); + afe->suspended = false; + return 0; +} + +static int mt8365_afe_init_registers(struct mtk_base_afe *afe) +{ + size_t i; + + static struct { + unsigned int reg; + unsigned int mask; + unsigned int val; + } init_regs[] = { + { AFE_CONN_24BIT, GENMASK(31, 0), GENMASK(31, 0) }, + { AFE_CONN_24BIT_1, GENMASK(21, 0), GENMASK(21, 0) }, + }; + + mt8365_afe_enable_main_clk(afe); + + for (i = 0; i < ARRAY_SIZE(init_regs); i++) + regmap_update_bits(afe->regmap, init_regs[i].reg, + init_regs[i].mask, init_regs[i].val); + + mt8365_afe_disable_main_clk(afe); + + return 0; +} + +static int mt8365_dai_memif_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mt8365_memif_dai_driver; + dai->num_dai_drivers = ARRAY_SIZE(mt8365_memif_dai_driver); + + dai->dapm_widgets = mt8365_memif_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mt8365_memif_widgets); + dai->dapm_routes = mt8365_memif_routes; + dai->num_dapm_routes = ARRAY_SIZE(mt8365_memif_routes); + return 0; +} + +typedef int (*dai_register_cb)(struct mtk_base_afe *); +static const dai_register_cb dai_register_cbs[] = { + mt8365_dai_pcm_register, + mt8365_dai_i2s_register, + mt8365_dai_adda_register, + mt8365_dai_dmic_register, + mt8365_dai_memif_register, +}; + +static int mt8365_afe_pcm_dev_probe(struct platform_device *pdev) +{ + struct mtk_base_afe *afe; + struct mt8365_afe_private *afe_priv; + struct device *dev; + int ret, i, sel_irq; + unsigned int irq_id; + struct resource *res; + + afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); + if (!afe) + return -ENOMEM; + platform_set_drvdata(pdev, afe); + + afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), + GFP_KERNEL); + if (!afe->platform_priv) + return -ENOMEM; + + afe_priv = afe->platform_priv; + afe->dev = &pdev->dev; + dev = afe->dev; + + spin_lock_init(&afe_priv->afe_ctrl_lock); + mutex_init(&afe_priv->afe_clk_mutex); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + afe->base_addr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(afe->base_addr)) + return PTR_ERR(afe->base_addr); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res) { + afe_priv->afe_sram_vir_addr = + devm_ioremap_resource(&pdev->dev, res); + if (!IS_ERR(afe_priv->afe_sram_vir_addr)) { + afe_priv->afe_sram_phy_addr = res->start; + afe_priv->afe_sram_size = resource_size(res); + } + } + + /* initial audio related clock */ + ret = mt8365_afe_init_audio_clk(afe); + if (ret) + return dev_err_probe(afe->dev, ret, "mt8365_afe_init_audio_clk fail\n"); + + afe->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "top_audio_sel", + afe->base_addr, + &mt8365_afe_regmap_config); + if (IS_ERR(afe->regmap)) + return PTR_ERR(afe->regmap); + + /* memif % irq initialize*/ + afe->memif_size = MT8365_AFE_MEMIF_NUM; + afe->memif = devm_kcalloc(afe->dev, afe->memif_size, + sizeof(*afe->memif), GFP_KERNEL); + if (!afe->memif) + return -ENOMEM; + + afe->irqs_size = MT8365_AFE_IRQ_NUM; + afe->irqs = devm_kcalloc(afe->dev, afe->irqs_size, + sizeof(*afe->irqs), GFP_KERNEL); + if (!afe->irqs) + return -ENOMEM; + + for (i = 0; i < afe->irqs_size; i++) + afe->irqs[i].irq_data = &irq_data[i]; + + irq_id = platform_get_irq(pdev, 0); + if (!irq_id) { + dev_err_probe(afe->dev, irq_id, "np %s no irq\n", afe->dev->of_node->name); + return -ENXIO; + } + ret = devm_request_irq(afe->dev, irq_id, mt8365_afe_irq_handler, + 0, "Afe_ISR_Handle", (void *)afe); + if (ret) + return dev_err_probe(afe->dev, ret, "could not request_irq\n"); + + /* init sub_dais */ + INIT_LIST_HEAD(&afe->sub_dais); + + for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) { + ret = dai_register_cbs[i](afe); + if (ret) { + dev_warn(afe->dev, "dai register i %d fail, ret %d\n", + i, ret); + return ret; + } + } + + /* init dai_driver and component_driver */ + ret = mtk_afe_combine_sub_dai(afe); + if (ret) { + dev_warn(afe->dev, "mtk_afe_combine_sub_dai fail, ret %d\n", + ret); + return ret; + } + + for (i = 0; i < afe->memif_size; i++) { + afe->memif[i].data = &memif_data[i]; + sel_irq = memif_specified_irqs[i]; + if (sel_irq >= 0) { + afe->memif[i].irq_usage = sel_irq; + afe->memif[i].const_irq = 1; + afe->irqs[sel_irq].irq_occupyed = true; + } else { + afe->memif[i].irq_usage = -1; + } + } + + afe->mtk_afe_hardware = &mt8365_afe_hardware; + afe->memif_fs = mt8365_memif_fs; + afe->irq_fs = mt8365_irq_fs; + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + + pm_runtime_get_sync(&pdev->dev); + afe->reg_back_up_list = mt8365_afe_backup_list; + afe->reg_back_up_list_num = ARRAY_SIZE(mt8365_afe_backup_list); + afe->runtime_resume = mt8365_afe_runtime_resume; + afe->runtime_suspend = mt8365_afe_runtime_suspend; + + /* open afe pdn for dapm read/write audio register */ + mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_AFE); + + /* Set 26m parent clk */ + mt8365_afe_set_clk_parent(afe, + afe_priv->clocks[MT8365_CLK_TOP_AUD_SEL], + afe_priv->clocks[MT8365_CLK_CLK26M]); + + ret = devm_snd_soc_register_component(&pdev->dev, + &mtk_afe_pcm_platform, + afe->dai_drivers, + afe->num_dai_drivers); + if (ret) { + dev_warn(dev, "err_platform\n"); + return ret; + } + + mt8365_afe_init_registers(afe); + + return 0; +} + +static void mt8365_afe_pcm_dev_remove(struct platform_device *pdev) +{ + struct mtk_base_afe *afe = platform_get_drvdata(pdev); + + mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_AFE); + + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + mt8365_afe_runtime_suspend(&pdev->dev); +} + +static const struct of_device_id mt8365_afe_pcm_dt_match[] = { + { .compatible = "mediatek,mt8365-afe-pcm", }, + { } +}; +MODULE_DEVICE_TABLE(of, mt8365_afe_pcm_dt_match); + +static const struct dev_pm_ops mt8365_afe_pm_ops = { + SET_RUNTIME_PM_OPS(mt8365_afe_dev_runtime_suspend, + mt8365_afe_dev_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(mt8365_afe_suspend, + mt8365_afe_resume) +}; + +static struct platform_driver mt8365_afe_pcm_driver = { + .driver = { + .name = "mt8365-afe-pcm", + .of_match_table = mt8365_afe_pcm_dt_match, + .pm = &mt8365_afe_pm_ops, + }, + .probe = mt8365_afe_pcm_dev_probe, + .remove_new = mt8365_afe_pcm_dev_remove, +}; + +module_platform_driver(mt8365_afe_pcm_driver); + +MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver"); +MODULE_AUTHOR("Jia Zeng "); +MODULE_AUTHOR("Alexandre Mergnat "); +MODULE_LICENSE("GPL"); From patchwork Fri Apr 26 17:22:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645166 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0B37EC04FFE for ; Fri, 26 Apr 2024 17:23:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4E2E1113860; Fri, 26 Apr 2024 17:23:33 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="XVpyOYCd"; dkim-atps=neutral Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0C5DF10ECC4 for ; Fri, 26 Apr 2024 17:23:00 +0000 (UTC) Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-a519e1b0e2dso335727866b.2 for ; Fri, 26 Apr 2024 10:22:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152178; x=1714756978; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=zgf/mXl2C5U7vlA8ACZFcZwllbegWSk2iQZif0CPOIs=; b=XVpyOYCdSumLMTQDUpVXkPDhVIbysylvAD5+KxGl5S72UO5K6Sz5E4SPUSmRn6zssS pGNZ32J+g8PRwA/pv9+x71tRGlM1ZnG9V/py3AymJ5nSuwWGaCn2ORqneS1ALDm1lCN7 GvckeaNiq4iPceNOqCESmdAaf0pThpne35+DgsodSPrgOxZ2/dDr6Z8i58TQIh9wuEqa UXaeeE1xxwfg1MiZTU6X9ZOpm7v7t3wReehuTQvSLg5WzdkQxDux+CLEpoKz25gP1wg8 HhVj0urbgm0fo/vaHDu+QVh24fKteZfL4UYuMk3kRTSevywuaLhenb8eBrCgbHVQXvV5 TYiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152178; x=1714756978; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zgf/mXl2C5U7vlA8ACZFcZwllbegWSk2iQZif0CPOIs=; b=qGHxjSrI687FgoU0A5j3AsbicV7MWoXCKf4OAkKag9mNsHdI2YLO2FFHwRmPiN5GgQ T+n2KPqI5slkR2vb66UqFBalvnfrv4q6th/Da+K41MIcHuyVKjvGrJgkdH5O/kOy1aZW 725A3+uDcZA6RjYdYMfNZ/AqwQP1snAScnjONIZxRDOd3sZxa3kb8xCaQi5B8bnCB3aW P4CbfRruU59grlarLOLK4mD3QTTQZIL6LPgABkgMSy9qhZoUgXbxnRvpeSWT4G/z2/bQ kBuc/ZTYRm+4RrK8ppvnbImVGW76BmjWnfhuQCs8nu/sWP7zt2eS5cw9MnpZBWzhs/zI f+ow== X-Forwarded-Encrypted: i=1; AJvYcCXLj/EP04P532DSjgWAheXGi/R31Z7WYAnrhZgSwwXp/Gv4+g7q9gKf68xA83sC1n4QoZ/c+fv0h3OPGbNdG/kGfypiznTwtyi0j7YmY1jB X-Gm-Message-State: AOJu0Yyrcof8EncD3rcR3+Kutb+fG7P+RngF/fJpOKCUi7VyjbtnwMwB x3QBRsoxBK1Gug/l1i7AnJ9o14I8WEMC7e3DWGRcyISnYwzCHLiPjaWmNofNbQk= X-Google-Smtp-Source: AGHT+IE9FC+DkyS6cAC0bNM0hNLA/SLAeV/RnHijpLiivM4WICirVevp6K/CHP8mDiS5M4D+UK69Xg== X-Received: by 2002:a17:906:c53:b0:a58:72c2:a64b with SMTP id t19-20020a1709060c5300b00a5872c2a64bmr2453583ejf.43.1714152178089; Fri, 26 Apr 2024 10:22:58 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:57 -0700 (PDT) From: amergnat@baylibre.com Date: Fri, 26 Apr 2024 19:22:41 +0200 Subject: [PATCH v4 12/16] ASoC: codecs: add MT6357 support MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-12-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat , Nicolas Belin X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=98869; i=amergnat@baylibre.com; h=from:subject:message-id; bh=SXiICfOdlrMZXIbwH6KNp1vppNcnArmuNy9qB2ma5s0=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaMlMCIg0oTfSY55L/TjqybGhaiJNVDWC+FLo8 w/V3AumJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURdKRD/ 9lte+vdMo/BY7hffvbc2BVr7HcIshVXXW2Y1SWyTrH6xvK25Eu6x5sQM30hGxRIvGsBuzrsgRIBPk2 Yz2CquVagwktRyXHCu/NfKZTwNc0vV6Zj/rVFSie0mT2jQXrJ6MgEppWUkPYV/EsZlPNBRimkg6hX2 oG/2DiOgJxwjTZZGtpOCles+vFNOAAdyIgr0xPm6ryd1nfGi0Bpso+esqSfhHVNB1Lr5+VXvDMGAEx gRbZWmWBALOoUzdN8tz8zCYnAaKU2og8tj4ctKdBaYV76a8zOOPRtOSs9Mj1BNoZMAdNALNdEcIUnW diztppp+PXogAefgze6TGbicKARcsSjWZIvul08eA+i/KXjNgbtuDJbJ9zqPzlHfMD4CWFBVZs1kfn ZGFKciiv3AyrYh9hSNFZ23W1+MZcb1AmB0xoLA81ft9WaUwYrx9AwYFc63CheSTdcJXodDUVcUKsGZ gxtR2uvG5EGdc1LFb5hzmTyPY/LmgDXnlgHKuqzVV4uDoOgyoqwAMEIMhM+ryJqTfYHp0nulFbobXl kis0SSIr5thSsjY0Z0xdrY+xrHE6pcGB5tpqztNtQrFnWl9VsFgISmMfbpHKzVeH/GcTjfXbBWZMwi HNsHVpgFw4bty7z6GAEVvecq4ZFfa6aT4SaZ6nX2DKjIAGHc3nmMJw3ojwYQ== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Nicolas Belin Add the support of MT6357 PMIC audio codec. Signed-off-by: Nicolas Belin Signed-off-by: Alexandre Mergnat --- sound/soc/codecs/Kconfig | 7 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/mt6357.c | 1898 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/mt6357.h | 662 ++++++++++++++++ 4 files changed, 2569 insertions(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 995eab954dd5..94674854c80e 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -154,6 +154,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_MC13783 imply SND_SOC_ML26124 imply SND_SOC_MT6351 + imply SND_SOC_MT6357 imply SND_SOC_MT6358 imply SND_SOC_MT6359 imply SND_SOC_MT6660 @@ -2425,6 +2426,12 @@ config SND_SOC_ML26124 config SND_SOC_MT6351 tristate "MediaTek MT6351 Codec" +config SND_SOC_MT6357 + tristate "MediaTek MT6357 Codec" + help + Enable support for the platform which uses MT6357 as + external codec device. + config SND_SOC_MT6358 tristate "MediaTek MT6358 Codec" help diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 9ba24fb870b1..d43a6065706c 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -172,6 +172,7 @@ snd-soc-ml26124-objs := ml26124.o snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o snd-soc-mt6351-objs := mt6351.o +snd-soc-mt6357-objs := mt6357.o snd-soc-mt6358-objs := mt6358.o snd-soc-mt6359-objs := mt6359.o snd-soc-mt6359-accdet-objs := mt6359-accdet.o @@ -563,6 +564,7 @@ obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o obj-$(CONFIG_SND_SOC_MT6351) += snd-soc-mt6351.o +obj-$(CONFIG_SND_SOC_MT6357) += snd-soc-mt6357.o obj-$(CONFIG_SND_SOC_MT6358) += snd-soc-mt6358.o obj-$(CONFIG_SND_SOC_MT6359) += snd-soc-mt6359.o obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o diff --git a/sound/soc/codecs/mt6357.c b/sound/soc/codecs/mt6357.c new file mode 100644 index 000000000000..667ba6854510 --- /dev/null +++ b/sound/soc/codecs/mt6357.c @@ -0,0 +1,1898 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MT6357 ALSA SoC audio codec driver + * + * Copyright (c) 2024 Baylibre + * Author: Nicolas Belin + */ + +#include +#include +#include +#include +#include + +#include "mt6357.h" + +static void set_playback_gpio(struct mt6357_priv *priv, bool enable) +{ + regmap_write(priv->regmap, MT6357_GPIO_MODE2_CLR, MT6357_GPIO_MODE2_CLEAR_ALL); + if (enable) { + /* set gpio mosi mode */ + regmap_write(priv->regmap, MT6357_GPIO_MODE2_SET, + MT6357_GPIO8_MODE_SET_AUD_CLK_MOSI | + MT6357_GPIO9_MODE_SET_AUD_DAT_MOSI0 | + MT6357_GPIO10_MODE_SET_AUD_DAT_MOSI1 | + MT6357_GPIO11_MODE_SET_AUD_SYNC_MOSI); + } else { + /* pad_aud_*_mosi are GPIO mode after clear and set them to dir input + * reason: + * pad_aud_dat_mosi*, because the pin is used as boot strap + */ + regmap_update_bits(priv->regmap, MT6357_GPIO_DIR0, + MT6357_GPIO8_DIR_MASK | + MT6357_GPIO9_DIR_MASK | + MT6357_GPIO10_DIR_MASK | + MT6357_GPIO11_DIR_MASK, + MT6357_GPIO8_DIR_INPUT | + MT6357_GPIO9_DIR_INPUT | + MT6357_GPIO10_DIR_INPUT | + MT6357_GPIO11_DIR_INPUT); + } +} + +static void set_capture_gpio(struct mt6357_priv *priv, bool enable) +{ + regmap_write(priv->regmap, MT6357_GPIO_MODE3_CLR, MT6357_GPIO_MODE3_CLEAR_ALL); + if (enable) { + /* set gpio miso mode */ + regmap_write(priv->regmap, MT6357_GPIO_MODE3_SET, + MT6357_GPIO12_MODE_SET_AUD_CLK_MISO | + MT6357_GPIO13_MODE_SET_AUD_DAT_MISO0 | + MT6357_GPIO14_MODE_SET_AUD_DAT_MISO1 | + MT6357_GPIO15_MODE_SET_AUD_SYNC_MISO); + } else { + /* pad_aud_*_mosi are GPIO mode after clear and set them to dir input + * reason: + * pad_aud_clk_miso, because when playback only the miso_clk + * will also have 26m, so will have power leak + * pad_aud_dat_miso*, because the pin is used as boot strap + */ + regmap_update_bits(priv->regmap, MT6357_GPIO_DIR0, + MT6357_GPIO12_DIR_MASK | + MT6357_GPIO13_DIR_MASK | + MT6357_GPIO14_DIR_MASK | + MT6357_GPIO15_DIR_MASK, + MT6357_GPIO12_DIR_INPUT | + MT6357_GPIO13_DIR_INPUT | + MT6357_GPIO14_DIR_INPUT | + MT6357_GPIO15_DIR_INPUT); + } +} + +static void hp_main_output_ramp(struct mt6357_priv *priv, bool up) +{ + int i, stage; + + /* Enable/Reduce HPL/R main output stage step by step */ + for (i = 0; i <= MT6357_HPLOUT_STG_CTRL_VAUDP15_MAX; i++) { + stage = up ? i : MT6357_HPLOUT_STG_CTRL_VAUDP15_MAX - i; + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPLOUT_STG_CTRL_VAUDP15_MASK, + stage << MT6357_HPLOUT_STG_CTRL_VAUDP15_SFT); + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPROUT_STG_CTRL_VAUDP15_MASK, + stage << MT6357_HPROUT_STG_CTRL_VAUDP15_SFT); + usleep_range(600, 700); + } +} + +static void hp_aux_feedback_loop_gain_ramp(struct mt6357_priv *priv, bool up) +{ + int i, stage; + + /* Reduce HP aux feedback loop gain step by step */ + for (i = 0; i <= MT6357_HP_AUX_LOOP_GAIN_MAX; i++) { + stage = up ? i : MT6357_HP_AUX_LOOP_GAIN_MAX - i; + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_HP_AUX_LOOP_GAIN_MASK, + stage << MT6357_HP_AUX_LOOP_GAIN_SFT); + usleep_range(600, 700); + } +} + +static void hp_pull_down(struct mt6357_priv *priv, bool enable) +{ + if (enable) + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2, + MT6357_HPP_SHORT_2VCM_VAUDP15_MASK, + MT6357_HPP_SHORT_2VCM_VAUDP15_ENABLE); + else + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2, + MT6357_HPP_SHORT_2VCM_VAUDP15_MASK, + MT6357_HPP_SHORT_2VCM_VAUDP15_DISABLE); +} + +static bool is_valid_hp_pga_idx(int reg_idx) +{ + return (reg_idx >= DL_GAIN_8DB && reg_idx <= DL_GAIN_N_12DB) || reg_idx == DL_GAIN_N_40DB; +} + +static void volume_ramp(struct mt6357_priv *priv, int lfrom, int lto, + int rfrom, int rto, unsigned int reg_addr) +{ + int lcount, rcount, sleep = 0; + + if (!is_valid_hp_pga_idx(lfrom) || !is_valid_hp_pga_idx(lto)) + pr_debug("%s(), invalid left volume index, from %d, to %d\n", + __func__, lfrom, lto); + + if (!is_valid_hp_pga_idx(rfrom) || !is_valid_hp_pga_idx(rto)) + pr_debug("%s(), invalid right volume index, from %d, to %d\n", + __func__, rfrom, rto); + + if (lto > lfrom) + lcount = 1; + else + lcount = -1; + + if (rto > rfrom) + rcount = 1; + else + rcount = -1; + + while ((lto != lfrom) || (rto != rfrom)) { + if (lto != lfrom) { + lfrom += lcount; + if (is_valid_hp_pga_idx(lfrom)) { + regmap_update_bits(priv->regmap, reg_addr, + MT6357_DL_GAIN_REG_LEFT_MASK, + lfrom << MT6357_DL_GAIN_REG_LEFT_SHIFT); + sleep = 1; + } + } + if (rto != rfrom) { + rfrom += rcount; + if (is_valid_hp_pga_idx(rfrom)) { + regmap_update_bits(priv->regmap, reg_addr, + MT6357_DL_GAIN_REG_RIGHT_MASK, + rfrom << MT6357_DL_GAIN_REG_RIGHT_SHIFT); + sleep = 1; + } + } + if (sleep) + usleep_range(200, 300); + } +} + +static void lo_volume_ramp(struct mt6357_priv *priv, int lfrom, int lto, int rfrom, int rto) +{ + volume_ramp(priv, lfrom, lto, rfrom, rto, MT6357_ZCD_CON1); +} + +static void hp_volume_ramp(struct mt6357_priv *priv, int lfrom, int lto, int rfrom, int rto) +{ + volume_ramp(priv, lfrom, lto, rfrom, rto, MT6357_ZCD_CON2); +} + +static void hs_volume_ramp(struct mt6357_priv *priv, int from, int to) +{ + volume_ramp(priv, from, to, 0, 0, MT6357_ZCD_CON3); +} + +/* Volume and channel swap controls */ +static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0); +static const DECLARE_TLV_DB_SCALE(capture_tlv, 0, 600, 0); +static const DECLARE_TLV_DB_SCALE(hp_degain_tlv, -1200, 1200, 0); + +static const struct snd_kcontrol_new mt6357_controls[] = { + /* dl pga gain */ + SOC_DOUBLE_TLV("Headphone Volume", + MT6357_ZCD_CON2, MT6357_AUD_HPL_GAIN_SFT, + MT6357_AUD_HPR_GAIN_SFT, MT6357_AUD_HP_GAIN_MAX, + 1, playback_tlv), + SOC_SINGLE_TLV("Headphone Vin Volume", + MT6357_AUDDEC_ANA_CON7, MT6357_HP_IVBUF_DEGAIN_SFT, + MT6357_HP_IVBUF_DEGAIN_MAX, 1, hp_degain_tlv), + SOC_DOUBLE_TLV("Lineout Volume", + MT6357_ZCD_CON1, MT6357_AUD_LOL_GAIN_SFT, + MT6357_AUD_LOR_GAIN_SFT, MT6357_AUD_LO_GAIN_MAX, + 1, playback_tlv), + SOC_SINGLE_TLV("Handset Volume", + MT6357_ZCD_CON3, MT6357_AUD_HS_GAIN_SFT, + MT6357_AUD_HS_GAIN_MAX, 1, playback_tlv), + /* ul pga gain */ + SOC_DOUBLE_R_TLV("Mic Volume", + MT6357_AUDENC_ANA_CON0, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPLGAIN_SFT, MT6357_AUDPREAMPLGAIN_MAX, + 0, capture_tlv), +}; + +/* Uplink controls */ + +enum { + MIC_TYPE_MUX_IDLE, + MIC_TYPE_MUX_ACC, + MIC_TYPE_MUX_DMIC, + MIC_TYPE_MUX_DCC, + MIC_TYPE_MUX_DCC_ECM_DIFF, + MIC_TYPE_MUX_DCC_ECM_SINGLE, + MIC_TYPE_MUX_LPBK, + MIC_TYPE_MUX_SGEN, +}; + +#define IS_DCC_BASE(type) ((type) == MIC_TYPE_MUX_DCC || \ + (type) == MIC_TYPE_MUX_DCC_ECM_DIFF || \ + (type) == MIC_TYPE_MUX_DCC_ECM_SINGLE) + +static const char * const mic_type_mux_map[] = { + "Idle", + "ACC", + "DMIC", + "DCC", + "DCC_ECM_DIFF", + "DCC_ECM_SINGLE", + "Loopback", + "Sine Generator", +}; + +static SOC_ENUM_SINGLE_DECL(mic_type_mux_map_enum, SND_SOC_NOPM, + 0, mic_type_mux_map); + +static const struct snd_kcontrol_new mic_type_mux_control = + SOC_DAPM_ENUM("Mic Type Select", mic_type_mux_map_enum); + +static const char * const pga_mux_map[] = { + "None", "AIN0", "AIN1", "AIN2" +}; + +static SOC_ENUM_SINGLE_DECL(pga_left_mux_map_enum, + MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLINPUTSEL_SFT, + pga_mux_map); + +static const struct snd_kcontrol_new pga_left_mux_control = + SOC_DAPM_ENUM("PGA L Select", pga_left_mux_map_enum); + +static SOC_ENUM_SINGLE_DECL(pga_right_mux_map_enum, + MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRINPUTSEL_SFT, + pga_mux_map); + +static const struct snd_kcontrol_new pga_right_mux_control = + SOC_DAPM_ENUM("PGA R Select", pga_right_mux_map_enum); + +/* Downlink controls */ +static const char * const hslo_mux_map[] = { + "Open", "DACR", "Playback", "Test mode" +}; + +static SOC_ENUM_SINGLE_DECL(lo_mux_map_enum, + MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOL_MUX_INPUT_VAUDP15_SFT, + hslo_mux_map); + +static const struct snd_kcontrol_new lo_mux_control = + SOC_DAPM_ENUM("Line out source", lo_mux_map_enum); + +static SOC_ENUM_SINGLE_DECL(hs_mux_map_enum, + MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HS_MUX_INPUT_VAUDP15_SFT, + hslo_mux_map); + +static const struct snd_kcontrol_new hs_mux_control = + SOC_DAPM_ENUM("Handset source", hs_mux_map_enum); + +static const char * const hplr_mux_map[] = { + "Open", "Line Out", "DAC", "Handset" +}; + +static SOC_ENUM_SINGLE_DECL(hpr_mux_map_enum, + MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_HPR_MUX_INPUT_VAUDP15_SFT, + hplr_mux_map); + +static const struct snd_kcontrol_new hpr_mux_control = + SOC_DAPM_ENUM("Headphone Right source", hpr_mux_map_enum); + +static SOC_ENUM_SINGLE_DECL(hpl_mux_map_enum, + MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_HPL_MUX_INPUT_VAUDP15_SFT, + hplr_mux_map); + +static const struct snd_kcontrol_new hpl_mux_control = + SOC_DAPM_ENUM("Headphone Left source", hpl_mux_map_enum); + +static const char * const dac_mux_map[] = { + "Normal Path", "Sine Generator" +}; + +static SOC_ENUM_SINGLE_DECL(dac_mux_map_enum, + MT6357_AFE_TOP_CON0, + MT6357_DL_SINE_ON_SFT, + dac_mux_map); + +static const struct snd_kcontrol_new dac_mux_control = + SOC_DAPM_ENUM("DAC Select", dac_mux_map_enum); + +static int mt6357_set_dmic(struct mt6357_priv *priv, bool enable) +{ + if (enable) { + /* DMIC enable */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON7, + MT6357_AUDDIGMICBIAS_MASK | MT6357_AUDDIGMICEN_MASK, + MT6357_AUDDIGMICBIAS_DEFAULT_VALUE | MT6357_AUDDIGMICEN_ENABLE); + /* enable aud_pad TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE); + /* UL dmic setting: dual mode */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_H, + MT6357_C_TWO_DIGITAL_MIC_CTL_MASK, + MT6357_C_TWO_DIGITAL_MIC_ENABLE); + /* UL turn on SDM 3 level mode */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SDM_3_LEVEL_CTL_MASK, + MT6357_UL_SDM_3_LEVEL_SELECT); + /* UL turn on */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SRC_ON_TMP_CTL_MASK, + MT6357_UL_SRC_ENABLE); + /* Wait to avoid any pop noises */ + msleep(100); + } else { + /* UL turn off */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SRC_ON_TMP_CTL_MASK, + MT6357_UL_SRC_DISABLE); + /* UL turn on SDM 3 level mode */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SDM_3_LEVEL_CTL_MASK, + MT6357_UL_SDM_3_LEVEL_DESELECT); + /* disable aud_pad TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE); + /* UL dmic setting: dual mode */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_H, + MT6357_C_TWO_DIGITAL_MIC_CTL_MASK, + MT6357_C_TWO_DIGITAL_MIC_DISABLE); + /* DMIC disable */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON7, + MT6357_AUDDIGMICBIAS_MASK | MT6357_AUDDIGMICEN_MASK, + MT6357_AUDDIGMICBIAS_OFF | MT6357_AUDDIGMICEN_DISABLE); + } + return 0; +} + +static int mt6357_set_amic(struct mt6357_priv *priv, bool enable, unsigned int mic_type) +{ + if (enable) { + if (IS_DCC_BASE(mic_type)) { + regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0, + MT6357_DCCLK_DIV_MASK, MT6357_DCCLK_DIV_RUN_VALUE); + regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0, + MT6357_DCCLK_PDN_MASK, MT6357_DCCLK_OUTPUT); + regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0, + MT6357_DCCLK_GEN_ON_MASK, MT6357_DCCLK_GEN_ON); + regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG1, + MT6357_DCCLK_RESYNC_BYPASS_MASK, + MT6357_DCCLK_RESYNC_BYPASS); + + /* mic bias 0: set the correct DC couple*/ + switch (mic_type) { + case MIC_TYPE_MUX_DCC_ECM_DIFF: + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8, + MT6357_AUD_MICBIAS0_DC_MASK, + MT6357_AUD_MICBIAS0_DC_ENABLE_ALL); + break; + case MIC_TYPE_MUX_DCC_ECM_SINGLE: + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8, + MT6357_AUD_MICBIAS0_DC_MASK, + MT6357_AUD_MICBIAS0_DC_ENABLE_P1); + break; + default: + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8, + MT6357_AUD_MICBIAS0_DC_MASK, + MT6357_AUD_MICBIAS0_DC_DISABLE_ALL); + break; + } + + /* mic bias 1: set the correct DC couple */ + if (mic_type == MIC_TYPE_MUX_DCC_ECM_SINGLE) + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON9, + MT6357_AUD_MICBIAS1_DCSW1P_EN_MASK, + MT6357_AUD_MICBIAS1_DCSW1P_ENABLE); + + /* Audio L/R preamplifier DCC precharge */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLDCPRECHARGE_MASK, + MT6357_AUDPREAMPLDCPRECHARGE_ENABLE); + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRDCPRECHARGE_MASK, + MT6357_AUDPREAMPRDCPRECHARGE_ENABLE); + /* L preamplifier DCCEN */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLDCCEN_MASK, + MT6357_AUDPREAMPLDCCEN_DC); + /* R preamplifier DCCEN */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRDCCEN_MASK, + MT6357_AUDPREAMPRDCCEN_DC); + } else { + /* Audio L preamplifier DCC precharge disable */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLDCPRECHARGE_MASK, + MT6357_AUDPREAMPLDCPRECHARGE_DISABLE); + /* L preamplifier ACC */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLDCCEN_MASK, + MT6357_AUDPREAMPLDCCEN_AC); + /* Audio R preamplifier DCC precharge disable */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRDCPRECHARGE_MASK, + MT6357_AUDPREAMPRDCPRECHARGE_DISABLE); + /* R preamplifier ACC */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRDCCEN_MASK, + MT6357_AUDPREAMPRDCCEN_AC); + } + } else { + /* disable any Mic Bias 0 DC couple */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8, + MT6357_AUD_MICBIAS0_DC_MASK, + MT6357_AUD_MICBIAS0_DC_DISABLE_ALL); + /* disable any Mic Bias 1 DC couple */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON9, + MT6357_AUD_MICBIAS1_DCSW1P_EN_MASK, + MT6357_AUD_MICBIAS1_DCSW1P_DISABLE); + if (IS_DCC_BASE(mic_type)) { + regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0, + MT6357_DCCLK_GEN_ON_MASK, MT6357_DCCLK_GEN_OFF); + regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0, + MT6357_DCCLK_PDN_MASK, MT6357_DCCLK_PDN); + regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0, + MT6357_DCCLK_DIV_MASK, MT6357_DCCLK_DIV_STOP_VALUE); + } + } + + return 0; +} + +static int mt6357_set_loopback(struct mt6357_priv *priv, bool enable) +{ + if (enable) { + /* enable aud_pad TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE); + /* enable aud_pad lpk TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_LPBK_MASK, + MT6357_AUD_PAD_TX_FIFO_LPBK_ENABLE); + /* Set UL Part: enable new lpbk 2 */ + regmap_update_bits(priv->regmap, MT6357_AFE_ADDA_MTKAIF_CFG0, + MT6357_ADDA_MTKAIF_LPBK_CTL_MASK, + MT6357_ADDA_MTKAIF_LPBK_ENABLE); + /* UL turn on */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SRC_ON_TMP_CTL_MASK, + MT6357_UL_SRC_ENABLE); + } else { + /* UL turn off */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SRC_ON_TMP_CTL_MASK, + MT6357_UL_SRC_DISABLE); + /* disable new lpbk 2 */ + regmap_update_bits(priv->regmap, MT6357_AFE_ADDA_MTKAIF_CFG0, + MT6357_ADDA_MTKAIF_LPBK_CTL_MASK, + MT6357_ADDA_MTKAIF_LPBK_DISABLE); + /* disable aud_pad lpbk TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_LPBK_MASK, + MT6357_AUD_PAD_TX_FIFO_LPBK_DISABLE); + /* disable aud_pad TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE); + } + + return 0; +} + +static int mt6357_set_ul_sine_gen(struct mt6357_priv *priv, bool enable) +{ + if (enable) { + /* enable aud_pad TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE); + /* UL turn on */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SRC_ON_TMP_CTL_MASK, + MT6357_UL_SRC_ENABLE); + } else { + /* UL turn off */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SRC_ON_TMP_CTL_MASK, + MT6357_UL_SRC_DISABLE); + /* disable aud_pad TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE); + } + + return 0; +} + +static int mt_aif_out_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + set_capture_gpio(priv, true); + break; + case SND_SOC_DAPM_POST_PMD: + set_capture_gpio(priv, false); + break; + default: + break; + } + + return 0; +} + +static int mt_adc_supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enable audio ADC CLKGEN */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11, + MT6357_RSTB_ENCODER_VA28_MASK, MT6357_RSTB_ENCODER_VA28_ENABLE); + /* Enable LCLDO_ENC 2P8V */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12, + MT6357_LCLDO_ENC_EN_VA28_MASK, MT6357_LCLDO_ENC_EN_VA28_ENABLE); + /* LCLDO_ENC remote sense */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12, + MT6357_VA28REFGEN_EN_VA28_MASK | + MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_MASK, + MT6357_VA28REFGEN_EN_VA28_ENABLE | + MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_ENABLE); + break; + case SND_SOC_DAPM_POST_PMD: + /* LCLDO_ENC remote sense off */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12, + MT6357_VA28REFGEN_EN_VA28_MASK | + MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_MASK, + MT6357_VA28REFGEN_EN_VA28_DISABLE | + MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_DISABLE); + /* disable LCLDO_ENC 2P8V */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12, + MT6357_LCLDO_ENC_EN_VA28_MASK, + MT6357_LCLDO_ENC_EN_VA28_DISABLE); + /* disable audio ADC CLKGEN */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11, + MT6357_RSTB_ENCODER_VA28_MASK, + MT6357_RSTB_ENCODER_VA28_DISABLE); + break; + default: + break; + } + + return 0; +} + +static int mt_mic_type_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + unsigned int mic_type = dapm_kcontrol_get_value(w->kcontrols[0]); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + switch (mic_type) { + case MIC_TYPE_MUX_DMIC: + mt6357_set_dmic(priv, true); + break; + case MIC_TYPE_MUX_LPBK: + mt6357_set_loopback(priv, true); + break; + case MIC_TYPE_MUX_SGEN: + mt6357_set_ul_sine_gen(priv, true); + break; + default: + mt6357_set_amic(priv, true, mic_type); + break; + } + break; + case SND_SOC_DAPM_POST_PMD: + switch (mic_type) { + case MIC_TYPE_MUX_DMIC: + mt6357_set_dmic(priv, false); + break; + case MIC_TYPE_MUX_LPBK: + mt6357_set_loopback(priv, false); + break; + case MIC_TYPE_MUX_SGEN: + mt6357_set_ul_sine_gen(priv, false); + break; + default: + mt6357_set_amic(priv, false, mic_type); + break; + } + break; + default: + break; + } + + return 0; +} + +static int mt_pga_left_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* L preamplifier enable */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLON_MASK, + MT6357_AUDPREAMPLON_ENABLE); + /* L ADC input sel : L PGA. Enable audio L ADC */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDADCLINPUTSEL_MASK, + MT6357_AUDADCLINPUTSEL_PREAMPLIFIER); + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDADCLPWRUP_MASK, + MT6357_AUDADCLPWRUP); + /* Audio L preamplifier DCC precharge off */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLDCPRECHARGE_MASK, + MT6357_AUDPREAMPLDCPRECHARGE_DISABLE); + break; + case SND_SOC_DAPM_PRE_PMD: + /* Audio L ADC input sel : off, disable audio L ADC */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDADCLPWRUP_MASK, + MT6357_AUDADCLPWRDOWN); + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDADCLINPUTSEL_MASK, + MT6357_AUDADCLINPUTSEL_IDLE); + /* L preamplifier ACC */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLDCCEN_MASK, + MT6357_AUDPREAMPLDCCEN_AC); + /* L preamplifier disable */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLON_MASK, + MT6357_AUDPREAMPLON_DISABLE); + /* disable Audio L preamplifier DCC precharge */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLDCPRECHARGE_MASK, + MT6357_AUDPREAMPLDCPRECHARGE_DISABLE); + break; + default: + break; + } + + return 0; +} + +static int mt_pga_right_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* R preamplifier enable */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRON_MASK, MT6357_AUDPREAMPRON_ENABLE); + /* R ADC input sel : R PGA. Enable audio R ADC */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDADCRINPUTSEL_MASK, + MT6357_AUDADCRINPUTSEL_PREAMPLIFIER); + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDADCRPWRUP_MASK, MT6357_AUDADCRPWRUP); + /* Audio R preamplifier DCC precharge off */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRDCPRECHARGE_MASK, + MT6357_AUDPREAMPRDCPRECHARGE_DISABLE); + break; + case SND_SOC_DAPM_PRE_PMD: + /* Audio R ADC input sel : off, disable audio R ADC */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDADCRPWRUP_MASK, MT6357_AUDADCRPWRDOWN); + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDADCRINPUTSEL_MASK, MT6357_AUDADCRINPUTSEL_IDLE); + /* R preamplifier ACC */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRDCCEN_MASK, MT6357_AUDPREAMPRDCCEN_AC); + /* R preamplifier disable */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRON_MASK, MT6357_AUDPREAMPRON_DISABLE); + /* disable Audio R preamplifier DCC precharge */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRDCPRECHARGE_MASK, + MT6357_AUDPREAMPRDCPRECHARGE_DISABLE); + break; + default: + break; + } + + return 0; +} + +static int adc_enable_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + int lgain, rgain; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + regmap_read(priv->regmap, MT6357_AUDENC_ANA_CON0, &lgain); + regmap_read(priv->regmap, MT6357_AUDENC_ANA_CON1, &rgain); + /* L PGA 0 dB gain */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLGAIN_MASK, + UL_GAIN_0DB << MT6357_AUDPREAMPLGAIN_SFT); + /* R PGA 0 dB gain */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRGAIN_MASK, + UL_GAIN_0DB << MT6357_AUDPREAMPRGAIN_SFT); + /* enable aud_pad TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE); + /* UL turn on */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SRC_ON_TMP_CTL_MASK, MT6357_UL_SRC_ENABLE); + /* Wait to avoid any pop noises */ + msleep(100); + /* set the mic gains to the stored values */ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, + MT6357_AUDPREAMPLGAIN_MASK, lgain); + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, + MT6357_AUDPREAMPRGAIN_MASK, rgain); + break; + case SND_SOC_DAPM_POST_PMD: + /* UL turn off */ + regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L, + MT6357_UL_SRC_ON_TMP_CTL_MASK, MT6357_UL_SRC_DISABLE); + /* disable aud_pad TX fifos */ + regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK, + MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE); + break; + default: + break; + } + + return 0; +} + +static void configure_downlinks(struct mt6357_priv *priv, bool enable) +{ + if (enable) { + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ELR_0, + MT6357_AUD_HP_TRIM_EN_VAUDP15_MASK, + MT6357_AUD_HP_TRIM_EN_VAUDP15_ENABLE); + /* Disable headphone short-circuit protection */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_HPR_SC_VAUDP15_MASK | MT6357_AUD_HPL_SC_VAUDP15_MASK, + MT6357_AUD_HPR_SC_VAUDP15_DISABLE | + MT6357_AUD_HPL_SC_VAUDP15_DISABLE); + /* Disable handset short-circuit protection */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HS_SC_VAUDP15_MASK, + MT6357_AUD_HS_SC_VAUDP15_DISABLE); + /* Disable lineout short-circuit protection */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOL_SC_VAUDP15_MASK, + MT6357_AUD_LOL_SC_VAUDP15_DISABLE); + /* Reduce ESD resistance of AU_REFN */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2, + MT6357_AUD_REFN_DERES_VAUDP15_MASK, + MT6357_AUD_REFN_DERES_VAUDP15_ENABLE); + /* Turn on DA_600K_NCP_VA18 */ + regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON1, MT6357_DIVCKS_ON); + /* Set NCP clock as 604kHz // 26MHz/43 = 604KHz */ + regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON2, 0x002c); + /* Toggle DIVCKS_CHG */ + regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON0, MT6357_DIVCKS_CHG); + /* Set NCP soft start mode as default mode: 150us */ + regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON4, + MT6357_DIVCKS_PWD_NCP_ST_150US); + /* Enable NCP */ + regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON3, + MT6357_DIVCKS_PWD_NCP_ENABLE); + usleep_range(250, 270); + /* Enable cap-less LDOs (1.5V) */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12, + MT6357_VA33REFGEN_EN_VA18_MASK | + MT6357_LCLDO_REMOTE_SENSE_VA18_MASK | + MT6357_LCLDO_EN_VA18_MASK | + MT6357_HCLDO_REMOTE_SENSE_VA18_MASK | + MT6357_HCLDO_EN_VA18_MASK, + MT6357_VA33REFGEN_EN_VA18_ENABLE | + MT6357_LCLDO_REMOTE_SENSE_VA18_ENABLE | + MT6357_LCLDO_EN_VA18_ENABLE | + MT6357_HCLDO_REMOTE_SENSE_VA18_ENABLE | + MT6357_HCLDO_EN_VA18_ENABLE); + /* Enable NV regulator (-1.2V) */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON13, + MT6357_NVREG_EN_VAUDP15_MASK, MT6357_NVREG_EN_VAUDP15_ENABLE); + usleep_range(100, 120); + /* Enable IBIST */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON10, + MT6357_AUD_IBIAS_PWRDN_VAUDP15_MASK, + MT6357_AUD_IBIAS_PWRDN_VAUDP15_ENABLE); + /* Enable AUD_CLK */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11, + MT6357_RSTB_DECODER_VA28_MASK, + MT6357_RSTB_DECODER_VA28_ENABLE); + /* Enable low-noise mode of DAC */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_DAC_LOW_NOISE_MODE_MASK, + MT6357_DAC_LOW_NOISE_MODE_ENABLE); + usleep_range(100, 120); + } else { + /* Disable low-noise mode of DAC */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_DAC_LOW_NOISE_MODE_MASK, + MT6357_DAC_LOW_NOISE_MODE_DISABLE); + /* Disable AUD_CLK */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11, + MT6357_RSTB_DECODER_VA28_MASK, + MT6357_RSTB_DECODER_VA28_DISABLE); + /* Enable linout short-circuit protection */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOL_SC_VAUDP15_MASK, + MT6357_AUD_LOL_SC_VAUDP15_ENABLE); + /* Enable handset short-circuit protection */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HS_SC_VAUDP15_MASK, + MT6357_AUD_HS_SC_VAUDP15_ENABLE); + /* Enable headphone short-circuit protection */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_HPR_SC_VAUDP15_MASK | + MT6357_AUD_HPL_SC_VAUDP15_MASK, + MT6357_AUD_HPR_SC_VAUDP15_ENABLE | + MT6357_AUD_HPL_SC_VAUDP15_ENABLE); + /* Disable IBIST */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON10, + MT6357_AUD_IBIAS_PWRDN_VAUDP15_MASK, + MT6357_AUD_IBIAS_PWRDN_VAUDP15_DISABLE); + /* Disable NV regulator (-1.2V) */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON13, + MT6357_NVREG_EN_VAUDP15_MASK, + MT6357_NVREG_EN_VAUDP15_DISABLE); + /* Disable cap-less LDOs (1.5V) */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12, + MT6357_VA33REFGEN_EN_VA18_MASK | + MT6357_LCLDO_REMOTE_SENSE_VA18_MASK | + MT6357_LCLDO_EN_VA18_MASK | + MT6357_HCLDO_REMOTE_SENSE_VA18_MASK | + MT6357_HCLDO_EN_VA18_MASK, + MT6357_VA33REFGEN_EN_VA18_DISABLE | + MT6357_LCLDO_REMOTE_SENSE_VA18_DISABLE | + MT6357_LCLDO_EN_VA18_DISABLE | + MT6357_HCLDO_REMOTE_SENSE_VA18_DISABLE | + MT6357_HCLDO_EN_VA18_DISABLE); + /* Disable NCP */ + regmap_update_bits(priv->regmap, MT6357_AUDNCP_CLKDIV_CON3, + MT6357_DIVCKS_PWD_NCP_MASK, MT6357_DIVCKS_PWD_NCP_DISABLE); + } +} + +static int mt_audio_in_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + set_playback_gpio(priv, true); + + /* Pull-down HPL/R to AVSS28_AUD */ + if (priv->pull_down_needed) + hp_pull_down(priv, true); + + /* Disable HP main CMFB Switch */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_HPRL_MAIN_CMFB_LOOP_MASK, + MT6357_HPRL_MAIN_CMFB_LOOP_DISABLE); + /* Audio system digital clock power down release */ + regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2, + MT6357_CCI_AUDIO_FIFO_DISABLE | + MT6357_CCI_ACD_MODE_NORMAL_PATH | + MT6357_CCI_AFIFO_CLK_PWDB_ON | + MT6357_CCI_ACD_FUNC_RSTB_RESET); + /* sdm audio fifo clock power on */ + regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON0, + MT6357_CCI_AUD_ANACK_INVERT | + (4 << MT6357_CCI_AUDIO_FIFO_WPTR_SFT) | + MT6357_CCI_SCRAMBLER_CG_ENABLE | + MT6357_CCI_RAND_ENABLE | + MT6357_CCI_SPLT_SCRMB_CLK_ON | + MT6357_CCI_SPLT_SCRMB_ON | + MT6357_CCI_ZERO_PADDING_DISABLE | + MT6357_CCI_SCRAMBLER_ENABLE); + /* scrambler clock on enable */ + regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2, + MT6357_CCI_AUDIO_FIFO_DISABLE | + MT6357_CCI_ACD_MODE_TEST_PATH | + MT6357_CCI_AFIFO_CLK_PWDB_ON | + MT6357_CCI_ACD_FUNC_RSTB_RELEASE); + /* sdm power on */ + regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2, + MT6357_CCI_AUDIO_FIFO_ENABLE | + MT6357_CCI_ACD_MODE_TEST_PATH | + MT6357_CCI_AFIFO_CLK_PWDB_ON | + MT6357_CCI_ACD_FUNC_RSTB_RELEASE); + + configure_downlinks(priv, true); + break; + case SND_SOC_DAPM_POST_PMD: + configure_downlinks(priv, false); + /* DL scrambler disabling sequence */ + regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2, + MT6357_CCI_AUDIO_FIFO_DISABLE | + MT6357_CCI_ACD_MODE_TEST_PATH | + MT6357_CCI_AFIFO_CLK_PWDB_DOWN | + MT6357_CCI_ACD_FUNC_RSTB_RESET); + regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON0, + MT6357_CCI_AUD_ANACK_INVERT | + (4 << MT6357_CCI_AUDIO_FIFO_WPTR_SFT) | + MT6357_CCI_SCRAMBLER_CG_ENABLE | + MT6357_CCI_RAND_ENABLE | + MT6357_CCI_SPLT_SCRMB_CLK_ON | + MT6357_CCI_SPLT_SCRMB_ON | + MT6357_CCI_ZERO_PADDING_DISABLE | + MT6357_CCI_SCRAMBLER_DISABLE); + + set_playback_gpio(priv, false); + + /* disable Pull-down HPL/R to AVSS28_AUD */ + if (priv->pull_down_needed) + hp_pull_down(priv, false); + break; + default: + break; + } + + return 0; +} + +static int mt_delay_250_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + usleep_range(250, 270); + break; + case SND_SOC_DAPM_PRE_PMD: + usleep_range(250, 270); + break; + default: + break; + } + + return 0; +} + +static int lo_mux_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + int lgain, rgain; + + /* Get current gain value */ + regmap_read(priv->regmap, MT6357_ZCD_CON1, &lgain); + rgain = (lgain & MT6357_AUD_LOR_GAIN_MASK) >> MT6357_AUD_LOR_GAIN_SFT; + lgain = lgain & MT6357_AUD_LOL_GAIN_MASK; + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Set -40dB before enable HS to avoid POP noise */ + regmap_update_bits(priv->regmap, MT6357_ZCD_CON1, + MT6357_AUD_LOL_GAIN_MASK | + MT6357_AUD_LOR_GAIN_MASK, + MT6357_DL_GAIN_N_40DB_REG); + /* Set LO STB enhance circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_MASK, + MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_ENABLE); + /* Enable LO driver bias circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_MASK, + MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_ENABLE); + /* Enable LO driver core circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOL_PWRUP_VAUDP15_MASK, + MT6357_AUD_LOL_PWRUP_VAUDP15_ENABLE); + /* Set LOL gain to normal gain step by step */ + lo_volume_ramp(priv, DL_GAIN_N_40DB, lgain, + DL_GAIN_N_40DB, rgain); + break; + case SND_SOC_DAPM_PRE_PMD: + /* decrease LOL gain to minimum gain step by step */ + + lo_volume_ramp(priv, lgain, DL_GAIN_N_40DB, + rgain, DL_GAIN_N_40DB); + /* Disable LO driver core circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOL_PWRUP_VAUDP15_MASK, + MT6357_AUD_LOL_PWRUP_VAUDP15_DISABLE); + /* Disable LO driver bias circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_MASK, + MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_DISABLE); + /* Clear LO STB enhance circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_MASK, + MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_DISABLE); + /* Save the gain value into the register*/ + regmap_update_bits(priv->regmap, MT6357_ZCD_CON1, + MT6357_AUD_LOL_GAIN_MASK | + MT6357_AUD_LOR_GAIN_MASK, + lgain << MT6357_AUD_LOL_GAIN_SFT | + rgain << MT6357_AUD_LOR_GAIN_SFT); + + break; + default: + break; + } + + return 0; +} + +static int hs_mux_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + int gain; /* HS register has only one gain slot */ + + /* Get current gain value */ + regmap_read(priv->regmap, MT6357_ZCD_CON3, &gain); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Set -40dB before enable HS to avoid POP noise */ + regmap_update_bits(priv->regmap, MT6357_ZCD_CON3, + MT6357_AUD_HS_GAIN_MASK, + DL_GAIN_N_40DB); + + /* Set HS STB enhance circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HSOUT_STB_ENH_VAUDP15_MASK, + MT6357_AUD_HSOUT_STB_ENH_VAUDP15_ENABLE); + /* Enable HS driver bias circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_MASK, + MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_ENABLE); + /* Enable HS driver core circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HS_PWRUP_VAUDP15_MASK, + MT6357_AUD_HS_PWRUP_VAUDP15_ENABLE); + /* Set HS gain to normal gain step by step */ + hs_volume_ramp(priv, DL_GAIN_N_40DB, gain); + break; + case SND_SOC_DAPM_PRE_PMD: + /* decrease HS gain to minimum gain step by step */ + hs_volume_ramp(priv, gain, DL_GAIN_N_40DB); + /* Disable HS driver core circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HS_PWRUP_VAUDP15_MASK, + MT6357_AUD_HS_PWRUP_VAUDP15_DISABLE); + /* Disable HS driver bias circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_MASK, + MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_ENABLE); + /* Clear HS STB enhance circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HSOUT_STB_ENH_VAUDP15_MASK, + MT6357_AUD_HSOUT_STB_ENH_VAUDP15_DISABLE); + /* Save the gain value into the register*/ + regmap_update_bits(priv->regmap, MT6357_ZCD_CON3, + MT6357_AUD_HS_GAIN_MASK, gain); + break; + default: + break; + } + + return 0; +} + +static int hp_main_mux_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + int lgain, rgain; + + /* Get current gain value */ + regmap_read(priv->regmap, MT6357_ZCD_CON2, &lgain); + rgain = (lgain & MT6357_AUD_HPR_GAIN_MASK) >> MT6357_AUD_HPR_GAIN_SFT; + lgain = lgain & MT6357_AUD_HPL_GAIN_MASK; + switch (event) { + case SND_SOC_DAPM_POST_PMU: + priv->hp_channel_number++; + if (priv->hp_channel_number > 1) + break; + /* Set -40dB before enable HS to avoid POP noise */ + regmap_update_bits(priv->regmap, MT6357_ZCD_CON2, + MT6357_AUD_HPL_GAIN_MASK | + MT6357_AUD_HPR_GAIN_MASK, + MT6357_DL_GAIN_N_40DB_REG); + /* Set HPP/N STB enhance circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2, + MT6357_HPROUT_STB_ENH_VAUDP15_MASK | + MT6357_HPLOUT_STB_ENH_VAUDP15_MASK, + MT6357_HPROUT_STB_ENH_VAUDP15_N470_P250 | + MT6357_HPLOUT_STB_ENH_VAUDP15_N470_P250); + /* Enable HP aux output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK | + MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK, + MT6357_HPROUT_AUX_PWRUP_VAUDP15_ENABLE | + MT6357_HPLOUT_AUX_PWRUP_VAUDP15_ENABLE); + /* Enable HP aux feedback loop */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPR_AUX_FBRSW_VAUDP15_MASK | + MT6357_HPL_AUX_FBRSW_VAUDP15_MASK, + MT6357_HPR_AUX_FBRSW_VAUDP15_ENABLE | + MT6357_HPL_AUX_FBRSW_VAUDP15_ENABLE); + /* Enable HP aux CMFB loop */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_HP_CMFB_RST_MASK | + MT6357_HPL_AUX_CMFB_LOOP_MASK | + MT6357_HPR_AUX_CMFB_LOOP_MASK, + MT6357_HP_CMFB_RST_NORMAL | + MT6357_HPL_AUX_CMFB_LOOP_ENABLE | + MT6357_HPR_AUX_CMFB_LOOP_ENABLE); + /* Enable HP driver bias circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_HPR_BIAS_VAUDP15_MASK | + MT6357_AUD_HPL_BIAS_VAUDP15_MASK, + MT6357_AUD_HPR_BIAS_VAUDP15_ENABLE | + MT6357_AUD_HPL_BIAS_VAUDP15_ENABLE); + /* Enable HP driver core circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_HPR_PWRUP_VAUDP15_MASK | + MT6357_AUD_HPL_PWRUP_VAUDP15_MASK, + MT6357_AUD_HPR_PWRUP_VAUDP15_ENABLE | + MT6357_AUD_HPL_PWRUP_VAUDP15_ENABLE); + /* Short HP main output to HP aux output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK | + MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK, + MT6357_HPR_SHORT2HPR_AUX_VAUDP15_ENABLE | + MT6357_HPL_SHORT2HPR_AUX_VAUDP15_ENABLE); + /* Enable HP main CMFB loop */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_HPRL_MAIN_CMFB_LOOP_MASK, + MT6357_HPRL_MAIN_CMFB_LOOP_ENABLE); + /* Disable HP aux CMFB loop */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_HPR_AUX_CMFB_LOOP_MASK | + MT6357_HPL_AUX_CMFB_LOOP_MASK, + MT6357_HPR_AUX_CMFB_LOOP_DISABLE | + MT6357_HPL_AUX_CMFB_LOOP_DISABLE); + /* Enable HP main output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPROUT_PWRUP_VAUDP15_MASK | + MT6357_HPLOUT_PWRUP_VAUDP15_MASK, + MT6357_HPROUT_PWRUP_VAUDP15_ENABLE | + MT6357_HPLOUT_PWRUP_VAUDP15_ENABLE); + /* Enable HPR/L main output stage step by step */ + hp_main_output_ramp(priv, true); + usleep_range(1000, 1200); + /* Reduce HP aux feedback loop gain */ + hp_aux_feedback_loop_gain_ramp(priv, true); + /* Disable HP aux feedback loop */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPR_AUX_FBRSW_VAUDP15_MASK | + MT6357_HPL_AUX_FBRSW_VAUDP15_MASK, + MT6357_HPR_AUX_FBRSW_VAUDP15_DISABLE | + MT6357_HPL_AUX_FBRSW_VAUDP15_DISABLE); + /* apply volume setting */ + hp_volume_ramp(priv, DL_GAIN_N_40DB, lgain, + DL_GAIN_N_40DB, rgain); + /* Disable HP aux output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK | + MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK, + MT6357_HPROUT_AUX_PWRUP_VAUDP15_DISABLE | + MT6357_HPLOUT_AUX_PWRUP_VAUDP15_DISABLE); + /* Unshort HP main output to HP aux output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK | + MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK, + MT6357_HPR_SHORT2HPR_AUX_VAUDP15_DISABLE | + MT6357_HPL_SHORT2HPR_AUX_VAUDP15_DISABLE); + usleep_range(100, 120); + break; + case SND_SOC_DAPM_PRE_PMD: + priv->hp_channel_number--; + if (priv->hp_channel_number > 0) + break; + /* Short HP main output to HP aux output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK | + MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK, + MT6357_HPR_SHORT2HPR_AUX_VAUDP15_ENABLE | + MT6357_HPL_SHORT2HPR_AUX_VAUDP15_ENABLE); + /* Enable HP aux output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK | + MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK, + MT6357_HPROUT_AUX_PWRUP_VAUDP15_ENABLE | + MT6357_HPLOUT_AUX_PWRUP_VAUDP15_ENABLE); + /* decrease HPL/R gain to normal gain step by step */ + hp_volume_ramp(priv, lgain, DL_GAIN_N_40DB, + rgain, DL_GAIN_N_40DB); + /* Enable HP aux feedback loop */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPR_AUX_FBRSW_VAUDP15_MASK | + MT6357_HPL_AUX_FBRSW_VAUDP15_MASK, + MT6357_HPR_AUX_FBRSW_VAUDP15_ENABLE | + MT6357_HPL_AUX_FBRSW_VAUDP15_ENABLE); + /* Reduce HP aux feedback loop gain */ + hp_aux_feedback_loop_gain_ramp(priv, false); + /* decrease HPR/L main output stage step by step */ + hp_main_output_ramp(priv, false); + /* Disable HP main output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPROUT_PWRUP_VAUDP15_MASK | + MT6357_HPLOUT_PWRUP_VAUDP15_MASK, + MT6357_HPROUT_PWRUP_VAUDP15_DISABLE | + MT6357_HPLOUT_PWRUP_VAUDP15_DISABLE); + /* Enable HP aux CMFB loop */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_HP_CMFB_RST_MASK | + MT6357_HPL_AUX_CMFB_LOOP_MASK | + MT6357_HPR_AUX_CMFB_LOOP_MASK, + MT6357_HP_CMFB_RST_RESET | + MT6357_HPL_AUX_CMFB_LOOP_ENABLE | + MT6357_HPR_AUX_CMFB_LOOP_ENABLE); + /* Disable HP main CMFB loop */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_HPRL_MAIN_CMFB_LOOP_MASK, + MT6357_HPRL_MAIN_CMFB_LOOP_DISABLE); + /* Unshort HP main output to HP aux output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK | + MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK, + MT6357_HPR_SHORT2HPR_AUX_VAUDP15_DISABLE | + MT6357_HPL_SHORT2HPR_AUX_VAUDP15_DISABLE); + /* Disable HP driver core circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_HPR_PWRUP_VAUDP15_MASK | + MT6357_AUD_HPL_PWRUP_VAUDP15_MASK, + MT6357_AUD_HPR_PWRUP_VAUDP15_DISABLE | + MT6357_AUD_HPL_PWRUP_VAUDP15_DISABLE); + /* Disable HP driver bias circuits */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_HPR_BIAS_VAUDP15_MASK | + MT6357_AUD_HPL_BIAS_VAUDP15_MASK, + MT6357_AUD_HPR_BIAS_VAUDP15_DISABLE | + MT6357_AUD_HPL_BIAS_VAUDP15_DISABLE); + /* Disable HP aux CMFB loop, + * Enable HP main CMFB for HP off state + */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6, + MT6357_HPRL_MAIN_CMFB_LOOP_MASK | + MT6357_HPR_AUX_CMFB_LOOP_MASK | + MT6357_HPL_AUX_CMFB_LOOP_MASK, + MT6357_HPRL_MAIN_CMFB_LOOP_ENABLE | + MT6357_HPR_AUX_CMFB_LOOP_DISABLE | + MT6357_HPL_AUX_CMFB_LOOP_DISABLE); + /* Disable HP aux feedback loop */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPR_AUX_FBRSW_VAUDP15_MASK | + MT6357_HPL_AUX_FBRSW_VAUDP15_MASK, + MT6357_HPR_AUX_FBRSW_VAUDP15_DISABLE | + MT6357_HPL_AUX_FBRSW_VAUDP15_DISABLE); + /* Disable HP aux output stage */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1, + MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK | + MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK, + MT6357_HPROUT_AUX_PWRUP_VAUDP15_DISABLE | + MT6357_HPLOUT_AUX_PWRUP_VAUDP15_DISABLE); + /* Save the gain value into the register*/ + regmap_update_bits(priv->regmap, MT6357_ZCD_CON2, + MT6357_AUD_HPL_GAIN_MASK | + MT6357_AUD_HPR_GAIN_MASK, + lgain << MT6357_AUD_HPL_GAIN_SFT | + rgain << MT6357_AUD_HPR_GAIN_SFT); + break; + default: + break; + } + + return 0; +} + +static int right_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enable Audio DAC and control audio bias gen */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_DACR_PWRUP_VA28_MASK | + MT6357_AUD_DACR_PWRUP_VAUDP15_MASK, + MT6357_AUD_DACR_PWRUP_VA28_ENABLE | + MT6357_AUD_DACR_PWRUP_VAUDP15_ENABLE); + break; + case SND_SOC_DAPM_POST_PMU: + /* disable Pull-down HPL/R to AVSS28_AUD */ + if (priv->pull_down_needed) + hp_pull_down(priv, false); + break; + case SND_SOC_DAPM_PRE_PMD: + /* Pull-down HPL/R to AVSS28_AUD */ + if (priv->pull_down_needed) + hp_pull_down(priv, true); + /* Disable Audio DAC and control audio bias gen */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_DACR_PWRUP_VA28_MASK | + MT6357_AUD_DACR_PWRUP_VAUDP15_MASK, + MT6357_AUD_DACR_PWRUP_VA28_DISABLE | + MT6357_AUD_DACR_PWRUP_VAUDP15_DISABLE); + break; + default: + break; + } + + return 0; +} + +static int left_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enable Audio DAC and control audio bias gen */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_DACL_PWRUP_VA28_MASK | + MT6357_AUD_DACL_PWRUP_VAUDP15_MASK, + MT6357_AUD_DACL_PWRUP_VA28_ENABLE | + MT6357_AUD_DACL_PWRUP_VAUDP15_ENABLE); + break; + case SND_SOC_DAPM_POST_PMU: + /* disable Pull-down HPL/R to AVSS28_AUD */ + if (priv->pull_down_needed) + hp_pull_down(priv, false); + break; + case SND_SOC_DAPM_PRE_PMD: + /* Pull-down HPL/R to AVSS28_AUD */ + if (priv->pull_down_needed) + hp_pull_down(priv, true); + /* Disable Audio DAC and control audio bias gen */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_DACL_PWRUP_VA28_MASK | + MT6357_AUD_DACL_PWRUP_VAUDP15_MASK, + MT6357_AUD_DACL_PWRUP_VA28_DISABLE | + MT6357_AUD_DACL_PWRUP_VAUDP15_DISABLE); + break; + default: + break; + } + + return 0; +} + +/* Supply widgets subsequence */ +enum { + /* common */ + SUPPLY_SEQ_CLK_BUF, + SUPPLY_SEQ_AUD_GLB, + SUPPLY_SEQ_CLKSQ, + SUPPLY_SEQ_VOW_AUD_LPW, + SUPPLY_SEQ_AUD_VOW, + SUPPLY_SEQ_VOW_CLK, + SUPPLY_SEQ_VOW_LDO, + SUPPLY_SEQ_TOP_CK, + SUPPLY_SEQ_TOP_CK_LAST, + SUPPLY_SEQ_AUD_TOP, + SUPPLY_SEQ_AUD_TOP_LAST, + SUPPLY_SEQ_AFE, + /* capture */ + SUPPLY_SEQ_ADC_SUPPLY, +}; + +/* DAPM Widgets */ +static const struct snd_soc_dapm_widget mt6357_dapm_widgets[] = { + /* Analog Clocks */ + SND_SOC_DAPM_SUPPLY_S("CLK_BUF", SUPPLY_SEQ_CLK_BUF, + MT6357_DCXO_CW14, + MT6357_XO_AUDIO_EN_M_SFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AUDGLB", SUPPLY_SEQ_AUD_GLB, + MT6357_AUDDEC_ANA_CON11, + MT6357_AUDGLB_PWRDN_VA28_SFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("CLKSQ Audio", SUPPLY_SEQ_CLKSQ, + MT6357_AUDENC_ANA_CON6, + MT6357_CLKSQ_EN_SFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AUDNCP_CK", SUPPLY_SEQ_TOP_CK, + MT6357_AUD_TOP_CKPDN_CON0, + MT6357_AUDNCP_CK_PDN_SFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ZCD13M_CK", SUPPLY_SEQ_TOP_CK, + MT6357_AUD_TOP_CKPDN_CON0, + MT6357_ZCD13M_CK_PDN_SFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AUD_CK", SUPPLY_SEQ_TOP_CK_LAST, + MT6357_AUD_TOP_CKPDN_CON0, + MT6357_AUD_CK_PDN_SFT, 1, + mt_delay_250_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY_S("AUDIF_CK", SUPPLY_SEQ_TOP_CK, + MT6357_AUD_TOP_CKPDN_CON0, + MT6357_AUDIF_CK_PDN_SFT, 1, NULL, 0), + + /* Digital Clocks */ + SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_AFE_CTL", SUPPLY_SEQ_AUD_TOP_LAST, + MT6357_AUDIO_TOP_CON0, + MT6357_PDN_AFE_CTL_SFT, 1, + mt_delay_250_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_DAC_CTL", SUPPLY_SEQ_AUD_TOP, + MT6357_AUDIO_TOP_CON0, + MT6357_PDN_DAC_CTL_SFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_ADC_CTL", SUPPLY_SEQ_AUD_TOP, + MT6357_AUDIO_TOP_CON0, + MT6357_PDN_ADC_CTL_SFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_I2S_DL", SUPPLY_SEQ_AUD_TOP, + MT6357_AUDIO_TOP_CON0, + MT6357_PDN_I2S_DL_CTL_SFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PWR_CLK", SUPPLY_SEQ_AUD_TOP, + MT6357_AUDIO_TOP_CON0, + MT6357_PWR_CLK_DIS_CTL_SFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_AFE_TESTMODEL", SUPPLY_SEQ_AUD_TOP, + MT6357_AUDIO_TOP_CON0, + MT6357_PDN_AFE_TESTMODEL_CTL_SFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_RESERVED", SUPPLY_SEQ_AUD_TOP, + MT6357_AUDIO_TOP_CON0, + MT6357_PDN_RESERVED_SFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_LPBK", SUPPLY_SEQ_AUD_TOP, + MT6357_AUDIO_TOP_CON0, + MT6357_PDN_LPBK_CTL_SFT, 1, NULL, 0), + + /* General */ + SND_SOC_DAPM_SUPPLY_S("AFE_ON", SUPPLY_SEQ_AFE, + MT6357_AFE_UL_DL_CON0, + MT6357_AFE_ON_SFT, 0, NULL, 0), + + /* Uplinks */ + SND_SOC_DAPM_AIF_OUT_E("AIF1TX", "MT6357 Capture", 0, + SND_SOC_NOPM, 0, 0, + mt_aif_out_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ADC Supply", SUPPLY_SEQ_ADC_SUPPLY, + SND_SOC_NOPM, 0, 0, + mt_adc_supply_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC", NULL, SND_SOC_NOPM, 0, 0, adc_enable_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("PGA L Mux", SND_SOC_NOPM, 0, 0, + &pga_left_mux_control, + mt_pga_left_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MUX_E("PGA R Mux", SND_SOC_NOPM, 0, 0, + &pga_right_mux_control, + mt_pga_right_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PGA("PGA L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("PGA R", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MUX_E("Mic Type Mux", SND_SOC_NOPM, 0, 0, + &mic_type_mux_control, + mt_mic_type_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("MICBIAS0", MT6357_AUDENC_ANA_CON8, + MT6357_AUD_MICBIAS0_PWD_SFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("MICBIAS1", MT6357_AUDENC_ANA_CON9, + MT6357_AUD_MICBIAS1_PWD_SFT, 0, NULL, 0), + + /* UL inputs */ + SND_SOC_DAPM_INPUT("AIN0"), + SND_SOC_DAPM_INPUT("AIN1"), + SND_SOC_DAPM_INPUT("AIN2"), + SND_SOC_DAPM_INPUT("LPBK"), + SND_SOC_DAPM_INPUT("SGEN UL"), + + /* Downlinks */ + SND_SOC_DAPM_AIF_IN_E("AIF_RX", "MT6357 Playback", 0, + SND_SOC_NOPM, 0, 0, + mt_audio_in_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_INPUT("SGEN DL"), + SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0, &dac_mux_control), + + SND_SOC_DAPM_DAC_E("DACR", NULL, SND_SOC_NOPM, 0, 0, right_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_DAC_E("DACL", NULL, SND_SOC_NOPM, 0, 0, left_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY("DL Digital Supply", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DL Analog Supply", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DL SRC", MT6357_AFE_DL_SRC2_CON0_L, + MT6357_DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("Line Out Source", SND_SOC_NOPM, 0, 0, &lo_mux_control, + lo_mux_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MUX_E("Handset Source", SND_SOC_NOPM, 0, 0, &hs_mux_control, + hs_mux_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MUX_E("Headphone Right Source", SND_SOC_NOPM, 0, 0, &hpr_mux_control, + hp_main_mux_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MUX_E("Headphone Left Source", SND_SOC_NOPM, 0, 0, &hpl_mux_control, + hp_main_mux_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + /* DL outputs */ + SND_SOC_DAPM_OUTPUT("Headphones"), + SND_SOC_DAPM_OUTPUT("Hansdet"), + SND_SOC_DAPM_OUTPUT("Line out"), + + /* Sine generator */ + SND_SOC_DAPM_SUPPLY("SGEN UL Enable", + MT6357_AFE_TOP_CON0, MT6357_UL_SINE_ON_SFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("SGEN Enable", + MT6357_AFE_SGEN_CFG0, + MT6357_SGEN_DAC_EN_CTL_SFT, 0, mt_audio_in_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("SGEN MUTE", + MT6357_AFE_SGEN_CFG0, + MT6357_SGEN_MUTE_SW_CTL_SFT, 1, NULL, 0) +}; + +static const struct snd_soc_dapm_route mt6357_dapm_routes[] = { + /* Capture */ + {"AIF1TX", NULL, "Mic Type Mux"}, + {"AIF1TX", NULL, "CLK_BUF"}, + {"AIF1TX", NULL, "AUDGLB"}, + {"AIF1TX", NULL, "CLKSQ Audio"}, + {"AIF1TX", NULL, "AUD_CK"}, + {"AIF1TX", NULL, "AUDIF_CK"}, + + {"AIF1TX", NULL, "AUDIO_TOP_AFE_CTL"}, + {"AIF1TX", NULL, "AUDIO_TOP_ADC_CTL"}, + {"AIF1TX", NULL, "AUDIO_TOP_PWR_CLK"}, + {"AIF1TX", NULL, "AUDIO_TOP_PDN_RESERVED"}, + {"AIF1TX", NULL, "AUDIO_TOP_I2S_DL"}, + {"AIF1TX", NULL, "AFE_ON"}, + + {"Mic Type Mux", "ACC", "ADC"}, + {"Mic Type Mux", "DCC", "ADC"}, + {"Mic Type Mux", "DCC_ECM_DIFF", "ADC"}, + {"Mic Type Mux", "DCC_ECM_SINGLE", "ADC"}, + {"Mic Type Mux", "DMIC", "AIN0"}, + {"Mic Type Mux", "DMIC", "AIN2"}, + {"Mic Type Mux", "Loopback", "LPBK"}, + {"Mic Type Mux", "Sine Generator", "SGEN UL"}, + + {"SGEN UL", NULL, "AUDIO_TOP_PDN_AFE_TESTMODEL"}, + {"SGEN UL", NULL, "SGEN UL Enable"}, + {"SGEN UL", NULL, "SGEN MUTE"}, + {"SGEN UL", NULL, "SGEN Enable"}, + + {"ADC", NULL, "PGA L Mux"}, + {"ADC", NULL, "PGA R Mux"}, + {"ADC", NULL, "ADC Supply"}, + + {"PGA L Mux", "AIN0", "AIN0"}, + {"PGA L Mux", "AIN1", "AIN1"}, + {"PGA L Mux", "AIN2", "AIN2"}, + + {"PGA R Mux", "AIN0", "AIN0"}, + {"PGA R Mux", "AIN1", "AIN1"}, + {"PGA R Mux", "AIN2", "AIN2"}, + + {"AIN0", NULL, "MICBIAS0"}, + {"AIN1", NULL, "MICBIAS1"}, + {"AIN2", NULL, "MICBIAS0"}, + {"LPBK", NULL, "AUDIO_TOP_LPBK"}, + + /* Playback */ + {"DAC Mux", "Normal Path", "AIF_RX"}, + {"DAC Mux", "Sine Generator", "SGEN DL"}, + + {"AIF_RX", NULL, "DL SRC"}, + + {"SGEN DL", NULL, "DL SRC"}, + {"SGEN DL", NULL, "SGEN MUTE"}, + {"SGEN DL", NULL, "SGEN Enable"}, + {"SGEN DL", NULL, "DL Digital Supply"}, + {"SGEN DL", NULL, "AUDIO_TOP_PDN_AFE_TESTMODEL"}, + + {"DACL", NULL, "DAC Mux"}, + {"DACR", NULL, "DAC Mux"}, + + {"DL Analog Supply", NULL, "CLK_BUF"}, + {"DL Analog Supply", NULL, "AUDGLB"}, + {"DL Analog Supply", NULL, "CLKSQ Audio"}, + {"DL Analog Supply", NULL, "AUDNCP_CK"}, + {"DL Analog Supply", NULL, "ZCD13M_CK"}, + {"DL Analog Supply", NULL, "AUD_CK"}, + {"DL Analog Supply", NULL, "AUDIF_CK"}, + + {"DL Digital Supply", NULL, "AUDIO_TOP_AFE_CTL"}, + {"DL Digital Supply", NULL, "AUDIO_TOP_DAC_CTL"}, + {"DL Digital Supply", NULL, "AUDIO_TOP_PWR_CLK"}, + {"DL Digital Supply", NULL, "AFE_ON"}, + + {"DACR", NULL, "DL Digital Supply"}, + {"DACR", NULL, "DL Analog Supply"}, + {"DACL", NULL, "DL Digital Supply"}, + {"DACL", NULL, "DL Analog Supply"}, + + {"Line Out Source", "DACR", "DACR"}, + {"Line Out Source", "Playback", "DACL"}, + {"Line Out Source", "Test mode", "DACL"}, + + {"Handset Source", "DACR", "DACR"}, + {"Handset Source", "Playback", "DACL"}, + {"Handset Source", "Test mode", "DACL"}, + + {"Headphone Right Source", "DAC", "DACR"}, + {"Headphone Right Source", "Line Out", "Line Out Source"}, + {"Headphone Right Source", "Handset", "Handset Source"}, + + {"Headphone Left Source", "DAC", "DACL"}, + {"Headphone Left Source", "Line Out", "Line Out Source"}, + {"Headphone Left Source", "Handset", "Handset Source"}, + + {"Line out", NULL, "Line Out Source"}, + {"Hansdet", NULL, "Handset Source"}, + + {"Headphones", NULL, "Headphone Right Source"}, + {"Headphones", NULL, "Headphone Left Source"}, +}; + +static struct snd_soc_dai_driver mtk_6357_dai_codecs[] = { + { + .name = "mt6357-snd-codec-aif1", + .playback = { + .stream_name = "MT6357 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = MT6357_SND_SOC_ADV_MT_FMTS, + }, + .capture = { + .stream_name = "MT6357 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MT6357_SOC_HIGH_USE_RATE, + .formats = MT6357_SND_SOC_ADV_MT_FMTS, + }, + }, +}; + +static void mt6357_codec_init(struct mt6357_priv *priv) +{ + /* Enable audio part */ + regmap_update_bits(priv->regmap, MT6357_DCXO_CW14, + MT6357_XO_AUDIO_EN_M_MASK, MT6357_XO_AUDIO_EN_M_ENABLE); + /* Disable HeadphoneL/HeadphoneR short circuit protection */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0, + MT6357_AUD_HPR_SC_VAUDP15_MASK | + MT6357_AUD_HPL_SC_VAUDP15_MASK, + MT6357_AUD_HPR_SC_VAUDP15_DISABLE | + MT6357_AUD_HPL_SC_VAUDP15_DISABLE); + /* Disable voice short circuit protection */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3, + MT6357_AUD_HS_SC_VAUDP15_MASK, + MT6357_AUD_HS_SC_VAUDP15_DISABLE); + /* disable LO buffer left short circuit protection */ + regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4, + MT6357_AUD_LOL_SC_VAUDP15_MASK, + MT6357_AUD_LOL_SC_VAUDP15_DISABLE); + /* set gpio */ + set_playback_gpio(priv, false); + set_capture_gpio(priv, false); + /* Disable audio part */ + regmap_update_bits(priv->regmap, MT6357_DCXO_CW14, + MT6357_XO_AUDIO_EN_M_MASK, + MT6357_XO_AUDIO_EN_M_DISABLE); + + /* gain default values*/ + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, MT6357_AUDPREAMPLGAIN_MASK, + UL_GAIN_0DB << MT6357_AUDPREAMPLGAIN_SFT); + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, MT6357_AUDPREAMPRGAIN_MASK, + UL_GAIN_0DB << MT6357_AUDPREAMPRGAIN_SFT); + + regmap_update_bits(priv->regmap, MT6357_ZCD_CON1, + MT6357_AUD_LOL_GAIN_MASK | + MT6357_AUD_LOR_GAIN_MASK, + DL_GAIN_0DB << MT6357_AUD_LOL_GAIN_SFT | + DL_GAIN_0DB << MT6357_AUD_LOR_GAIN_SFT); + + regmap_update_bits(priv->regmap, MT6357_ZCD_CON2, + MT6357_AUD_HPL_GAIN_MASK | + MT6357_AUD_HPR_GAIN_MASK, + DL_GAIN_0DB << MT6357_AUD_HPL_GAIN_SFT | + DL_GAIN_0DB << MT6357_AUD_HPR_GAIN_SFT); + + regmap_update_bits(priv->regmap, MT6357_ZCD_CON3, + MT6357_AUD_HS_GAIN_MASK, DL_GAIN_0DB); +} + +static int mt6357_codec_probe(struct snd_soc_component *codec) +{ + struct mt6357_priv *priv = snd_soc_component_get_drvdata(codec); + + mt6357_codec_init(priv); + return 0; +} + +static unsigned int mt6357_read(struct snd_soc_component *codec, unsigned int reg) +{ + struct mt6357_priv *priv = snd_soc_component_get_drvdata(codec); + unsigned int val; + + regmap_read(priv->regmap, reg, &val); + return val; +} + +static int mt6357_write(struct snd_soc_component *codec, unsigned int reg, unsigned int value) +{ + struct mt6357_priv *priv = snd_soc_component_get_drvdata(codec); + + return regmap_update_bits(priv->regmap, reg, 0xffff, value); +} + +static const struct snd_soc_component_driver mt6357_soc_component_driver = { + .probe = mt6357_codec_probe, + .read = mt6357_read, + .write = mt6357_write, + .controls = mt6357_controls, + .num_controls = ARRAY_SIZE(mt6357_controls), + .dapm_widgets = mt6357_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(mt6357_dapm_widgets), + .dapm_routes = mt6357_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(mt6357_dapm_routes), +}; + +static const u32 micbias_values[MT6357_MICBIAS_ARRAY_SIZE] = { + 1700000, 1800000, 1900000, 2000000, + 2100000, 2500000, 2600000, 2700000 +}; + +static u32 mt6357_get_micbias_idx(struct device_node *np, const char *micbias) +{ + int err; + u32 idx, val; + + err = of_property_read_u32(np, micbias, &val); + if (err) + return 0; + + for (idx = 0; idx < MT6357_MICBIAS_ARRAY_SIZE; idx++) { + if (val == micbias_values[idx]) + return idx; + } + return 0; +} + +static int mt6357_parse_dt(struct mt6357_priv *priv) +{ + u32 micbias_voltage_index = 0; + struct device_node *np; + + np = of_get_child_by_name(priv->dev->parent->of_node, "audio-codec"); + if (!np) + return -EINVAL; + + priv->pull_down_needed = false; + if (of_property_read_bool(np, "mediatek,hp-pull-down")) + priv->pull_down_needed = true; + + micbias_voltage_index = mt6357_get_micbias_idx(np, "mediatek,micbias0-microvolt"); + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8, + MT6357_AUD_MICBIAS0_VREF_MASK, + micbias_voltage_index << MT6357_AUD_MICBIAS0_VREF_SFT); + + micbias_voltage_index = mt6357_get_micbias_idx(np, "mediatek,micbias1-microvolt"); + regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON9, + MT6357_AUD_MICBIAS1_VREF_MASK, + micbias_voltage_index << MT6357_AUD_MICBIAS1_VREF_SFT); + + return 0; +} + +static int mt6357_platform_driver_probe(struct platform_device *pdev) +{ + struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent); + struct mt6357_priv *priv; + int ret; + + ret = devm_regulator_get_enable(&pdev->dev, "vaud28"); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Failed to enable vaud28 regulator\n"); + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev_set_drvdata(&pdev->dev, priv); + priv->dev = &pdev->dev; + + priv->regmap = mt6397->regmap; + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + ret = mt6357_parse_dt(priv); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Failed to parse dts\n", __func__); + + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64); + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + + return devm_snd_soc_register_component(&pdev->dev, + &mt6357_soc_component_driver, + mtk_6357_dai_codecs, + ARRAY_SIZE(mtk_6357_dai_codecs)); +} + +static const struct platform_device_id mt6357_platform_ids[] = { + {"mt6357-sound", 0}, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(platform, mt6357_platform_ids); + +static struct platform_driver mt6357_platform_driver = { + .driver = { + .name = "mt6357-sound", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, + .probe = mt6357_platform_driver_probe, + .id_table = mt6357_platform_ids, +}; + +module_platform_driver(mt6357_platform_driver) + +MODULE_DESCRIPTION("MT6357 ALSA SoC codec driver"); +MODULE_AUTHOR("Nicolas Belin "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/mt6357.h b/sound/soc/codecs/mt6357.h new file mode 100644 index 000000000000..68fd2ed90353 --- /dev/null +++ b/sound/soc/codecs/mt6357.h @@ -0,0 +1,662 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt6357.h -- mt6357 ALSA SoC audio codec driver + * + * Copyright (c) 2024 Baylibre + * Author: Nicolas Belin + */ + +#ifndef __MT6357_H__ +#define __MT6357_H__ + +#include + +/* Reg bit defines */ +/* MT6357_GPIO_DIR0 */ +#define MT6357_GPIO8_DIR_MASK BIT(8) +#define MT6357_GPIO8_DIR_INPUT 0 +#define MT6357_GPIO8_DIR_OUTPUT BIT(8) +#define MT6357_GPIO9_DIR_MASK BIT(9) +#define MT6357_GPIO9_DIR_INPUT 0 +#define MT6357_GPIO9_DIR_OUTPUT BIT(9) +#define MT6357_GPIO10_DIR_MASK BIT(10) +#define MT6357_GPIO10_DIR_INPUT 0 +#define MT6357_GPIO10_DIR_OUTPUT BIT(10) +#define MT6357_GPIO11_DIR_MASK BIT(11) +#define MT6357_GPIO11_DIR_INPUT 0 +#define MT6357_GPIO11_DIR_OUTPUT BIT(11) +#define MT6357_GPIO12_DIR_MASK BIT(12) +#define MT6357_GPIO12_DIR_INPUT 0 +#define MT6357_GPIO12_DIR_OUTPUT BIT(12) +#define MT6357_GPIO13_DIR_MASK BIT(13) +#define MT6357_GPIO13_DIR_INPUT 0 +#define MT6357_GPIO13_DIR_OUTPUT BIT(13) +#define MT6357_GPIO14_DIR_MASK BIT(14) +#define MT6357_GPIO14_DIR_INPUT 0 +#define MT6357_GPIO14_DIR_OUTPUT BIT(14) +#define MT6357_GPIO15_DIR_MASK BIT(15) +#define MT6357_GPIO15_DIR_INPUT 0 +#define MT6357_GPIO15_DIR_OUTPUT BIT(15) + +/* MT6357_GPIO_MODE2 */ +#define MT6357_GPIO8_MODE_MASK GENMASK(2, 0) +#define MT6357_GPIO8_MODE_AUD_CLK_MOSI BIT(0) +#define MT6357_GPIO8_MODE_GPIO 0 +#define MT6357_GPIO9_MODE_MASK GENMASK(5, 3) +#define MT6357_GPIO9_MODE_AUD_DAT_MOSI0 BIT(3) +#define MT6357_GPIO9_MODE_GPIO 0 +#define MT6357_GPIO10_MODE_MASK GENMASK(8, 6) +#define MT6357_GPIO10_MODE_AUD_DAT_MOSI1 BIT(6) +#define MT6357_GPIO10_MODE_GPIO 0 +#define MT6357_GPIO11_MODE_MASK GENMASK(11, 9) +#define MT6357_GPIO11_MODE_AUD_SYNC_MOSI BIT(9) +#define MT6357_GPIO11_MODE_GPIO 0 + +/* MT6357_GPIO_MODE2_SET */ +#define MT6357_GPIO8_MODE_SET_MASK GENMASK(2, 0) +#define MT6357_GPIO8_MODE_SET_AUD_CLK_MOSI BIT(0) +#define MT6357_GPIO9_MODE_SET_MASK GENMASK(5, 3) +#define MT6357_GPIO9_MODE_SET_AUD_DAT_MOSI0 BIT(3) +#define MT6357_GPIO10_MODE_SET_MASK GENMASK(8, 6) +#define MT6357_GPIO10_MODE_SET_AUD_DAT_MOSI1 BIT(6) +#define MT6357_GPIO11_MODE_SET_MASK GENMASK(11, 9) +#define MT6357_GPIO11_MODE_SET_AUD_SYNC_MOSI BIT(9) + +/* MT6357_GPIO_MODE2_CLR */ +#define MT6357_GPIO_MODE2_CLEAR_ALL GENMASK(15, 0) + +/* MT6357_GPIO_MODE3 */ +#define MT6357_GPIO12_MODE_MASK GENMASK(2, 0) +#define MT6357_GPIO12_MODE_AUD_CLK_MISO BIT(0) +#define MT6357_GPIO12_MODE_GPIO 0 +#define MT6357_GPIO13_MODE_MASK GENMASK(5, 3) +#define MT6357_GPIO13_MODE_AUD_DAT_MISO0 BIT(3) +#define MT6357_GPIO13_MODE_GPIO 0 +#define MT6357_GPIO14_MODE_MASK GENMASK(8, 6) +#define MT6357_GPIO14_MODE_AUD_DAT_MISO1 BIT(6) +#define MT6357_GPIO14_MODE_GPIO 0 +#define MT6357_GPIO15_MODE_MASK GENMASK(11, 9) +#define MT6357_GPIO15_MODE_AUD_SYNC_MISO BIT(9) +#define MT6357_GPIO15_MODE_GPIO 0 + +/* MT6357_GPIO_MODE3_SET */ +#define MT6357_GPIO12_MODE_SET_MASK GENMASK(2, 0) +#define MT6357_GPIO12_MODE_SET_AUD_CLK_MISO BIT(0) +#define MT6357_GPIO13_MODE_SET_MASK GENMASK(5, 3) +#define MT6357_GPIO13_MODE_SET_AUD_DAT_MISO0 BIT(3) +#define MT6357_GPIO14_MODE_SET_MASK GENMASK(8, 6) +#define MT6357_GPIO14_MODE_SET_AUD_DAT_MISO1 BIT(6) +#define MT6357_GPIO15_MODE_SET_MASK GENMASK(11, 9) +#define MT6357_GPIO15_MODE_SET_AUD_SYNC_MISO BIT(9) + +/* MT6357_GPIO_MODE3_CLR */ +#define MT6357_GPIO_MODE3_CLEAR_ALL GENMASK(15, 0) + +/* MT6357_DCXO_CW14 */ +#define MT6357_XO_AUDIO_EN_M_SFT 13 +#define MT6357_XO_AUDIO_EN_M_MASK BIT(13) +#define MT6357_XO_AUDIO_EN_M_ENABLE BIT(13) +#define MT6357_XO_AUDIO_EN_M_DISABLE 0 + +/* MT6357_AUD_TOP_CKPDN_CON0 */ +#define MT6357_AUDNCP_CK_PDN_SFT 6 +#define MT6357_ZCD13M_CK_PDN_SFT 5 +#define MT6357_AUDIF_CK_PDN_SFT 2 +#define MT6357_AUD_CK_PDN_SFT 1 + +/* MT6357_AUDNCP_CLKDIV_CON0 */ +#define MT6357_DIVCKS_CHG BIT(0) + +/* MT6357_AUDNCP_CLKDIV_CON1 */ +#define MT6357_DIVCKS_ON BIT(0) + +/* MT6357_AUDNCP_CLKDIV_CON3 */ +#define MT6357_DIVCKS_PWD_NCP_MASK BIT(0) +#define MT6357_DIVCKS_PWD_NCP_DISABLE BIT(0) +#define MT6357_DIVCKS_PWD_NCP_ENABLE 0 + +/* MT6357_AUDNCP_CLKDIV_CON4 */ +#define MT6357_DIVCKS_PWD_NCP_ST_SEL_MASK GENMASK(1, 0) +#define MT6357_DIVCKS_PWD_NCP_ST_50US 0 +#define MT6357_DIVCKS_PWD_NCP_ST_100US 1 +#define MT6357_DIVCKS_PWD_NCP_ST_150US 2 +#define MT6357_DIVCKS_PWD_NCP_ST_200US 3 + +/* MT6357_AFE_UL_DL_CON0 */ +#define MT6357_AFE_UL_LR_SWAP_SFT 15 +#define MT6357_AFE_ON_SFT 0 + +/* MT6357_AFE_DL_SRC2_CON0_L */ +#define MT6357_DL_2_SRC_ON_TMP_CTL_PRE_SFT 0 + +/* MT6357_AFE_UL_SRC_CON0_H */ +#define MT6357_C_TWO_DIGITAL_MIC_CTL_MASK BIT(7) +#define MT6357_C_TWO_DIGITAL_MIC_ENABLE BIT(7) +#define MT6357_C_TWO_DIGITAL_MIC_DISABLE 0 + +/* MT6357_AFE_UL_SRC_CON0_L */ +#define MT6357_UL_SDM_3_LEVEL_CTL_MASK BIT(1) +#define MT6357_UL_SDM_3_LEVEL_SELECT BIT(1) +#define MT6357_UL_SDM_3_LEVEL_DESELECT 0 +#define MT6357_UL_SRC_ON_TMP_CTL_MASK BIT(0) +#define MT6357_UL_SRC_ENABLE BIT(0) +#define MT6357_UL_SRC_DISABLE 0 + +/* MT6357_AFE_TOP_CON0 */ +#define MT6357_UL_SINE_ON_SFT 1 +#define MT6357_UL_SINE_ON_MASK BIT(1) +#define MT6357_DL_SINE_ON_SFT 0 +#define MT6357_DL_SINE_ON_MASK BIT(0) + +/* MT6357_AUDIO_TOP_CON0 */ +#define MT6357_PDN_LPBK_CTL_SFT 15 +#define MT6357_PDN_AFE_CTL_SFT 7 +#define MT6357_PDN_DAC_CTL_SFT 6 +#define MT6357_PDN_ADC_CTL_SFT 5 +#define MT6357_PDN_I2S_DL_CTL_SFT 3 +#define MT6357_PWR_CLK_DIS_CTL_SFT 2 +#define MT6357_PDN_AFE_TESTMODEL_CTL_SFT 1 +#define MT6357_PDN_RESERVED_SFT 0 + +/* MT6357_AFUNC_AUD_CON0 */ +#define MT6357_CCI_AUD_ANACK_INVERT BIT(15) +#define MT6357_CCI_AUD_ANACK_NORMAL 0 +#define MT6357_CCI_AUDIO_FIFO_WPTR_SFT 12 +#define MT6357_CCI_SCRAMBLER_CG_ENABLE BIT(11) +#define MT6357_CCI_SCRAMBLER_CG_DISABLE 0 +#define MT6357_CCI_LCK_INV_OUT_OF_PHASE BIT(10) +#define MT6357_CCI_LCK_INV_IN_PHASE 0 +#define MT6357_CCI_RAND_ENABLE BIT(9) +#define MT6357_CCI_RAND_DISABLE 0 +#define MT6357_CCI_SPLT_SCRMB_CLK_ON BIT(8) +#define MT6357_CCI_SPLT_SCRMB_CLK_OFF 0 +#define MT6357_CCI_SPLT_SCRMB_ON BIT(7) +#define MT6357_CCI_SPLT_SCRMB_OFF 0 +#define MT6357_CCI_AUD_IDAC_TEST_EN_FROM_TEST_IN BIT(6) +#define MT6357_CCI_AUD_IDAC_TEST_EN_NORMAL_PATH 0 +#define MT6357_CCI_ZERO_PADDING_DISABLE BIT(5) +#define MT6357_CCI_ZERO_PADDING_ENABLE 0 +#define MT6357_CCI_AUD_SPLIT_TEST_EN_FROM_TEST_IN BIT(4) +#define MT6357_CCI_AUD_SPLIT_TEST_EN_NORMAL_PATH 0 +#define MT6357_CCI_AUD_SDM_MUTE_L_REG_CTL BIT(3) +#define MT6357_CCI_AUD_SDM_MUTE_L_NO_CTL 0 +#define MT6357_CCI_AUD_SDM_MUTE_R_REG_CTL BIT(2) +#define MT6357_CCI_AUD_SDM_MUTE_R_NO_CTL 0 +#define MT6357_CCI_AUD_SDM_7BIT_FROM_SPLITTER3 BIT(1) +#define MT6357_CCI_AUD_SDM_7BIT_FROM_SPLITTER1 0 +#define MT6357_CCI_SCRAMBLER_ENABLE BIT(0) +#define MT6357_CCI_SCRAMBLER_DISABLE 0 + +/* MT6357_AFUNC_AUD_CON2 */ +#define MT6357_CCI_AUDIO_FIFO_ENABLE BIT(3) +#define MT6357_CCI_AUDIO_FIFO_DISABLE 0 +#define MT6357_CCI_ACD_MODE_NORMAL_PATH BIT(2) +#define MT6357_CCI_ACD_MODE_TEST_PATH 0 +#define MT6357_CCI_AFIFO_CLK_PWDB_ON BIT(1) +#define MT6357_CCI_AFIFO_CLK_PWDB_DOWN 0 +#define MT6357_CCI_ACD_FUNC_RSTB_RELEASE BIT(0) +#define MT6357_CCI_ACD_FUNC_RSTB_RESET 0 + +/* MT6357_AFE_ADDA_MTKAIF_CFG0 */ +#define MT6357_ADDA_MTKAIF_LPBK_CTL_MASK BIT(1) +#define MT6357_ADDA_MTKAIF_LPBK_ENABLE BIT(1) +#define MT6357_ADDA_MTKAIF_LPBK_DISABLE 0 + +/* MT6357_AFE_SGEN_CFG0 */ +#define MT6357_SGEN_DAC_EN_CTL_SFT 7 +#define MT6357_SGEN_DAC_ENABLE BIT(7) +#define MT6357_SGEN_MUTE_SW_CTL_SFT 6 +#define MT6357_SGEN_MUTE_SW_DISABLE 0 + +/* MT6357_AFE_DCCLK_CFG0 */ +#define MT6357_DCCLK_DIV_MASK GENMASK(15, 5) +#define MT6357_DCCLK_DIV_SFT 5 +#define MT6357_DCCLK_DIV_RUN_VALUE (32 << MT6357_DCCLK_DIV_SFT) +#define MT6357_DCCLK_DIV_STOP_VALUE (259 << MT6357_DCCLK_DIV_SFT) +#define MT6357_DCCLK_PDN_MASK BIT(1) +#define MT6357_DCCLK_PDN BIT(1) +#define MT6357_DCCLK_OUTPUT 0 +#define MT6357_DCCLK_GEN_ON_MASK BIT(0) +#define MT6357_DCCLK_GEN_ON BIT(0) +#define MT6357_DCCLK_GEN_OFF 0 + +/* MT6357_AFE_DCCLK_CFG1 */ +#define MT6357_DCCLK_RESYNC_BYPASS_MASK BIT(8) +#define MT6357_DCCLK_RESYNC_BYPASS BIT(8) + +/* MT6357_AFE_AUD_PAD_TOP */ +#define MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK GENMASK(15, 8) +#define MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE (BIT(13) | BIT(12) | BIT(8)) +#define MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE (BIT(13) | BIT(12)) +#define MT6357_AUD_PAD_TX_FIFO_LPBK_MASK GENMASK(7, 0) +#define MT6357_AUD_PAD_TX_FIFO_LPBK_ENABLE (BIT(5) | BIT(4) | BIT(0)) +#define MT6357_AUD_PAD_TX_FIFO_LPBK_DISABLE 0 + +/* MT6357_AUDENC_ANA_CON0 */ +#define MT6357_AUDADCLINPUTSEL_MASK GENMASK(14, 13) +#define MT6357_AUDADCLINPUTSEL_PREAMPLIFIER BIT(14) +#define MT6357_AUDADCLINPUTSEL_IDLE 0 +#define MT6357_AUDADCLPWRUP_SFT 12 +#define MT6357_AUDADCLPWRUP_MASK BIT(12) +#define MT6357_AUDADCLPWRUP BIT(12) +#define MT6357_AUDADCLPWRDOWN 0 +#define MT6357_AUDPREAMPLGAIN_SFT 8 +#define MT6357_AUDPREAMPLGAIN_MASK GENMASK(10, 8) +#define MT6357_AUDPREAMPLGAIN_MAX 4 +#define MT6357_AUDPREAMPLINPUTSEL_SFT 6 +#define MT6357_AUDPREAMPLINPUTSEL_MASK_NOSFT GENMASK(1, 0) +#define MT6357_AUDPREAMPLDCPRECHARGE_MASK BIT(2) +#define MT6357_AUDPREAMPLDCPRECHARGE_ENABLE BIT(2) +#define MT6357_AUDPREAMPLDCPRECHARGE_DISABLE 0 +#define MT6357_AUDPREAMPLDCCEN_MASK BIT(1) +#define MT6357_AUDPREAMPLDCCEN_DC BIT(1) +#define MT6357_AUDPREAMPLDCCEN_AC 0 +#define MT6357_AUDPREAMPLON_MASK BIT(0) +#define MT6357_AUDPREAMPLON_ENABLE BIT(0) +#define MT6357_AUDPREAMPLON_DISABLE 0 + +/* MT6357_AUDENC_ANA_CON1 */ +#define MT6357_AUDADCRINPUTSEL_MASK GENMASK(14, 13) +#define MT6357_AUDADCRINPUTSEL_PREAMPLIFIER BIT(14) +#define MT6357_AUDADCRINPUTSEL_IDLE 0 +#define MT6357_AUDADCRPWRUP_SFT 12 +#define MT6357_AUDADCRPWRUP_MASK BIT(12) +#define MT6357_AUDADCRPWRUP BIT(12) +#define MT6357_AUDADCRPWRDOWN 0 +#define MT6357_AUDPREAMPRGAIN_SFT 8 +#define MT6357_AUDPREAMPRGAIN_MASK GENMASK(10, 8) +#define MT6357_AUDPREAMPRGAIN_MAX 4 +#define MT6357_AUDPREAMPRINPUTSEL_SFT 6 +#define MT6357_AUDPREAMPRINPUTSEL_MASK_NOSFT GENMASK(1, 0) +#define MT6357_AUDPREAMPRDCPRECHARGE_MASK BIT(2) +#define MT6357_AUDPREAMPRDCPRECHARGE_ENABLE BIT(2) +#define MT6357_AUDPREAMPRDCPRECHARGE_DISABLE 0 +#define MT6357_AUDPREAMPRDCCEN_MASK BIT(1) +#define MT6357_AUDPREAMPRDCCEN_DC BIT(1) +#define MT6357_AUDPREAMPRDCCEN_AC 0 +#define MT6357_AUDPREAMPRON_MASK BIT(0) +#define MT6357_AUDPREAMPRON_ENABLE BIT(0) +#define MT6357_AUDPREAMPRON_DISABLE 0 + +/* MT6357_AUDENC_ANA_CON6 */ +#define MT6357_CLKSQ_EN_SFT 0 + +/* MT6357_AUDENC_ANA_CON7 */ +#define MT6357_AUDDIGMICBIAS_MASK GENMASK(2, 1) +#define MT6357_AUDDIGMICBIAS_DEFAULT_VALUE BIT(2) +#define MT6357_AUDDIGMICBIAS_OFF 0 +#define MT6357_AUDDIGMICEN_MASK BIT(0) +#define MT6357_AUDDIGMICEN_ENABLE BIT(0) +#define MT6357_AUDDIGMICEN_DISABLE 0 + +/* MT6357_AUDENC_ANA_CON8 */ +#define MT6357_AUD_MICBIAS0_DCSW2N_EN_MASK BIT(14) +#define MT6357_AUD_MICBIAS0_DCSW2N_ENABLE BIT(14) +#define MT6357_AUD_MICBIAS0_DCSW2N_DISABLE 0 +#define MT6357_AUD_MICBIAS0_DCSW2P2_EN_MASK BIT(13) +#define MT6357_AUD_MICBIAS0_DCSW2P2_ENABLE BIT(13) +#define MT6357_AUD_MICBIAS0_DCSW2P2_DISABLE 0 +#define MT6357_AUD_MICBIAS0_DCSW2P1_EN_MASK BIT(12) +#define MT6357_AUD_MICBIAS0_DCSW2P1_ENABLE BIT(12) +#define MT6357_AUD_MICBIAS0_DCSW2P1_DISABLE 0 +#define MT6357_AUD_MICBIAS0_DCSW0N_EN_MASK BIT(10) +#define MT6357_AUD_MICBIAS0_DCSW0N_ENABLE BIT(10) +#define MT6357_AUD_MICBIAS0_DCSWN_DISABLE 0 +#define MT6357_AUD_MICBIAS0_DCSW0P2_EN_MASK BIT(9) +#define MT6357_AUD_MICBIAS0_DCSW0P2_ENABLE BIT(9) +#define MT6357_AUD_MICBIAS0_DCSW0P2_DISABLE 0 +#define MT6357_AUD_MICBIAS0_DCSW0P1_EN_MASK BIT(8) +#define MT6357_AUD_MICBIAS0_DCSW0P1_ENABLE BIT(8) +#define MT6357_AUD_MICBIAS0_DCSW0P1_DISABLE 0 +#define MT6357_AUD_MICBIAS0_VREF_MASK GENMASK(6, 4) +#define MT6357_AUD_MICBIAS0_VREF_SFT 4 +#define MT6357_AUD_MICBIAS0_PWD_SFT 0 + +#define MT6357_AUD_MICBIAS0_DC_MASK (MT6357_AUD_MICBIAS0_DCSW2N_EN_MASK | \ + MT6357_AUD_MICBIAS0_DCSW2P2_EN_MASK | \ + MT6357_AUD_MICBIAS0_DCSW2P1_EN_MASK | \ + MT6357_AUD_MICBIAS0_DCSW0N_EN_MASK | \ + MT6357_AUD_MICBIAS0_DCSW0P2_EN_MASK | \ + MT6357_AUD_MICBIAS0_DCSW0P1_EN_MASK) + +#define MT6357_AUD_MICBIAS0_DC_ENABLE_ALL (MT6357_AUD_MICBIAS0_DCSW2N_ENABLE | \ + MT6357_AUD_MICBIAS0_DCSW2P2_ENABLE | \ + MT6357_AUD_MICBIAS0_DCSW2P1_ENABLE | \ + MT6357_AUD_MICBIAS0_DCSW0N_ENABLE | \ + MT6357_AUD_MICBIAS0_DCSW0P2_ENABLE | \ + MT6357_AUD_MICBIAS0_DCSW0P1_ENABLE) + +#define MT6357_AUD_MICBIAS0_DC_ENABLE_P1 (MT6357_AUD_MICBIAS0_DCSW2P1_ENABLE | \ + MT6357_AUD_MICBIAS0_DCSW0P1_ENABLE) + +#define MT6357_AUD_MICBIAS0_DC_DISABLE_ALL 0 + +/* MT6357_AUDENC_ANA_CON9 */ +#define MT6357_AUD_MICBIAS1_DCSW1P_EN_MASK BIT(8) +#define MT6357_AUD_MICBIAS1_DCSW1P_ENABLE BIT(8) +#define MT6357_AUD_MICBIAS1_DCSW1P_DISABLE 0 +#define MT6357_AUD_MICBIAS1_VREF_MASK GENMASK(6, 4) +#define MT6357_AUD_MICBIAS1_VREF_SFT 4 +#define MT6357_AUD_MICBIAS1_PWD_SFT 0 + +/* MT6357_AUDDEC_ANA_CON0 */ +#define MT6357_AUD_HPR_SC_VAUDP15_MASK BIT(13) +#define MT6357_AUD_HPR_SC_VAUDP15_DISABLE BIT(13) +#define MT6357_AUD_HPR_SC_VAUDP15_ENABLE 0 +#define MT6357_AUD_HPL_SC_VAUDP15_MASK BIT(12) +#define MT6357_AUD_HPL_SC_VAUDP15_DISABLE BIT(12) +#define MT6357_AUD_HPL_SC_VAUDP15_ENABLE 0 +#define MT6357_AUD_HPR_MUX_INPUT_VAUDP15_MASK_NOSFT GENMASK(1, 0) +#define MT6357_AUD_HPR_MUX_INPUT_VAUDP15_SFT 10 +#define MT6357_AUD_HPL_MUX_INPUT_VAUDP15_MASK_NOSFT GENMASK(1, 0) +#define MT6357_AUD_HPL_MUX_INPUT_VAUDP15_SFT 8 +#define MT6357_AUD_HPR_BIAS_VAUDP15_MASK BIT(7) +#define MT6357_AUD_HPR_BIAS_VAUDP15_ENABLE BIT(7) +#define MT6357_AUD_HPR_BIAS_VAUDP15_DISABLE 0 +#define MT6357_AUD_HPL_BIAS_VAUDP15_MASK BIT(6) +#define MT6357_AUD_HPL_BIAS_VAUDP15_ENABLE BIT(6) +#define MT6357_AUD_HPL_BIAS_VAUDP15_DISABLE 0 +#define MT6357_AUD_HPR_PWRUP_VAUDP15_MASK BIT(5) +#define MT6357_AUD_HPR_PWRUP_VAUDP15_ENABLE BIT(5) +#define MT6357_AUD_HPR_PWRUP_VAUDP15_DISABLE 0 +#define MT6357_AUD_HPL_PWRUP_VAUDP15_MASK BIT(4) +#define MT6357_AUD_HPL_PWRUP_VAUDP15_ENABLE BIT(4) +#define MT6357_AUD_HPL_PWRUP_VAUDP15_DISABLE 0 +#define MT6357_AUD_DACL_PWRUP_VA28_MASK BIT(3) +#define MT6357_AUD_DACL_PWRUP_VA28_ENABLE BIT(3) +#define MT6357_AUD_DACL_PWRUP_VA28_DISABLE 0 +#define MT6357_AUD_DACR_PWRUP_VA28_MASK BIT(2) +#define MT6357_AUD_DACR_PWRUP_VA28_ENABLE BIT(2) +#define MT6357_AUD_DACR_PWRUP_VA28_DISABLE 0 +#define MT6357_AUD_DACR_PWRUP_VAUDP15_MASK BIT(1) +#define MT6357_AUD_DACR_PWRUP_VAUDP15_ENABLE BIT(1) +#define MT6357_AUD_DACR_PWRUP_VAUDP15_DISABLE 0 +#define MT6357_AUD_DACL_PWRUP_VAUDP15_MASK BIT(0) +#define MT6357_AUD_DACL_PWRUP_VAUDP15_ENABLE BIT(0) +#define MT6357_AUD_DACL_PWRUP_VAUDP15_DISABLE 0 + +/* MT6357_AUDDEC_ANA_CON1 */ +#define MT6357_HPROUT_STG_CTRL_VAUDP15_MASK GENMASK(14, 12) +#define MT6357_HPROUT_STG_CTRL_VAUDP15_SFT 12 +#define MT6357_HPLOUT_STG_CTRL_VAUDP15_MASK GENMASK(10, 8) +#define MT6357_HPLOUT_STG_CTRL_VAUDP15_SFT 8 +#define MT6357_HPLOUT_STG_CTRL_VAUDP15_MAX 7 +#define MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK BIT(7) +#define MT6357_HPR_SHORT2HPR_AUX_VAUDP15_ENABLE BIT(7) +#define MT6357_HPR_SHORT2HPR_AUX_VAUDP15_DISABLE 0 +#define MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK BIT(6) +#define MT6357_HPL_SHORT2HPR_AUX_VAUDP15_ENABLE BIT(6) +#define MT6357_HPL_SHORT2HPR_AUX_VAUDP15_DISABLE 0 +#define MT6357_HPR_AUX_FBRSW_VAUDP15_MASK BIT(5) +#define MT6357_HPR_AUX_FBRSW_VAUDP15_ENABLE BIT(5) +#define MT6357_HPR_AUX_FBRSW_VAUDP15_DISABLE 0 +#define MT6357_HPL_AUX_FBRSW_VAUDP15_MASK BIT(4) +#define MT6357_HPL_AUX_FBRSW_VAUDP15_ENABLE BIT(4) +#define MT6357_HPL_AUX_FBRSW_VAUDP15_DISABLE 0 +#define MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK BIT(3) +#define MT6357_HPROUT_AUX_PWRUP_VAUDP15_ENABLE BIT(3) +#define MT6357_HPROUT_AUX_PWRUP_VAUDP15_DISABLE 0 +#define MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK BIT(2) +#define MT6357_HPLOUT_AUX_PWRUP_VAUDP15_ENABLE BIT(2) +#define MT6357_HPLOUT_AUX_PWRUP_VAUDP15_DISABLE 0 +#define MT6357_HPROUT_PWRUP_VAUDP15_MASK BIT(1) +#define MT6357_HPROUT_PWRUP_VAUDP15_ENABLE BIT(1) +#define MT6357_HPROUT_PWRUP_VAUDP15_DISABLE 0 +#define MT6357_HPLOUT_PWRUP_VAUDP15_MASK BIT(0) +#define MT6357_HPLOUT_PWRUP_VAUDP15_ENABLE BIT(0) +#define MT6357_HPLOUT_PWRUP_VAUDP15_DISABLE 0 + +/* MT6357_AUDDEC_ANA_CON2 */ +#define MT6357_HPP_SHORT_2VCM_VAUDP15_MASK BIT(10) +#define MT6357_HPP_SHORT_2VCM_VAUDP15_ENABLE BIT(10) +#define MT6357_HPP_SHORT_2VCM_VAUDP15_DISABLE 0 +#define MT6357_AUD_REFN_DERES_VAUDP15_MASK BIT(9) +#define MT6357_AUD_REFN_DERES_VAUDP15_ENABLE BIT(9) +#define MT6357_AUD_REFN_DERES_VAUDP15_DISABLE 0 +#define MT6357_HPROUT_STB_ENH_VAUDP15_MASK GENMASK(6, 4) +#define MT6357_HPROUT_STB_ENH_VAUDP15_OPEN 0 +#define MT6357_HPROUT_STB_ENH_VAUDP15_NOPEN_P250 BIT(4) +#define MT6357_HPROUT_STB_ENH_VAUDP15_N470_POPEN BIT(5) +#define MT6357_HPROUT_STB_ENH_VAUDP15_N470_P250 (BIT(4) | BIT(5)) +#define MT6357_HPROUT_STB_ENH_VAUDP15_NOPEN_P470 (BIT(4) | BIT(6)) +#define MT6357_HPROUT_STB_ENH_VAUDP15_N470_P470 (BIT(4) | BIT(5) | BIT(6)) +#define MT6357_HPLOUT_STB_ENH_VAUDP15_MASK GENMASK(2, 0) +#define MT6357_HPLOUT_STB_ENH_VAUDP15_OPEN 0 +#define MT6357_HPLOUT_STB_ENH_VAUDP15_NOPEN_P250 BIT(0) +#define MT6357_HPLOUT_STB_ENH_VAUDP15_N470_POPEN BIT(1) +#define MT6357_HPLOUT_STB_ENH_VAUDP15_N470_P250 (BIT(0) | BIT(1)) +#define MT6357_HPLOUT_STB_ENH_VAUDP15_NOPEN_P470 (BIT(0) | BIT(2)) +#define MT6357_HPLOUT_STB_ENH_VAUDP15_N470_P470 (BIT(0) | BIT(1) | BIT(2)) + +/* MT6357_AUDDEC_ANA_CON3 */ +#define MT6357_AUD_HSOUT_STB_ENH_VAUDP15_MASK BIT(7) +#define MT6357_AUD_HSOUT_STB_ENH_VAUDP15_ENABLE BIT(7) +#define MT6357_AUD_HSOUT_STB_ENH_VAUDP15_DISABLE 0 +#define MT6357_AUD_HS_SC_VAUDP15_MASK BIT(4) +#define MT6357_AUD_HS_SC_VAUDP15_DISABLE BIT(4) +#define MT6357_AUD_HS_SC_VAUDP15_ENABLE 0 +#define MT6357_AUD_HS_MUX_INPUT_VAUDP15_MASK_NOSFT GENMASK(1, 0) +#define MT6357_AUD_HS_MUX_INPUT_VAUDP15_SFT 2 +#define MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_MASK BIT(1) +#define MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_ENABLE BIT(1) +#define MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_DISABLE 0 +#define MT6357_AUD_HS_PWRUP_VAUDP15_MASK BIT(0) +#define MT6357_AUD_HS_PWRUP_VAUDP15_ENABLE BIT(0) +#define MT6357_AUD_HS_PWRUP_VAUDP15_DISABLE 0 + +/* MT6357_AUDDEC_ANA_CON4 */ +#define MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_MASK BIT(8) +#define MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_ENABLE BIT(8) +#define MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_DISABLE 0 +#define MT6357_AUD_LOL_SC_VAUDP15_MASK BIT(4) +#define MT6357_AUD_LOL_SC_VAUDP15_DISABLE BIT(4) +#define MT6357_AUD_LOL_SC_VAUDP15_ENABLE 0 +#define MT6357_AUD_LOL_MUX_INPUT_VAUDP15_MASK_NOSFT GENMASK(1, 0) +#define MT6357_AUD_LOL_MUX_INPUT_VAUDP15_SFT 2 +#define MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_MASK BIT(1) +#define MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_ENABLE BIT(1) +#define MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_DISABLE 0 +#define MT6357_AUD_LOL_PWRUP_VAUDP15_MASK BIT(0) +#define MT6357_AUD_LOL_PWRUP_VAUDP15_ENABLE BIT(0) +#define MT6357_AUD_LOL_PWRUP_VAUDP15_DISABLE 0 + +/* MT6357_AUDDEC_ANA_CON6 */ +#define MT6357_HP_AUX_LOOP_GAIN_MASK GENMASK(15, 12) +#define MT6357_HP_AUX_LOOP_GAIN_SFT 12 +#define MT6357_HP_AUX_LOOP_GAIN_MAX 0x0f +#define MT6357_HPR_AUX_CMFB_LOOP_MASK BIT(11) +#define MT6357_HPR_AUX_CMFB_LOOP_ENABLE BIT(11) +#define MT6357_HPR_AUX_CMFB_LOOP_DISABLE 0 +#define MT6357_HPL_AUX_CMFB_LOOP_MASK BIT(10) +#define MT6357_HPL_AUX_CMFB_LOOP_ENABLE BIT(10) +#define MT6357_HPL_AUX_CMFB_LOOP_DISABLE 0 +#define MT6357_HPRL_MAIN_CMFB_LOOP_MASK BIT(9) +#define MT6357_HPRL_MAIN_CMFB_LOOP_ENABLE BIT(9) +#define MT6357_HPRL_MAIN_CMFB_LOOP_DISABLE 0 +#define MT6357_HP_CMFB_RST_MASK BIT(7) +#define MT6357_HP_CMFB_RST_NORMAL BIT(7) +#define MT6357_HP_CMFB_RST_RESET 0 +#define MT6357_DAC_LOW_NOISE_MODE_MASK BIT(0) +#define MT6357_DAC_LOW_NOISE_MODE_ENABLE BIT(0) +#define MT6357_DAC_LOW_NOISE_MODE_DISABLE 0 + +/* MT6357_AUDDEC_ANA_CON7 */ +#define MT6357_HP_IVBUF_DEGAIN_SFT 2 +#define MT6357_HP_IVBUF_DEGAIN_MAX 1 + +/* MT6357_AUDDEC_ANA_CON10 */ +#define MT6357_AUD_IBIAS_PWRDN_VAUDP15_MASK BIT(8) +#define MT6357_AUD_IBIAS_PWRDN_VAUDP15_DISABLE BIT(8) +#define MT6357_AUD_IBIAS_PWRDN_VAUDP15_ENABLE 0 + +/* MT6357_AUDDEC_ANA_CON11 */ +#define MT6357_RSTB_ENCODER_VA28_MASK BIT(5) +#define MT6357_RSTB_ENCODER_VA28_ENABLE BIT(5) +#define MT6357_RSTB_ENCODER_VA28_DISABLE 0 +#define MT6357_AUDGLB_PWRDN_VA28_SFT 4 +#define MT6357_RSTB_DECODER_VA28_MASK BIT(0) +#define MT6357_RSTB_DECODER_VA28_ENABLE BIT(0) +#define MT6357_RSTB_DECODER_VA28_DISABLE 0 + +/* MT6357_AUDDEC_ANA_CON12 */ +#define MT6357_VA28REFGEN_EN_VA28_MASK BIT(13) +#define MT6357_VA28REFGEN_EN_VA28_ENABLE BIT(13) +#define MT6357_VA28REFGEN_EN_VA28_DISABLE 0 +#define MT6357_VA33REFGEN_EN_VA18_MASK BIT(12) +#define MT6357_VA33REFGEN_EN_VA18_ENABLE BIT(12) +#define MT6357_VA33REFGEN_EN_VA18_DISABLE 0 +#define MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_MASK BIT(10) +#define MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_ENABLE BIT(10) +#define MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_DISABLE 0 +#define MT6357_LCLDO_ENC_EN_VA28_MASK BIT(8) +#define MT6357_LCLDO_ENC_EN_VA28_ENABLE BIT(8) +#define MT6357_LCLDO_ENC_EN_VA28_DISABLE 0 +#define MT6357_LCLDO_REMOTE_SENSE_VA18_MASK BIT(6) +#define MT6357_LCLDO_REMOTE_SENSE_VA18_ENABLE BIT(6) +#define MT6357_LCLDO_REMOTE_SENSE_VA18_DISABLE 0 +#define MT6357_LCLDO_EN_VA18_MASK BIT(4) +#define MT6357_LCLDO_EN_VA18_ENABLE BIT(4) +#define MT6357_LCLDO_EN_VA18_DISABLE 0 +#define MT6357_HCLDO_REMOTE_SENSE_VA18_MASK BIT(2) +#define MT6357_HCLDO_REMOTE_SENSE_VA18_ENABLE BIT(2) +#define MT6357_HCLDO_REMOTE_SENSE_VA18_DISABLE 0 +#define MT6357_HCLDO_EN_VA18_MASK BIT(0) +#define MT6357_HCLDO_EN_VA18_ENABLE BIT(0) +#define MT6357_HCLDO_EN_VA18_DISABLE 0 + +/* MT6357_AUDDEC_ANA_CON13 */ +#define MT6357_NVREG_EN_VAUDP15_MASK BIT(0) +#define MT6357_NVREG_EN_VAUDP15_ENABLE BIT(0) +#define MT6357_NVREG_EN_VAUDP15_DISABLE 0 + +/* MT6357_AUDDEC_ELR_0 */ +#define MT6357_AUD_HP_TRIM_EN_VAUDP15_MASK BIT(12) +#define MT6357_AUD_HP_TRIM_EN_VAUDP15_ENABLE BIT(12) +#define MT6357_AUD_HP_TRIM_EN_VAUDP15_DISABLE 0 + +/* MT6357_ZCD_CON1 */ +#define MT6357_AUD_LOL_GAIN_MASK GENMASK(4, 0) +#define MT6357_AUD_LOL_GAIN_SFT 0 +#define MT6357_AUD_LOR_GAIN_MASK GENMASK(11, 7) +#define MT6357_AUD_LOR_GAIN_SFT 7 +#define MT6357_AUD_LO_GAIN_MAX 0x12 + +/* MT6357_ZCD_CON2 */ +#define MT6357_AUD_HPL_GAIN_MASK GENMASK(4, 0) +#define MT6357_AUD_HPL_GAIN_SFT 0 +#define MT6357_AUD_HPR_GAIN_MASK GENMASK(11, 7) +#define MT6357_AUD_HPR_GAIN_SFT 7 +#define MT6357_AUD_HP_GAIN_MAX 0x12 + +/* MT6357_ZCD_CON3 */ +#define MT6357_AUD_HS_GAIN_MASK GENMASK(4, 0) +#define MT6357_AUD_HS_GAIN_SFT 0 +#define MT6357_AUD_HS_GAIN_MAX 0x12 + +/* Registers list */ +/* gpio direction */ +#define MT6357_GPIO_DIR0 0x0088 +/* mosi */ +#define MT6357_GPIO_MODE2 0x00B6 +#define MT6357_GPIO_MODE2_SET 0x00B8 +#define MT6357_GPIO_MODE2_CLR 0x00BA +/* miso */ +#define MT6357_GPIO_MODE3 0x00BC +#define MT6357_GPIO_MODE3_SET 0x00BE +#define MT6357_GPIO_MODE3_CLR 0x00C0 + +#define MT6357_DCXO_CW14 0x07AC + +#define MT6357_AUD_TOP_CKPDN_CON0 0x208C +#define MT6357_AUDNCP_CLKDIV_CON0 0x20B4 +#define MT6357_AUDNCP_CLKDIV_CON1 0x20B6 +#define MT6357_AUDNCP_CLKDIV_CON2 0x20B8 +#define MT6357_AUDNCP_CLKDIV_CON3 0x20BA +#define MT6357_AUDNCP_CLKDIV_CON4 0x20BC +#define MT6357_AFE_UL_DL_CON0 0x2108 +#define MT6357_AFE_DL_SRC2_CON0_L 0x210A +#define MT6357_AFE_UL_SRC_CON0_H 0x210C +#define MT6357_AFE_UL_SRC_CON0_L 0x210E +#define MT6357_AFE_TOP_CON0 0x2110 +#define MT6357_AUDIO_TOP_CON0 0x2112 +#define MT6357_AFUNC_AUD_CON0 0x2116 +#define MT6357_AFUNC_AUD_CON2 0x211A +#define MT6357_AFE_ADDA_MTKAIF_CFG0 0x2134 +#define MT6357_AFE_SGEN_CFG0 0x2140 +#define MT6357_AFE_DCCLK_CFG0 0x2146 +#define MT6357_AFE_DCCLK_CFG1 0x2148 +#define MT6357_AFE_AUD_PAD_TOP 0x214C +#define MT6357_AUDENC_ANA_CON0 0x2188 +#define MT6357_AUDENC_ANA_CON1 0x218A +#define MT6357_AUDENC_ANA_CON6 0x2194 +#define MT6357_AUDENC_ANA_CON7 0x2196 +#define MT6357_AUDENC_ANA_CON8 0x2198 +#define MT6357_AUDENC_ANA_CON9 0x219A +#define MT6357_AUDDEC_ANA_CON0 0x2208 +#define MT6357_AUDDEC_ANA_CON1 0x220A +#define MT6357_AUDDEC_ANA_CON2 0x220C +#define MT6357_AUDDEC_ANA_CON3 0x220E +#define MT6357_AUDDEC_ANA_CON4 0x2210 +#define MT6357_AUDDEC_ANA_CON6 0x2214 +#define MT6357_AUDDEC_ANA_CON7 0x2216 +#define MT6357_AUDDEC_ANA_CON10 0x221C +#define MT6357_AUDDEC_ANA_CON11 0x221E +#define MT6357_AUDDEC_ANA_CON12 0x2220 +#define MT6357_AUDDEC_ANA_CON13 0x2222 +#define MT6357_AUDDEC_ELR_0 0x2226 +#define MT6357_ZCD_CON1 0x228A +#define MT6357_ZCD_CON2 0x228C +#define MT6357_ZCD_CON3 0x228E + +enum { + DL_GAIN_8DB = 0, + DL_GAIN_0DB = 8, + DL_GAIN_N_1DB = 9, + DL_GAIN_N_10DB = 18, + DL_GAIN_N_12DB = 20, + DL_GAIN_N_40DB = 0x1f, +}; + +enum { + UL_GAIN_0DB = 0, + UL_GAIN_6DB, + UL_GAIN_12DB, + UL_GAIN_18DB, + UL_GAIN_24DB, +}; + +#define MT6357_DL_GAIN_N_40DB_REG (DL_GAIN_N_40DB << 7 | DL_GAIN_N_40DB) +#define MT6357_DL_GAIN_REG_LEFT_MASK 0x001f +#define MT6357_DL_GAIN_REG_LEFT_SHIFT 0 +#define MT6357_DL_GAIN_REG_RIGHT_MASK 0x0f80 +#define MT6357_DL_GAIN_REG_RIGHT_SHIFT 7 +#define MT6357_DL_GAIN_REG_MASK 0x0f9f + +#define MT6357_SND_SOC_ADV_MT_FMTS (\ + SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S16_BE |\ + SNDRV_PCM_FMTBIT_U16_LE |\ + SNDRV_PCM_FMTBIT_U16_BE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_BE |\ + SNDRV_PCM_FMTBIT_U24_LE |\ + SNDRV_PCM_FMTBIT_U24_BE |\ + SNDRV_PCM_FMTBIT_S32_LE |\ + SNDRV_PCM_FMTBIT_S32_BE |\ + SNDRV_PCM_FMTBIT_U32_LE |\ + SNDRV_PCM_FMTBIT_U32_BE) + +#define MT6357_SOC_HIGH_USE_RATE (\ + SNDRV_PCM_RATE_CONTINUOUS |\ + SNDRV_PCM_RATE_8000_192000) + +#define MT6357_MICBIAS_ARRAY_SIZE 8 + +/* codec private structure */ +struct mt6357_priv { + struct device *dev; + struct regmap *regmap; + bool pull_down_needed; + int hp_channel_number; +}; +#endif From patchwork Fri Apr 26 17:22:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645164 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 11F5DC19F4F for ; Fri, 26 Apr 2024 17:23:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 05067113706; Fri, 26 Apr 2024 17:23:32 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="hihAWTzL"; dkim-atps=neutral Received: from mail-ed1-f41.google.com (mail-ed1-f41.google.com [209.85.208.41]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8DFAE10ECC4 for ; Fri, 26 Apr 2024 17:23:01 +0000 (UTC) Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-571bddddbc2so2982562a12.1 for ; Fri, 26 Apr 2024 10:23:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152180; x=1714756980; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=+HA5hs8xf/jy+EOJ7+HP5joeg+9+VSnSpeoghvWaVeM=; b=hihAWTzLYw/eO1KYSXelGHGdoc0JznW0k0pDOZuUSYf8nEnqdvfjCWfUs6YDZd0aNk W0RooC/2UKy8JigxWm3XsPYRoPaeB7Dr67567qifITh9nDpWGwFdC1pwSLamNemCiWLo sIaUF8eTzs46stpEJAUHWEckMUEW6m/Fp0I/MwYO+cp7vKcBMuv2n9RkwA0MiXgNP69S ywtB8+/PLt9nxNudM9T3pXHy2ysLCh4VzZ++nLzZ2VOago0sWdXI9hQnBEKaoMVgk9lG KWE7xVS5JJ0oogiN4Cc9ttkuyjJCuQxw+BV+2/dmmjcaSe5OJs1BjkKHQf+p9cFpzLmk hclw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152180; x=1714756980; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+HA5hs8xf/jy+EOJ7+HP5joeg+9+VSnSpeoghvWaVeM=; b=cLexb539FnrnMtcN830hYKDdZW2PTHS3Y2lpfg+XtJrAdYjFRBI8LkGwoLeKr0spI7 w8TvNuuVc18nwwi+qz2HuModC/RGnUxmtcuCT8OplTYG8P6WooUu1s+lhFnhTFwqaOWc 0kSTrJJAlGOLmhYB5zQczuvlM5BXoel9Xq8MQpvoi2agcafxKL6ds4EVvDf5jNsVCjAW Rt/yrDUA1wOedIY7RMF4VVbDupxEaQ/GdeTodtFheBaFDkNtVp/PtT0U04TL+XBh7qa5 b20brE401Xnxd0pSuEfVNCoE9fS7rQeTuGjeEEyrO1oLXXYbEPAzv1tdYOd4minuw8j0 3Fhw== X-Forwarded-Encrypted: i=1; AJvYcCUULZ+2Z1QJjNo1yv24q5uJ2R1ZoZrBXlr4EBjQztAwOPQs2XVh8yJtGbAVtuVH9anCkOijMDnsOVvIJEv5SQRRjOvCe5XM4HkeyjuKA/0d X-Gm-Message-State: AOJu0YwCdAZbtvoseJfMGq6EsT2QW+32/IYhTFpGQ1aeZY5Kql5S9cYH WD0w227VcgWzOBS0u4Kb0yCq9V9I5CKIJ6oImq70+FsDUe7f+rED7VUO3SrWpG0= X-Google-Smtp-Source: AGHT+IHbc56Ak+iiZKc6UM6Y4436Jjedt2ZE6Lfg8rDGrCH/hYHwl421b4ny1eWhX3iqzBHxLgcC0Q== X-Received: by 2002:a17:907:20d6:b0:a58:828b:554e with SMTP id qq22-20020a17090720d600b00a58828b554emr2613172ejb.71.1714152179855; Fri, 26 Apr 2024 10:22:59 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.22.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:22:59 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:42 +0200 Subject: [PATCH v4 13/16] ASoC: mediatek: Add MT8365 support MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-13-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2430; i=amergnat@baylibre.com; h=from:subject:message-id; bh=A2PASoilqpYSI/+vuK5IOoXc5LlU1gMN/yOVGVWPN5c=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+La2MbhNuLjWxwp2m2IbEOSPve0e5649hcdKnUy eFfF2Z2JAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURVS9D/ 9wJyopXYFZ8sHNU/hOFop7d7AhUUMqWMTq6ghx4GKwXdqRxY+U+1R1ozjFG51w0l2XrMFJTEZp5NNq /R4N1hJo3MUpx0LwK+xh1AgS9m1BGfZeGvy870ANxleqrn2Th5OzVYYub6CvHmSTwazS/OCu/LW8vU ngh8zEeFys9AcCIoqgEjBdF5vCzsRGJ7n9PINqZqOFiPxm+gf7ZYexa/TNOZjjm/nabcgXvyFXdsou 9LCMWY5YxWbSNYnzpemqgVdjdDLPjz9yn1w0uCOuQvbJsBLh4I1EcLHyRBkSwELYE2F92zhHHFoFxP nddG05Yu+XTwsO/xDxzn4sj5+EA/Y7gKilUEvQiPECyAD+ANWhSY3DDE/nuIclOYFuvRFA4DI3Ya8Q SNwNWtpdIQSeMMotCEoCKHgatqCKzTP8BUiaoCkoIJwhfFFxKHjkOqnvaMXoSDKZjzu1Zlxx3ftWZR HTGGofaOk+LOade2EywQL7K1X6pwIX6uSW/T0XkT7dA9HSVee2ne4Z2gojbAW6saTNssOTHihVQlqa 6WsFMzHqNmh4J+Te9JsysGF8q2RU5jmV8iyDnhBb58KNGPKTaQjScWYIw5aqRjObOwoiYj5y+GSCB3 RubdN5kTRddimfOUPsFzSFR/lvjy3GHo247bkweyYeUh/PXbZ9014W5fGMiA== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" - Add specific config to enable: - MT8365 sound support - MT6357 audio codec support - Add the mt8365 directory and all drivers under it. Signed-off-by: Alexandre Mergnat --- sound/soc/mediatek/Kconfig | 20 ++++++++++++++++++++ sound/soc/mediatek/Makefile | 1 + sound/soc/mediatek/mt8365/Makefile | 15 +++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 5a8476e1ecca..c1c86ecc0601 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -298,3 +298,23 @@ config SND_SOC_MT8195_MT6359 boards with the MT6359 and other I2S audio codecs. Select Y if you have such device. If unsure select "N". + +config SND_SOC_MT8365 + tristate "ASoC support for Mediatek MT8365 chip" + depends on ARCH_MEDIATEK + select SND_SOC_MEDIATEK + help + This adds ASoC platform driver support for Mediatek MT8365 chip + that can be used with other codecs. + Select Y if you have such device. + If unsure select "N". + +config SND_SOC_MT8365_MT6357 + tristate "ASoC Audio driver for MT8365 with MT6357 codec" + depends on SND_SOC_MT8365 && MTK_PMIC_WRAP + select SND_SOC_MT6357 + help + This adds support for ASoC machine driver for Mediatek MT8365 + boards with the MT6357 codec. + Select Y if you have such device. + If unsure select "N". diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 3938e7f75c2e..4b55434f2168 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_SND_SOC_MT8186) += mt8186/ obj-$(CONFIG_SND_SOC_MT8188) += mt8188/ obj-$(CONFIG_SND_SOC_MT8192) += mt8192/ obj-$(CONFIG_SND_SOC_MT8195) += mt8195/ +obj-$(CONFIG_SND_SOC_MT8365) += mt8365/ diff --git a/sound/soc/mediatek/mt8365/Makefile b/sound/soc/mediatek/mt8365/Makefile new file mode 100644 index 000000000000..52ba45a8498a --- /dev/null +++ b/sound/soc/mediatek/mt8365/Makefile @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 + +# MTK Platform driver +snd-soc-mt8365-pcm-objs := \ + mt8365-afe-clk.o \ + mt8365-afe-pcm.o \ + mt8365-dai-adda.o \ + mt8365-dai-dmic.o \ + mt8365-dai-i2s.o \ + mt8365-dai-pcm.o + +obj-$(CONFIG_SND_SOC_MT8365) += snd-soc-mt8365-pcm.o + +# Machine driver +obj-$(CONFIG_SND_SOC_MT8365_MT6357) += mt8365-mt6357.o From patchwork Fri Apr 26 17:22:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6BFD2C4345F for ; Fri, 26 Apr 2024 17:23:32 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7337011266B; Fri, 26 Apr 2024 17:23:31 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="zfbEzkln"; dkim-atps=neutral Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6972310ECC4 for ; Fri, 26 Apr 2024 17:23:03 +0000 (UTC) Received: by mail-ej1-f47.google.com with SMTP id a640c23a62f3a-a5200202c1bso311623466b.0 for ; Fri, 26 Apr 2024 10:23:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152182; x=1714756982; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=xcpfNzgF4Pxbm0LNn8/0bg6Ray8UkamWuHdRS27GJF4=; b=zfbEzklnVSGXw0sD/8OCMEJsr/KW/hU8aLy4kmVc9VnPrjQ8mqJKMHFhWKr/CeO2m1 9RA+FiB+JHsgLwTUdFvSyEnhjez3xvmhGqBAtW6gRLNFtaX0kGF9RwH7thKKwCKndqT4 z4fFHfmYvRiig2i3ELrnn5OE5d1KNSBisrXcynNhnLJp+zPcH2gSaRdlpbSzOyTTF0pA 8Ij0x/jq6a14kDaCC9ofv8ERhCSwq1lpbnyT8GL/UjghuGsi8pxIxFpG1gyI0s4tg01s FWJO4Q6TIx4Az1UnUMzOgaIfsV6G/bisvKRm7l7C2GnuGvQe409kntLeic7cGwfePVsI M5eQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152182; x=1714756982; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xcpfNzgF4Pxbm0LNn8/0bg6Ray8UkamWuHdRS27GJF4=; b=dsrmRIOiEF8NOmdDavh2fTshRMuLq5Qun9tF95zNj8DvqCUcDZQB+XRBCloK2BYo0/ Z321zlJrgQT2zrHuS3240bAuYdG0m7WQMLlyz6c7GA/jUql2CEDf+c1Eu8s+dCxy8G73 qfozfkeaOmriJBaVN3/WPIOVCCZuuB7Yi82RimNr/Y1xMHwGVnT3yK9LmE3+3Roc7A9n N91YTbex8bQm/wBQhhrx47a0ZnFkumbQKHZY7n2d4lNek8loEJZNA+OtbdeUYFjs6D5h 43sZLa8QP6g/1V9EJrPk9mU0i2q3SqwWZ1FDLYWSdMGn09Yg4X7K59V5LpqBwaEixcZZ D+gQ== X-Forwarded-Encrypted: i=1; AJvYcCUC5j4Ap7bRjRHgEKurioCirM+ybnstKvGQ7gy1+Oltwp7e0hc1t0lb9is0i18kQORJiXq10qxAhrkXOq9615ArZP3NASkIu1VEH003d1Ch X-Gm-Message-State: AOJu0YxYWNHC7yVAkNdRWmGzXFpK+/8Bfn7rYINDLP6lsJDWPRF+JH1C t2q6hO2nrWx4ubzaubAxq2ooMB2qzn0HjXDy/0FXBwkw1irDdGor0YxQ5Xh43pA= X-Google-Smtp-Source: AGHT+IGmV772pWcBFFswx8n1IxjhIJ0x0YA21t+MT9LToWGyNEPcTNukKiSKMrBp3S1NfSOajrN0ng== X-Received: by 2002:a17:906:a891:b0:a52:6159:5064 with SMTP id ha17-20020a170906a89100b00a5261595064mr3051872ejb.52.1714152181727; Fri, 26 Apr 2024 10:23:01 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.23.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:23:01 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:43 +0200 Subject: [PATCH v4 14/16] arm64: defconfig: enable mt8365 sound MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-14-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=777; i=amergnat@baylibre.com; h=from:subject:message-id; bh=rklTeGdgjcr8HpkwnLXFeP3xtFTG5m2BfNOFT4tOLv8=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaCp9ZVTItyYTqXVHXkRe07IHi+GgD/LNAxSnV VoN96EmJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURXNkD/ 9u5HUKfktWXA52P/DVWjf9SNrUwcHyS+3vetaBi7qI27CfzXCbQDJnpz3/PL3n0C79B6A+sX1jkGKM 60cKtdXeibqQo+DbAVJnZhxN7ijZz+xCslh96h8NwTXPDIJzXg/GrP0LOT8j6YzTyDD2akcTG8Nq5k ynO+FcnNN3kk1Trt+Fqq/nlY6IS9FqMiYj68Ch3zQzv5galw8rzUGmwK1ytAk1mf+GffJeauLZjIWz PnS7NB2gzhbf/4NlURVM6EKl0qLWeQfHhQY07nstES4z1CfygEoGrTpb0+9Z0D0d3gqk9FPNyKF3rt IXF6DiuXwJY/P7yVqHSU0po05JBpT+ghWfZcdRe7a/NqzqAWPsgY1Y+Ug6UGVpef5v23LEttxXBzfe WlFRJz6TQT5O93zSsmp/p/Ccds+tq9smGidiQ6DFPjo1v9YtGcm8MmdmyXQjozN1UiElk5LYl/kSiy IOe88WsQ0dTYG/BVomOdUsrpMZrOsZ2DYhYHdDsE2bziUj/cngmXdlb9vJ9nPZclz5mecfo5AlsdBQ ZeAMfQKMVO1NY1Ad5qR78yXmyzKTtkr0Qnw9m0flAeyf79Zcv1OP7/SngMLkOvUQcORd5Jaa4hDDVo wl1VU0X6TjlmCfEzejZsMNIHMrgmGvnc5dkIqrenbp/4WcHgE5xdWjOQCDWQ== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Enable the MediaTek MT8365-EVK sound support. The audio feature is handled by the MT8365 SoC and the MT6357 PMIC codec audio. Signed-off-by: Alexandre Mergnat Reviewed-by: AngeloGioacchino Del Regno --- arch/arm64/configs/defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 998b71d5789e..faf39d837674 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -948,6 +948,8 @@ CONFIG_SND_SOC_MT8192=m CONFIG_SND_SOC_MT8192_MT6359_RT1015_RT5682=m CONFIG_SND_SOC_MT8195=m CONFIG_SND_SOC_MT8195_MT6359=m +CONFIG_SND_SOC_MT8365=m +CONFIG_SND_SOC_MT8365_MT6357=m CONFIG_SND_MESON_AXG_SOUND_CARD=m CONFIG_SND_MESON_GX_SOUND_CARD=m CONFIG_SND_SOC_QCOM=m From patchwork Fri Apr 26 17:22:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645161 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8F4F3C19F4F for ; Fri, 26 Apr 2024 17:23:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5EC9110ECC4; Fri, 26 Apr 2024 17:23:24 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="XL3sjFn6"; dkim-atps=neutral Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0467F10ECC4 for ; Fri, 26 Apr 2024 17:23:04 +0000 (UTC) Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-a55911bff66so312502866b.0 for ; Fri, 26 Apr 2024 10:23:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152183; x=1714756983; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Qi1a6qRL/sSf88RkAxOBKeEEBw29sLy7LzarlapS72s=; b=XL3sjFn6usHots4S2rsNDXg5uUx5UrBDw5p8YenQESAB4lYTlC798LCUQn60lSOaP3 6kFewQCLyehwi+WTFbSF1aFFF6zyw2ILA8fVbWAmW4R3HiPosNu7uXSgPMPORDgUafAz Rtdmwx/LcPtx29zvwBF3fodF9fmTErftzrZT8XnjWx3CJMfKN2Chyv+uNBSDHR1GXWnc C4rmOY70fcE2SYWEvCTWeE1nklCRrmVUMZy5wjBvS/0JwGl+7k/jNUZ8lx6QZN0V9FgC sJH0fqRc9nE9mazbZaPKRsnE0Fg3hfWFBVvrahiRA+ZNUm1Cvo721zqAkL9v7KcTg1ZQ gB3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152183; x=1714756983; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Qi1a6qRL/sSf88RkAxOBKeEEBw29sLy7LzarlapS72s=; b=XEK97AJoRvTkAL6YUqo6k9chS9ObmVWDbyHildjLEhZcGzQU8BaGLfrrBiMf5DAr/M H5S/lrQtjlxC1WHNnVa9HfWFvs4a0pqgNyb6ZejOC3KjzgXPG1O7Na2mQsBJ/DWthrwG My4EmkOL42eS1yQeuJRpnzy3WNm/NC9DxHVpMk55fXHdpTm9f2Wj2uoXPdFVCoFhtHOq o2XquMLpG2FZHEiZ7wmLcAVO+fB6W0lQu6ofan24Rua6/sf/2Y0O1tY/sO1Ze8/r78Mn 5flbfx8fikW3hrwBEpTJK7QXK/VM5s66rZTAq6SuHmzUMpIIdmLTBVaGTO35fZe/WkSa yx2A== X-Forwarded-Encrypted: i=1; AJvYcCWdL7FF1lgT2xQVZYFTWwkbeY/a+UoI59kWxnoHUtiOM0sjsAg7Vx8tqOjfLApZStxMK5aZ/5/U3k3SGeXjJX6UX1sIbfKqAGyepD8/FCTz X-Gm-Message-State: AOJu0Yy7/hbvOnUdGFddt8DAcf2oa9WLfAyHEKOPPOY+xsEcSH93GKUc Ot2gPfjYHaoeZpuinUmIB2vRJ25ImjLhbJ2wz+/Itg6XYamtg3S3yaVIk5uK5u8= X-Google-Smtp-Source: AGHT+IHHf2XIxcORUWzjtLX1VaD207j1YSFJervSBcjnJPk8N+OEALIdFKf7g6Y8lzNaper92rOirg== X-Received: by 2002:a17:906:4a83:b0:a55:5e89:a158 with SMTP id x3-20020a1709064a8300b00a555e89a158mr109798eju.68.1714152183470; Fri, 26 Apr 2024 10:23:03 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.23.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:23:03 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:44 +0200 Subject: [PATCH v4 15/16] arm64: dts: mediatek: add afe support for mt8365 SoC MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-15-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2357; i=amergnat@baylibre.com; h=from:subject:message-id; bh=t0tf5ggyvEv3KEhg9dzpup8fwcOHLyJsYbfkqMonRjM=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaFSju2HTEJJUlWwHPPq7cLwG3TIXZFwziZS9e 4Ndyr3yJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURepjD/ 97NUzCvItOp1IP3I06MoHhHvjQUV16QIZ462zo18PKYz6IOSU0Q53W0KrB4Awgr5T3o5wwwQi1w6cZ OUV0dR6H58erDJR16xRZk+YWtdSs67XXC72rmHb41qYDwoyHXemShR8E279guAnE7Tbx4ZPo8ACYMc 3JmtdNg+M+d9Cxjokjl9k3zJ//9MnyNIVzrxwJO12N+Yo6mKuUfDjBVoEPhEi/yeOXcgea8dNL7KHQ ZDZhqi7u/iK5mawCxqIVbf72ly2fB7Dt1heFWlYc3qP7IJuTjU6D0vrr1LLOc5SuUV8Rqga7gVXAIo mYO9qXOd5JFk2I7y+F2LvL6xYqTgKCjWAc30pH1eBO0Nqab7RjEUh4EJBdnIoa1rbSrt5uF/5S+uC+ Cwn3Bb1jofzgvU3ty+c7gNN5GTf+j+CQF99el4eZk2IUs9wP+ackEu25Ox/4I+CijWimgylznvh+yz A01xh3kn9MI03Y9HebFSM2lHe7iVkz+pfZo/jxAMNifMZsc2OuFTM0//JCutoMpbtfYUSfK59b8e8x FvWKt2Q+1DWnz/jz9jVBLrbzrJVhwgF7u4t9TKhZtzqhcDohsrXMw+mkEAMTrSAB4RHtZu8CsH0MR9 KN+57ulLLxu4t92OP7ZWl3tq8A2QrY96atz2Olvugu76QClJPWJ2XX28O/pA== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add audio front end support of MT8365 SoC. Update the file header. Signed-off-by: Alexandre Mergnat --- arch/arm64/boot/dts/mediatek/mt8365.dtsi | 43 ++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8365.dtsi b/arch/arm64/boot/dts/mediatek/mt8365.dtsi index 24581f7410aa..0051d5613bcb 100644 --- a/arch/arm64/boot/dts/mediatek/mt8365.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8365.dtsi @@ -2,9 +2,11 @@ /* * (C) 2018 MediaTek Inc. * Copyright (C) 2022 BayLibre SAS - * Fabien Parent - * Bernhard Rosenkränzer + * Authors: Fabien Parent + * Bernhard Rosenkränzer + * Alexandre Mergnat */ + #include #include #include @@ -813,6 +815,43 @@ apu: syscon@19020000 { reg = <0 0x19020000 0 0x1000>; #clock-cells = <1>; }; + + afe: audio-controller@11220000 { + compatible = "mediatek,mt8365-afe-pcm"; + reg = <0 0x11220000 0 0x1000>; + #sound-dai-cells = <0>; + clocks = <&clk26m>, + <&topckgen CLK_TOP_AUDIO_SEL>, + <&topckgen CLK_TOP_AUD_I2S0_M>, + <&topckgen CLK_TOP_AUD_I2S1_M>, + <&topckgen CLK_TOP_AUD_I2S2_M>, + <&topckgen CLK_TOP_AUD_I2S3_M>, + <&topckgen CLK_TOP_AUD_ENGEN1_SEL>, + <&topckgen CLK_TOP_AUD_ENGEN2_SEL>, + <&topckgen CLK_TOP_AUD_1_SEL>, + <&topckgen CLK_TOP_AUD_2_SEL>, + <&topckgen CLK_TOP_APLL_I2S0_SEL>, + <&topckgen CLK_TOP_APLL_I2S1_SEL>, + <&topckgen CLK_TOP_APLL_I2S2_SEL>, + <&topckgen CLK_TOP_APLL_I2S3_SEL>; + clock-names = "top_clk26m_clk", + "top_audio_sel", + "audio_i2s0_m", + "audio_i2s1_m", + "audio_i2s2_m", + "audio_i2s3_m", + "engen1", + "engen2", + "aud1", + "aud2", + "i2s0_m_sel", + "i2s1_m_sel", + "i2s2_m_sel", + "i2s3_m_sel"; + interrupts = ; + power-domains = <&spm MT8365_POWER_DOMAIN_AUDIO>; + status = "disabled"; + }; }; timer { From patchwork Fri Apr 26 17:22:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexandre Mergnat X-Patchwork-Id: 13645159 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 29225C19F4F for ; Fri, 26 Apr 2024 17:23:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A7C5310EF8C; Fri, 26 Apr 2024 17:23:12 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="zMSJJ9Ze"; dkim-atps=neutral Received: from mail-ed1-f41.google.com (mail-ed1-f41.google.com [209.85.208.41]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9986F10ECC4 for ; Fri, 26 Apr 2024 17:23:06 +0000 (UTC) Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-572229f196bso3028960a12.0 for ; Fri, 26 Apr 2024 10:23:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714152185; x=1714756985; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=o8YtHIDpzdHx4sXqMfJFiepO7h+jia5jAgm2xcDtDns=; b=zMSJJ9ZehmCm+hRb5fzm2n4k8fYnEy3F0Hz+CmKSo6Brxw/QTpeQTQMSQIyai325Ym HrROZwMln/Icca+QYURdGVNVyc9xXzIDqJak6zxkncT8YuUR9znrp/FqvcvDsZ6U2JMj Ccz/yPHVQNaTqpRZjCxgld+ozZMdOKktRx9pdaJQ+anvxL8EjH8JMRn4X0GHdEhBLtU4 ndj/QOeS2wS+u++Af+cVrhKCAKx4Y8dNO3JRtdUiLEDqVue/V2At1oS7basEEw49x0ql Z/VTcxSCHQgCSMsKV4iDbD+JNxypbwc4qq/Tez/3nQgD4ETBMDSeNvr0rBxXxWTTFreD uXUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714152185; x=1714756985; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=o8YtHIDpzdHx4sXqMfJFiepO7h+jia5jAgm2xcDtDns=; b=CaClFc4gfAzKkXl4FL9TRi9CXzWot5ngZ5svb42mLVbXyYAB+yK05Lf7OlXmkwonR9 Z84lOKzNgEjxevkp3aIgPxdyYfXhEJ9gdU+Z9IysOUG3UmMP2OwWqUg7B6lKH0RkXw8/ 7VI3OYfNT/OoPHNz1OaJvA+zgww0ljDPFnuOHOIjeSvmew0sJpNAQz+Jw1SHKmmI7Q2h ks+vuR3h7eCVcKA00sj+J+iL2SLBh0QfM25NVjptL3SMOrS0WjDKvxFFaMepqqvY9yEl PqE/Snm/8p58NOgvTj8LrHrq1UL7C8bauOCLSiauxzvdsnpkD3ianAqjI1wCShF2922T PxcQ== X-Forwarded-Encrypted: i=1; AJvYcCU7Js38MzxBka/lTkxUXpHC97KdVfd1SSZOm+eHaXGj+CkDPkLrgjgawNvLT2GaocwGWyBBb1zZBTw7POtVDN3ZlZB/MaKT/aYiBEURJLeL X-Gm-Message-State: AOJu0Yxu+wMH5vOvfZlwoIgL9d7YbEfmrbFNQzDboHdZFwkLesxycH34 koZX85tuO3kJAZnELlels+7b5mtnw3yNVIUxRCtPaomqRFaoyzJ6d1ZMTfbN1iI= X-Google-Smtp-Source: AGHT+IFe8cPyxYKPbB10bsA22HXOnNfS2uZCqL9dCr5CCChCqjSUjXJYhasnPEIlUBFiAuMlS60jng== X-Received: by 2002:a17:906:2c06:b0:a55:64bd:2544 with SMTP id e6-20020a1709062c0600b00a5564bd2544mr2122960ejh.60.1714152185108; Fri, 26 Apr 2024 10:23:05 -0700 (PDT) Received: from [127.0.1.1] ([93.5.22.158]) by smtp.googlemail.com with ESMTPSA id ot15-20020a170906cccf00b00a5239720044sm10763363ejb.8.2024.04.26.10.23.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:23:04 -0700 (PDT) From: Alexandre Mergnat Date: Fri, 26 Apr 2024 19:22:45 +0200 Subject: [PATCH v4 16/16] arm64: dts: mediatek: add audio support for mt8365-evk MIME-Version: 1.0 Message-Id: <20240226-audio-i350-v4-16-082b22186d4c@baylibre.com> References: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> In-Reply-To: <20240226-audio-i350-v4-0-082b22186d4c@baylibre.com> To: Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Lee Jones , Flora Fu , Jaroslav Kysela , Takashi Iwai , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Catalin Marinas , Will Deacon , Rob Herring , Krzysztof Kozlowski Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Alexandre Mergnat X-Mailer: b4 0.12.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3675; i=amergnat@baylibre.com; h=from:subject:message-id; bh=SJCQ9iTy0gf3MF6NpcJbnv0eqLDS85mr0GL7yiG+BlA=; b=owEBbQKS/ZANAwAKAStGSZ1+MdRFAcsmYgBmK+LaAKHbepcmLOlZloUS5NBbwlGYMM92geHkpJU7 XXa0I1qJAjMEAAEKAB0WIQQjG17X8+qqcA5g/osrRkmdfjHURQUCZivi2gAKCRArRkmdfjHURTMzD/ 9qgSi0I2CHYULuwM1Nav9rRhgAYJZAbLZdgfNHsBQc8L4p0cJrd9BxqKmxruQ4EwPq8BkmZJTpIzWE iExHW/L8zCFlE6ksIo7WhitWXf5jkNImBAqiEDrhcImecZMqWJuCrE3+RTKcYi0432KkK8ZP/uxnHB pBvGzyTTbbVz3kmVZ3fmAfCsYEgeO0b/tUMVqZGYuBexCYTKHrvDlqOJ4cX7BfJg4v5cGSDnjaqi8E TLDGHYHZ18jQYlYrUwmsqQ2w0hpnDwb+1HJ7A8ahgjdwJEf4LEBJVYZR1NL86N8ZMi2zg5QUW5qhZ1 dZqON3mLt5LIcg8AbAZpwK8oRy/dsHkC+78KqmjleWYhCFwupn4oYUi87ZWNGmpZvOynMhtk+ZTvCz 2l7DMC/2Q0XF643D8disbp/yiMevYeBnnPg/ayz7A4evpXVmOEBPN4bb/aB2qKYru1vKz5teiWLFAC +Av/KPOz3MQwqUcjThylnvpy7+Enhq0WVK4i7bUoC0LlClRV4MblSz4vkmC4/CtX+t3Y3Ipb5t87c2 Y+oHm6LmIGV4dVLgez38gDWlGSxW6xs71wlTPyYgaxs3QCO6UklKMLcBZwPBhraGMQoYuNElQRpW// hTPVT5adtgXdUQQn4Rt/rXB/0zCVw2PoI7W/Kbg7YMrjQfHssQjxtLVyEzQQ== X-Developer-Key: i=amergnat@baylibre.com; a=openpgp; fpr=231B5ED7F3EAAA700E60FE8B2B46499D7E31D445 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add the sound node which is linked to the MT8365 SoC AFE and the MT6357 audio codec. Update the file header. Signed-off-by: Alexandre Mergnat --- arch/arm64/boot/dts/mediatek/mt8365-evk.dts | 89 +++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8365-evk.dts b/arch/arm64/boot/dts/mediatek/mt8365-evk.dts index 50cbaefa1a99..32ae7d599272 100644 --- a/arch/arm64/boot/dts/mediatek/mt8365-evk.dts +++ b/arch/arm64/boot/dts/mediatek/mt8365-evk.dts @@ -4,6 +4,7 @@ * Authors: * Fabien Parent * Bernhard Rosenkränzer + * Alexandre Mergnat */ /dts-v1/; @@ -86,6 +87,28 @@ optee_reserved: optee@43200000 { reg = <0 0x43200000 0 0x00c00000>; }; }; + + sound: sound { + compatible = "mediatek,mt8365-mt6357"; + pinctrl-names = "default", + "dmic", + "miso_off", + "miso_on", + "mosi_off", + "mosi_on"; + pinctrl-0 = <&aud_default_pins>; + pinctrl-1 = <&aud_dmic_pins>; + pinctrl-2 = <&aud_miso_off_pins>; + pinctrl-3 = <&aud_miso_on_pins>; + pinctrl-4 = <&aud_mosi_off_pins>; + pinctrl-5 = <&aud_mosi_on_pins>; + mediatek,platform = <&afe>; + }; +}; + +&afe { + mediatek,dmic-mode = <1>; + status = "okay"; }; &cpu0 { @@ -178,9 +201,75 @@ &mt6357_pmic { interrupts-extended = <&pio 145 IRQ_TYPE_LEVEL_HIGH>; interrupt-controller; #interrupt-cells = <2>; + audio-codec { + vaud28-supply = <&mt6357_vaud28_reg>; + mediatek,micbias0-microvolt = <1900000>; + mediatek,micbias1-microvolt = <1700000>; + }; }; &pio { + aud_default_pins: audiodefault-pins { + pins { + pinmux = , + , + , + ; + }; + }; + + aud_dmic_pins: audiodmic-pins { + pins { + pinmux = , + , + ; + }; + }; + + aud_miso_off_pins: misooff-pins { + pins { + pinmux = , + , + , + ; + input-enable; + bias-pull-down; + drive-strength = ; + }; + }; + + aud_miso_on_pins: misoon-pins { + pins { + pinmux = , + , + , + ; + drive-strength = ; + }; + }; + + aud_mosi_off_pins: mosioff-pins { + pins { + pinmux = , + , + , + ; + input-enable; + bias-pull-down; + drive-strength = ; + }; + }; + + aud_mosi_on_pins: mosion-pins { + pins { + pinmux = , + , + , + ; + drive-strength = ; + }; + }; + ethernet_pins: ethernet-pins { phy_reset_pins { pinmux = ;