From patchwork Thu Jan 28 14:19:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 372607 Delivered-To: patch@linaro.org Received: by 2002:a02:a60d:0:0:0:0:0 with SMTP id c13csp1296762jam; Thu, 28 Jan 2021 06:22:08 -0800 (PST) X-Google-Smtp-Source: ABdhPJwDKrwX1VViiP+AY7S341SQTnr2hzXsm+Q5VxZbA4OIVNEsf9YaADD631qf13mz25+ONRe9 X-Received: by 2002:a17:907:724a:: with SMTP id ds10mr11049781ejc.28.1611843727923; Thu, 28 Jan 2021 06:22:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611843727; cv=none; d=google.com; s=arc-20160816; b=uNz98U0Vuo9FU4ZzUpEV7FB/lMralIVvwS/eqYht6PAfVXckwvv0xaObB3pvNf2V7L 11Z0EF1YB2iyA4E7h2Av1rjG3EfCiClqM5I1m/hM/X1CO0L/AH3CQw7Pq2NBM7VdfBww xMk2/wx+9gnRvL5ZxoPaUIl9BYg6iVvvxT5LLvEVPJluVjk82BoNIW5PtdYRpvw5fG2B WOp6JRzB1PZm/Wbk+Vt0OwkAMOiMTelgjiPHhbrgPDVyHVZOkPmPnKbz4c3OLr3mayHI Lr3qEQd/bNWvIKfSmNgwpccUnKSMz94OaUaA3qyHdXlQuLiAT1ayIGClg6vem/B/Vz7R 3Imw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=5s1sQMKmA5X4b0lhaDVUuKBYgKx/IDMprYcIvq92de4=; b=YTAOJAfzmhHZvdegg1mgk1yn4JQEmuwiRmknZBeSpzhEvGnol9G25n+dsmlL4XdACx g0ct7BLtjLQxdHKdfferulq8+lZPX53tZC6cILaOkTnJeYxjGnZO6h9YWtu1NSAtNOVc JHwxVuiXLcTjSR7Zc0NClh827pv5xOoXX5bT/w1ToOKedRl2v77dhbYcKqZpvxuaPIEC V10BmX3a6e1hxlR3EbVvvGv8wEGXEMFX/iAJBvtJWPeC/ZsPwz03YqQM2giEGJRJDQvG xIbGz9Es1OffJ1KcjlTQhByyJtNvsZYgDzMQF4uGyxStWHfSW0I4MJVfzJTQXUHNen+G VxzQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="I9vxJn/1"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id lz12si2615142ejb.518.2021.01.28.06.22.07; Thu, 28 Jan 2021 06:22:07 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="I9vxJn/1"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231484AbhA1OUz (ORCPT + 6 others); Thu, 28 Jan 2021 09:20:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231420AbhA1OUh (ORCPT ); Thu, 28 Jan 2021 09:20:37 -0500 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB494C0613D6 for ; Thu, 28 Jan 2021 06:19:56 -0800 (PST) Received: by mail-wr1-x431.google.com with SMTP id 7so5593794wrz.0 for ; Thu, 28 Jan 2021 06:19:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5s1sQMKmA5X4b0lhaDVUuKBYgKx/IDMprYcIvq92de4=; b=I9vxJn/1Ck4iP8t6coN1ZOIjPhSLezBeAAAS9ehzuUmjGKMEXA3fWU7U0vAwJX/gXN +oqWM4aU24qPDxv4ZJf/4WPyimDFaAKc1PeEm9pD8wY++AIttSyIFovhY6iI6xL50o85 Y25DgXuisgkciQiFDHYol1jrJrOle6w8mSIgOZfwMglkJM3ffY0J/w5LpJnOBBro3QsL 9qXtGqg81IrdNX30Ww018hT2j4JbAZy2KcGeCCUkLfa1MyUdIsxGluATXUULuVFZqxOo RXbDNWeIF3EGccYB/tfb5zFBodWkA0XG3uCyVkS04nt09iL7lfUcaCbVrwVU5Vaav9zD zSAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5s1sQMKmA5X4b0lhaDVUuKBYgKx/IDMprYcIvq92de4=; b=LCj/fH7RS55LuiUGLJeDOyc0kS9SnNte/QmEBjOPwzcGc6C8R0PQ0qDa9PaYs3gbE4 bEEohSZTprlwwd8rzUfZD6sBBuFkXGWGK4/9bVXpOpsyKFtlx0NN4symdbdmJILDnifK DFOBGeE9zNyScNsxA3EIF85XGeERaBgfpKSB4M5jpm1ZIFIixb8vEG+PAZuDsBHEShGI PkVXJuYT4Z7ZUx+WxhIQ8bXeUcYPEjqMxtB/+bZKyQ5H2p0dSSDwxN7nfkNcvPM3/nUq G442Ipp4s2VX2gDhGAgwUxH6CQAKrbYuz//Wa1zX7lI7aqV15xpOj70WSXT9xoh1mjJI ecFA== X-Gm-Message-State: AOAM531HxhejJ1OP8f4mvUDCw7LHa74qJMuJEUVrZ0B3sDbHGcW/b0R8 7L811WUaTiqcGmIeqgY9rbCi6dVUt2LhDg== X-Received: by 2002:adf:efc2:: with SMTP id i2mr16095837wrp.422.1611843595619; Thu, 28 Jan 2021 06:19:55 -0800 (PST) Received: from srini-hackbox.lan (cpc86377-aztw32-2-0-cust226.18-1.cable.virginm.net. [92.233.226.227]) by smtp.gmail.com with ESMTPSA id d9sm7257096wrq.74.2021.01.28.06.19.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 06:19:55 -0800 (PST) From: Srinivas Kandagatla To: broonie@kernel.org Cc: perex@perex.cz, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, devicetree@vger.kernel.org, robh+dt@kernel.org, Srinivas Kandagatla Subject: [PATCH 1/7] ASoC: qcom: dt-bindings: add bindings for lpass rx macro codec Date: Thu, 28 Jan 2021 14:19:23 +0000 Message-Id: <20210128141929.26573-2-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> References: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This binding is for LPASS has internal codec RX macro which is for connecting with SoundWire RX codecs like WCD938x. Signed-off-by: Srinivas Kandagatla --- .../bindings/sound/qcom,lpass-rx-macro.yaml | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml -- 2.21.0 diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml new file mode 100644 index 000000000000..443d556caa69 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/qcom,lpass-rx-macro.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LPASS(Low Power Audio Subsystem) RX Macro audio codec DT bindings + +maintainers: + - Srinivas Kandagatla + +properties: + compatible: + const: qcom,sm8250-lpass-rx-macro + + reg: + maxItems: 1 + + "#sound-dai-cells": + const: 1 + + '#clock-cells': + const: 0 + + clocks: + maxItems: 5 + + clock-names: + items: + - const: mclk + - const: npl + - const: macro + - const: dcodec + - const: fsgen + + clock-output-names: + items: + - const: mclk + +required: + - compatible + - reg + - "#sound-dai-cells" + +additionalProperties: false + +examples: + - | + #include + codec@3200000 { + compatible = "qcom,sm8250-lpass-rx-macro"; + reg = <0x3200000 0x1000>; + #sound-dai-cells = <1>; + #clock-cells = <0>; + clocks = <&audiocc 0>, + <&audiocc 1>, + <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&vamacro>; + clock-names = "mclk", "npl", "macro", "dcodec", "fsgen"; + clock-output-names = "mclk"; + }; From patchwork Thu Jan 28 14:19:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 372608 Delivered-To: patch@linaro.org Received: by 2002:a02:a60d:0:0:0:0:0 with SMTP id c13csp1296794jam; Thu, 28 Jan 2021 06:22:10 -0800 (PST) X-Google-Smtp-Source: ABdhPJwIWCl5nMlon6ucwqqBK9kQOOH9xsp7+k78ZgrZ0uKnAOIW7SfzJHGJYGSrOO0E/Nmo5L0t X-Received: by 2002:a50:fb0e:: with SMTP id d14mr14281980edq.369.1611843730024; Thu, 28 Jan 2021 06:22:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611843730; cv=none; d=google.com; s=arc-20160816; b=lr3GcAWj5Q83cr3RZYcRn9wJRVX9uI1+sg819WXVOB1m4tVDKG1vVL5HXbdXuZJX6I c0jo2k9gofoJmv6dZMGk06fnxicWpmjs1ZH6KupiOmo9eYgp4bb8xwdtMpooF/7L2AtC S2jo7SoA3y6CVUVN9iPLBieSDjtrdwzJPW9o9jkRdBkXg7gDpcGAVDtEDSIAaQy3JcTP udEace0WGlS6gdjPWZdxxPKo0pAFPeIrGIf+8G0AZNRYlpL4iB8+S9iKWFfy70DGohfR Nwn1vDKRMrXNCLv5aScuQe9WUpwTjdDgrZCN+IjTjG1mx1UrUJf+UxY8DyY16qUS67Nb pgIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=v1Xvuy3gfwr5TpPlmWSqzF0p12mWJHTiiMlIEZNjfGs=; b=wWnYxoZt4QRQrvhi/c+/OjKehRrm2YD8OL+4LBZmNP+TmQDwNjRJa2gnDRIBkzjFAc IoPN4kj69fYo9CDRgFelVHtAeqOwqU9ZvgIo3qIdVFmnk4UNcXpdqj9SCHs7o1fSRc2M t67NqqH1GGHBJnrJBSjDt9RBVDaKEa3jPK2qwhi1r51eBHFHxB2dYkqFf6LxqVvXUbrQ MXypF0Y9vDQKtLrIoxn3D9xVggpTasaPMBJV+8g9VUUo3bRzVli/8jPPXuZpsjku3sBM yKEAC6wG4il9QSOK5rYmulPX0WpS8efKo7tUD804K5tkDmZMCf5qzHmF42lHARmNyHgC er+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=X9bH2STL; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id lz12si2615142ejb.518.2021.01.28.06.22.08; Thu, 28 Jan 2021 06:22:10 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=X9bH2STL; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231373AbhA1OVH (ORCPT + 6 others); Thu, 28 Jan 2021 09:21:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40980 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231421AbhA1OUj (ORCPT ); Thu, 28 Jan 2021 09:20:39 -0500 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BE54BC0613ED for ; Thu, 28 Jan 2021 06:19:58 -0800 (PST) Received: by mail-wr1-x42b.google.com with SMTP id p15so5552983wrq.8 for ; Thu, 28 Jan 2021 06:19:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=v1Xvuy3gfwr5TpPlmWSqzF0p12mWJHTiiMlIEZNjfGs=; b=X9bH2STLyk7pJRAei9t5pCAK5VjPctbymZKPfgcYdYwhuVYi8sxtXeK4KqSiiVWkHo H3XhMvIlsVZdkfD2oHKLBgcuePFu8u/TvguXnstxj/sXwnRpHhm1EQBoT01U9QK2hpMi 6XToWqga9vWTuFQ14GRo3V8U3eTCtRC/R91syYOj/iLEy9rX6G+jfJdFvYXxJ+ItvjYH FVWMGW3MQI3I3lP5cwU7gIdBzB2ZeADanmr3N3nlRrB+IyqBwZtqOFR4xOCR8pkIBuRa zA8dQFEcLp/K677QJ7fm0VBP1CvVipMPXGf0YFo8Mt4TTtgKAC6AWZtPeAWgDgd1GOrp jC/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=v1Xvuy3gfwr5TpPlmWSqzF0p12mWJHTiiMlIEZNjfGs=; b=XcmB6t2hqm1w1QVrYmQ6smSLNeQFy/1i0KpBF6/NaL227LJLBFfRpFvRUP9v35+uC3 BqX4x4dPtNmHC98Ie0jXppjMqruQ0vuwx8QRGNCj8273ubu0OgBCWj02QV6VdBbrCKsd CF5pdLCU0yslPOmv9qOaiWKADqC353E9J+imr20TnLdHHNQY6YPtdQeKHbbKDQfWNHq4 lnE/hoca2KXjfcFw0UTgTPEIKT9Ppn07SKa/crEuwXbs0L3ItojQ7vvLTKYHB9AGX49O f9Dw6w9wUYaInzr2l3lWJxFkMRKwfMtleVzfi7jQuVl39rzr+nF05i+BhkQY3Nv7flGS Ta3g== X-Gm-Message-State: AOAM533shDYPxDgCXI8NvMsWjrKIZn08Q8HwxowgM5SeSVGe5xTFJ0bD TJ6JoCjHE1ybwLK/5/PFhLrj/Nwal/3BVA== X-Received: by 2002:adf:f183:: with SMTP id h3mr16897329wro.30.1611843597164; Thu, 28 Jan 2021 06:19:57 -0800 (PST) Received: from srini-hackbox.lan (cpc86377-aztw32-2-0-cust226.18-1.cable.virginm.net. [92.233.226.227]) by smtp.gmail.com with ESMTPSA id d9sm7257096wrq.74.2021.01.28.06.19.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 06:19:56 -0800 (PST) From: Srinivas Kandagatla To: broonie@kernel.org Cc: perex@perex.cz, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, devicetree@vger.kernel.org, robh+dt@kernel.org, Srinivas Kandagatla Subject: [PATCH 2/7] ASoC: codec: lpass-rx-macro: add support for lpass rx macro Date: Thu, 28 Jan 2021 14:19:24 +0000 Message-Id: <20210128141929.26573-3-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> References: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Signed-off-by: Srinivas Kandagatla --- sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/lpass-rx-macro.c | 2020 +++++++++++++++++++++++++++++ 3 files changed, 2027 insertions(+) create mode 100644 sound/soc/codecs/lpass-rx-macro.c -- 2.21.0 diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 9bf6bfdaf11e..5dbe2bf2d329 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -227,6 +227,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_UDA1380 imply SND_SOC_WCD9335 imply SND_SOC_WCD934X + imply SND_SOC_LPASS_RX_MACRO imply SND_SOC_WL1273 imply SND_SOC_WM0010 imply SND_SOC_WM1250_EV1 @@ -1820,4 +1821,8 @@ config SND_SOC_LPASS_VA_MACRO depends on COMMON_CLK tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)" +config SND_SOC_LPASS_RX_MACRO + depends on COMMON_CLK + tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)" + endmenu diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 628b0c9b3e2a..045263122761 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -108,6 +108,7 @@ snd-soc-lm49453-objs := lm49453.o snd-soc-lochnagar-sc-objs := lochnagar-sc.o snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o snd-soc-lpass-va-macro-objs := lpass-va-macro.o +snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o snd-soc-madera-objs := madera.o snd-soc-max9759-objs := max9759.o snd-soc-max9768-objs := max9768.o @@ -623,6 +624,7 @@ obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o +obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o # Mux obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c new file mode 100644 index 000000000000..30f4b7b3189c --- /dev/null +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -0,0 +1,2020 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CDC_RX_TOP_TOP_CFG0 (0x0000) +#define CDC_RX_TOP_SWR_CTRL (0x0008) +#define CDC_RX_TOP_DEBUG (0x000C) +#define CDC_RX_TOP_DEBUG_BUS (0x0010) +#define CDC_RX_TOP_DEBUG_EN0 (0x0014) +#define CDC_RX_TOP_DEBUG_EN1 (0x0018) +#define CDC_RX_TOP_DEBUG_EN2 (0x001C) +#define CDC_RX_TOP_HPHL_COMP_WR_LSB (0x0020) +#define CDC_RX_TOP_HPHL_COMP_WR_MSB (0x0024) +#define CDC_RX_TOP_HPHL_COMP_LUT (0x0028) +#define CDC_RX_TOP_HPH_LUT_BYPASS_MASK BIT(7) +#define CDC_RX_TOP_HPHL_COMP_RD_LSB (0x002C) +#define CDC_RX_TOP_HPHL_COMP_RD_MSB (0x0030) +#define CDC_RX_TOP_HPHR_COMP_WR_LSB (0x0034) +#define CDC_RX_TOP_HPHR_COMP_WR_MSB (0x0038) +#define CDC_RX_TOP_HPHR_COMP_LUT (0x003C) +#define CDC_RX_TOP_HPHR_COMP_RD_LSB (0x0040) +#define CDC_RX_TOP_HPHR_COMP_RD_MSB (0x0044) +#define CDC_RX_TOP_DSD0_DEBUG_CFG0 (0x0070) +#define CDC_RX_TOP_DSD0_DEBUG_CFG1 (0x0074) +#define CDC_RX_TOP_DSD0_DEBUG_CFG2 (0x0078) +#define CDC_RX_TOP_DSD0_DEBUG_CFG3 (0x007C) +#define CDC_RX_TOP_DSD1_DEBUG_CFG0 (0x0080) +#define CDC_RX_TOP_DSD1_DEBUG_CFG1 (0x0084) +#define CDC_RX_TOP_DSD1_DEBUG_CFG2 (0x0088) +#define CDC_RX_TOP_DSD1_DEBUG_CFG3 (0x008C) +#define CDC_RX_TOP_RX_I2S_CTL (0x0090) +#define CDC_RX_TOP_TX_I2S2_CTL (0x0094) +#define CDC_RX_TOP_I2S_CLK (0x0098) +#define CDC_RX_TOP_I2S_RESET (0x009C) +#define CDC_RX_TOP_I2S_MUX (0x00A0) +#define CDC_RX_CLK_RST_CTRL_MCLK_CONTROL (0x0100) +#define CDC_RX_CLK_MCLK_EN_MASK BIT(0) +#define CDC_RX_CLK_MCLK_ENABLE BIT(0) +#define CDC_RX_CLK_MCLK2_EN_MASK BIT(1) +#define CDC_RX_CLK_MCLK2_ENABLE BIT(1) +#define CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL (0x0104) +#define CDC_RX_FS_MCLK_CNT_EN_MASK BIT(0) +#define CDC_RX_FS_MCLK_CNT_ENABLE BIT(0) +#define CDC_RX_FS_MCLK_CNT_CLR_MASK BIT(1) +#define CDC_RX_FS_MCLK_CNT_CLR BIT(1) +#define CDC_RX_CLK_RST_CTRL_SWR_CONTROL (0x0108) +#define CDC_RX_CLK_RST_CTRL_DSD_CONTROL (0x010C) +#define CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL (0x0110) +#define CDC_RX_SOFTCLIP_CRC (0x0140) +#define CDC_RX_SOFTCLIP_CLK_EN_MASK BIT(0) +#define CDC_RX_SOFTCLIP_SOFTCLIP_CTRL (0x0144) +#define CDC_RX_SOFTCLIP_EN_MASK BIT(0) +#define CDC_RX_INP_MUX_RX_INT0_CFG0 (0x0180) +#define CDC_RX_INTX_1_MIX_INP0_SEL_MASK GENMASK(3, 0) +#define CDC_RX_INTX_1_MIX_INP1_SEL_MASK GENMASK(7, 4) +#define CDC_RX_INP_MUX_RX_INT0_CFG1 (0x0184) +#define CDC_RX_INTX_2_SEL_MASK GENMASK(3, 0) +#define CDC_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(7, 4) +#define CDC_RX_INP_MUX_RX_INT1_CFG0 (0x0188) +#define CDC_RX_INP_MUX_RX_INT1_CFG1 (0x018C) +#define CDC_RX_INP_MUX_RX_INT2_CFG0 (0x0190) +#define CDC_RX_INP_MUX_RX_INT2_CFG1 (0x0194) +#define CDC_RX_INP_MUX_RX_MIX_CFG4 (0x0198) +#define CDC_RX_INP_MUX_RX_MIX_CFG5 (0x019C) +#define CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (0x01A0) +#define CDC_RX_CLSH_CRC (0x0200) +#define CDC_RX_CLSH_CLK_EN_MASK BIT(0) +#define CDC_RX_CLSH_DLY_CTRL (0x0204) +#define CDC_RX_CLSH_DECAY_CTRL (0x0208) +#define CDC_RX_CLSH_DECAY_RATE_MASK GENMASK(2, 0) +#define CDC_RX_CLSH_HPH_V_PA (0x020C) +#define CDC_RX_CLSH_HPH_V_PA_MIN_MASK GENMASK(5, 0) +#define CDC_RX_CLSH_EAR_V_PA (0x0210) +#define CDC_RX_CLSH_HPH_V_HD (0x0214) +#define CDC_RX_CLSH_EAR_V_HD (0x0218) +#define CDC_RX_CLSH_K1_MSB (0x021C) +#define CDC_RX_CLSH_K1_MSB_COEFF_MASK GENMASK(3, 0) +#define CDC_RX_CLSH_K1_LSB (0x0220) +#define CDC_RX_CLSH_K2_MSB (0x0224) +#define CDC_RX_CLSH_K2_LSB (0x0228) +#define CDC_RX_CLSH_IDLE_CTRL (0x022C) +#define CDC_RX_CLSH_IDLE_HPH (0x0230) +#define CDC_RX_CLSH_IDLE_EAR (0x0234) +#define CDC_RX_CLSH_TEST0 (0x0238) +#define CDC_RX_CLSH_TEST1 (0x023C) +#define CDC_RX_CLSH_OVR_VREF (0x0240) +#define CDC_RX_CLSH_CLSG_CTL (0x0244) +#define CDC_RX_CLSH_CLSG_CFG1 (0x0248) +#define CDC_RX_CLSH_CLSG_CFG2 (0x024C) +#define CDC_RX_BCL_VBAT_PATH_CTL (0x0280) +#define CDC_RX_BCL_VBAT_CFG (0x0284) +#define CDC_RX_BCL_VBAT_ADC_CAL1 (0x0288) +#define CDC_RX_BCL_VBAT_ADC_CAL2 (0x028C) +#define CDC_RX_BCL_VBAT_ADC_CAL3 (0x0290) +#define CDC_RX_BCL_VBAT_PK_EST1 (0x0294) +#define CDC_RX_BCL_VBAT_PK_EST2 (0x0298) +#define CDC_RX_BCL_VBAT_PK_EST3 (0x029C) +#define CDC_RX_BCL_VBAT_RF_PROC1 (0x02A0) +#define CDC_RX_BCL_VBAT_RF_PROC2 (0x02A4) +#define CDC_RX_BCL_VBAT_TAC1 (0x02A8) +#define CDC_RX_BCL_VBAT_TAC2 (0x02AC) +#define CDC_RX_BCL_VBAT_TAC3 (0x02B0) +#define CDC_RX_BCL_VBAT_TAC4 (0x02B4) +#define CDC_RX_BCL_VBAT_GAIN_UPD1 (0x02B8) +#define CDC_RX_BCL_VBAT_GAIN_UPD2 (0x02BC) +#define CDC_RX_BCL_VBAT_GAIN_UPD3 (0x02C0) +#define CDC_RX_BCL_VBAT_GAIN_UPD4 (0x02C4) +#define CDC_RX_BCL_VBAT_GAIN_UPD5 (0x02C8) +#define CDC_RX_BCL_VBAT_DEBUG1 (0x02CC) +#define CDC_RX_BCL_VBAT_GAIN_UPD_MON (0x02D0) +#define CDC_RX_BCL_VBAT_GAIN_MON_VAL (0x02D4) +#define CDC_RX_BCL_VBAT_BAN (0x02D8) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD1 (0x02DC) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD2 (0x02E0) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD3 (0x02E4) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD4 (0x02E8) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD5 (0x02EC) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD6 (0x02F0) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD7 (0x02F4) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD8 (0x02F8) +#define CDC_RX_BCL_VBAT_BCL_GAIN_UPD9 (0x02FC) +#define CDC_RX_BCL_VBAT_ATTN1 (0x0300) +#define CDC_RX_BCL_VBAT_ATTN2 (0x0304) +#define CDC_RX_BCL_VBAT_ATTN3 (0x0308) +#define CDC_RX_BCL_VBAT_DECODE_CTL1 (0x030C) +#define CDC_RX_BCL_VBAT_DECODE_CTL2 (0x0310) +#define CDC_RX_BCL_VBAT_DECODE_CFG1 (0x0314) +#define CDC_RX_BCL_VBAT_DECODE_CFG2 (0x0318) +#define CDC_RX_BCL_VBAT_DECODE_CFG3 (0x031C) +#define CDC_RX_BCL_VBAT_DECODE_CFG4 (0x0320) +#define CDC_RX_BCL_VBAT_DECODE_ST (0x0324) +#define CDC_RX_INTR_CTRL_CFG (0x0340) +#define CDC_RX_INTR_CTRL_CLR_COMMIT (0x0344) +#define CDC_RX_INTR_CTRL_PIN1_MASK0 (0x0360) +#define CDC_RX_INTR_CTRL_PIN1_STATUS0 (0x0368) +#define CDC_RX_INTR_CTRL_PIN1_CLEAR0 (0x0370) +#define CDC_RX_INTR_CTRL_PIN2_MASK0 (0x0380) +#define CDC_RX_INTR_CTRL_PIN2_STATUS0 (0x0388) +#define CDC_RX_INTR_CTRL_PIN2_CLEAR0 (0x0390) +#define CDC_RX_INTR_CTRL_LEVEL0 (0x03C0) +#define CDC_RX_INTR_CTRL_BYPASS0 (0x03C8) +#define CDC_RX_INTR_CTRL_SET0 (0x03D0) +#define CDC_RX_RXn_RX_PATH_CTL(n) (0x0400 + 0x80 * n) +#define CDC_RX_RX0_RX_PATH_CTL (0x0400) +#define CDC_RX_PATH_RESET_EN_MASK BIT(6) +#define CDC_RX_PATH_CLK_EN_MASK BIT(5) +#define CDC_RX_PATH_CLK_ENABLE BIT(5) +#define CDC_RX_PATH_PGA_MUTE_MASK BIT(4) +#define CDC_RX_PATH_PGA_MUTE_ENABLE BIT(4) +#define CDC_RX_PATH_PCM_RATE_MASK GENMASK(3, 0) +#define CDC_RX_RXn_RX_PATH_CFG0(n) (0x0404 + 0x80 * n) +#define CDC_RX_RXn_COMP_EN_MASK BIT(1) +#define CDC_RX_RX0_RX_PATH_CFG0 (0x0404) +#define CDC_RX_RXn_CLSH_EN_MASK BIT(6) +#define CDC_RX_DLY_ZN_EN_MASK BIT(3) +#define CDC_RX_DLY_ZN_ENABLE BIT(3) +#define CDC_RX_RXn_HD2_EN_MASK BIT(2) +#define CDC_RX_RXn_RX_PATH_CFG1(n) (0x0408 + 0x80 * n) +#define CDC_RX_RXn_SIDETONE_EN_MASK BIT(4) +#define CDC_RX_RX0_RX_PATH_CFG1 (0x0408) +#define CDC_RX_RX0_HPH_L_EAR_SEL_MASK BIT(1) +#define CDC_RX_RXn_RX_PATH_CFG2(n) (0x040C + 0x80 * n) +#define CDC_RX_RXn_HPF_CUT_FREQ_MASK GENMASK(1, 0) +#define CDC_RX_RX0_RX_PATH_CFG2 (0x040C) +#define CDC_RX_RXn_RX_PATH_CFG3(n) (0x0410 + 0x80 * n) +#define CDC_RX_RX0_RX_PATH_CFG3 (0x0410) +#define CDC_RX_DC_COEFF_SEL_MASK GENMASK(1, 0) +#define CDC_RX_DC_COEFF_SEL_TWO 0x2 +#define CDC_RX_RXn_RX_VOL_CTL(n) (0x0414 + 0x80 * n) +#define CDC_RX_RX0_RX_VOL_CTL (0x0414) +#define CDC_RX_RXn_RX_PATH_MIX_CTL(n) (0x0418 + 0x80 * n) +#define CDC_RX_RXn_MIX_PCM_RATE_MASK GENMASK(3, 0) +#define CDC_RX_RXn_MIX_RESET_MASK BIT(6) +#define CDC_RX_RXn_MIX_RESET BIT(6) +#define CDC_RX_RXn_MIX_CLK_EN_MASK BIT(5) +#define CDC_RX_RXn_MIX_PGA_MUTE_MASK BIT(4) +#define CDC_RX_RX0_RX_PATH_MIX_CTL (0x0418) +#define CDC_RX_RX0_RX_PATH_MIX_CFG (0x041C) +#define CDC_RX_RXn_RX_VOL_MIX_CTL(n) (0x0420 + 0x80 * n) +#define CDC_RX_RX0_RX_VOL_MIX_CTL (0x0420) +#define CDC_RX_RX0_RX_PATH_SEC1 (0x0424) +#define CDC_RX_RX0_RX_PATH_SEC2 (0x0428) +#define CDC_RX_RX0_RX_PATH_SEC3 (0x042C) +#define CDC_RX_RX0_RX_PATH_SEC4 (0x0430) +#define CDC_RX_RX0_RX_PATH_SEC7 (0x0434) +#define CDC_RX_DSM_OUT_DELAY_SEL_MASK GENMASK(2, 0) +#define CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE 0x2 +#define CDC_RX_RX0_RX_PATH_MIX_SEC0 (0x0438) +#define CDC_RX_RX0_RX_PATH_MIX_SEC1 (0x043C) +#define CDC_RX_RXn_RX_PATH_DSM_CTL(n) (0x0440 + 0x80 * n) +#define CDC_RX_RXn_DSM_CLK_EN_MASK BIT(0) +#define CDC_RX_RX0_RX_PATH_DSM_CTL (0x0440) +#define CDC_RX_RX0_RX_PATH_DSM_DATA1 (0x0444) +#define CDC_RX_RX0_RX_PATH_DSM_DATA2 (0x0448) +#define CDC_RX_RX0_RX_PATH_DSM_DATA3 (0x044C) +#define CDC_RX_RX0_RX_PATH_DSM_DATA4 (0x0450) +#define CDC_RX_RX0_RX_PATH_DSM_DATA5 (0x0454) +#define CDC_RX_RX0_RX_PATH_DSM_DATA6 (0x0458) +#define CDC_RX_RX1_RX_PATH_CTL (0x0480) +#define CDC_RX_RX1_RX_PATH_CFG0 (0x0484) +#define CDC_RX_RX1_RX_PATH_CFG1 (0x0488) +#define CDC_RX_RX1_RX_PATH_CFG2 (0x048C) +#define CDC_RX_RX1_RX_PATH_CFG3 (0x0490) +#define CDC_RX_RX1_RX_VOL_CTL (0x0494) +#define CDC_RX_RX1_RX_PATH_MIX_CTL (0x0498) +#define CDC_RX_RX1_RX_PATH_MIX_CFG (0x049C) +#define CDC_RX_RX1_RX_VOL_MIX_CTL (0x04A0) +#define CDC_RX_RX1_RX_PATH_SEC1 (0x04A4) +#define CDC_RX_RX1_RX_PATH_SEC2 (0x04A8) +#define CDC_RX_RX1_RX_PATH_SEC3 (0x04AC) +#define CDC_RX_RXn_HD2_ALPHA_MASK GENMASK(5, 2) +#define CDC_RX_RX1_RX_PATH_SEC4 (0x04B0) +#define CDC_RX_RX1_RX_PATH_SEC7 (0x04B4) +#define CDC_RX_RX1_RX_PATH_MIX_SEC0 (0x04B8) +#define CDC_RX_RX1_RX_PATH_MIX_SEC1 (0x04BC) +#define CDC_RX_RX1_RX_PATH_DSM_CTL (0x04C0) +#define CDC_RX_RX1_RX_PATH_DSM_DATA1 (0x04C4) +#define CDC_RX_RX1_RX_PATH_DSM_DATA2 (0x04C8) +#define CDC_RX_RX1_RX_PATH_DSM_DATA3 (0x04CC) +#define CDC_RX_RX1_RX_PATH_DSM_DATA4 (0x04D0) +#define CDC_RX_RX1_RX_PATH_DSM_DATA5 (0x04D4) +#define CDC_RX_RX1_RX_PATH_DSM_DATA6 (0x04D8) +#define CDC_RX_RX2_RX_PATH_CTL (0x0500) +#define CDC_RX_RX2_RX_PATH_CFG0 (0x0504) +#define CDC_RX_RX2_CLSH_EN_MASK BIT(4) +#define CDC_RX_RX2_DLY_Z_EN_MASK BIT(3) +#define CDC_RX_RX2_RX_PATH_CFG1 (0x0508) +#define CDC_RX_RX2_RX_PATH_CFG2 (0x050C) +#define CDC_RX_RX2_RX_PATH_CFG3 (0x0510) +#define CDC_RX_RX2_RX_VOL_CTL (0x0514) +#define CDC_RX_RX2_RX_PATH_MIX_CTL (0x0518) +#define CDC_RX_RX2_RX_PATH_MIX_CFG (0x051C) +#define CDC_RX_RX2_RX_VOL_MIX_CTL (0x0520) +#define CDC_RX_RX2_RX_PATH_SEC0 (0x0524) +#define CDC_RX_RX2_RX_PATH_SEC1 (0x0528) +#define CDC_RX_RX2_RX_PATH_SEC2 (0x052C) +#define CDC_RX_RX2_RX_PATH_SEC3 (0x0530) +#define CDC_RX_RX2_RX_PATH_SEC4 (0x0534) +#define CDC_RX_RX2_RX_PATH_SEC5 (0x0538) +#define CDC_RX_RX2_RX_PATH_SEC6 (0x053C) +#define CDC_RX_RX2_RX_PATH_SEC7 (0x0540) +#define CDC_RX_RX2_RX_PATH_MIX_SEC0 (0x0544) +#define CDC_RX_RX2_RX_PATH_MIX_SEC1 (0x0548) +#define CDC_RX_RX2_RX_PATH_DSM_CTL (0x054C) +#define CDC_RX_IDLE_DETECT_PATH_CTL (0x0780) +#define CDC_RX_IDLE_DETECT_CFG0 (0x0784) +#define CDC_RX_IDLE_DETECT_CFG1 (0x0788) +#define CDC_RX_IDLE_DETECT_CFG2 (0x078C) +#define CDC_RX_IDLE_DETECT_CFG3 (0x0790) +#define CDC_RX_COMPANDERn_CTL0(n) (0x0800 + 0x40 * n) +#define CDC_RX_COMPANDERn_CLK_EN_MASK BIT(0) +#define CDC_RX_COMPANDERn_SOFT_RST_MASK BIT(1) +#define CDC_RX_COMPANDERn_HALT_MASK BIT(2) +#define CDC_RX_COMPANDERn_DROPOUT_EN_MASK BIT(3) +#define CDC_RX_COMPANDER0_CTL0 (0x0800) +#define CDC_RX_COMPANDER0_CTL1 (0x0804) +#define CDC_RX_COMPANDER0_CTL2 (0x0808) +#define CDC_RX_COMPANDER0_CTL3 (0x080C) +#define CDC_RX_COMPANDER0_CTL4 (0x0810) +#define CDC_RX_COMPANDER0_CTL5 (0x0814) +#define CDC_RX_COMPANDER0_CTL6 (0x0818) +#define CDC_RX_COMPANDER0_CTL7 (0x081C) +#define CDC_RX_COMPANDER1_CTL0 (0x0840) +#define CDC_RX_COMPANDER1_CTL1 (0x0844) +#define CDC_RX_COMPANDER1_CTL2 (0x0848) +#define CDC_RX_COMPANDER1_CTL3 (0x084C) +#define CDC_RX_COMPANDER1_CTL4 (0x0850) +#define CDC_RX_COMPANDER1_CTL5 (0x0854) +#define CDC_RX_COMPANDER1_CTL6 (0x0858) +#define CDC_RX_COMPANDER1_CTL7 (0x085C) +#define CDC_RX_COMPANDER1_HPH_LOW_PWR_MODE_MASK BIT(5) +#define CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL (0x0A00) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL (0x0A04) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL (0x0A08) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL (0x0A0C) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL (0x0A10) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL (0x0A14) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL (0x0A18) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL (0x0A1C) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL (0x0A20) +#define CDC_RX_SIDETONE_IIR0_IIR_CTL (0x0A24) +#define CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL (0x0A28) +#define CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL (0x0A2C) +#define CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL (0x0A30) +#define CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL (0x0A80) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL (0x0A84) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL (0x0A88) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL (0x0A8C) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL (0x0A90) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL (0x0A94) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL (0x0A98) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL (0x0A9C) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL (0x0AA0) +#define CDC_RX_SIDETONE_IIR1_IIR_CTL (0x0AA4) +#define CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL (0x0AA8) +#define CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL (0x0AAC) +#define CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL (0x0AB0) +#define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0 (0x0B00) +#define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1 (0x0B04) +#define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2 (0x0B08) +#define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3 (0x0B0C) +#define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0 (0x0B10) +#define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1 (0x0B14) +#define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2 (0x0B18) +#define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3 (0x0B1C) +#define CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL (0x0B40) +#define CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1 (0x0B44) +#define CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL (0x0B50) +#define CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1 (0x0B54) +#define CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL (0x0C00) +#define CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 (0x0C04) +#define CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL (0x0C40) +#define CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0 (0x0C44) +#define CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL (0x0C80) +#define CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0 (0x0C84) +#define CDC_RX_EC_ASRC0_CLK_RST_CTL (0x0D00) +#define CDC_RX_EC_ASRC0_CTL0 (0x0D04) +#define CDC_RX_EC_ASRC0_CTL1 (0x0D08) +#define CDC_RX_EC_ASRC0_FIFO_CTL (0x0D0C) +#define CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB (0x0D10) +#define CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB (0x0D14) +#define CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB (0x0D18) +#define CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB (0x0D1C) +#define CDC_RX_EC_ASRC0_STATUS_FIFO (0x0D20) +#define CDC_RX_EC_ASRC1_CLK_RST_CTL (0x0D40) +#define CDC_RX_EC_ASRC1_CTL0 (0x0D44) +#define CDC_RX_EC_ASRC1_CTL1 (0x0D48) +#define CDC_RX_EC_ASRC1_FIFO_CTL (0x0D4C) +#define CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB (0x0D50) +#define CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB (0x0D54) +#define CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB (0x0D58) +#define CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB (0x0D5C) +#define CDC_RX_EC_ASRC1_STATUS_FIFO (0x0D60) +#define CDC_RX_EC_ASRC2_CLK_RST_CTL (0x0D80) +#define CDC_RX_EC_ASRC2_CTL0 (0x0D84) +#define CDC_RX_EC_ASRC2_CTL1 (0x0D88) +#define CDC_RX_EC_ASRC2_FIFO_CTL (0x0D8C) +#define CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB (0x0D90) +#define CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB (0x0D94) +#define CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB (0x0D98) +#define CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB (0x0D9C) +#define CDC_RX_EC_ASRC2_STATUS_FIFO (0x0DA0) +#define CDC_RX_DSD0_PATH_CTL (0x0F00) +#define CDC_RX_DSD0_CFG0 (0x0F04) +#define CDC_RX_DSD0_CFG1 (0x0F08) +#define CDC_RX_DSD0_CFG2 (0x0F0C) +#define CDC_RX_DSD1_PATH_CTL (0x0F80) +#define CDC_RX_DSD1_CFG0 (0x0F84) +#define CDC_RX_DSD1_CFG1 (0x0F88) +#define CDC_RX_DSD1_CFG2 (0x0F8C) +#define RX_MAX_OFFSET (0x0F8C) + +#define MCLK_FREQ 9600000 + +#define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ + SNDRV_PCM_RATE_384000) +/* Fractional Rates */ +#define RX_MACRO_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800) + +#define RX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + +#define RX_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_48000) +#define RX_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define RX_MACRO_MAX_DMA_CH_PER_PORT 2 +#define RX_MACRO_INTERP_MUX_NUM_INPUTS 3 +#define RX_MACRO_SIDETONE_IIR_COEFF_MAX 5 + +#define MAX_IMPED_PARAMS 6 + +#define RX_MACRO_EC_MIX_TX0_MASK 0xf0 +#define RX_MACRO_EC_MIX_TX1_MASK 0x0f +#define RX_MACRO_EC_MIX_TX2_MASK 0x0f + +#define COMP_MAX_COEFF 25 + +struct comp_coeff_val { + u8 lsb; + u8 msb; +}; + +enum { + HPH_ULP, + HPH_LOHIFI, + HPH_MODE_MAX, +}; + +static const struct comp_coeff_val comp_coeff_table[HPH_MODE_MAX][COMP_MAX_COEFF] = { + { + {0x40, 0x00}, + {0x4C, 0x00}, + {0x5A, 0x00}, + {0x6B, 0x00}, + {0x7F, 0x00}, + {0x97, 0x00}, + {0xB3, 0x00}, + {0xD5, 0x00}, + {0xFD, 0x00}, + {0x2D, 0x01}, + {0x66, 0x01}, + {0xA7, 0x01}, + {0xF8, 0x01}, + {0x57, 0x02}, + {0xC7, 0x02}, + {0x4B, 0x03}, + {0xE9, 0x03}, + {0xA3, 0x04}, + {0x7D, 0x05}, + {0x90, 0x06}, + {0xD1, 0x07}, + {0x49, 0x09}, + {0x00, 0x0B}, + {0x01, 0x0D}, + {0x59, 0x0F}, + }, + { + {0x40, 0x00}, + {0x4C, 0x00}, + {0x5A, 0x00}, + {0x6B, 0x00}, + {0x80, 0x00}, + {0x98, 0x00}, + {0xB4, 0x00}, + {0xD5, 0x00}, + {0xFE, 0x00}, + {0x2E, 0x01}, + {0x66, 0x01}, + {0xA9, 0x01}, + {0xF8, 0x01}, + {0x56, 0x02}, + {0xC4, 0x02}, + {0x4F, 0x03}, + {0xF0, 0x03}, + {0xAE, 0x04}, + {0x8B, 0x05}, + {0x8E, 0x06}, + {0xBC, 0x07}, + {0x56, 0x09}, + {0x0F, 0x0B}, + {0x13, 0x0D}, + {0x6F, 0x0F}, + }, +}; + +struct rx_macro_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +enum { + INTERP_HPHL, + INTERP_HPHR, + INTERP_AUX, + INTERP_MAX +}; + +enum { + RX_MACRO_RX0, + RX_MACRO_RX1, + RX_MACRO_RX2, + RX_MACRO_RX3, + RX_MACRO_RX4, + RX_MACRO_RX5, + RX_MACRO_PORTS_MAX +}; + +enum { + RX_MACRO_COMP1, /* HPH_L */ + RX_MACRO_COMP2, /* HPH_R */ + RX_MACRO_COMP_MAX +}; + +enum { + RX_MACRO_EC0_MUX = 0, + RX_MACRO_EC1_MUX, + RX_MACRO_EC2_MUX, + RX_MACRO_EC_MUX_MAX, +}; + +enum { + INTn_1_INP_SEL_ZERO = 0, + INTn_1_INP_SEL_DEC0, + INTn_1_INP_SEL_DEC1, + INTn_1_INP_SEL_IIR0, + INTn_1_INP_SEL_IIR1, + INTn_1_INP_SEL_RX0, + INTn_1_INP_SEL_RX1, + INTn_1_INP_SEL_RX2, + INTn_1_INP_SEL_RX3, + INTn_1_INP_SEL_RX4, + INTn_1_INP_SEL_RX5, +}; + +enum { + INTn_2_INP_SEL_ZERO = 0, + INTn_2_INP_SEL_RX0, + INTn_2_INP_SEL_RX1, + INTn_2_INP_SEL_RX2, + INTn_2_INP_SEL_RX3, + INTn_2_INP_SEL_RX4, + INTn_2_INP_SEL_RX5, +}; + +enum { + INTERP_MAIN_PATH, + INTERP_MIX_PATH, +}; + +struct interp_sample_rate { + int sample_rate; + int rate_val; +}; + +static struct interp_sample_rate sr_val_tbl[] = { + {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, + {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, + {176400, 0xB}, {352800, 0xC}, +}; + +enum { + RX_MACRO_AIF_INVALID = 0, + RX_MACRO_AIF1_PB, + RX_MACRO_AIF2_PB, + RX_MACRO_AIF3_PB, + RX_MACRO_AIF4_PB, + RX_MACRO_AIF_ECHO, + RX_MACRO_MAX_DAIS, +}; + +enum { + RX_MACRO_AIF1_CAP = 0, + RX_MACRO_AIF2_CAP, + RX_MACRO_AIF3_CAP, + RX_MACRO_MAX_AIF_CAP_DAIS +}; + +#define RX_NUM_CLKS_MAX 5 + +struct rx_macro { + struct device *dev; + int comp_enabled[RX_MACRO_COMP_MAX]; + /* Main path clock users count */ + int main_clk_users[INTERP_MAX]; + int rx_port_value[RX_MACRO_PORTS_MAX]; + u16 prim_int_users[INTERP_MAX]; + int rx_mclk_users; + bool reset_swr; + int clsh_users; + int rx_mclk_cnt; + bool is_ear_mode_on; + bool hph_pwr_mode; + bool hph_hd2_mode; + struct snd_soc_component *component; + unsigned long active_ch_mask[RX_MACRO_MAX_DAIS]; + unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS]; + u16 bit_width[RX_MACRO_MAX_DAIS]; + int is_softclip_on; + int is_aux_hpf_on; + int softclip_clk_users; + + struct regmap *regmap; + struct clk_bulk_data clks[RX_NUM_CLKS_MAX]; + struct clk_hw hw; +}; +#define to_rx_macro(_hw) container_of(_hw, struct rx_macro, hw) + +static struct snd_soc_dai_driver rx_macro_dai[]; +static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); + +static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"}; +static const struct soc_enum rx_macro_ear_mode_enum = + SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text); + +static const char *const rx_macro_hph_hd2_mode_text[] = {"OFF", "ON"}; +static const struct soc_enum rx_macro_hph_hd2_mode_enum = + SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_hd2_mode_text); + +static const char *const rx_macro_hph_pwr_mode_text[] = {"ULP", "LOHIFI"}; +static const struct soc_enum rx_macro_hph_pwr_mode_enum = + SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text); + +static const struct reg_default rx_defaults[] = { + /* RX Macro */ + { CDC_RX_TOP_TOP_CFG0, 0x00 }, + { CDC_RX_TOP_SWR_CTRL, 0x00 }, + { CDC_RX_TOP_DEBUG, 0x00 }, + { CDC_RX_TOP_DEBUG_BUS, 0x00 }, + { CDC_RX_TOP_DEBUG_EN0, 0x00 }, + { CDC_RX_TOP_DEBUG_EN1, 0x00 }, + { CDC_RX_TOP_DEBUG_EN2, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_WR_LSB, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_WR_MSB, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_LUT, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_RD_LSB, 0x00 }, + { CDC_RX_TOP_HPHL_COMP_RD_MSB, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_WR_LSB, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_WR_MSB, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_LUT, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_RD_LSB, 0x00 }, + { CDC_RX_TOP_HPHR_COMP_RD_MSB, 0x00 }, + { CDC_RX_TOP_DSD0_DEBUG_CFG0, 0x11 }, + { CDC_RX_TOP_DSD0_DEBUG_CFG1, 0x20 }, + { CDC_RX_TOP_DSD0_DEBUG_CFG2, 0x00 }, + { CDC_RX_TOP_DSD0_DEBUG_CFG3, 0x00 }, + { CDC_RX_TOP_DSD1_DEBUG_CFG0, 0x11 }, + { CDC_RX_TOP_DSD1_DEBUG_CFG1, 0x20 }, + { CDC_RX_TOP_DSD1_DEBUG_CFG2, 0x00 }, + { CDC_RX_TOP_DSD1_DEBUG_CFG3, 0x00 }, + { CDC_RX_TOP_RX_I2S_CTL, 0x0C }, + { CDC_RX_TOP_TX_I2S2_CTL, 0x0C }, + { CDC_RX_TOP_I2S_CLK, 0x0C }, + { CDC_RX_TOP_I2S_RESET, 0x00 }, + { CDC_RX_TOP_I2S_MUX, 0x00 }, + { CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, + { CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, + { CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x00 }, + { CDC_RX_CLK_RST_CTRL_DSD_CONTROL, 0x00 }, + { CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x08 }, + { CDC_RX_SOFTCLIP_CRC, 0x00 }, + { CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x38 }, + { CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00 }, + { CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00 }, + { CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00 }, + { CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00 }, + { CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00 }, + { CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00 }, + { CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00 }, + { CDC_RX_INP_MUX_RX_MIX_CFG5, 0x00 }, + { CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00 }, + { CDC_RX_CLSH_CRC, 0x00 }, + { CDC_RX_CLSH_DLY_CTRL, 0x03 }, + { CDC_RX_CLSH_DECAY_CTRL, 0x02 }, + { CDC_RX_CLSH_HPH_V_PA, 0x1C }, + { CDC_RX_CLSH_EAR_V_PA, 0x39 }, + { CDC_RX_CLSH_HPH_V_HD, 0x0C }, + { CDC_RX_CLSH_EAR_V_HD, 0x0C }, + { CDC_RX_CLSH_K1_MSB, 0x01 }, + { CDC_RX_CLSH_K1_LSB, 0x00 }, + { CDC_RX_CLSH_K2_MSB, 0x00 }, + { CDC_RX_CLSH_K2_LSB, 0x80 }, + { CDC_RX_CLSH_IDLE_CTRL, 0x00 }, + { CDC_RX_CLSH_IDLE_HPH, 0x00 }, + { CDC_RX_CLSH_IDLE_EAR, 0x00 }, + { CDC_RX_CLSH_TEST0, 0x07 }, + { CDC_RX_CLSH_TEST1, 0x00 }, + { CDC_RX_CLSH_OVR_VREF, 0x00 }, + { CDC_RX_CLSH_CLSG_CTL, 0x02 }, + { CDC_RX_CLSH_CLSG_CFG1, 0x9A }, + { CDC_RX_CLSH_CLSG_CFG2, 0x10 }, + { CDC_RX_BCL_VBAT_PATH_CTL, 0x00 }, + { CDC_RX_BCL_VBAT_CFG, 0x10 }, + { CDC_RX_BCL_VBAT_ADC_CAL1, 0x00 }, + { CDC_RX_BCL_VBAT_ADC_CAL2, 0x00 }, + { CDC_RX_BCL_VBAT_ADC_CAL3, 0x04 }, + { CDC_RX_BCL_VBAT_PK_EST1, 0xE0 }, + { CDC_RX_BCL_VBAT_PK_EST2, 0x01 }, + { CDC_RX_BCL_VBAT_PK_EST3, 0x40 }, + { CDC_RX_BCL_VBAT_RF_PROC1, 0x2A }, + { CDC_RX_BCL_VBAT_RF_PROC1, 0x00 }, + { CDC_RX_BCL_VBAT_TAC1, 0x00 }, + { CDC_RX_BCL_VBAT_TAC2, 0x18 }, + { CDC_RX_BCL_VBAT_TAC3, 0x18 }, + { CDC_RX_BCL_VBAT_TAC4, 0x03 }, + { CDC_RX_BCL_VBAT_GAIN_UPD1, 0x01 }, + { CDC_RX_BCL_VBAT_GAIN_UPD2, 0x00 }, + { CDC_RX_BCL_VBAT_GAIN_UPD3, 0x00 }, + { CDC_RX_BCL_VBAT_GAIN_UPD4, 0x64 }, + { CDC_RX_BCL_VBAT_GAIN_UPD5, 0x01 }, + { CDC_RX_BCL_VBAT_DEBUG1, 0x00 }, + { CDC_RX_BCL_VBAT_GAIN_UPD_MON, 0x00 }, + { CDC_RX_BCL_VBAT_GAIN_MON_VAL, 0x00 }, + { CDC_RX_BCL_VBAT_BAN, 0x0C }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, 0x00 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, 0x77 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, 0x01 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, 0x00 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, 0x4B }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, 0x00 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, 0x01 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, 0x00 }, + { CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, 0x00 }, + { CDC_RX_BCL_VBAT_ATTN1, 0x04 }, + { CDC_RX_BCL_VBAT_ATTN2, 0x08 }, + { CDC_RX_BCL_VBAT_ATTN3, 0x0C }, + { CDC_RX_BCL_VBAT_DECODE_CTL1, 0xE0 }, + { CDC_RX_BCL_VBAT_DECODE_CTL2, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_CFG1, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_CFG2, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_CFG3, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_CFG4, 0x00 }, + { CDC_RX_BCL_VBAT_DECODE_ST, 0x00 }, + { CDC_RX_INTR_CTRL_CFG, 0x00 }, + { CDC_RX_INTR_CTRL_CLR_COMMIT, 0x00 }, + { CDC_RX_INTR_CTRL_PIN1_MASK0, 0xFF }, + { CDC_RX_INTR_CTRL_PIN1_STATUS0, 0x00 }, + { CDC_RX_INTR_CTRL_PIN1_CLEAR0, 0x00 }, + { CDC_RX_INTR_CTRL_PIN2_MASK0, 0xFF }, + { CDC_RX_INTR_CTRL_PIN2_STATUS0, 0x00 }, + { CDC_RX_INTR_CTRL_PIN2_CLEAR0, 0x00 }, + { CDC_RX_INTR_CTRL_LEVEL0, 0x00 }, + { CDC_RX_INTR_CTRL_BYPASS0, 0x00 }, + { CDC_RX_INTR_CTRL_SET0, 0x00 }, + { CDC_RX_RX0_RX_PATH_CTL, 0x04 }, + { CDC_RX_RX0_RX_PATH_CFG0, 0x00 }, + { CDC_RX_RX0_RX_PATH_CFG1, 0x64 }, + { CDC_RX_RX0_RX_PATH_CFG2, 0x8F }, + { CDC_RX_RX0_RX_PATH_CFG3, 0x00 }, + { CDC_RX_RX0_RX_VOL_CTL, 0x00 }, + { CDC_RX_RX0_RX_PATH_MIX_CTL, 0x04 }, + { CDC_RX_RX0_RX_PATH_MIX_CFG, 0x7E }, + { CDC_RX_RX0_RX_VOL_MIX_CTL, 0x00 }, + { CDC_RX_RX0_RX_PATH_SEC1, 0x08 }, + { CDC_RX_RX0_RX_PATH_SEC2, 0x00 }, + { CDC_RX_RX0_RX_PATH_SEC3, 0x00 }, + { CDC_RX_RX0_RX_PATH_SEC4, 0x00 }, + { CDC_RX_RX0_RX_PATH_SEC7, 0x00 }, + { CDC_RX_RX0_RX_PATH_MIX_SEC0, 0x08 }, + { CDC_RX_RX0_RX_PATH_MIX_SEC1, 0x00 }, + { CDC_RX_RX0_RX_PATH_DSM_CTL, 0x08 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA1, 0x00 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA2, 0x00 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA3, 0x00 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA4, 0x55 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA5, 0x55 }, + { CDC_RX_RX0_RX_PATH_DSM_DATA6, 0x55 }, + { CDC_RX_RX1_RX_PATH_CTL, 0x04 }, + { CDC_RX_RX1_RX_PATH_CFG0, 0x00 }, + { CDC_RX_RX1_RX_PATH_CFG1, 0x64 }, + { CDC_RX_RX1_RX_PATH_CFG2, 0x8F }, + { CDC_RX_RX1_RX_PATH_CFG3, 0x00 }, + { CDC_RX_RX1_RX_VOL_CTL, 0x00 }, + { CDC_RX_RX1_RX_PATH_MIX_CTL, 0x04 }, + { CDC_RX_RX1_RX_PATH_MIX_CFG, 0x7E }, + { CDC_RX_RX1_RX_VOL_MIX_CTL, 0x00 }, + { CDC_RX_RX1_RX_PATH_SEC1, 0x08 }, + { CDC_RX_RX1_RX_PATH_SEC2, 0x00 }, + { CDC_RX_RX1_RX_PATH_SEC3, 0x00 }, + { CDC_RX_RX1_RX_PATH_SEC4, 0x00 }, + { CDC_RX_RX1_RX_PATH_SEC7, 0x00 }, + { CDC_RX_RX1_RX_PATH_MIX_SEC0, 0x08 }, + { CDC_RX_RX1_RX_PATH_MIX_SEC1, 0x00 }, + { CDC_RX_RX1_RX_PATH_DSM_CTL, 0x08 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA1, 0x00 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA2, 0x00 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA3, 0x00 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA4, 0x55 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA5, 0x55 }, + { CDC_RX_RX1_RX_PATH_DSM_DATA6, 0x55 }, + { CDC_RX_RX2_RX_PATH_CTL, 0x04 }, + { CDC_RX_RX2_RX_PATH_CFG0, 0x00 }, + { CDC_RX_RX2_RX_PATH_CFG1, 0x64 }, + { CDC_RX_RX2_RX_PATH_CFG2, 0x8F }, + { CDC_RX_RX2_RX_PATH_CFG3, 0x00 }, + { CDC_RX_RX2_RX_VOL_CTL, 0x00 }, + { CDC_RX_RX2_RX_PATH_MIX_CTL, 0x04 }, + { CDC_RX_RX2_RX_PATH_MIX_CFG, 0x7E }, + { CDC_RX_RX2_RX_VOL_MIX_CTL, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC0, 0x04 }, + { CDC_RX_RX2_RX_PATH_SEC1, 0x08 }, + { CDC_RX_RX2_RX_PATH_SEC2, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC3, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC4, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC5, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC6, 0x00 }, + { CDC_RX_RX2_RX_PATH_SEC7, 0x00 }, + { CDC_RX_RX2_RX_PATH_MIX_SEC0, 0x08 }, + { CDC_RX_RX2_RX_PATH_MIX_SEC1, 0x00 }, + { CDC_RX_RX2_RX_PATH_DSM_CTL, 0x00 }, + { CDC_RX_IDLE_DETECT_PATH_CTL, 0x00 }, + { CDC_RX_IDLE_DETECT_CFG0, 0x07 }, + { CDC_RX_IDLE_DETECT_CFG1, 0x3C }, + { CDC_RX_IDLE_DETECT_CFG2, 0x00 }, + { CDC_RX_IDLE_DETECT_CFG3, 0x00 }, + { CDC_RX_COMPANDER0_CTL0, 0x60 }, + { CDC_RX_COMPANDER0_CTL1, 0xDB }, + { CDC_RX_COMPANDER0_CTL2, 0xFF }, + { CDC_RX_COMPANDER0_CTL3, 0x35 }, + { CDC_RX_COMPANDER0_CTL4, 0xFF }, + { CDC_RX_COMPANDER0_CTL5, 0x00 }, + { CDC_RX_COMPANDER0_CTL6, 0x01 }, + { CDC_RX_COMPANDER0_CTL7, 0x28 }, + { CDC_RX_COMPANDER1_CTL0, 0x60 }, + { CDC_RX_COMPANDER1_CTL1, 0xDB }, + { CDC_RX_COMPANDER1_CTL2, 0xFF }, + { CDC_RX_COMPANDER1_CTL3, 0x35 }, + { CDC_RX_COMPANDER1_CTL4, 0xFF }, + { CDC_RX_COMPANDER1_CTL5, 0x00 }, + { CDC_RX_COMPANDER1_CTL6, 0x01 }, + { CDC_RX_COMPANDER1_CTL7, 0x28 }, + { CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_CTL, 0x40 }, + { CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_CTL, 0x40 }, + { CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL, 0x00 }, + { CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0x00 }, + { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0x00 }, + { CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04 }, + { CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00 }, + { CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, 0x04 }, + { CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1, 0x00 }, + { CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00 }, + { CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01 }, + { CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00 }, + { CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01 }, + { CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL, 0x00 }, + { CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0, 0x01 }, + { CDC_RX_EC_ASRC0_CLK_RST_CTL, 0x00 }, + { CDC_RX_EC_ASRC0_CTL0, 0x00 }, + { CDC_RX_EC_ASRC0_CTL1, 0x00 }, + { CDC_RX_EC_ASRC0_FIFO_CTL, 0xA8 }, + { CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC0_STATUS_FIFO, 0x00 }, + { CDC_RX_EC_ASRC1_CLK_RST_CTL, 0x00 }, + { CDC_RX_EC_ASRC1_CTL0, 0x00 }, + { CDC_RX_EC_ASRC1_CTL1, 0x00 }, + { CDC_RX_EC_ASRC1_FIFO_CTL, 0xA8 }, + { CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC1_STATUS_FIFO, 0x00 }, + { CDC_RX_EC_ASRC2_CLK_RST_CTL, 0x00 }, + { CDC_RX_EC_ASRC2_CTL0, 0x00 }, + { CDC_RX_EC_ASRC2_CTL1, 0x00 }, + { CDC_RX_EC_ASRC2_FIFO_CTL, 0xA8 }, + { CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00 }, + { CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00 }, + { CDC_RX_EC_ASRC2_STATUS_FIFO, 0x00 }, + { CDC_RX_DSD0_PATH_CTL, 0x00 }, + { CDC_RX_DSD0_CFG0, 0x00 }, + { CDC_RX_DSD0_CFG1, 0x62 }, + { CDC_RX_DSD0_CFG2, 0x96 }, + { CDC_RX_DSD1_PATH_CTL, 0x00 }, + { CDC_RX_DSD1_CFG0, 0x00 }, + { CDC_RX_DSD1_CFG1, 0x62 }, + { CDC_RX_DSD1_CFG2, 0x96 }, +}; + +static bool rx_is_wronly_register(struct device *dev, + unsigned int reg) +{ + switch (reg) { + case CDC_RX_BCL_VBAT_GAIN_UPD_MON: + case CDC_RX_INTR_CTRL_CLR_COMMIT: + case CDC_RX_INTR_CTRL_PIN1_CLEAR0: + case CDC_RX_INTR_CTRL_PIN2_CLEAR0: + return true; + } + + return false; +} + +static bool rx_is_volatile_register(struct device *dev, unsigned int reg) +{ + /* Update volatile list for rx/tx macros */ + switch (reg) { + case CDC_RX_TOP_HPHL_COMP_RD_LSB: + case CDC_RX_TOP_HPHL_COMP_WR_LSB: + case CDC_RX_TOP_HPHL_COMP_RD_MSB: + case CDC_RX_TOP_HPHL_COMP_WR_MSB: + case CDC_RX_TOP_HPHR_COMP_RD_LSB: + case CDC_RX_TOP_HPHR_COMP_WR_LSB: + case CDC_RX_TOP_HPHR_COMP_RD_MSB: + case CDC_RX_TOP_HPHR_COMP_WR_MSB: + case CDC_RX_TOP_DSD0_DEBUG_CFG2: + case CDC_RX_TOP_DSD1_DEBUG_CFG2: + case CDC_RX_BCL_VBAT_GAIN_MON_VAL: + case CDC_RX_BCL_VBAT_DECODE_ST: + case CDC_RX_INTR_CTRL_PIN1_STATUS0: + case CDC_RX_INTR_CTRL_PIN2_STATUS0: + case CDC_RX_COMPANDER0_CTL6: + case CDC_RX_COMPANDER1_CTL6: + case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC0_STATUS_FIFO: + case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC1_STATUS_FIFO: + case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC2_STATUS_FIFO: + return true; + } + return false; +} + +static bool rx_is_rw_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CDC_RX_TOP_TOP_CFG0: + case CDC_RX_TOP_SWR_CTRL: + case CDC_RX_TOP_DEBUG: + case CDC_RX_TOP_DEBUG_BUS: + case CDC_RX_TOP_DEBUG_EN0: + case CDC_RX_TOP_DEBUG_EN1: + case CDC_RX_TOP_DEBUG_EN2: + case CDC_RX_TOP_HPHL_COMP_WR_LSB: + case CDC_RX_TOP_HPHL_COMP_WR_MSB: + case CDC_RX_TOP_HPHL_COMP_LUT: + case CDC_RX_TOP_HPHR_COMP_WR_LSB: + case CDC_RX_TOP_HPHR_COMP_WR_MSB: + case CDC_RX_TOP_HPHR_COMP_LUT: + case CDC_RX_TOP_DSD0_DEBUG_CFG0: + case CDC_RX_TOP_DSD0_DEBUG_CFG1: + case CDC_RX_TOP_DSD0_DEBUG_CFG3: + case CDC_RX_TOP_DSD1_DEBUG_CFG0: + case CDC_RX_TOP_DSD1_DEBUG_CFG1: + case CDC_RX_TOP_DSD1_DEBUG_CFG3: + case CDC_RX_TOP_RX_I2S_CTL: + case CDC_RX_TOP_TX_I2S2_CTL: + case CDC_RX_TOP_I2S_CLK: + case CDC_RX_TOP_I2S_RESET: + case CDC_RX_TOP_I2S_MUX: + case CDC_RX_CLK_RST_CTRL_MCLK_CONTROL: + case CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL: + case CDC_RX_CLK_RST_CTRL_SWR_CONTROL: + case CDC_RX_CLK_RST_CTRL_DSD_CONTROL: + case CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL: + case CDC_RX_SOFTCLIP_CRC: + case CDC_RX_SOFTCLIP_SOFTCLIP_CTRL: + case CDC_RX_INP_MUX_RX_INT0_CFG0: + case CDC_RX_INP_MUX_RX_INT0_CFG1: + case CDC_RX_INP_MUX_RX_INT1_CFG0: + case CDC_RX_INP_MUX_RX_INT1_CFG1: + case CDC_RX_INP_MUX_RX_INT2_CFG0: + case CDC_RX_INP_MUX_RX_INT2_CFG1: + case CDC_RX_INP_MUX_RX_MIX_CFG4: + case CDC_RX_INP_MUX_RX_MIX_CFG5: + case CDC_RX_INP_MUX_SIDETONE_SRC_CFG0: + case CDC_RX_CLSH_CRC: + case CDC_RX_CLSH_DLY_CTRL: + case CDC_RX_CLSH_DECAY_CTRL: + case CDC_RX_CLSH_HPH_V_PA: + case CDC_RX_CLSH_EAR_V_PA: + case CDC_RX_CLSH_HPH_V_HD: + case CDC_RX_CLSH_EAR_V_HD: + case CDC_RX_CLSH_K1_MSB: + case CDC_RX_CLSH_K1_LSB: + case CDC_RX_CLSH_K2_MSB: + case CDC_RX_CLSH_K2_LSB: + case CDC_RX_CLSH_IDLE_CTRL: + case CDC_RX_CLSH_IDLE_HPH: + case CDC_RX_CLSH_IDLE_EAR: + case CDC_RX_CLSH_TEST0: + case CDC_RX_CLSH_TEST1: + case CDC_RX_CLSH_OVR_VREF: + case CDC_RX_CLSH_CLSG_CTL: + case CDC_RX_CLSH_CLSG_CFG1: + case CDC_RX_CLSH_CLSG_CFG2: + case CDC_RX_BCL_VBAT_PATH_CTL: + case CDC_RX_BCL_VBAT_CFG: + case CDC_RX_BCL_VBAT_ADC_CAL1: + case CDC_RX_BCL_VBAT_ADC_CAL2: + case CDC_RX_BCL_VBAT_ADC_CAL3: + case CDC_RX_BCL_VBAT_PK_EST1: + case CDC_RX_BCL_VBAT_PK_EST2: + case CDC_RX_BCL_VBAT_PK_EST3: + case CDC_RX_BCL_VBAT_RF_PROC1: + case CDC_RX_BCL_VBAT_RF_PROC2: + case CDC_RX_BCL_VBAT_TAC1: + case CDC_RX_BCL_VBAT_TAC2: + case CDC_RX_BCL_VBAT_TAC3: + case CDC_RX_BCL_VBAT_TAC4: + case CDC_RX_BCL_VBAT_GAIN_UPD1: + case CDC_RX_BCL_VBAT_GAIN_UPD2: + case CDC_RX_BCL_VBAT_GAIN_UPD3: + case CDC_RX_BCL_VBAT_GAIN_UPD4: + case CDC_RX_BCL_VBAT_GAIN_UPD5: + case CDC_RX_BCL_VBAT_DEBUG1: + case CDC_RX_BCL_VBAT_BAN: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD1: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD2: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD3: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD4: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD5: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD6: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD7: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD8: + case CDC_RX_BCL_VBAT_BCL_GAIN_UPD9: + case CDC_RX_BCL_VBAT_ATTN1: + case CDC_RX_BCL_VBAT_ATTN2: + case CDC_RX_BCL_VBAT_ATTN3: + case CDC_RX_BCL_VBAT_DECODE_CTL1: + case CDC_RX_BCL_VBAT_DECODE_CTL2: + case CDC_RX_BCL_VBAT_DECODE_CFG1: + case CDC_RX_BCL_VBAT_DECODE_CFG2: + case CDC_RX_BCL_VBAT_DECODE_CFG3: + case CDC_RX_BCL_VBAT_DECODE_CFG4: + case CDC_RX_INTR_CTRL_CFG: + case CDC_RX_INTR_CTRL_PIN1_MASK0: + case CDC_RX_INTR_CTRL_PIN2_MASK0: + case CDC_RX_INTR_CTRL_LEVEL0: + case CDC_RX_INTR_CTRL_BYPASS0: + case CDC_RX_INTR_CTRL_SET0: + case CDC_RX_RX0_RX_PATH_CTL: + case CDC_RX_RX0_RX_PATH_CFG0: + case CDC_RX_RX0_RX_PATH_CFG1: + case CDC_RX_RX0_RX_PATH_CFG2: + case CDC_RX_RX0_RX_PATH_CFG3: + case CDC_RX_RX0_RX_VOL_CTL: + case CDC_RX_RX0_RX_PATH_MIX_CTL: + case CDC_RX_RX0_RX_PATH_MIX_CFG: + case CDC_RX_RX0_RX_VOL_MIX_CTL: + case CDC_RX_RX0_RX_PATH_SEC1: + case CDC_RX_RX0_RX_PATH_SEC2: + case CDC_RX_RX0_RX_PATH_SEC3: + case CDC_RX_RX0_RX_PATH_SEC4: + case CDC_RX_RX0_RX_PATH_SEC7: + case CDC_RX_RX0_RX_PATH_MIX_SEC0: + case CDC_RX_RX0_RX_PATH_MIX_SEC1: + case CDC_RX_RX0_RX_PATH_DSM_CTL: + case CDC_RX_RX0_RX_PATH_DSM_DATA1: + case CDC_RX_RX0_RX_PATH_DSM_DATA2: + case CDC_RX_RX0_RX_PATH_DSM_DATA3: + case CDC_RX_RX0_RX_PATH_DSM_DATA4: + case CDC_RX_RX0_RX_PATH_DSM_DATA5: + case CDC_RX_RX0_RX_PATH_DSM_DATA6: + case CDC_RX_RX1_RX_PATH_CTL: + case CDC_RX_RX1_RX_PATH_CFG0: + case CDC_RX_RX1_RX_PATH_CFG1: + case CDC_RX_RX1_RX_PATH_CFG2: + case CDC_RX_RX1_RX_PATH_CFG3: + case CDC_RX_RX1_RX_VOL_CTL: + case CDC_RX_RX1_RX_PATH_MIX_CTL: + case CDC_RX_RX1_RX_PATH_MIX_CFG: + case CDC_RX_RX1_RX_VOL_MIX_CTL: + case CDC_RX_RX1_RX_PATH_SEC1: + case CDC_RX_RX1_RX_PATH_SEC2: + case CDC_RX_RX1_RX_PATH_SEC3: + case CDC_RX_RX1_RX_PATH_SEC4: + case CDC_RX_RX1_RX_PATH_SEC7: + case CDC_RX_RX1_RX_PATH_MIX_SEC0: + case CDC_RX_RX1_RX_PATH_MIX_SEC1: + case CDC_RX_RX1_RX_PATH_DSM_CTL: + case CDC_RX_RX1_RX_PATH_DSM_DATA1: + case CDC_RX_RX1_RX_PATH_DSM_DATA2: + case CDC_RX_RX1_RX_PATH_DSM_DATA3: + case CDC_RX_RX1_RX_PATH_DSM_DATA4: + case CDC_RX_RX1_RX_PATH_DSM_DATA5: + case CDC_RX_RX1_RX_PATH_DSM_DATA6: + case CDC_RX_RX2_RX_PATH_CTL: + case CDC_RX_RX2_RX_PATH_CFG0: + case CDC_RX_RX2_RX_PATH_CFG1: + case CDC_RX_RX2_RX_PATH_CFG2: + case CDC_RX_RX2_RX_PATH_CFG3: + case CDC_RX_RX2_RX_VOL_CTL: + case CDC_RX_RX2_RX_PATH_MIX_CTL: + case CDC_RX_RX2_RX_PATH_MIX_CFG: + case CDC_RX_RX2_RX_VOL_MIX_CTL: + case CDC_RX_RX2_RX_PATH_SEC0: + case CDC_RX_RX2_RX_PATH_SEC1: + case CDC_RX_RX2_RX_PATH_SEC2: + case CDC_RX_RX2_RX_PATH_SEC3: + case CDC_RX_RX2_RX_PATH_SEC4: + case CDC_RX_RX2_RX_PATH_SEC5: + case CDC_RX_RX2_RX_PATH_SEC6: + case CDC_RX_RX2_RX_PATH_SEC7: + case CDC_RX_RX2_RX_PATH_MIX_SEC0: + case CDC_RX_RX2_RX_PATH_MIX_SEC1: + case CDC_RX_RX2_RX_PATH_DSM_CTL: + case CDC_RX_IDLE_DETECT_PATH_CTL: + case CDC_RX_IDLE_DETECT_CFG0: + case CDC_RX_IDLE_DETECT_CFG1: + case CDC_RX_IDLE_DETECT_CFG2: + case CDC_RX_IDLE_DETECT_CFG3: + case CDC_RX_COMPANDER0_CTL0: + case CDC_RX_COMPANDER0_CTL1: + case CDC_RX_COMPANDER0_CTL2: + case CDC_RX_COMPANDER0_CTL3: + case CDC_RX_COMPANDER0_CTL4: + case CDC_RX_COMPANDER0_CTL5: + case CDC_RX_COMPANDER0_CTL7: + case CDC_RX_COMPANDER1_CTL0: + case CDC_RX_COMPANDER1_CTL1: + case CDC_RX_COMPANDER1_CTL2: + case CDC_RX_COMPANDER1_CTL3: + case CDC_RX_COMPANDER1_CTL4: + case CDC_RX_COMPANDER1_CTL5: + case CDC_RX_COMPANDER1_CTL7: + case CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL: + case CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL: + case CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL: + case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0: + case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1: + case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2: + case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3: + case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0: + case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1: + case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2: + case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3: + case CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL: + case CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1: + case CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL: + case CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1: + case CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL: + case CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0: + case CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL: + case CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0: + case CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL: + case CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0: + case CDC_RX_EC_ASRC0_CLK_RST_CTL: + case CDC_RX_EC_ASRC0_CTL0: + case CDC_RX_EC_ASRC0_CTL1: + case CDC_RX_EC_ASRC0_FIFO_CTL: + case CDC_RX_EC_ASRC1_CLK_RST_CTL: + case CDC_RX_EC_ASRC1_CTL0: + case CDC_RX_EC_ASRC1_CTL1: + case CDC_RX_EC_ASRC1_FIFO_CTL: + case CDC_RX_EC_ASRC2_CLK_RST_CTL: + case CDC_RX_EC_ASRC2_CTL0: + case CDC_RX_EC_ASRC2_CTL1: + case CDC_RX_EC_ASRC2_FIFO_CTL: + case CDC_RX_DSD0_PATH_CTL: + case CDC_RX_DSD0_CFG0: + case CDC_RX_DSD0_CFG1: + case CDC_RX_DSD0_CFG2: + case CDC_RX_DSD1_PATH_CTL: + case CDC_RX_DSD1_CFG0: + case CDC_RX_DSD1_CFG1: + case CDC_RX_DSD1_CFG2: + return true; + } + + return false; +} + +static bool rx_is_writeable_register(struct device *dev, unsigned int reg) +{ + bool ret; + + ret = rx_is_rw_register(dev, reg); + if (!ret) + return rx_is_wronly_register(dev, reg); + + return ret; +} + +static bool rx_is_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CDC_RX_TOP_HPHL_COMP_RD_LSB: + case CDC_RX_TOP_HPHL_COMP_RD_MSB: + case CDC_RX_TOP_HPHR_COMP_RD_LSB: + case CDC_RX_TOP_HPHR_COMP_RD_MSB: + case CDC_RX_TOP_DSD0_DEBUG_CFG2: + case CDC_RX_TOP_DSD1_DEBUG_CFG2: + case CDC_RX_BCL_VBAT_GAIN_MON_VAL: + case CDC_RX_BCL_VBAT_DECODE_ST: + case CDC_RX_INTR_CTRL_PIN1_STATUS0: + case CDC_RX_INTR_CTRL_PIN2_STATUS0: + case CDC_RX_COMPANDER0_CTL6: + case CDC_RX_COMPANDER1_CTL6: + case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC0_STATUS_FIFO: + case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC1_STATUS_FIFO: + case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB: + case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB: + case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB: + case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB: + case CDC_RX_EC_ASRC2_STATUS_FIFO: + return true; + } + + return rx_is_rw_register(dev, reg); +} + +static const struct regmap_config rx_regmap_config = { + .name = "rx_macro", + .reg_bits = 16, + .val_bits = 32, /* 8 but with 32 bit read/write */ + .reg_stride = 4, + .cache_type = REGCACHE_FLAT, + .reg_defaults = rx_defaults, + .num_reg_defaults = ARRAY_SIZE(rx_defaults), + .max_register = RX_MAX_OFFSET, + .writeable_reg = rx_is_writeable_register, + .volatile_reg = rx_is_volatile_register, + .readable_reg = rx_is_readable_register, +}; + +static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, + int rate_reg_val, u32 sample_rate) +{ + + u8 int_1_mix1_inp; + u32 j, port; + u16 int_mux_cfg0, int_mux_cfg1; + u16 int_fs_reg; + u8 inp0_sel, inp1_sel, inp2_sel; + struct snd_soc_component *component = dai->component; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + for_each_set_bit(port, &rx->active_ch_mask[dai->id], RX_MACRO_PORTS_MAX) { + int_1_mix1_inp = port; + int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0; + /* + * Loop through all interpolator MUX inputs and find out + * to which interpolator input, the rx port + * is connected + */ + for (j = 0; j < INTERP_MAX; j++) { + int_mux_cfg1 = int_mux_cfg0 + 4; + + inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_RX_INTX_1_MIX_INP0_SEL_MASK); + inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_RX_INTX_1_MIX_INP1_SEL_MASK); + inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1, + CDC_RX_INTX_1_MIX_INP2_SEL_MASK); + + if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || + (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || + (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { + int_fs_reg = CDC_RX_RXn_RX_PATH_CTL(j); + /* sample_rate is in Hz */ + snd_soc_component_update_bits(component, int_fs_reg, + CDC_RX_PATH_PCM_RATE_MASK, + rate_reg_val); + } + int_mux_cfg0 += 8; + } + } + + return 0; +} + +static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, + int rate_reg_val, u32 sample_rate) +{ + + u8 int_2_inp; + u32 j, port; + u16 int_mux_cfg1, int_fs_reg; + u8 int_mux_cfg1_val; + struct snd_soc_component *component = dai->component; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + for_each_set_bit(port, &rx->active_ch_mask[dai->id], RX_MACRO_PORTS_MAX) { + int_2_inp = port; + + int_mux_cfg1 = CDC_RX_INP_MUX_RX_INT0_CFG1; + for (j = 0; j < INTERP_MAX; j++) { + int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1, + CDC_RX_INTX_2_SEL_MASK); + + if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) { + int_fs_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(j); + snd_soc_component_update_bits(component, int_fs_reg, + CDC_RX_RXn_MIX_PCM_RATE_MASK, + rate_reg_val); + } + int_mux_cfg1 += 8; + } + } + return 0; +} + +static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + int rate_val = 0; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) + if (sample_rate == sr_val_tbl[i].sample_rate) + rate_val = sr_val_tbl[i].rate_val; + + ret = rx_macro_set_prim_interpolator_rate(dai, rate_val, sample_rate); + if (ret) + return ret; + + ret = rx_macro_set_mix_interpolator_rate(dai, rate_val, sample_rate); + if (ret) + return ret; + + return ret; +} + +static int rx_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + int ret; + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ret = rx_macro_set_interpolator_rate(dai, params_rate(params)); + if (ret) { + dev_err(component->dev, "%s: cannot set sample rate: %u\n", + __func__, params_rate(params)); + return ret; + } + rx->bit_width[dai->id] = params_width(params); + break; + default: + break; + } + return 0; +} + +static int rx_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct snd_soc_component *component = dai->component; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + u16 val, mask = 0, cnt = 0, temp; + + switch (dai->id) { + case RX_MACRO_AIF1_PB: + case RX_MACRO_AIF2_PB: + case RX_MACRO_AIF3_PB: + case RX_MACRO_AIF4_PB: + for_each_set_bit(temp, &rx->active_ch_mask[dai->id], + RX_MACRO_PORTS_MAX) { + mask |= (1 << temp); + if (++cnt == RX_MACRO_MAX_DMA_CH_PER_PORT) + break; + } + /* + * CDC_DMA_RX_0 port drives RX0/RX1 -- ch_mask 0x1/0x2/0x3 + * CDC_DMA_RX_1 port drives RX2/RX3 -- ch_mask 0x1/0x2/0x3 + * CDC_DMA_RX_2 port drives RX4 -- ch_mask 0x1 + * CDC_DMA_RX_3 port drives RX5 -- ch_mask 0x1 + * AIFn can pair to any CDC_DMA_RX_n port. + * In general, below convention is used:: + * CDC_DMA_RX_0(AIF1)/CDC_DMA_RX_1(AIF2)/ + * CDC_DMA_RX_2(AIF3)/CDC_DMA_RX_3(AIF4) + */ + if (mask & 0x0C) + mask = mask >> 2; + if ((mask & 0x10) || (mask & 0x20)) + mask = 0x1; + *rx_slot = mask; + *rx_num = rx->active_ch_cnt[dai->id]; + break; + case RX_MACRO_AIF_ECHO: + val = snd_soc_component_read(component, CDC_RX_INP_MUX_RX_MIX_CFG4); + if (val & RX_MACRO_EC_MIX_TX0_MASK) { + mask |= 0x1; + cnt++; + } + if (val & RX_MACRO_EC_MIX_TX1_MASK) { + mask |= 0x2; + cnt++; + } + val = snd_soc_component_read(component, + CDC_RX_INP_MUX_RX_MIX_CFG5); + if (val & RX_MACRO_EC_MIX_TX2_MASK) { + mask |= 0x4; + cnt++; + } + *tx_slot = mask; + *tx_num = cnt; + break; + default: + dev_err(component->dev, "%s: Invalid AIF\n", __func__); + break; + } + return 0; +} + +static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_component *component = dai->component; + uint16_t j, reg, mix_reg, dsm_reg; + u16 int_mux_cfg0, int_mux_cfg1; + u8 int_mux_cfg0_val, int_mux_cfg1_val; + + switch (dai->id) { + case RX_MACRO_AIF1_PB: + case RX_MACRO_AIF2_PB: + case RX_MACRO_AIF3_PB: + case RX_MACRO_AIF4_PB: + for (j = 0; j < INTERP_MAX; j++) { + reg = CDC_RX_RXn_RX_PATH_CTL(j); + mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(j); + dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(j); + + if (mute) { + snd_soc_component_update_bits(component, reg, + CDC_RX_PATH_PGA_MUTE_MASK, + CDC_RX_PATH_PGA_MUTE_ENABLE); + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_PATH_PGA_MUTE_MASK, + CDC_RX_PATH_PGA_MUTE_ENABLE); + } else { + snd_soc_component_update_bits(component, reg, + CDC_RX_PATH_PGA_MUTE_MASK, 0x0); + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_PATH_PGA_MUTE_MASK, 0x0); + } + + if (j == INTERP_AUX) + dsm_reg = CDC_RX_RX2_RX_PATH_DSM_CTL; + + int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8; + int_mux_cfg1 = int_mux_cfg0 + 4; + int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1); + + if (snd_soc_component_read(component, dsm_reg) & 0x01) { + if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0)) + snd_soc_component_update_bits(component, reg, 0x20, 0x20); + if (int_mux_cfg1_val & 0x0F) { + snd_soc_component_update_bits(component, reg, 0x20, 0x20); + snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20); + } + } + } + break; + default: + break; + } + return 0; +} + +static struct snd_soc_dai_ops rx_macro_dai_ops = { + .hw_params = rx_macro_hw_params, + .get_channel_map = rx_macro_get_channel_map, + .mute_stream = rx_macro_digital_mute, +}; + +static struct snd_soc_dai_driver rx_macro_dai[] = { + { + .name = "rx_macro_rx1", + .id = RX_MACRO_AIF1_PB, + .playback = { + .stream_name = "RX_MACRO_AIF1 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_rx2", + .id = RX_MACRO_AIF2_PB, + .playback = { + .stream_name = "RX_MACRO_AIF2 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_rx3", + .id = RX_MACRO_AIF3_PB, + .playback = { + .stream_name = "RX_MACRO_AIF3 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_rx4", + .id = RX_MACRO_AIF4_PB, + .playback = { + .stream_name = "RX_MACRO_AIF4 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_echo", + .id = RX_MACRO_AIF_ECHO, + .capture = { + .stream_name = "RX_AIF_ECHO Capture", + .rates = RX_MACRO_ECHO_RATES, + .formats = RX_MACRO_ECHO_FORMATS, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 3, + }, + .ops = &rx_macro_dai_ops, + }, +}; + +static void rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable) +{ + struct regmap *regmap = rx->regmap; + + if (mclk_enable) { + if (rx->rx_mclk_users == 0) { + regcache_mark_dirty(regmap); + regcache_sync(regmap); + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, + CDC_RX_CLK_MCLK_EN_MASK | + CDC_RX_CLK_MCLK2_EN_MASK, + CDC_RX_CLK_MCLK_ENABLE | + CDC_RX_CLK_MCLK2_ENABLE); + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_RX_FS_MCLK_CNT_CLR_MASK, 0x00); + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_RX_FS_MCLK_CNT_EN_MASK, + CDC_RX_FS_MCLK_CNT_ENABLE); + } + rx->rx_mclk_users++; + } else { + if (rx->rx_mclk_users <= 0) { + dev_err(rx->dev, "%s: clock already disabled\n", __func__); + rx->rx_mclk_users = 0; + return; + } + rx->rx_mclk_users--; + if (rx->rx_mclk_users == 0) { + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_RX_FS_MCLK_CNT_EN_MASK, 0x0); + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_RX_FS_MCLK_CNT_CLR_MASK, + CDC_RX_FS_MCLK_CNT_CLR); + regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, + CDC_RX_CLK_MCLK_EN_MASK | + CDC_RX_CLK_MCLK2_EN_MASK, 0x0); + } + } +} + +static inline void rx_macro_enable_clsh_block(struct rx_macro *rx, bool enable) +{ + if ((enable && ++rx->clsh_users == 1) || (!enable && --rx->clsh_users == 0)) + snd_soc_component_update_bits(rx->component, CDC_RX_CLSH_CRC, + CDC_RX_CLSH_CLK_EN_MASK, enable); + if (rx->clsh_users < 0) + rx->clsh_users = 0; +} + +static int rx_macro_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->comp_enabled[comp]; + return 0; +} + +static int rx_macro_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->comp_enabled[comp] = value; + + return 0; +} + +static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->is_ear_mode_on; + return 0; +} + +static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->is_ear_mode_on = (!ucontrol->value.integer.value[0] ? false : true); + return 0; +} + +static int rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->hph_hd2_mode; + return 0; +} + +static int rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->hph_hd2_mode = ucontrol->value.integer.value[0]; + return 0; +} + +static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->hph_pwr_mode; + return 0; +} + +static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->hph_pwr_mode = ucontrol->value.integer.value[0]; + return 0; +} + +static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->is_softclip_on; + + return 0; +} + +static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->is_softclip_on = ucontrol->value.integer.value[0]; + + return 0; +} + +static int rx_macro_aux_hpf_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rx->is_aux_hpf_on; + + return 0; +} + +static int rx_macro_aux_hpf_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + rx->is_aux_hpf_on = ucontrol->value.integer.value[0]; + + return 0; +} + +static const struct snd_kcontrol_new rx_macro_snd_controls[] = { + SOC_SINGLE_S8_TLV("RX_RX0 Digital Volume", + CDC_RX_RX0_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX1 Digital Volume", + CDC_RX_RX1_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX2 Digital Volume", + CDC_RX_RX2_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX0 Mix Digital Volume", + CDC_RX_RX0_RX_VOL_MIX_CTL, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX1 Mix Digital Volume", + CDC_RX_RX1_RX_VOL_MIX_CTL, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX_RX2 Mix Digital Volume", + CDC_RX_RX2_RX_VOL_MIX_CTL, -84, 40, digital_gain), + + SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, RX_MACRO_COMP1, 1, 0, + rx_macro_get_compander, rx_macro_set_compander), + SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0, + rx_macro_get_compander, rx_macro_set_compander), + + SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum, + rx_macro_get_ear_mode, rx_macro_put_ear_mode), + + SOC_ENUM_EXT("RX_HPH HD2 Mode", rx_macro_hph_hd2_mode_enum, + rx_macro_get_hph_hd2_mode, rx_macro_put_hph_hd2_mode), + + SOC_ENUM_EXT("RX_HPH_PWR_MODE", rx_macro_hph_pwr_mode_enum, + rx_macro_get_hph_pwr_mode, rx_macro_put_hph_pwr_mode), + + SOC_SINGLE_EXT("RX_Softclip Enable", SND_SOC_NOPM, 0, 1, 0, + rx_macro_soft_clip_enable_get, + rx_macro_soft_clip_enable_put), + SOC_SINGLE_EXT("AUX_HPF Enable", SND_SOC_NOPM, 0, 1, 0, + rx_macro_aux_hpf_mode_get, + rx_macro_aux_hpf_mode_put), +}; + +static int rx_swrm_clock(struct rx_macro *rx, bool enable) +{ + struct regmap *regmap = rx->regmap; + + if (enable) { + rx_macro_mclk_enable(rx, true); + if (rx->reset_swr) + regmap_update_bits(regmap, + CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x02); + regmap_update_bits(regmap, + CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x01); + if (rx->reset_swr) + regmap_update_bits(regmap, + CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x00); + rx->reset_swr = false; + } else { + regmap_update_bits(regmap, + CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + rx_macro_mclk_enable(rx, false); + } + + return 0; +} + +static int rx_macro_component_probe(struct snd_soc_component *component) +{ + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + snd_soc_component_init_regmap(component, rx->regmap); + + snd_soc_component_update_bits(component, CDC_RX_RX0_RX_PATH_SEC7, + CDC_RX_DSM_OUT_DELAY_SEL_MASK, + CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE); + snd_soc_component_update_bits(component, CDC_RX_RX1_RX_PATH_SEC7, + CDC_RX_DSM_OUT_DELAY_SEL_MASK, + CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE); + snd_soc_component_update_bits(component, CDC_RX_RX2_RX_PATH_SEC7, + CDC_RX_DSM_OUT_DELAY_SEL_MASK, + CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE); + snd_soc_component_update_bits(component, CDC_RX_RX0_RX_PATH_CFG3, + CDC_RX_DC_COEFF_SEL_MASK, + CDC_RX_DC_COEFF_SEL_TWO); + snd_soc_component_update_bits(component, CDC_RX_RX1_RX_PATH_CFG3, + CDC_RX_DC_COEFF_SEL_MASK, + CDC_RX_DC_COEFF_SEL_TWO); + snd_soc_component_update_bits(component, CDC_RX_RX2_RX_PATH_CFG3, + CDC_RX_DC_COEFF_SEL_MASK, + CDC_RX_DC_COEFF_SEL_TWO); + + rx->component = component; + + return 0; +} + +static int swclk_gate_enable(struct clk_hw *hw) +{ + return rx_swrm_clock(to_rx_macro(hw), true); +} + +static void swclk_gate_disable(struct clk_hw *hw) +{ + rx_swrm_clock(to_rx_macro(hw), false); +} + +static int swclk_gate_is_enabled(struct clk_hw *hw) +{ + struct rx_macro *rx = to_rx_macro(hw); + int ret, val; + + regmap_read(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, &val); + ret = val & BIT(0); + + return ret; +} + +static unsigned long swclk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate / 2; +} + +static const struct clk_ops swclk_gate_ops = { + .prepare = swclk_gate_enable, + .unprepare = swclk_gate_disable, + .is_enabled = swclk_gate_is_enabled, + .recalc_rate = swclk_recalc_rate, + +}; + +static struct clk *rx_macro_register_mclk_output(struct rx_macro *rx) +{ + struct device *dev = rx->dev; + struct device_node *np = dev->of_node; + const char *parent_clk_name = NULL; + const char *clk_name = "lpass-rx-mclk"; + struct clk_hw *hw; + struct clk_init_data init; + int ret; + + parent_clk_name = __clk_get_name(rx->clks[2].clk); + + init.name = clk_name; + init.ops = &swclk_gate_ops; + init.flags = 0; + init.parent_names = &parent_clk_name; + init.num_parents = 1; + rx->hw.init = &init; + hw = &rx->hw; + ret = clk_hw_register(rx->dev, hw); + if (ret) + return ERR_PTR(ret); + + of_clk_add_provider(np, of_clk_src_simple_get, hw->clk); + + return NULL; +} + +static const struct snd_soc_component_driver rx_macro_component_drv = { + .name = "RX-MACRO", + .probe = rx_macro_component_probe, + .controls = rx_macro_snd_controls, + .num_controls = ARRAY_SIZE(rx_macro_snd_controls), +}; + +static int rx_macro_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rx_macro *rx; + void __iomem *base; + int ret; + + rx = devm_kzalloc(dev, sizeof(*rx), GFP_KERNEL); + if (!rx) + return -ENOMEM; + + rx->clks[0].id = "macro"; + rx->clks[1].id = "dcodec"; + rx->clks[2].id = "mclk"; + rx->clks[3].id = "npl"; + rx->clks[4].id = "fsgen"; + + ret = devm_clk_bulk_get(dev, RX_NUM_CLKS_MAX, rx->clks); + if (ret) { + dev_err(dev, "Error getting RX Clocks (%d)\n", ret); + return ret; + } + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + rx->regmap = devm_regmap_init_mmio(dev, base, &rx_regmap_config); + + dev_set_drvdata(dev, rx); + + rx->reset_swr = true; + rx->dev = dev; + + /* set MCLK and NPL rates */ + clk_set_rate(rx->clks[2].clk, MCLK_FREQ); + clk_set_rate(rx->clks[3].clk, MCLK_FREQ); + + ret = clk_bulk_prepare_enable(RX_NUM_CLKS_MAX, rx->clks); + if (ret) + return ret; + + rx_macro_register_mclk_output(rx); + rx_swrm_clock(rx, true); + + ret = devm_snd_soc_register_component(dev, &rx_macro_component_drv, + rx_macro_dai, + ARRAY_SIZE(rx_macro_dai)); + if (ret) + goto err; + + rx_swrm_clock(rx, true); + + return ret; +err: + clk_bulk_disable_unprepare(RX_NUM_CLKS_MAX, rx->clks); + return ret; +} + +static int rx_macro_remove(struct platform_device *pdev) +{ + struct rx_macro *rx = dev_get_drvdata(&pdev->dev); + + of_clk_del_provider(pdev->dev.of_node); + clk_bulk_disable_unprepare(RX_NUM_CLKS_MAX, rx->clks); + return 0; +} + +static const struct of_device_id rx_macro_dt_match[] = { + { .compatible = "qcom,sm8250-lpass-rx-macro" }, + { } +}; + +static struct platform_driver rx_macro_driver = { + .driver = { + .name = "rx_macro", + .owner = THIS_MODULE, + .of_match_table = rx_macro_dt_match, + .suppress_bind_attrs = true, + }, + .probe = rx_macro_probe, + .remove = rx_macro_remove, +}; + +module_platform_driver(rx_macro_driver); + +MODULE_DESCRIPTION("RX macro driver"); +MODULE_LICENSE("GPL"); From patchwork Thu Jan 28 14:19:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 372611 Delivered-To: patch@linaro.org Received: by 2002:a02:a60d:0:0:0:0:0 with SMTP id c13csp1298345jam; Thu, 28 Jan 2021 06:23:48 -0800 (PST) X-Google-Smtp-Source: ABdhPJwzyoY6STYVlarSoklBv3i8k45EuPW76yHUM6OZW7twP/sGO3E1dhWSXv7JYy8Zzt3ezG3l X-Received: by 2002:a05:6402:2211:: with SMTP id cq17mr13956092edb.167.1611843827848; Thu, 28 Jan 2021 06:23:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611843827; cv=none; d=google.com; s=arc-20160816; b=DycVIYqrwzbaeX1gu5BzF6Cx3f6ebdoTz7OhIdECqQ3TrQYNwS9n5O9SKy4ohoRb2Y XuHVw4k+ju/Aha5jCP61dj0sHARIL8Y93UKkX+Dq147li2E7vL0lHF3souYyUThh41xq MT8cJlyzWGZrgTHMLRDnCzY7tU7wAKLx4IWEg6VwPyz2AryNCt6k/uFE6s1KyHg1ZNzO BdAz0JUiZTNU92K477Fc4mGFbgQMP1SHxpBtjecMcw+UmS7oENb5SLY4uIOmTuG4Qliy xUVCmBlHtO+FnQepmsCMkF6ruFZISijF0tllbOg57sYteYAqfxJdnUCmzDrClu9a4mQp SknA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=OoqA0k9iYKLPBu83Nxlsy6u/wBHD7mGjL8pZO3qbT2Q=; b=qkIsO5yPgkEkZLZHp9BclGh/YWyFChuLw1ttQYwlDo5qSbhIkGKR/QRhLd4Xt77Cul +LkUuSAaX8RtFPLMulcGMYQuA3h58elsQWDsTacrzH/DcOoVjCsH4bFv9YlqlnqC23zJ xiJlFp0Vz81P7qjZAioNIp4ukOUVe0LhKyqmk8AGHEvO7lVNIk/lHRdVQ4h6qnB/2hOw 8BB4X87WBf7Jwdx41JfVTjr0y++XtsI0wF1bLvDLPnA+VPkhmYRbhbHSFll3MfRgEUUW 3R7eIDnZwv9bmQiQgN1qYQDXuz9rIAeHOfcBRpzehNXbPEronxWjIdKT4QnCQMOfOsSb 4z+g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YiPXeoGs; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h4si2917852edv.124.2021.01.28.06.23.47; Thu, 28 Jan 2021 06:23:47 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YiPXeoGs; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231623AbhA1OW1 (ORCPT + 6 others); Thu, 28 Jan 2021 09:22:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231516AbhA1OV0 (ORCPT ); Thu, 28 Jan 2021 09:21:26 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3EEB5C06178A for ; Thu, 28 Jan 2021 06:20:00 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id v15so5587778wrx.4 for ; Thu, 28 Jan 2021 06:20:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OoqA0k9iYKLPBu83Nxlsy6u/wBHD7mGjL8pZO3qbT2Q=; b=YiPXeoGs2mJJPS1KY4D99RoabtuFIG3FIE4ox0U3AkS5Htx4Q9cfKShkAJVi5hpqVl oqguBZCR+EneewhswS6xlAxbNKLop9LFKD47fLazKadHF+7Ghb9cA7E1Em6yJZEqv4qE tM2zSpwA3Wzt0Ei4K7qJK9JcimoZrGst3iJ3UDhKpc9aT/owvx/9sdkadgxSDgD/EvPl eDnoW7TqjirSA92mteciZgJZPmyyPVjtY0M109Yvk/MAfWV3RcLUqX4TnGWfzdHD5ao7 TxLrNg39Hd1o6tT0LJoqcTHqyot/P+6fIt5SCZfT0zzcQ8nPvO0Ixjp2XoAp0KDF7GtE XN+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OoqA0k9iYKLPBu83Nxlsy6u/wBHD7mGjL8pZO3qbT2Q=; b=UG9L0882tuF2JuSKGZ8cu1BQlYOcSfp+4zZ2Lz9dYRUhCRGwYqqDm5yFxEJLkiEVHt InpJOqidOhpoi+5AVK/JAlctidKV3DDuME2NPC8ZPBohei9ZIAjrvfhniQfkMcaq/aK9 /qxPT+bTZWYzQ6ErlDaQpyOElpoQZPjlFOMmLyOw5V0A2TSnoVa956zdHLZAx7kS30tO dnAConeoL1UjnF3vVMuHrdT6vQ/abg8LwawpyJJBiDOasp0yvsNFxgtgOd+CehMOJbxA CmU+e3GTQYswPM5M4/wmoXrCJqSXsDTzjVDH/QKXCzHQjgsHlSkDgNKL2MaIKf3MMZmY Q+8w== X-Gm-Message-State: AOAM532sx/dk+pETGkTO/sJHGpQIJNraKTuYB9dpcI0c22+o22iNbp6t pZG8ahkdQ/pMqhc4YzwYmj84fw== X-Received: by 2002:a5d:6509:: with SMTP id x9mr16795137wru.229.1611843598628; Thu, 28 Jan 2021 06:19:58 -0800 (PST) Received: from srini-hackbox.lan (cpc86377-aztw32-2-0-cust226.18-1.cable.virginm.net. [92.233.226.227]) by smtp.gmail.com with ESMTPSA id d9sm7257096wrq.74.2021.01.28.06.19.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 06:19:57 -0800 (PST) From: Srinivas Kandagatla To: broonie@kernel.org Cc: perex@perex.cz, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, devicetree@vger.kernel.org, robh+dt@kernel.org, Srinivas Kandagatla Subject: [PATCH 3/7] ASoC: codec: lpass-rx-macro: add dapm widgets and route Date: Thu, 28 Jan 2021 14:19:25 +0000 Message-Id: <20210128141929.26573-4-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> References: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds dapm widgets and routes on this codec Signed-off-by: Srinivas Kandagatla --- sound/soc/codecs/lpass-rx-macro.c | 1339 +++++++++++++++++++++++++++++ 1 file changed, 1339 insertions(+) -- 2.21.0 diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 30f4b7b3189c..5ceb81e8f1d4 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -589,6 +589,56 @@ struct rx_macro { static struct snd_soc_dai_driver rx_macro_dai[]; static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); +static const char * const rx_int_mix_mux_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5" +}; + +static const char * const rx_prim_mix_text[] = { + "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2", + "RX3", "RX4", "RX5" +}; + +static const char * const rx_sidetone_mix_text[] = { + "ZERO", "SRC0", "SRC1", "SRC_SUM" +}; + +static const char * const iir_inp_mux_text[] = { + "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", + "RX0", "RX1", "RX2", "RX3", "RX4", "RX5" +}; + +static const char * const rx_int_dem_inp_mux_text[] = { + "NORMAL_DSM_OUT", "CLSH_DSM_OUT", +}; + +static const char * const rx_int0_1_interp_mux_text[] = { + "ZERO", "RX INT0_1 MIX1", +}; + +static const char * const rx_int1_1_interp_mux_text[] = { + "ZERO", "RX INT1_1 MIX1", +}; + +static const char * const rx_int2_1_interp_mux_text[] = { + "ZERO", "RX INT2_1 MIX1", +}; + +static const char * const rx_int0_2_interp_mux_text[] = { + "ZERO", "RX INT0_2 MUX", +}; + +static const char * const rx_int1_2_interp_mux_text[] = { + "ZERO", "RX INT1_2 MUX", +}; + +static const char * const rx_int2_2_interp_mux_text[] = { + "ZERO", "RX INT2_2 MUX", +}; + +static const char *const rx_macro_mux_text[] = { + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" +}; + static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"}; static const struct soc_enum rx_macro_ear_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text); @@ -601,6 +651,154 @@ static const char *const rx_macro_hph_pwr_mode_text[] = {"ULP", "LOHIFI"}; static const struct soc_enum rx_macro_hph_pwr_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text); +static SOC_ENUM_SINGLE_DECL(rx_int0_2_enum, CDC_RX_INP_MUX_RX_INT0_CFG1, 0, + rx_int_mix_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_2_enum, CDC_RX_INP_MUX_RX_INT1_CFG1, 0, + rx_int_mix_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_2_enum, CDC_RX_INP_MUX_RX_INT2_CFG1, 0, + rx_int_mix_mux_text); +static const struct snd_kcontrol_new rx_int0_2_mux = SOC_DAPM_ENUM("rx_int0_2", rx_int0_2_enum); +static const struct snd_kcontrol_new rx_int1_2_mux = SOC_DAPM_ENUM("rx_int1_2", rx_int1_2_enum); +static const struct snd_kcontrol_new rx_int2_2_mux = SOC_DAPM_ENUM("rx_int2_2", rx_int2_2_enum); + +static SOC_ENUM_SINGLE_DECL(rx_int0_1_mix_inp0_enum, CDC_RX_INP_MUX_RX_INT0_CFG0, 0, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int0_1_mix_inp1_enum, CDC_RX_INP_MUX_RX_INT0_CFG0, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int0_1_mix_inp2_enum, CDC_RX_INP_MUX_RX_INT0_CFG1, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_1_mix_inp0_enum, CDC_RX_INP_MUX_RX_INT1_CFG0, 0, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_1_mix_inp1_enum, CDC_RX_INP_MUX_RX_INT1_CFG0, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_1_mix_inp2_enum, CDC_RX_INP_MUX_RX_INT1_CFG1, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_1_mix_inp0_enum, CDC_RX_INP_MUX_RX_INT2_CFG0, 0, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_1_mix_inp1_enum, CDC_RX_INP_MUX_RX_INT2_CFG0, 4, + rx_prim_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_1_mix_inp2_enum, CDC_RX_INP_MUX_RX_INT2_CFG1, 4, + rx_prim_mix_text); +static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux = + SOC_DAPM_ENUM("rx_int0_1_mix_inp0", rx_int0_1_mix_inp0_enum); +static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux = + SOC_DAPM_ENUM("rx_int0_1_mix_inp1", rx_int0_1_mix_inp1_enum); +static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux = + SOC_DAPM_ENUM("rx_int0_1_mix_inp2", rx_int0_1_mix_inp2_enum); +static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux = + SOC_DAPM_ENUM("rx_int1_1_mix_inp0", rx_int1_1_mix_inp0_enum); +static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux = + SOC_DAPM_ENUM("rx_int1_1_mix_inp1", rx_int1_1_mix_inp1_enum); +static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux = + SOC_DAPM_ENUM("rx_int1_1_mix_inp2", rx_int1_1_mix_inp2_enum); +static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux = + SOC_DAPM_ENUM("rx_int2_1_mix_inp0", rx_int2_1_mix_inp0_enum); +static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux = + SOC_DAPM_ENUM("rx_int2_1_mix_inp1", rx_int2_1_mix_inp1_enum); +static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux = + SOC_DAPM_ENUM("rx_int2_1_mix_inp2", rx_int2_1_mix_inp2_enum); + +static SOC_ENUM_SINGLE_DECL(rx_int0_mix2_inp_enum, CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, + rx_sidetone_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_mix2_inp_enum, CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, + rx_sidetone_mix_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_mix2_inp_enum, CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, + rx_sidetone_mix_text); +static const struct snd_kcontrol_new rx_int0_mix2_inp_mux = + SOC_DAPM_ENUM("rx_int0_mix2_inp", rx_int0_mix2_inp_enum); +static const struct snd_kcontrol_new rx_int1_mix2_inp_mux = + SOC_DAPM_ENUM("rx_int1_mix2_inp", rx_int1_mix2_inp_enum); +static const struct snd_kcontrol_new rx_int2_mix2_inp_mux = + SOC_DAPM_ENUM("rx_int2_mix2_inp", rx_int2_mix2_inp_enum); + +static SOC_ENUM_SINGLE_DECL(iir0_inp0_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir0_inp1_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir0_inp2_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir0_inp3_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir1_inp0_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir1_inp1_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir1_inp2_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0, + iir_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(iir1_inp3_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0, + iir_inp_mux_text); +static const struct snd_kcontrol_new iir0_inp0_mux = SOC_DAPM_ENUM("iir0_inp0", iir0_inp0_enum); +static const struct snd_kcontrol_new iir0_inp1_mux = SOC_DAPM_ENUM("iir0_inp1", iir0_inp1_enum); +static const struct snd_kcontrol_new iir0_inp2_mux = SOC_DAPM_ENUM("iir0_inp2", iir0_inp2_enum); +static const struct snd_kcontrol_new iir0_inp3_mux = SOC_DAPM_ENUM("iir0_inp3", iir0_inp3_enum); +static const struct snd_kcontrol_new iir1_inp0_mux = SOC_DAPM_ENUM("iir1_inp0", iir1_inp0_enum); +static const struct snd_kcontrol_new iir1_inp1_mux = SOC_DAPM_ENUM("iir1_inp1", iir1_inp1_enum); +static const struct snd_kcontrol_new iir1_inp2_mux = SOC_DAPM_ENUM("iir1_inp2", iir1_inp2_enum); +static const struct snd_kcontrol_new iir1_inp3_mux = SOC_DAPM_ENUM("iir1_inp3", iir1_inp3_enum); + +static SOC_ENUM_SINGLE_DECL(rx_int0_1_interp_enum, SND_SOC_NOPM, 0, + rx_int0_1_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_1_interp_enum, SND_SOC_NOPM, 0, + rx_int1_1_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_1_interp_enum, SND_SOC_NOPM, 0, + rx_int2_1_interp_mux_text); +static const struct snd_kcontrol_new rx_int0_1_interp_mux = + SOC_DAPM_ENUM("rx_int0_1_interp", rx_int0_1_interp_enum); +static const struct snd_kcontrol_new rx_int1_1_interp_mux = + SOC_DAPM_ENUM("rx_int1_1_interp", rx_int1_1_interp_enum); +static const struct snd_kcontrol_new rx_int2_1_interp_mux = + SOC_DAPM_ENUM("rx_int2_1_interp", rx_int2_1_interp_enum); + +static SOC_ENUM_SINGLE_DECL(rx_int0_2_interp_enum, SND_SOC_NOPM, 0, + rx_int0_2_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_2_interp_enum, SND_SOC_NOPM, 0, + rx_int1_2_interp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int2_2_interp_enum, SND_SOC_NOPM, 0, + rx_int2_2_interp_mux_text); +static const struct snd_kcontrol_new rx_int0_2_interp_mux = + SOC_DAPM_ENUM("rx_int0_2_interp", rx_int0_2_interp_enum); +static const struct snd_kcontrol_new rx_int1_2_interp_mux = + SOC_DAPM_ENUM("rx_int1_2_interp", rx_int1_2_interp_enum); +static const struct snd_kcontrol_new rx_int2_2_interp_mux = + SOC_DAPM_ENUM("rx_int2_2_interp", rx_int2_2_interp_enum); + +static SOC_ENUM_SINGLE_DECL(rx_int0_dem_inp_enum, CDC_RX_RX0_RX_PATH_CFG1, 0, + rx_int_dem_inp_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_int1_dem_inp_enum, CDC_RX_RX1_RX_PATH_CFG1, 0, + rx_int_dem_inp_mux_text); + +static SOC_ENUM_SINGLE_DECL(rx_macro_rx0_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx1_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx2_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx3_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx4_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); +static SOC_ENUM_SINGLE_DECL(rx_macro_rx5_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); + +static const char * const rx_echo_mux_text[] = { + "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2" +}; + +static const struct soc_enum rx_mix_tx2_mux_enum = + SOC_ENUM_SINGLE(CDC_RX_INP_MUX_RX_MIX_CFG5, 0, 4, + rx_echo_mux_text); + +static const struct snd_kcontrol_new rx_mix_tx2_mux = + SOC_DAPM_ENUM("RX MIX TX2_MUX Mux", rx_mix_tx2_mux_enum); + +static const struct soc_enum rx_mix_tx1_mux_enum = + SOC_ENUM_SINGLE(CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 4, + rx_echo_mux_text); + +static const struct snd_kcontrol_new rx_mix_tx1_mux = + SOC_DAPM_ENUM("RX MIX TX1_MUX Mux", rx_mix_tx1_mux_enum); + +static const struct soc_enum rx_mix_tx0_mux_enum = + SOC_ENUM_SINGLE(CDC_RX_INP_MUX_RX_MIX_CFG4, 4, 4, + rx_echo_mux_text); + +static const struct snd_kcontrol_new rx_mix_tx0_mux = + SOC_DAPM_ENUM("RX MIX TX0_MUX Mux", rx_mix_tx0_mux_enum); + static const struct reg_default rx_defaults[] = { /* RX Macro */ { CDC_RX_TOP_TOP_CFG0, 0x00 }, @@ -1268,6 +1466,41 @@ static const struct regmap_config rx_regmap_config = { .readable_reg = rx_is_readable_register, }; +static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned short look_ahead_dly_reg; + unsigned int val; + + val = ucontrol->value.enumerated.item[0]; + + if (e->reg == CDC_RX_RX0_RX_PATH_CFG1) + look_ahead_dly_reg = CDC_RX_RX0_RX_PATH_CFG0; + else if (e->reg == CDC_RX_RX1_RX_PATH_CFG1) + look_ahead_dly_reg = CDC_RX_RX1_RX_PATH_CFG0; + + /* Set Look Ahead Delay */ + if (val) + snd_soc_component_update_bits(component, look_ahead_dly_reg, + CDC_RX_DLY_ZN_EN_MASK, + CDC_RX_DLY_ZN_ENABLE); + else + snd_soc_component_update_bits(component, look_ahead_dly_reg, + CDC_RX_DLY_ZN_EN_MASK, 0); + /* Set DEM INP Select */ + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static const struct snd_kcontrol_new rx_int0_dem_inp_mux = + SOC_DAPM_ENUM_EXT("rx_int0_dem_inp", rx_int0_dem_inp_enum, + snd_soc_dapm_get_enum_double, rx_macro_int_dem_inp_mux_put); +static const struct snd_kcontrol_new rx_int1_dem_inp_mux = + SOC_DAPM_ENUM_EXT("rx_int1_dem_inp", rx_int1_dem_inp_enum, + snd_soc_dapm_get_enum_double, rx_macro_int_dem_inp_mux_put); + static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, int rate_reg_val, u32 sample_rate) { @@ -1626,6 +1859,282 @@ static void rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable) } } +static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + int ret = 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_mclk_enable(rx, true); + break; + case SND_SOC_DAPM_POST_PMD: + rx_macro_mclk_enable(rx, false); + break; + default: + dev_err(component->dev, "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + +static int rx_macro_enable_interp_clk(struct snd_soc_component *component, + int event, int interp_idx); +static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + u16 gain_reg, mix_reg; + + gain_reg = CDC_RX_RXn_RX_VOL_MIX_CTL(w->shift); + mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(w->shift); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_enable_interp_clk(component, event, w->shift); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_write(component, gain_reg, + snd_soc_component_read(component, gain_reg)); + break; + case SND_SOC_DAPM_POST_PMD: + /* Clk Disable */ + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_RXn_MIX_CLK_EN_MASK, 0x00); + rx_macro_enable_interp_clk(component, event, w->shift); + /* Reset enable and disable */ + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_RXn_MIX_RESET_MASK, + CDC_RX_RXn_MIX_RESET); + snd_soc_component_update_bits(component, mix_reg, + CDC_RX_RXn_MIX_RESET_MASK, 0x00); + break; + } + + return 0; +} + +static bool rx_macro_adie_lb(struct snd_soc_component *component, + int interp_idx) +{ + u16 int_mux_cfg0, int_mux_cfg1; + u8 int_n_inp0, int_n_inp1, int_n_inp2; + + int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; + int_mux_cfg1 = int_mux_cfg0 + 4; + + int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_RX_INTX_1_MIX_INP0_SEL_MASK); + int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0, + CDC_RX_INTX_1_MIX_INP1_SEL_MASK); + int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1, + CDC_RX_INTX_1_MIX_INP2_SEL_MASK); + + if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || + int_n_inp0 == INTn_1_INP_SEL_DEC1 || + int_n_inp0 == INTn_1_INP_SEL_IIR0 || + int_n_inp0 == INTn_1_INP_SEL_IIR1) + return true; + + if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || + int_n_inp1 == INTn_1_INP_SEL_DEC1 || + int_n_inp1 == INTn_1_INP_SEL_IIR0 || + int_n_inp1 == INTn_1_INP_SEL_IIR1) + return true; + + if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || + int_n_inp2 == INTn_1_INP_SEL_DEC1 || + int_n_inp2 == INTn_1_INP_SEL_IIR0 || + int_n_inp2 == INTn_1_INP_SEL_IIR1) + return true; + + return false; +} + +static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + u16 gain_reg, reg; + + reg = CDC_RX_RXn_RX_PATH_CTL(w->shift); + gain_reg = CDC_RX_RXn_RX_VOL_CTL(w->shift); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_enable_interp_clk(component, event, w->shift); + if (rx_macro_adie_lb(component, w->shift)) + snd_soc_component_update_bits(component, reg, + CDC_RX_PATH_CLK_EN_MASK, + CDC_RX_PATH_CLK_ENABLE); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_write(component, gain_reg, + snd_soc_component_read(component, gain_reg)); + break; + case SND_SOC_DAPM_POST_PMD: + rx_macro_enable_interp_clk(component, event, w->shift); + break; + } + + return 0; +} + +static int rx_macro_config_compander(struct snd_soc_component *component, + struct rx_macro *rx, + int comp, int event) +{ + u8 pcm_rate, val; + + /* AUX does not have compander */ + if (comp == INTERP_AUX) + return 0; + + pcm_rate = snd_soc_component_read(component, CDC_RX_RXn_RX_PATH_CTL(comp)) & 0x0F; + if (pcm_rate < 0x06) + val = 0x03; + else if (pcm_rate < 0x08) + val = 0x01; + else if (pcm_rate < 0x0B) + val = 0x02; + else + val = 0x00; + + if (SND_SOC_DAPM_EVENT_ON(event)) + snd_soc_component_update_bits(component, CDC_RX_RXn_RX_PATH_CFG3(comp), + CDC_RX_DC_COEFF_SEL_MASK, val); + + if (SND_SOC_DAPM_EVENT_OFF(event)) + snd_soc_component_update_bits(component, CDC_RX_RXn_RX_PATH_CFG3(comp), + CDC_RX_DC_COEFF_SEL_MASK, 0x3); + if (!rx->comp_enabled[comp]) + return 0; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_CLK_EN_MASK, 0x1); + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_SOFT_RST_MASK, 0x1); + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_SOFT_RST_MASK, 0x0); + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG0(comp), + CDC_RX_RXn_COMP_EN_MASK, 0x1); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_HALT_MASK, 0x1); + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG0(comp), + CDC_RX_RXn_COMP_EN_MASK, 0x0); + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_CLK_EN_MASK, 0x0); + snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), + CDC_RX_COMPANDERn_HALT_MASK, 0x0); + } + + return 0; +} + +static int rx_macro_load_compander_coeff(struct snd_soc_component *component, + struct rx_macro *rx, + int comp, int event) +{ + u16 comp_coeff_lsb_reg, comp_coeff_msb_reg; + int i; + int hph_pwr_mode = HPH_LOHIFI; + + if (!rx->comp_enabled[comp]) + return 0; + + if (comp == INTERP_HPHL) { + comp_coeff_lsb_reg = CDC_RX_TOP_HPHL_COMP_WR_LSB; + comp_coeff_msb_reg = CDC_RX_TOP_HPHL_COMP_WR_MSB; + } else if (comp == INTERP_HPHR) { + comp_coeff_lsb_reg = CDC_RX_TOP_HPHR_COMP_WR_LSB; + comp_coeff_msb_reg = CDC_RX_TOP_HPHR_COMP_WR_MSB; + } else { + /* compander coefficients are loaded only for hph path */ + return 0; + } + + hph_pwr_mode = rx->hph_pwr_mode; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Load Compander Coeff */ + for (i = 0; i < COMP_MAX_COEFF; i++) { + snd_soc_component_write(component, comp_coeff_lsb_reg, + comp_coeff_table[hph_pwr_mode][i].lsb); + snd_soc_component_write(component, comp_coeff_msb_reg, + comp_coeff_table[hph_pwr_mode][i].msb); + } + } + + return 0; +} + +static void rx_macro_enable_softclip_clk(struct snd_soc_component *component, + struct rx_macro *rx, bool enable) +{ + if (enable) { + if (rx->softclip_clk_users == 0) + snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_CRC, + CDC_RX_SOFTCLIP_CLK_EN_MASK, 1); + rx->softclip_clk_users++; + } else { + rx->softclip_clk_users--; + if (rx->softclip_clk_users == 0) + snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_CRC, + CDC_RX_SOFTCLIP_CLK_EN_MASK, 0); + } +} + +static int rx_macro_config_softclip(struct snd_soc_component *component, + struct rx_macro *rx, int event) +{ + + if (!rx->is_softclip_on) + return 0; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Softclip clock */ + rx_macro_enable_softclip_clk(component, rx, true); + /* Enable Softclip control */ + snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, + CDC_RX_SOFTCLIP_EN_MASK, 0x01); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, + CDC_RX_SOFTCLIP_EN_MASK, 0x0); + rx_macro_enable_softclip_clk(component, rx, false); + } + + return 0; +} + +static int rx_macro_config_aux_hpf(struct snd_soc_component *component, + struct rx_macro *rx, int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Update Aux HPF control */ + if (!rx->is_aux_hpf_on) + snd_soc_component_update_bits(component, + CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x00); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + /* Reset to default (HPF=ON) */ + snd_soc_component_update_bits(component, + CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x04); + } + + return 0; +} + static inline void rx_macro_enable_clsh_block(struct rx_macro *rx, bool enable) { if ((enable && ++rx->clsh_users == 1) || (!enable && --rx->clsh_users == 0)) @@ -1635,6 +2144,106 @@ static inline void rx_macro_enable_clsh_block(struct rx_macro *rx, bool enable) rx->clsh_users = 0; } +static int rx_macro_config_classh(struct snd_soc_component *component, + struct rx_macro *rx, + int interp_n, int event) +{ + if (SND_SOC_DAPM_EVENT_OFF(event)) { + rx_macro_enable_clsh_block(rx, false); + return 0; + } + + if (!SND_SOC_DAPM_EVENT_ON(event)) + return 0; + + rx_macro_enable_clsh_block(rx, true); + if (interp_n == INTERP_HPHL || + interp_n == INTERP_HPHR) { + /* + * These K1 values depend on the Headphone Impedance + * For now it is assumed to be 16 ohm + */ + snd_soc_component_write(component, CDC_RX_CLSH_K1_LSB, 0xc0); + snd_soc_component_write_field(component, CDC_RX_CLSH_K1_MSB, + CDC_RX_CLSH_K1_MSB_COEFF_MASK, 0); + } + switch (interp_n) { + case INTERP_HPHL: + if (rx->is_ear_mode_on) + snd_soc_component_update_bits(component, + CDC_RX_CLSH_HPH_V_PA, + CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x39); + else + snd_soc_component_update_bits(component, + CDC_RX_CLSH_HPH_V_PA, + CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x1c); + snd_soc_component_update_bits(component, + CDC_RX_CLSH_DECAY_CTRL, + CDC_RX_CLSH_DECAY_RATE_MASK, 0x0); + snd_soc_component_write_field(component, + CDC_RX_RX0_RX_PATH_CFG0, + CDC_RX_RXn_CLSH_EN_MASK, 0x1); + break; + case INTERP_HPHR: + if (rx->is_ear_mode_on) + snd_soc_component_update_bits(component, + CDC_RX_CLSH_HPH_V_PA, + CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x39); + else + snd_soc_component_update_bits(component, + CDC_RX_CLSH_HPH_V_PA, + CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x1c); + snd_soc_component_update_bits(component, + CDC_RX_CLSH_DECAY_CTRL, + CDC_RX_CLSH_DECAY_RATE_MASK, 0x0); + snd_soc_component_update_bits(component, + CDC_RX_RX1_RX_PATH_CFG0, + CDC_RX_RXn_CLSH_EN_MASK, 0x1); + break; + case INTERP_AUX: + snd_soc_component_update_bits(component, + CDC_RX_RX2_RX_PATH_CFG0, + CDC_RX_RX2_DLY_Z_EN_MASK, 1); + snd_soc_component_write_field(component, + CDC_RX_RX2_RX_PATH_CFG0, + CDC_RX_RX2_CLSH_EN_MASK, 1); + break; + } + + return 0; +} + +static void rx_macro_hd2_control(struct snd_soc_component *component, + u16 interp_idx, int event) +{ + u16 hd2_scale_reg, hd2_enable_reg; + + switch (interp_idx) { + case INTERP_HPHL: + hd2_scale_reg = CDC_RX_RX0_RX_PATH_SEC3; + hd2_enable_reg = CDC_RX_RX0_RX_PATH_CFG0; + break; + case INTERP_HPHR: + hd2_scale_reg = CDC_RX_RX1_RX_PATH_SEC3; + hd2_enable_reg = CDC_RX_RX1_RX_PATH_CFG0; + break; + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_component_update_bits(component, hd2_scale_reg, + CDC_RX_RXn_HD2_ALPHA_MASK, 0x14); + snd_soc_component_write_field(component, hd2_enable_reg, + CDC_RX_RXn_HD2_EN_MASK, 1); + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_write_field(component, hd2_enable_reg, + CDC_RX_RXn_HD2_EN_MASK, 0); + snd_soc_component_update_bits(component, hd2_scale_reg, + CDC_RX_RXn_HD2_ALPHA_MASK, 0x0); + } +} + static int rx_macro_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1660,6 +2269,91 @@ static int rx_macro_set_compander(struct snd_kcontrol *kcontrol, return 0; } +static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = + rx->rx_port_value[widget->shift]; + return 0; +} + +static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + u32 rx_port_value = ucontrol->value.integer.value[0]; + u32 aif_rst; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + aif_rst = rx->rx_port_value[widget->shift]; + if (!rx_port_value) { + if (aif_rst == 0) { + dev_err(component->dev, "%s:AIF reset already\n", __func__); + return 0; + } + if (aif_rst > RX_MACRO_AIF4_PB) { + dev_err(component->dev, "%s: Invalid AIF reset\n", __func__); + return 0; + } + } + rx->rx_port_value[widget->shift] = rx_port_value; + + switch (rx_port_value) { + case 0: + if (rx->active_ch_cnt[aif_rst]) { + clear_bit(widget->shift, + &rx->active_ch_mask[aif_rst]); + rx->active_ch_cnt[aif_rst]--; + } + break; + case 1: + case 2: + case 3: + case 4: + set_bit(widget->shift, + &rx->active_ch_mask[rx_port_value]); + rx->active_ch_cnt[rx_port_value]++; + break; + default: + dev_err(component->dev, + "%s:Invalid AIF_ID for RX_MACRO MUX %d\n", + __func__, rx_port_value); + goto err; + } + + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + rx_port_value, e, update); + return 0; +err: + return -EINVAL; +} + +static const struct snd_kcontrol_new rx_macro_rx0_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx0", rx_macro_rx0_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx1_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx1", rx_macro_rx1_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx2_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx2", rx_macro_rx2_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx3_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx3", rx_macro_rx3_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx4_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx4", rx_macro_rx4_enum, + rx_macro_mux_get, rx_macro_mux_put); +static const struct snd_kcontrol_new rx_macro_rx5_mux = + SOC_DAPM_ENUM_EXT("rx_macro_rx5", rx_macro_rx5_enum, + rx_macro_mux_get, rx_macro_mux_put); + static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1764,6 +2458,153 @@ static int rx_macro_aux_hpf_mode_put(struct snd_kcontrol *kcontrol, return 0; } +static void rx_macro_hphdelay_lutbypass(struct snd_soc_component *component, + struct rx_macro *rx, + u16 interp_idx, int event) +{ + u16 hph_lut_bypass_reg; + u16 hph_comp_ctrl7; + + switch (interp_idx) { + case INTERP_HPHL: + hph_lut_bypass_reg = CDC_RX_TOP_HPHL_COMP_LUT; + hph_comp_ctrl7 = CDC_RX_COMPANDER0_CTL7; + break; + case INTERP_HPHR: + hph_lut_bypass_reg = CDC_RX_TOP_HPHR_COMP_LUT; + hph_comp_ctrl7 = CDC_RX_COMPANDER1_CTL7; + break; + default: + break; + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { + if (interp_idx == INTERP_HPHL) { + if (rx->is_ear_mode_on) + snd_soc_component_write_field(component, + CDC_RX_RX0_RX_PATH_CFG1, + CDC_RX_RX0_HPH_L_EAR_SEL_MASK, 0x1); + else + snd_soc_component_write_field(component, + hph_lut_bypass_reg, + CDC_RX_TOP_HPH_LUT_BYPASS_MASK, 1); + } else { + snd_soc_component_write_field(component, hph_lut_bypass_reg, + CDC_RX_TOP_HPH_LUT_BYPASS_MASK, 1); + } + if (rx->hph_pwr_mode) + snd_soc_component_write_field(component, hph_comp_ctrl7, + CDC_RX_COMPANDER1_HPH_LOW_PWR_MODE_MASK, 0x0); + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_write_field(component, + CDC_RX_RX0_RX_PATH_CFG1, + CDC_RX_RX0_HPH_L_EAR_SEL_MASK, 0x0); + snd_soc_component_update_bits(component, hph_lut_bypass_reg, + CDC_RX_TOP_HPH_LUT_BYPASS_MASK, 0); + snd_soc_component_write_field(component, hph_comp_ctrl7, + CDC_RX_COMPANDER1_HPH_LOW_PWR_MODE_MASK, 0x1); + } +} + +static int rx_macro_enable_interp_clk(struct snd_soc_component *component, + int event, int interp_idx) +{ + u16 main_reg, dsm_reg, rx_cfg2_reg; + struct rx_macro *rx = snd_soc_component_get_drvdata(component); + + main_reg = CDC_RX_RXn_RX_PATH_CTL(interp_idx); + dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(interp_idx); + if (interp_idx == INTERP_AUX) + dsm_reg = CDC_RX_RX2_RX_PATH_DSM_CTL; + rx_cfg2_reg = CDC_RX_RXn_RX_PATH_CFG2(interp_idx); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (rx->main_clk_users[interp_idx] == 0) { + /* Main path PGA mute enable */ + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_PGA_MUTE_MASK, 0x1); + snd_soc_component_write_field(component, dsm_reg, + CDC_RX_RXn_DSM_CLK_EN_MASK, 0x1); + snd_soc_component_update_bits(component, rx_cfg2_reg, + CDC_RX_RXn_HPF_CUT_FREQ_MASK, 0x03); + rx_macro_load_compander_coeff(component, rx, interp_idx, event); + if (rx->hph_hd2_mode) + rx_macro_hd2_control(component, interp_idx, event); + rx_macro_hphdelay_lutbypass(component, rx, interp_idx, event); + rx_macro_config_compander(component, rx, interp_idx, event); + if (interp_idx == INTERP_AUX) { + rx_macro_config_softclip(component, rx, event); + rx_macro_config_aux_hpf(component, rx, event); + } + rx_macro_config_classh(component, rx, interp_idx, event); + } + rx->main_clk_users[interp_idx]++; + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + rx->main_clk_users[interp_idx]--; + if (rx->main_clk_users[interp_idx] <= 0) { + rx->main_clk_users[interp_idx] = 0; + /* Main path PGA mute enable */ + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_PGA_MUTE_MASK, 0x1); + /* Clk Disable */ + snd_soc_component_write_field(component, dsm_reg, + CDC_RX_RXn_DSM_CLK_EN_MASK, 0); + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_CLK_EN_MASK, 0); + /* Reset enable and disable */ + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_RESET_EN_MASK, 1); + snd_soc_component_write_field(component, main_reg, + CDC_RX_PATH_RESET_EN_MASK, 0); + /* Reset rate to 48K*/ + snd_soc_component_update_bits(component, main_reg, + CDC_RX_PATH_PCM_RATE_MASK, + 0x04); + snd_soc_component_update_bits(component, rx_cfg2_reg, + CDC_RX_RXn_HPF_CUT_FREQ_MASK, 0x00); + rx_macro_config_classh(component, rx, interp_idx, event); + rx_macro_config_compander(component, rx, interp_idx, event); + if (interp_idx == INTERP_AUX) { + rx_macro_config_softclip(component, rx, event); + rx_macro_config_aux_hpf(component, rx, event); + } + rx_macro_hphdelay_lutbypass(component, rx, interp_idx, event); + if (rx->hph_hd2_mode) + rx_macro_hd2_control(component, interp_idx, event); + } + } + + return rx->main_clk_users[interp_idx]; +} + +static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_enable_interp_clk(component, event, w->shift); + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG1(w->shift), + CDC_RX_RXn_SIDETONE_EN_MASK, 1); + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CTL(w->shift), + CDC_RX_PATH_CLK_EN_MASK, 1); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG1(w->shift), + CDC_RX_RXn_SIDETONE_EN_MASK, 0); + rx_macro_enable_interp_clk(component, event, w->shift); + break; + default: + break; + }; + return 0; +} + static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_S8_TLV("RX_RX0 Digital Volume", CDC_RX_RX0_RX_VOL_CTL, @@ -1803,6 +2644,500 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { rx_macro_aux_hpf_mode_put), }; +static int rx_macro_enable_echo(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + u16 val, ec_hq_reg; + int ec_tx; + + val = snd_soc_component_read(component, + CDC_RX_INP_MUX_RX_MIX_CFG4); + if (!(strcmp(w->name, "RX MIX TX0 MUX"))) + ec_tx = ((val & 0xf0) >> 0x4) - 1; + else if (!(strcmp(w->name, "RX MIX TX1 MUX"))) + ec_tx = (val & 0x0f) - 1; + + val = snd_soc_component_read(component, + CDC_RX_INP_MUX_RX_MIX_CFG5); + if (!(strcmp(w->name, "RX MIX TX2 MUX"))) + ec_tx = (val & 0x0f) - 1; + + if (ec_tx < 0 || (ec_tx >= RX_MACRO_EC_MUX_MAX)) { + dev_err(component->dev, "%s: EC mix control not set correctly\n", + __func__); + return -EINVAL; + } + ec_hq_reg = CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL + + 0x40 * ec_tx; + snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01); + ec_hq_reg = CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 + + 0x40 * ec_tx; + /* default set to 48k */ + snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08); + + return 0; +} + +static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("RX AIF1 PB", "RX_MACRO_AIF1 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("RX AIF2 PB", "RX_MACRO_AIF2 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("RX AIF3 PB", "RX_MACRO_AIF3 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("RX AIF4 PB", "RX_MACRO_AIF4 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MUX("RX_MACRO RX0 MUX", SND_SOC_NOPM, RX_MACRO_RX0, 0, + &rx_macro_rx0_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX1 MUX", SND_SOC_NOPM, RX_MACRO_RX1, 0, + &rx_macro_rx1_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX2 MUX", SND_SOC_NOPM, RX_MACRO_RX2, 0, + &rx_macro_rx2_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX3 MUX", SND_SOC_NOPM, RX_MACRO_RX3, 0, + &rx_macro_rx3_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX4 MUX", SND_SOC_NOPM, RX_MACRO_RX4, 0, + &rx_macro_rx4_mux), + SND_SOC_DAPM_MUX("RX_MACRO RX5 MUX", SND_SOC_NOPM, RX_MACRO_RX5, 0, + &rx_macro_rx5_mux), + + SND_SOC_DAPM_MIXER("RX_RX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX5", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux), + SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux), + SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux), + SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux), + SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux), + SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux), + SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux), + SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux), + + SND_SOC_DAPM_MUX_E("RX MIX TX0 MUX", SND_SOC_NOPM, + RX_MACRO_EC0_MUX, 0, + &rx_mix_tx0_mux, rx_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX MIX TX1 MUX", SND_SOC_NOPM, + RX_MACRO_EC1_MUX, 0, + &rx_mix_tx1_mux, rx_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX MIX TX2 MUX", SND_SOC_NOPM, + RX_MACRO_EC2_MUX, 0, + &rx_mix_tx2_mux, rx_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("SRC0", CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SRC1", CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + + SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0, + &rx_int0_dem_inp_mux), + SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0, + &rx_int1_dem_inp_mux), + + SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int0_2_mux, rx_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int1_2_mux, rx_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0, + &rx_int2_2_mux, rx_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, &rx_int0_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_int0_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, &rx_int0_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, &rx_int1_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_int1_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, &rx_int1_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, &rx_int2_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_int2_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, &rx_int2_1_mix_inp2_mux), + + SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int0_1_interp_mux, rx_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int1_1_interp_mux, rx_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0, + &rx_int2_1_interp_mux, rx_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("RX INT0_2 INTERP", SND_SOC_NOPM, 0, 0, + &rx_int0_2_interp_mux), + SND_SOC_DAPM_MUX("RX INT1_2 INTERP", SND_SOC_NOPM, 0, 0, + &rx_int1_2_interp_mux), + SND_SOC_DAPM_MUX("RX INT2_2 INTERP", SND_SOC_NOPM, 0, 0, + &rx_int2_2_interp_mux), + + SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL, + 0, &rx_int0_mix2_inp_mux, rx_macro_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR, + 0, &rx_int1_mix2_inp_mux, rx_macro_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_AUX, + 0, &rx_int2_mix2_inp_mux, rx_macro_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("HPHL_OUT"), + SND_SOC_DAPM_OUTPUT("HPHR_OUT"), + SND_SOC_DAPM_OUTPUT("AUX_OUT"), + + SND_SOC_DAPM_INPUT("RX_TX DEC0_INP"), + SND_SOC_DAPM_INPUT("RX_TX DEC1_INP"), + SND_SOC_DAPM_INPUT("RX_TX DEC2_INP"), + SND_SOC_DAPM_INPUT("RX_TX DEC3_INP"), + + SND_SOC_DAPM_SUPPLY_S("RX_MCLK", 0, SND_SOC_NOPM, 0, 0, + rx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route rx_audio_map[] = { + {"RX AIF1 PB", NULL, "RX_MCLK"}, + {"RX AIF2 PB", NULL, "RX_MCLK"}, + {"RX AIF3 PB", NULL, "RX_MCLK"}, + {"RX AIF4 PB", NULL, "RX_MCLK"}, + + {"RX_MACRO RX0 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX1 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX2 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX3 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX4 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX5 MUX", "AIF1_PB", "RX AIF1 PB"}, + + {"RX_MACRO RX0 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX1 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX2 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX3 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX4 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX5 MUX", "AIF2_PB", "RX AIF2 PB"}, + + {"RX_MACRO RX0 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX1 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX2 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX3 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX4 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX5 MUX", "AIF3_PB", "RX AIF3 PB"}, + + {"RX_MACRO RX0 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX1 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX2 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX3 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX4 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX5 MUX", "AIF4_PB", "RX AIF4 PB"}, + + {"RX_RX0", NULL, "RX_MACRO RX0 MUX"}, + {"RX_RX1", NULL, "RX_MACRO RX1 MUX"}, + {"RX_RX2", NULL, "RX_MACRO RX2 MUX"}, + {"RX_RX3", NULL, "RX_MACRO RX3 MUX"}, + {"RX_RX4", NULL, "RX_MACRO RX4 MUX"}, + {"RX_RX5", NULL, "RX_MACRO RX5 MUX"}, + + {"RX INT0_1 MIX1 INP0", "RX0", "RX_RX0"}, + {"RX INT0_1 MIX1 INP0", "RX1", "RX_RX1"}, + {"RX INT0_1 MIX1 INP0", "RX2", "RX_RX2"}, + {"RX INT0_1 MIX1 INP0", "RX3", "RX_RX3"}, + {"RX INT0_1 MIX1 INP0", "RX4", "RX_RX4"}, + {"RX INT0_1 MIX1 INP0", "RX5", "RX_RX5"}, + {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT0_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT0_1 MIX1 INP1", "RX0", "RX_RX0"}, + {"RX INT0_1 MIX1 INP1", "RX1", "RX_RX1"}, + {"RX INT0_1 MIX1 INP1", "RX2", "RX_RX2"}, + {"RX INT0_1 MIX1 INP1", "RX3", "RX_RX3"}, + {"RX INT0_1 MIX1 INP1", "RX4", "RX_RX4"}, + {"RX INT0_1 MIX1 INP1", "RX5", "RX_RX5"}, + {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT0_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT0_1 MIX1 INP2", "RX0", "RX_RX0"}, + {"RX INT0_1 MIX1 INP2", "RX1", "RX_RX1"}, + {"RX INT0_1 MIX1 INP2", "RX2", "RX_RX2"}, + {"RX INT0_1 MIX1 INP2", "RX3", "RX_RX3"}, + {"RX INT0_1 MIX1 INP2", "RX4", "RX_RX4"}, + {"RX INT0_1 MIX1 INP2", "RX5", "RX_RX5"}, + {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT0_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, + + {"RX INT1_1 MIX1 INP0", "RX0", "RX_RX0"}, + {"RX INT1_1 MIX1 INP0", "RX1", "RX_RX1"}, + {"RX INT1_1 MIX1 INP0", "RX2", "RX_RX2"}, + {"RX INT1_1 MIX1 INP0", "RX3", "RX_RX3"}, + {"RX INT1_1 MIX1 INP0", "RX4", "RX_RX4"}, + {"RX INT1_1 MIX1 INP0", "RX5", "RX_RX5"}, + {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT1_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT1_1 MIX1 INP1", "RX0", "RX_RX0"}, + {"RX INT1_1 MIX1 INP1", "RX1", "RX_RX1"}, + {"RX INT1_1 MIX1 INP1", "RX2", "RX_RX2"}, + {"RX INT1_1 MIX1 INP1", "RX3", "RX_RX3"}, + {"RX INT1_1 MIX1 INP1", "RX4", "RX_RX4"}, + {"RX INT1_1 MIX1 INP1", "RX5", "RX_RX5"}, + {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT1_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT1_1 MIX1 INP2", "RX0", "RX_RX0"}, + {"RX INT1_1 MIX1 INP2", "RX1", "RX_RX1"}, + {"RX INT1_1 MIX1 INP2", "RX2", "RX_RX2"}, + {"RX INT1_1 MIX1 INP2", "RX3", "RX_RX3"}, + {"RX INT1_1 MIX1 INP2", "RX4", "RX_RX4"}, + {"RX INT1_1 MIX1 INP2", "RX5", "RX_RX5"}, + {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT1_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, + + {"RX INT2_1 MIX1 INP0", "RX0", "RX_RX0"}, + {"RX INT2_1 MIX1 INP0", "RX1", "RX_RX1"}, + {"RX INT2_1 MIX1 INP0", "RX2", "RX_RX2"}, + {"RX INT2_1 MIX1 INP0", "RX3", "RX_RX3"}, + {"RX INT2_1 MIX1 INP0", "RX4", "RX_RX4"}, + {"RX INT2_1 MIX1 INP0", "RX5", "RX_RX5"}, + {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT2_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT2_1 MIX1 INP1", "RX0", "RX_RX0"}, + {"RX INT2_1 MIX1 INP1", "RX1", "RX_RX1"}, + {"RX INT2_1 MIX1 INP1", "RX2", "RX_RX2"}, + {"RX INT2_1 MIX1 INP1", "RX3", "RX_RX3"}, + {"RX INT2_1 MIX1 INP1", "RX4", "RX_RX4"}, + {"RX INT2_1 MIX1 INP1", "RX5", "RX_RX5"}, + {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT2_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, + {"RX INT2_1 MIX1 INP2", "RX0", "RX_RX0"}, + {"RX INT2_1 MIX1 INP2", "RX1", "RX_RX1"}, + {"RX INT2_1 MIX1 INP2", "RX2", "RX_RX2"}, + {"RX INT2_1 MIX1 INP2", "RX3", "RX_RX3"}, + {"RX INT2_1 MIX1 INP2", "RX4", "RX_RX4"}, + {"RX INT2_1 MIX1 INP2", "RX5", "RX_RX5"}, + {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT2_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, + + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"}, + + {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX AIF_ECHO", NULL, "RX MIX TX0 MUX"}, + {"RX AIF_ECHO", NULL, "RX MIX TX1 MUX"}, + {"RX AIF_ECHO", NULL, "RX MIX TX2 MUX"}, + {"RX AIF_ECHO", NULL, "RX_MCLK"}, + + /* Mixing path INT0 */ + {"RX INT0_2 MUX", "RX0", "RX_RX0"}, + {"RX INT0_2 MUX", "RX1", "RX_RX1"}, + {"RX INT0_2 MUX", "RX2", "RX_RX2"}, + {"RX INT0_2 MUX", "RX3", "RX_RX3"}, + {"RX INT0_2 MUX", "RX4", "RX_RX4"}, + {"RX INT0_2 MUX", "RX5", "RX_RX5"}, + {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"}, + + /* Mixing path INT1 */ + {"RX INT1_2 MUX", "RX0", "RX_RX0"}, + {"RX INT1_2 MUX", "RX1", "RX_RX1"}, + {"RX INT1_2 MUX", "RX2", "RX_RX2"}, + {"RX INT1_2 MUX", "RX3", "RX_RX3"}, + {"RX INT1_2 MUX", "RX4", "RX_RX4"}, + {"RX INT1_2 MUX", "RX5", "RX_RX5"}, + {"RX INT1_2 INTERP", NULL, "RX INT1_2 MUX"}, + {"RX INT1 SEC MIX", NULL, "RX INT1_2 INTERP"}, + + /* Mixing path INT2 */ + {"RX INT2_2 MUX", "RX0", "RX_RX0"}, + {"RX INT2_2 MUX", "RX1", "RX_RX1"}, + {"RX INT2_2 MUX", "RX2", "RX_RX2"}, + {"RX INT2_2 MUX", "RX3", "RX_RX3"}, + {"RX INT2_2 MUX", "RX4", "RX_RX4"}, + {"RX INT2_2 MUX", "RX5", "RX_RX5"}, + {"RX INT2_2 INTERP", NULL, "RX INT2_2 MUX"}, + {"RX INT2 SEC MIX", NULL, "RX INT2_2 INTERP"}, + + {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"}, + {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"}, + {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"}, + {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"}, + {"HPHL_OUT", NULL, "RX INT0 DEM MUX"}, + {"HPHL_OUT", NULL, "RX_MCLK"}, + + {"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"}, + {"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"}, + {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"}, + {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"}, + {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX2"}, + {"HPHR_OUT", NULL, "RX INT1 DEM MUX"}, + {"HPHR_OUT", NULL, "RX_MCLK"}, + + {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"}, + + {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"}, + {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"}, + {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"}, + {"AUX_OUT", NULL, "RX INT2 MIX2"}, + {"AUX_OUT", NULL, "RX_MCLK"}, + + {"IIR0", NULL, "RX_MCLK"}, + {"IIR0", NULL, "IIR0 INP0 MUX"}, + {"IIR0 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP0 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP0 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP0 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP0 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP0 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP0 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP0 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP0 MUX", "RX5", "RX_RX5"}, + {"IIR0", NULL, "IIR0 INP1 MUX"}, + {"IIR0 INP1 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP1 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP1 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP1 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP1 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP1 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP1 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP1 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP1 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP1 MUX", "RX5", "RX_RX5"}, + {"IIR0", NULL, "IIR0 INP2 MUX"}, + {"IIR0 INP2 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP2 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP2 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP2 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP2 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP2 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP2 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP2 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP2 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP2 MUX", "RX5", "RX_RX5"}, + {"IIR0", NULL, "IIR0 INP3 MUX"}, + {"IIR0 INP3 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP3 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP3 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP3 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP3 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP3 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP3 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP3 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP3 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP3 MUX", "RX5", "RX_RX5"}, + + {"IIR1", NULL, "RX_MCLK"}, + {"IIR1", NULL, "IIR1 INP0 MUX"}, + {"IIR1 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP0 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP0 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP0 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP0 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP0 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP0 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP0 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP0 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "IIR1 INP1 MUX"}, + {"IIR1 INP1 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP1 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP1 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP1 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP1 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP1 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP1 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP1 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP1 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP1 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "IIR1 INP2 MUX"}, + {"IIR1 INP2 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP2 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP2 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP2 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP2 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP2 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP2 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP2 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP2 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP2 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "IIR1 INP3 MUX"}, + {"IIR1 INP3 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP3 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP3 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP3 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP3 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP3 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP3 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP3 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP3 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP3 MUX", "RX5", "RX_RX5"}, + + {"SRC0", NULL, "IIR0"}, + {"SRC1", NULL, "IIR1"}, + {"RX INT0 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT0 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT1 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT1 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT2 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT2 MIX2 INP", "SRC1", "SRC1"}, +}; + static int rx_swrm_clock(struct rx_macro *rx, bool enable) { struct regmap *regmap = rx->regmap; @@ -1929,6 +3264,10 @@ static const struct snd_soc_component_driver rx_macro_component_drv = { .probe = rx_macro_component_probe, .controls = rx_macro_snd_controls, .num_controls = ARRAY_SIZE(rx_macro_snd_controls), + .dapm_widgets = rx_macro_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(rx_macro_dapm_widgets), + .dapm_routes = rx_audio_map, + .num_dapm_routes = ARRAY_SIZE(rx_audio_map), }; static int rx_macro_probe(struct platform_device *pdev) From patchwork Thu Jan 28 14:19:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 372610 Delivered-To: patch@linaro.org Received: by 2002:a02:a60d:0:0:0:0:0 with SMTP id c13csp1298352jam; Thu, 28 Jan 2021 06:23:48 -0800 (PST) X-Google-Smtp-Source: ABdhPJwuUep2PmSFcp7Skm3A9itF28EwOBaOF1frvhg1RZ+rIS4Nke47Kf0iNgKbwweRj+/dNemg X-Received: by 2002:a17:906:1f45:: with SMTP id d5mr11613440ejk.76.1611843828292; Thu, 28 Jan 2021 06:23:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611843828; cv=none; d=google.com; s=arc-20160816; b=a9ATNRkD51Le5k7qhkWPN56bcHKQh4Y1AvJgxU0oRgzXkIhT38lUoGr0zX+DY33+4W wwtypS1wg/rUW69Q0gPO3btJF7grdz024a/ihwoMNa8xg5xQMRudIvBgobATbAvIOT+l vYDC/jAOr9VURDmQWTWaOuUNxljY5Rz2WO+5mmqs0U6kIysankz1TEH037Lsu0Gn56IX 2mKh193DOQUJWQgZFfVPgCGqjZz2G2kzi7988vyQJvhI/KrdMvxsg0TwK4krm3I/KjQL zNhQ8qKc7L+Qj5OWBazMxk9vyW6Vhj+BaEon09TWb1FxFnjq5IDUNWHbKKkxzd3fbTCu PMNQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=yOIp9QtjeyWXIAt+jtQ8VX7A/Az7txNIlXuQGUmt+5s=; b=R87jik+Ac9rj+SiDAQYGVOLaQuDycxRw+sR4oTHofxE4VjO/YFdP8ZNV94BB4mO++6 oQL1R0pao3XM2J6meb3jPYx40nW/GlfODOJwekTnMlpNOMBOrYAe908Ty2bqijeHVS0r +KBxhDUcEzMcnKCXp47eyao2QBL9oAkidWvZMJC5JRYHQqF6ChcsMjANUMD/nZBl2D/w d5aAlFLGGuaxOGsc2kQoCdFN6yZImhCLStRBZxjOy9d/4/5ul5J9A3szy4myExC/z17E +wViZvv6unSC2eaKPXojAsZqPWhRyAR739uZaw9o75FmGEYJLeR1thm6nBhKcL+exB/e qYzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="pi/TSuiZ"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h4si2917852edv.124.2021.01.28.06.23.48; Thu, 28 Jan 2021 06:23:48 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="pi/TSuiZ"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231516AbhA1OW2 (ORCPT + 6 others); Thu, 28 Jan 2021 09:22:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231518AbhA1OV1 (ORCPT ); Thu, 28 Jan 2021 09:21:27 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 43613C06178B for ; Thu, 28 Jan 2021 06:20:01 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id q7so5534162wre.13 for ; Thu, 28 Jan 2021 06:20:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yOIp9QtjeyWXIAt+jtQ8VX7A/Az7txNIlXuQGUmt+5s=; b=pi/TSuiZReugFt8U4lIlNELRG42MYFzCorpC2efG7Y2oJrlUl3UpKci8mEbFye4vFx z6YYdfiX9BSKGRGTw0BiQmbb7LS32cjiD+uDYi3bXfp8F0SgTbxujZaQFWcJoIwzlfZL 95QCA52CQ7ySrd4OOEk0x+juUIQQRhSvAy1/p7cmtcBpGY1hayXsBSsYXMnRJq9hTku9 fa5MVw3J8zEwF6RuUeUboGkmvTFW5SrHYVpo8IoSnfiRr3+DPC9ocFM3MYxgenMUYzRI yTyf0BZwOuPUg11YHHOcqfTohkrjKf2FFnd0qMSn0HWWRBSEdrS1t1JXS45qKAsI1ABF 4PfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yOIp9QtjeyWXIAt+jtQ8VX7A/Az7txNIlXuQGUmt+5s=; b=Z6Z61ORRYNhYVeN1re2RQytDO/ai7CxefLZvYqNhysIRqMpt1uzlk08UV6kYx3kkIg 8SxQa7ihrW9k+v9f/Hc4lJSBZGAidAvVtfDtYk/O9sad1efozO+yM6L26TY3xWVoaaho ZG4cR180q0zORHJ8gT81uKxHmKZn9TNqHyCG48QYtQrClIGf9WBQpYfOpYSSXPFcWDPo oxfdbh3gsnauvRcwHlcMj/DtVxgie95eBH9ijH/x+fe4EfN9s3PP5rR0Sz3aej11iugy C/+cCJEFtruVv7K4S4mrGxyXn/m98TDEuxTJUC1lpwTj8IleDfL0BXUgY0xAwsPZA1ZZ H+5A== X-Gm-Message-State: AOAM531XkfG2UDLhfCVL5BydOFFrR32Bw2aREQ1+SdN/oxPY/0M9TSWF atbEM7kcWJgSvTjqyeZUwLaF6A== X-Received: by 2002:a5d:6a02:: with SMTP id m2mr16736038wru.364.1611843600014; Thu, 28 Jan 2021 06:20:00 -0800 (PST) Received: from srini-hackbox.lan (cpc86377-aztw32-2-0-cust226.18-1.cable.virginm.net. [92.233.226.227]) by smtp.gmail.com with ESMTPSA id d9sm7257096wrq.74.2021.01.28.06.19.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 06:19:59 -0800 (PST) From: Srinivas Kandagatla To: broonie@kernel.org Cc: perex@perex.cz, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, devicetree@vger.kernel.org, robh+dt@kernel.org, Srinivas Kandagatla Subject: [PATCH 4/7] ASoC: codec: lpass-rx-macro: add iir widgets Date: Thu, 28 Jan 2021 14:19:26 +0000 Message-Id: <20210128141929.26573-5-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> References: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds irr widgets and mixers on this codec Signed-off-by: Srinivas Kandagatla --- sound/soc/codecs/lpass-rx-macro.c | 264 ++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) -- 2.21.0 diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 5ceb81e8f1d4..439af551e3a9 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -528,6 +528,38 @@ enum { INTERP_MIX_PATH, }; +/* Codec supports 2 IIR filters */ +enum { + IIR0 = 0, + IIR1, + IIR_MAX, +}; + +/* Each IIR has 5 Filter Stages */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +#define RX_MACRO_IIR_FILTER_SIZE (sizeof(u32) * BAND_MAX) + +#define RX_MACRO_IIR_FILTER_CTL(xname, iidx, bidx) \ +{ \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = rx_macro_iir_filter_info, \ + .get = rx_macro_get_iir_band_audio_mixer, \ + .put = rx_macro_put_iir_band_audio_mixer, \ + .private_value = (unsigned long)&(struct wcd_iir_filter_ctl) { \ + .iir_idx = iidx, \ + .band_idx = bidx, \ + .bytes_ext = {.max = RX_MACRO_IIR_FILTER_SIZE, }, \ + } \ +} + struct interp_sample_rate { int sample_rate; int rate_val; @@ -586,6 +618,12 @@ struct rx_macro { }; #define to_rx_macro(_hw) container_of(_hw, struct rx_macro, hw) +struct wcd_iir_filter_ctl { + unsigned int iir_idx; + unsigned int band_idx; + struct soc_bytes_ext bytes_ext; +}; + static struct snd_soc_dai_driver rx_macro_dai[]; static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); @@ -2605,6 +2643,166 @@ static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w, return 0; } +static int rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: /* fall through */ + case SND_SOC_DAPM_PRE_PMD: + if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); + } else { + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL)); + snd_soc_component_write(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, + snd_soc_component_read(component, + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL)); + } + break; + } + return 0; +} + +static uint32_t get_iir_band_coeff(struct snd_soc_component *component, + int iir_idx, int band_idx, int coeff_idx) +{ + u32 value; + int reg, b2_reg; + + /* Address does not automatically update if reading */ + reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx; + b2_reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; + + snd_soc_component_write(component, reg, + ((band_idx * BAND_MAX + coeff_idx) * + sizeof(uint32_t)) & 0x7F); + + value = snd_soc_component_read(component, b2_reg); + snd_soc_component_write(component, reg, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_component_read(component, b2_reg) << 8); + snd_soc_component_write(component, reg, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_component_read(component, b2_reg) << 16); + snd_soc_component_write(component, reg, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= (snd_soc_component_read(component, b2_reg) << 24); + return value; +} + +static void set_iir_band_coeff(struct snd_soc_component *component, + int iir_idx, int band_idx, uint32_t value) +{ + int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; + + snd_soc_component_write(component, reg, (value & 0xFF)); + snd_soc_component_write(component, reg, (value >> 8) & 0xFF); + snd_soc_component_write(component, reg, (value >> 16) & 0xFF); + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_component_write(component, reg, (value >> 24) & 0x3F); +} + +static int rx_macro_put_iir_band_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd_iir_filter_ctl *ctl = + (struct wcd_iir_filter_ctl *)kcontrol->private_value; + struct soc_bytes_ext *params = &ctl->bytes_ext; + int iir_idx = ctl->iir_idx; + int band_idx = ctl->band_idx; + u32 coeff[BAND_MAX]; + int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx; + + memcpy(&coeff[0], ucontrol->value.bytes.data, params->max); + + /* Mask top bit it is reserved */ + /* Updates addr automatically for each B2 write */ + snd_soc_component_write(component, reg, (band_idx * BAND_MAX * + sizeof(uint32_t)) & 0x7F); + + set_iir_band_coeff(component, iir_idx, band_idx, coeff[0]); + set_iir_band_coeff(component, iir_idx, band_idx, coeff[1]); + set_iir_band_coeff(component, iir_idx, band_idx, coeff[2]); + set_iir_band_coeff(component, iir_idx, band_idx, coeff[3]); + set_iir_band_coeff(component, iir_idx, band_idx, coeff[4]); + + return 0; +} + +static int rx_macro_get_iir_band_audio_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd_iir_filter_ctl *ctl = + (struct wcd_iir_filter_ctl *)kcontrol->private_value; + struct soc_bytes_ext *params = &ctl->bytes_ext; + int iir_idx = ctl->iir_idx; + int band_idx = ctl->band_idx; + u32 coeff[BAND_MAX]; + + coeff[0] = get_iir_band_coeff(component, iir_idx, band_idx, 0); + coeff[1] = get_iir_band_coeff(component, iir_idx, band_idx, 1); + coeff[2] = get_iir_band_coeff(component, iir_idx, band_idx, 2); + coeff[3] = get_iir_band_coeff(component, iir_idx, band_idx, 3); + coeff[4] = get_iir_band_coeff(component, iir_idx, band_idx, 4); + + memcpy(ucontrol->value.bytes.data, &coeff[0], params->max); + + return 0; +} + +static int rx_macro_iir_filter_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *ucontrol) +{ + struct wcd_iir_filter_ctl *ctl = + (struct wcd_iir_filter_ctl *)kcontrol->private_value; + struct soc_bytes_ext *params = &ctl->bytes_ext; + + ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; + ucontrol->count = params->max; + + return 0; +} + static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_S8_TLV("RX_RX0 Digital Volume", CDC_RX_RX0_RX_VOL_CTL, @@ -2642,6 +2840,65 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_EXT("AUX_HPF Enable", SND_SOC_NOPM, 0, 1, 0, rx_macro_aux_hpf_mode_get, rx_macro_aux_hpf_mode_put), + + SOC_SINGLE_S8_TLV("IIR0 INP0 Volume", + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR0 INP1 Volume", + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR0 INP2 Volume", + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR0 INP3 Volume", + CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP0 Volume", + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, -84, 40, + digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", + CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, -84, 40, + digital_gain), + + SOC_SINGLE("IIR1 Band1 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 0, 1, 0), + SOC_SINGLE("IIR1 Band2 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 1, 1, 0), + SOC_SINGLE("IIR1 Band3 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 2, 1, 0), + SOC_SINGLE("IIR1 Band4 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 3, 1, 0), + SOC_SINGLE("IIR1 Band5 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, + 4, 1, 0), + SOC_SINGLE("IIR2 Band1 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 0, 1, 0), + SOC_SINGLE("IIR2 Band2 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 1, 1, 0), + SOC_SINGLE("IIR2 Band3 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 2, 1, 0), + SOC_SINGLE("IIR2 Band4 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 3, 1, 0), + SOC_SINGLE("IIR2 Band5 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, + 4, 1, 0), + + RX_MACRO_IIR_FILTER_CTL("IIR0 Band1", IIR0, BAND1), + RX_MACRO_IIR_FILTER_CTL("IIR0 Band2", IIR0, BAND2), + RX_MACRO_IIR_FILTER_CTL("IIR0 Band3", IIR0, BAND3), + RX_MACRO_IIR_FILTER_CTL("IIR0 Band4", IIR0, BAND4), + RX_MACRO_IIR_FILTER_CTL("IIR0 Band5", IIR0, BAND5), + + RX_MACRO_IIR_FILTER_CTL("IIR1 Band1", IIR1, BAND1), + RX_MACRO_IIR_FILTER_CTL("IIR1 Band2", IIR1, BAND2), + RX_MACRO_IIR_FILTER_CTL("IIR1 Band3", IIR1, BAND3), + RX_MACRO_IIR_FILTER_CTL("IIR1 Band4", IIR1, BAND4), + RX_MACRO_IIR_FILTER_CTL("IIR1 Band5", IIR1, BAND5), + }; static int rx_macro_enable_echo(struct snd_soc_dapm_widget *w, @@ -2737,6 +2994,13 @@ static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { RX_MACRO_EC2_MUX, 0, &rx_mix_tx2_mux, rx_macro_enable_echo, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("IIR0", CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, + 4, 0, NULL, 0, rx_macro_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MIXER_E("IIR1", CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, + 4, 0, NULL, 0, rx_macro_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_MIXER("SRC0", CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, 4, 0, NULL, 0), SND_SOC_DAPM_MIXER("SRC1", CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, From patchwork Thu Jan 28 14:19:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 372612 Delivered-To: patch@linaro.org Received: by 2002:a02:a60d:0:0:0:0:0 with SMTP id c13csp1298373jam; Thu, 28 Jan 2021 06:23:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJwC7Op6hjeZ3SIJ3WNhoEPRJk0TT8BtrRcisFD4VpxaJabNund/CYhC33723hcRqIarXJNn X-Received: by 2002:a17:906:3883:: with SMTP id q3mr11149169ejd.160.1611843829606; Thu, 28 Jan 2021 06:23:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611843829; cv=none; d=google.com; s=arc-20160816; b=cnXxDtcx9OdsUa9MBI1HqQ+nFZI5P4+qgxPVPqGy45JzJ8Y8jbm4BLn+GAKf0lV9Pc 1mQRHd/ABIYXqOZiXCYkj2D/tdMn1WQgHd88aj3g7a6LSqNKx/SBJQq2P/aAun8MX94m cvMHxh7e6kwy5OvGqJ1CXa/qSCMz8vBkaC+z/4iiW+xvDaEgb/Esnp+HWAgMFw0Sgq0S 0Gpn/6zU7XMgw/XtzP8mo1sOfyckd+ZV9UyvqKxLij2HIj7KkAcBocT7nacmbv0DlE+g riJmROzI/aUn6N+LrsCtZ6ySDf2OtcgACljFP6pCGMC7F0v9Consf2RngcJfW80iPgvh K17A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=y4A5Uf4Os6WPGl/YWHkNN/4TU8yF2iW13SGgEG1fF60=; b=bksn5JYEit605Cq3F8xZ8R4+OS2BFQGJcvtjWr5Lh1QESdjxkK1yjF2u94o0MulXBB 6ynSczY9JyFImtBaGOSPZVpBJhE120uuTO+A0LyXfWfjAdaI0UdatzWIGJaUYICwojRo Jbg1oH5j5JzkdQFxWr6ttEZL/fdFWlZXAjf1ui1NmQya5ACTx6xBpFmvDfUAsutC7Rj9 jomfqoWlIwcuualvhlckMMV4NaPYWMN0zaoqY3m9vqb4DcnXbeTuxE/+lmP3yNk+zsgr qxC+E0hLGGGxsnSSaeNEOoPoyCWZ703tCq8CEpGtMkCdhes/fHpxDJJ/r90U055ZFHtC XJgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="h9QKz/rb"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h4si2917852edv.124.2021.01.28.06.23.49; Thu, 28 Jan 2021 06:23:49 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="h9QKz/rb"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231672AbhA1OWw (ORCPT + 6 others); Thu, 28 Jan 2021 09:22:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231529AbhA1OV3 (ORCPT ); Thu, 28 Jan 2021 09:21:29 -0500 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A511C061794 for ; Thu, 28 Jan 2021 06:20:02 -0800 (PST) Received: by mail-wr1-x42d.google.com with SMTP id g10so5584911wrx.1 for ; Thu, 28 Jan 2021 06:20:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=y4A5Uf4Os6WPGl/YWHkNN/4TU8yF2iW13SGgEG1fF60=; b=h9QKz/rb7BLkCNbgzJD+55FjmmybjmFgtq+sPIlpDNLzLjN/vdTTlclqj/Ss4YY2Pc 5x0RmRkhd8insWMIKw3t3H5aGbuSoGap0l4Mq7RlmxooiRGd5gwr7jY2stypHqwk7d32 fTL2mm/OJgJcEYRG5iuaOXrJf8jitJEaFCGCj7I6I3lutoHAyJi1oIZorbdrgkMYKax6 H8JfSkM0ScIXRRi21KlPS3BXk0qPZ3kPeAot/2ALxnCRWxhwVp+QEBNdlFMYrozoyhn+ gR5aFptgw8oDhPeGEFIbpzWxAly1gYLHatDDKOZbQax/4iFksZBt6rl08sgu5v23uMjU H0hg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=y4A5Uf4Os6WPGl/YWHkNN/4TU8yF2iW13SGgEG1fF60=; b=MfYeu64+aVngm8Bflm9bIWw70bBYxBTxItyyfWFkJe8eE+wJtx39Yj7eNTUvt0Pj/o 11A04n7DUYdleAyOoCVzVEWyuNqfSFNRjIBuxTrZJyX6qhaOKxXbFRhh/t7xVo9q8tpe YwG8cLzSLVx8CeiD/MOntE74O5mkcB+AoeUj78ImRvsfYT5VSVsQLSoQkIt1uoN7VCVL WmyxXXAnvDRlQ12c1xpF61UOoqcLudx02XwEF2LPNB4E/CJR1fJGxei3Ru6GUK5hF+i5 mY25i2SQkLq+cILvrQhymXbiKyiFTvkt+UqxSvvVlPhhse8mcfCrO6VLg6QYIHEXJtyS YAyw== X-Gm-Message-State: AOAM532cphvi1zT3F9reKVsi75KpwTHa0TqfwMXdo5MN1cF5dX9U+QGi bSAYjNjwO2QIJrepn9ob+uFlwg== X-Received: by 2002:adf:f58b:: with SMTP id f11mr16624976wro.3.1611843601338; Thu, 28 Jan 2021 06:20:01 -0800 (PST) Received: from srini-hackbox.lan (cpc86377-aztw32-2-0-cust226.18-1.cable.virginm.net. [92.233.226.227]) by smtp.gmail.com with ESMTPSA id d9sm7257096wrq.74.2021.01.28.06.20.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 06:20:00 -0800 (PST) From: Srinivas Kandagatla To: broonie@kernel.org Cc: perex@perex.cz, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, devicetree@vger.kernel.org, robh+dt@kernel.org, Srinivas Kandagatla Subject: [PATCH 5/7] ASoC: qcom: dt-bindings: add bindings for lpass tx macro codec Date: Thu, 28 Jan 2021 14:19:27 +0000 Message-Id: <20210128141929.26573-6-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> References: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This binding is for LPASS has internal codec TX macro which is for connecting with Soundwire TX codecs like WCD938x. Signed-off-by: Srinivas Kandagatla --- .../bindings/sound/qcom,lpass-tx-macro.yaml | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml -- 2.21.0 diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml new file mode 100644 index 000000000000..6b5ca02ccce4 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/qcom,lpass-tx-macro.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LPASS(Low Power Audio Subsystem) TX Macro audio codec DT bindings + +maintainers: + - Srinivas Kandagatla + +properties: + compatible: + const: qcom,sm8250-lpass-tx-macro + + reg: + maxItems: 1 + + "#sound-dai-cells": + const: 1 + + '#clock-cells': + const: 0 + + clocks: + maxItems: 5 + + clock-names: + items: + - const: mclk + - const: npl + - const: macro + - const: dcodec + - const: fsgen + + clock-output-names: + items: + - const: mclk + + qcom,dmic-sample-rate: + description: dmic sample rate + $ref: /schemas/types.yaml#/definitions/uint32 + +required: + - compatible + - reg + - "#sound-dai-cells" + +additionalProperties: false + +examples: + - | + #include + codec@3220000 { + compatible = "qcom,sm8250-lpass-tx-macro"; + reg = <0x3220000 0x1000>; + #sound-dai-cells = <1>; + #clock-cells = <0>; + clocks = <&aoncc 0>, + <&aoncc 1>, + <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&vamacro>; + clock-names = "mclk", "npl", "macro", "dcodec", "fsgen"; + clock-output-names = "mclk"; + qcom,dmic-sample-rate = <600000>; + }; From patchwork Thu Jan 28 14:19:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 372609 Delivered-To: patch@linaro.org Received: by 2002:a02:a60d:0:0:0:0:0 with SMTP id c13csp1296874jam; Thu, 28 Jan 2021 06:22:15 -0800 (PST) X-Google-Smtp-Source: ABdhPJy+xUVrW7fweToAO+53QfAPQQgxfVsncWKI1VrERiH1D2mfyEcP+TPcC7g1yENhJw/b1gq0 X-Received: by 2002:a05:6402:110b:: with SMTP id u11mr14826670edv.57.1611843735099; Thu, 28 Jan 2021 06:22:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611843735; cv=none; d=google.com; s=arc-20160816; b=HSUXidJH3vF+V4dQdhWFL+db7C0dEAShTknvS22SHZAwlSHB2BYxxWLk9rdYyzQZIA ZghLOrr5q2qi0RbAkM6i3ic5cWdJdPf3z0WqxQr1XMm0jqhO++p8iFhRnW1Olwl/dI1h RS8lZ9Xq2ghCQfyIrRPCZx0raR8/IabLR4JM6IWmQlUeWvqhtTcv4enzrdBBhEOoqbl2 pIXWMnRNA9V650Wq8Ygkn4urjSZROqzmF4R/yHaF7wqoHAqsZHQBM+YwmHlvhk4ylKI8 ejjF6aOLU1K9puln5DdM0F22wXT5OD2nVL7UtLgyzP5mHIlFPqu5/Tru0cFz31qqBhgt cKPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=mrodypDf8SiV6V+E8i14JMGAydKD3GU3nenXzdoPth4=; b=KF0UTQbnnVI7pLTOGR19eq/ITbWwi9ZG2lXvPOM2bBXt2SfhdUeTO8o3Is415LnZPe rgPR1rZq0zpHxPgr6nNnT4v6Rlv4X4N1iBHN21pu2gWyN/Hl6QcskE+8Y8DHPsCsjy9Q YdU8i1qYH/bfRjS2SMZdHL1Ih3WeqWNBIqqsR/YvRXxEWEnrrfWRcDf34ZF74aZo/wzr 0faVRKvkSKi3CB3u7Hosy3dEKhq4I6/wPieFaF+nxseETpwWU/wiA/0Tm7Mzr9XNSoTu CKYtmsePkSMt4Cr2YXeuvoEFd9QB7IWIpZ75zN0Tiu0e6Ab++bgYQaE075ZyzgGVusD+ 5aWg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="wjdp2i/e"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id lz12si2615142ejb.518.2021.01.28.06.22.14; Thu, 28 Jan 2021 06:22:15 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="wjdp2i/e"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231426AbhA1OVt (ORCPT + 6 others); Thu, 28 Jan 2021 09:21:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231509AbhA1OVF (ORCPT ); Thu, 28 Jan 2021 09:21:05 -0500 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E7BBC061797 for ; Thu, 28 Jan 2021 06:20:04 -0800 (PST) Received: by mail-wr1-x431.google.com with SMTP id d16so5533181wro.11 for ; Thu, 28 Jan 2021 06:20:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mrodypDf8SiV6V+E8i14JMGAydKD3GU3nenXzdoPth4=; b=wjdp2i/eL6C15UTm74ubwMLZ0Cf5k1jqDJKwEeJSqE6gYdPokPPTkMQPVY+dVdCr5Z 2l4WQ1HOi4cIVln46OPkmG4TkgUbIz6xh4826Zewf0ZhFP7BZNAyVd7v9KfGEUR2VDBX WhU3jE2hjaNi/P4gKme+1XMc3iFR0DR8PJAx5oO0iRKgL0qTOXOCJvpILy2EW0T0xPb6 5RPNaGjIeqQ7L0MOh2DPzn0fjJKrzbP2FhQ0LLHPbw5o9GEQMe5bCb3JKHTcoZHplTrd tZrkSTjW98unxBdZEK+Xgtn+nQRNQFcXmtZ/jTM5HDdPI29864WWfRcrjMZjmDy0uTS7 A31g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mrodypDf8SiV6V+E8i14JMGAydKD3GU3nenXzdoPth4=; b=hIsQOZcyhT4Dk6e/E2CwskXHFtzVoaJzoS/jT+ujXYQFJEghMeBLfVwSntwu7Ld9xi 0FawhM3kmu+9TvaQi7CjDqFcOum1n6d5rGGV+SoV5p/ETpRkTO72OgJ3lWzTM471Ww5f 2ClK2aTfnQFVN9wXWj7yWhT7kQM5nYFCXCm1FGqBxKuV3EM+1BqFOkZDiQuzDDkXq0YA ZJERRycQQ29oCx+mIDDQamQ2tvVKtxHOIv52A9UHKaRy1DRXkp9Nb5jEW7GKwI1CdlDJ SEjVYK9mkV3za0BCJlsnSoFF3+DtqfUJyNWgL8bo2QwKVk3X8jvJglvwKJIUzWpngDGt 2F4A== X-Gm-Message-State: AOAM530DvJi9mcnGG9mxPJwmpe4ztaahS9UIGMKZ4Tjw0QC3raHKqx3R vKnVriBiEV4cGAyhPRBWRJ+gJw== X-Received: by 2002:a05:6000:41:: with SMTP id k1mr16421863wrx.386.1611843602696; Thu, 28 Jan 2021 06:20:02 -0800 (PST) Received: from srini-hackbox.lan (cpc86377-aztw32-2-0-cust226.18-1.cable.virginm.net. [92.233.226.227]) by smtp.gmail.com with ESMTPSA id d9sm7257096wrq.74.2021.01.28.06.20.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 06:20:02 -0800 (PST) From: Srinivas Kandagatla To: broonie@kernel.org Cc: perex@perex.cz, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, devicetree@vger.kernel.org, robh+dt@kernel.org, Srinivas Kandagatla Subject: [PATCH 6/7] ASoC: codec: lpass-tx-macro: add support for lpass tx macro Date: Thu, 28 Jan 2021 14:19:28 +0000 Message-Id: <20210128141929.26573-7-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> References: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Qualcomm LPASS (Low Power Audio SubSystem) has internal codec TX macro block which is used for connecting with external Soundwire TX Codecs like WCD938x. This patch adds support to the codec part of the TX Macro block Signed-off-by: Srinivas Kandagatla --- sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/lpass-tx-macro.c | 1196 +++++++++++++++++++++++++++++ 3 files changed, 1203 insertions(+) create mode 100644 sound/soc/codecs/lpass-tx-macro.c -- 2.21.0 diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 5dbe2bf2d329..66194ed7e3e2 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -228,6 +228,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_WCD9335 imply SND_SOC_WCD934X imply SND_SOC_LPASS_RX_MACRO + imply SND_SOC_LPASS_TX_MACRO imply SND_SOC_WL1273 imply SND_SOC_WM0010 imply SND_SOC_WM1250_EV1 @@ -1825,4 +1826,8 @@ config SND_SOC_LPASS_RX_MACRO depends on COMMON_CLK tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)" +config SND_SOC_LPASS_TX_MACRO + depends on COMMON_CLK + tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)" + endmenu diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 045263122761..d068166ed668 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -109,6 +109,7 @@ snd-soc-lochnagar-sc-objs := lochnagar-sc.o snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o snd-soc-lpass-va-macro-objs := lpass-va-macro.o snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o +snd-soc-lpass-tx-macro-objs := lpass-tx-macro.o snd-soc-madera-objs := madera.o snd-soc-max9759-objs := max9759.o snd-soc-max9768-objs := max9768.o @@ -625,6 +626,7 @@ obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o +obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) += snd-soc-lpass-tx-macro.o # Mux obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c new file mode 100644 index 000000000000..604bd14860a3 --- /dev/null +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -0,0 +1,1196 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CDC_TX_CLK_RST_CTRL_MCLK_CONTROL (0x0000) +#define CDC_TX_MCLK_EN_MASK BIT(0) +#define CDC_TX_MCLK_ENABLE BIT(0) +#define CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL (0x0004) +#define CDC_TX_FS_CNT_CLR_MASK BIT(1) +#define CDC_TX_FS_CNT_EN_MASK BIT(0) +#define CDC_TX_FS_CNT_ENABLE BIT(0) +#define CDC_TX_CLK_RST_CTRL_SWR_CONTROL (0x0008) +#define CDC_TX_SWR_RESET_MASK BIT(1) +#define CDC_TX_SWR_RESET_ENABLE BIT(1) +#define CDC_TX_SWR_CLK_EN_MASK BIT(0) +#define CDC_TX_SWR_CLK_ENABLE BIT(0) +#define CDC_TX_TOP_CSR_TOP_CFG0 (0x0080) +#define CDC_TX_TOP_CSR_ANC_CFG (0x0084) +#define CDC_TX_TOP_CSR_SWR_CTRL (0x0088) +#define CDC_TX_TOP_CSR_FREQ_MCLK (0x0090) +#define CDC_TX_TOP_CSR_DEBUG_BUS (0x0094) +#define CDC_TX_TOP_CSR_DEBUG_EN (0x0098) +#define CDC_TX_TOP_CSR_TX_I2S_CTL (0x00A4) +#define CDC_TX_TOP_CSR_I2S_CLK (0x00A8) +#define CDC_TX_TOP_CSR_I2S_RESET (0x00AC) +#define CDC_TX_TOP_CSR_SWR_DMICn_CTL(n) (0x00C0 + n * 0x4) +#define CDC_TX_TOP_CSR_SWR_DMIC0_CTL (0x00C0) +#define CDC_TX_SWR_DMIC_CLK_SEL_MASK GENMASK(3, 1) +#define CDC_TX_TOP_CSR_SWR_DMIC1_CTL (0x00C4) +#define CDC_TX_TOP_CSR_SWR_DMIC2_CTL (0x00C8) +#define CDC_TX_TOP_CSR_SWR_DMIC3_CTL (0x00CC) +#define CDC_TX_TOP_CSR_SWR_AMIC0_CTL (0x00D0) +#define CDC_TX_TOP_CSR_SWR_AMIC1_CTL (0x00D4) +#define CDC_TX_INP_MUX_ADC_MUXn_CFG0(n) (0x0100 + 0x8 * n) +#define CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK GENMASK(3, 0) +#define CDC_TX_INP_MUX_ADC_MUX0_CFG0 (0x0100) +#define CDC_TX_INP_MUX_ADC_MUXn_CFG1(n) (0x0104 + 0x8 * n) +#define CDC_TX_INP_MUX_ADC_MUX0_CFG1 (0x0104) +#define CDC_TX_INP_MUX_ADC_MUX1_CFG0 (0x0108) +#define CDC_TX_INP_MUX_ADC_MUX1_CFG1 (0x010C) +#define CDC_TX_INP_MUX_ADC_MUX2_CFG0 (0x0110) +#define CDC_TX_INP_MUX_ADC_MUX2_CFG1 (0x0114) +#define CDC_TX_INP_MUX_ADC_MUX3_CFG0 (0x0118) +#define CDC_TX_INP_MUX_ADC_MUX3_CFG1 (0x011C) +#define CDC_TX_INP_MUX_ADC_MUX4_CFG0 (0x0120) +#define CDC_TX_INP_MUX_ADC_MUX4_CFG1 (0x0124) +#define CDC_TX_INP_MUX_ADC_MUX5_CFG0 (0x0128) +#define CDC_TX_INP_MUX_ADC_MUX5_CFG1 (0x012C) +#define CDC_TX_INP_MUX_ADC_MUX6_CFG0 (0x0130) +#define CDC_TX_INP_MUX_ADC_MUX6_CFG1 (0x0134) +#define CDC_TX_INP_MUX_ADC_MUX7_CFG0 (0x0138) +#define CDC_TX_INP_MUX_ADC_MUX7_CFG1 (0x013C) +#define CDC_TX_ANC0_CLK_RESET_CTL (0x0200) +#define CDC_TX_ANC0_MODE_1_CTL (0x0204) +#define CDC_TX_ANC0_MODE_2_CTL (0x0208) +#define CDC_TX_ANC0_FF_SHIFT (0x020C) +#define CDC_TX_ANC0_FB_SHIFT (0x0210) +#define CDC_TX_ANC0_LPF_FF_A_CTL (0x0214) +#define CDC_TX_ANC0_LPF_FF_B_CTL (0x0218) +#define CDC_TX_ANC0_LPF_FB_CTL (0x021C) +#define CDC_TX_ANC0_SMLPF_CTL (0x0220) +#define CDC_TX_ANC0_DCFLT_SHIFT_CTL (0x0224) +#define CDC_TX_ANC0_IIR_ADAPT_CTL (0x0228) +#define CDC_TX_ANC0_IIR_COEFF_1_CTL (0x022C) +#define CDC_TX_ANC0_IIR_COEFF_2_CTL (0x0230) +#define CDC_TX_ANC0_FF_A_GAIN_CTL (0x0234) +#define CDC_TX_ANC0_FF_B_GAIN_CTL (0x0238) +#define CDC_TX_ANC0_FB_GAIN_CTL (0x023C) +#define CDC_TXn_TX_PATH_CTL(n) (0x0400 + 0x80 * n) +#define CDC_TXn_PCM_RATE_MASK GENMASK(3, 0) +#define CDC_TXn_PGA_MUTE_MASK BIT(4) +#define CDC_TXn_CLK_EN_MASK BIT(5) +#define CDC_TX0_TX_PATH_CTL (0x0400) +#define CDC_TXn_TX_PATH_CFG0(n) (0x0404 + 0x80 * n) +#define CDC_TX0_TX_PATH_CFG0 (0x0404) +#define CDC_TXn_PH_EN_MASK BIT(0) +#define CDC_TXn_ADC_MODE_MASK GENMASK(2, 1) +#define CDC_TXn_HPF_CUT_FREQ_MASK GENMASK(6, 5) +#define CDC_TXn_ADC_DMIC_SEL_MASK BIT(7) +#define CDC_TX0_TX_PATH_CFG1 (0x0408) +#define CDC_TXn_TX_VOL_CTL(n) (0x040C + 0x80 * n) +#define CDC_TX0_TX_VOL_CTL (0x040C) +#define CDC_TX0_TX_PATH_SEC0 (0x0410) +#define CDC_TX0_TX_PATH_SEC1 (0x0414) +#define CDC_TXn_TX_PATH_SEC2(n) (0x0418 + 0x80 * n) +#define CDC_TXn_HPF_F_CHANGE_MASK BIT(1) +#define CDC_TXn_HPF_ZERO_GATE_MASK BIT(0) +#define CDC_TX0_TX_PATH_SEC2 (0x0418) +#define CDC_TX0_TX_PATH_SEC3 (0x041C) +#define CDC_TX0_TX_PATH_SEC4 (0x0420) +#define CDC_TX0_TX_PATH_SEC5 (0x0424) +#define CDC_TX0_TX_PATH_SEC6 (0x0428) +#define CDC_TX0_TX_PATH_SEC7 (0x042C) +#define CDC_TX0_MBHC_CTL_EN_MASK BIT(6) +#define CDC_TX1_TX_PATH_CTL (0x0480) +#define CDC_TX1_TX_PATH_CFG0 (0x0484) +#define CDC_TX1_TX_PATH_CFG1 (0x0488) +#define CDC_TX1_TX_VOL_CTL (0x048C) +#define CDC_TX1_TX_PATH_SEC0 (0x0490) +#define CDC_TX1_TX_PATH_SEC1 (0x0494) +#define CDC_TX1_TX_PATH_SEC2 (0x0498) +#define CDC_TX1_TX_PATH_SEC3 (0x049C) +#define CDC_TX1_TX_PATH_SEC4 (0x04A0) +#define CDC_TX1_TX_PATH_SEC5 (0x04A4) +#define CDC_TX1_TX_PATH_SEC6 (0x04A8) +#define CDC_TX2_TX_PATH_CTL (0x0500) +#define CDC_TX2_TX_PATH_CFG0 (0x0504) +#define CDC_TX2_TX_PATH_CFG1 (0x0508) +#define CDC_TX2_TX_VOL_CTL (0x050C) +#define CDC_TX2_TX_PATH_SEC0 (0x0510) +#define CDC_TX2_TX_PATH_SEC1 (0x0514) +#define CDC_TX2_TX_PATH_SEC2 (0x0518) +#define CDC_TX2_TX_PATH_SEC3 (0x051C) +#define CDC_TX2_TX_PATH_SEC4 (0x0520) +#define CDC_TX2_TX_PATH_SEC5 (0x0524) +#define CDC_TX2_TX_PATH_SEC6 (0x0528) +#define CDC_TX3_TX_PATH_CTL (0x0580) +#define CDC_TX3_TX_PATH_CFG0 (0x0584) +#define CDC_TX3_TX_PATH_CFG1 (0x0588) +#define CDC_TX3_TX_VOL_CTL (0x058C) +#define CDC_TX3_TX_PATH_SEC0 (0x0590) +#define CDC_TX3_TX_PATH_SEC1 (0x0594) +#define CDC_TX3_TX_PATH_SEC2 (0x0598) +#define CDC_TX3_TX_PATH_SEC3 (0x059C) +#define CDC_TX3_TX_PATH_SEC4 (0x05A0) +#define CDC_TX3_TX_PATH_SEC5 (0x05A4) +#define CDC_TX3_TX_PATH_SEC6 (0x05A8) +#define CDC_TX4_TX_PATH_CTL (0x0600) +#define CDC_TX4_TX_PATH_CFG0 (0x0604) +#define CDC_TX4_TX_PATH_CFG1 (0x0608) +#define CDC_TX4_TX_VOL_CTL (0x060C) +#define CDC_TX4_TX_PATH_SEC0 (0x0610) +#define CDC_TX4_TX_PATH_SEC1 (0x0614) +#define CDC_TX4_TX_PATH_SEC2 (0x0618) +#define CDC_TX4_TX_PATH_SEC3 (0x061C) +#define CDC_TX4_TX_PATH_SEC4 (0x0620) +#define CDC_TX4_TX_PATH_SEC5 (0x0624) +#define CDC_TX4_TX_PATH_SEC6 (0x0628) +#define CDC_TX5_TX_PATH_CTL (0x0680) +#define CDC_TX5_TX_PATH_CFG0 (0x0684) +#define CDC_TX5_TX_PATH_CFG1 (0x0688) +#define CDC_TX5_TX_VOL_CTL (0x068C) +#define CDC_TX5_TX_PATH_SEC0 (0x0690) +#define CDC_TX5_TX_PATH_SEC1 (0x0694) +#define CDC_TX5_TX_PATH_SEC2 (0x0698) +#define CDC_TX5_TX_PATH_SEC3 (0x069C) +#define CDC_TX5_TX_PATH_SEC4 (0x06A0) +#define CDC_TX5_TX_PATH_SEC5 (0x06A4) +#define CDC_TX5_TX_PATH_SEC6 (0x06A8) +#define CDC_TX6_TX_PATH_CTL (0x0700) +#define CDC_TX6_TX_PATH_CFG0 (0x0704) +#define CDC_TX6_TX_PATH_CFG1 (0x0708) +#define CDC_TX6_TX_VOL_CTL (0x070C) +#define CDC_TX6_TX_PATH_SEC0 (0x0710) +#define CDC_TX6_TX_PATH_SEC1 (0x0714) +#define CDC_TX6_TX_PATH_SEC2 (0x0718) +#define CDC_TX6_TX_PATH_SEC3 (0x071C) +#define CDC_TX6_TX_PATH_SEC4 (0x0720) +#define CDC_TX6_TX_PATH_SEC5 (0x0724) +#define CDC_TX6_TX_PATH_SEC6 (0x0728) +#define CDC_TX7_TX_PATH_CTL (0x0780) +#define CDC_TX7_TX_PATH_CFG0 (0x0784) +#define CDC_TX7_TX_PATH_CFG1 (0x0788) +#define CDC_TX7_TX_VOL_CTL (0x078C) +#define CDC_TX7_TX_PATH_SEC0 (0x0790) +#define CDC_TX7_TX_PATH_SEC1 (0x0794) +#define CDC_TX7_TX_PATH_SEC2 (0x0798) +#define CDC_TX7_TX_PATH_SEC3 (0x079C) +#define CDC_TX7_TX_PATH_SEC4 (0x07A0) +#define CDC_TX7_TX_PATH_SEC5 (0x07A4) +#define CDC_TX7_TX_PATH_SEC6 (0x07A8) +#define TX_MAX_OFFSET (0x07A8) + +#define TX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) +#define TX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 +#define TX_ADC_MAX 5 +#define TX_ADC_TO_DMIC(n) ((n - TX_ADC_MAX)/2) +#define NUM_DECIMATORS 8 +#define TX_NUM_CLKS_MAX 5 +#define TX_MACRO_DMIC_UNMUTE_DELAY_MS 40 +#define TX_MACRO_AMIC_UNMUTE_DELAY_MS 100 +#define TX_MACRO_DMIC_HPF_DELAY_MS 300 +#define TX_MACRO_AMIC_HPF_DELAY_MS 300 +#define MCLK_FREQ 9600000 + +enum { + TX_MACRO_AIF_INVALID = 0, + TX_MACRO_AIF1_CAP, + TX_MACRO_AIF2_CAP, + TX_MACRO_AIF3_CAP, + TX_MACRO_MAX_DAIS +}; + +enum { + TX_MACRO_DEC0, + TX_MACRO_DEC1, + TX_MACRO_DEC2, + TX_MACRO_DEC3, + TX_MACRO_DEC4, + TX_MACRO_DEC5, + TX_MACRO_DEC6, + TX_MACRO_DEC7, + TX_MACRO_DEC_MAX, +}; + +enum { + TX_MACRO_CLK_DIV_2, + TX_MACRO_CLK_DIV_3, + TX_MACRO_CLK_DIV_4, + TX_MACRO_CLK_DIV_6, + TX_MACRO_CLK_DIV_8, + TX_MACRO_CLK_DIV_16, +}; + +enum { + MSM_DMIC, + SWR_MIC, + ANC_FB_TUNE1 +}; + +struct tx_mute_work { + struct tx_macro *tx; + u32 decimator; + struct delayed_work dwork; +}; + +struct hpf_work { + struct tx_macro *tx; + u8 decimator; + u8 hpf_cut_off_freq; + struct delayed_work dwork; +}; + +struct tx_macro { + struct device *dev; + struct snd_soc_component *component; + struct hpf_work tx_hpf_work[NUM_DECIMATORS]; + struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; + unsigned long active_ch_mask[TX_MACRO_MAX_DAIS]; + unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS]; + unsigned long active_decimator[TX_MACRO_MAX_DAIS]; + struct regmap *regmap; + struct clk_bulk_data clks[TX_NUM_CLKS_MAX]; + struct clk_hw hw; + bool dec_active[NUM_DECIMATORS]; + bool reset_swr; + int tx_mclk_users; + u16 dmic_clk_div; + bool bcs_enable; + int dec_mode[NUM_DECIMATORS]; + bool bcs_clk_en; +}; +#define to_tx_macro(_hw) container_of(_hw, struct tx_macro, hw) + +static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); + +static const struct reg_default tx_defaults[] = { + /* TX Macro */ + { CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, + { CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, + { CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x00}, + { CDC_TX_TOP_CSR_TOP_CFG0, 0x00}, + { CDC_TX_TOP_CSR_ANC_CFG, 0x00}, + { CDC_TX_TOP_CSR_SWR_CTRL, 0x00}, + { CDC_TX_TOP_CSR_FREQ_MCLK, 0x00}, + { CDC_TX_TOP_CSR_DEBUG_BUS, 0x00}, + { CDC_TX_TOP_CSR_DEBUG_EN, 0x00}, + { CDC_TX_TOP_CSR_TX_I2S_CTL, 0x0C}, + { CDC_TX_TOP_CSR_I2S_CLK, 0x00}, + { CDC_TX_TOP_CSR_I2S_RESET, 0x00}, + { CDC_TX_TOP_CSR_SWR_DMIC0_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_DMIC1_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_DMIC2_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_DMIC3_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_AMIC0_CTL, 0x00}, + { CDC_TX_TOP_CSR_SWR_AMIC1_CTL, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX4_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX5_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX6_CFG1, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00}, + { CDC_TX_INP_MUX_ADC_MUX7_CFG1, 0x00}, + { CDC_TX_ANC0_CLK_RESET_CTL, 0x00}, + { CDC_TX_ANC0_MODE_1_CTL, 0x00}, + { CDC_TX_ANC0_MODE_2_CTL, 0x00}, + { CDC_TX_ANC0_FF_SHIFT, 0x00}, + { CDC_TX_ANC0_FB_SHIFT, 0x00}, + { CDC_TX_ANC0_LPF_FF_A_CTL, 0x00}, + { CDC_TX_ANC0_LPF_FF_B_CTL, 0x00}, + { CDC_TX_ANC0_LPF_FB_CTL, 0x00}, + { CDC_TX_ANC0_SMLPF_CTL, 0x00}, + { CDC_TX_ANC0_DCFLT_SHIFT_CTL, 0x00}, + { CDC_TX_ANC0_IIR_ADAPT_CTL, 0x00}, + { CDC_TX_ANC0_IIR_COEFF_1_CTL, 0x00}, + { CDC_TX_ANC0_IIR_COEFF_2_CTL, 0x00}, + { CDC_TX_ANC0_FF_A_GAIN_CTL, 0x00}, + { CDC_TX_ANC0_FF_B_GAIN_CTL, 0x00}, + { CDC_TX_ANC0_FB_GAIN_CTL, 0x00}, + { CDC_TX0_TX_PATH_CTL, 0x04}, + { CDC_TX0_TX_PATH_CFG0, 0x10}, + { CDC_TX0_TX_PATH_CFG1, 0x0B}, + { CDC_TX0_TX_VOL_CTL, 0x00}, + { CDC_TX0_TX_PATH_SEC0, 0x00}, + { CDC_TX0_TX_PATH_SEC1, 0x00}, + { CDC_TX0_TX_PATH_SEC2, 0x01}, + { CDC_TX0_TX_PATH_SEC3, 0x3C}, + { CDC_TX0_TX_PATH_SEC4, 0x20}, + { CDC_TX0_TX_PATH_SEC5, 0x00}, + { CDC_TX0_TX_PATH_SEC6, 0x00}, + { CDC_TX0_TX_PATH_SEC7, 0x25}, + { CDC_TX1_TX_PATH_CTL, 0x04}, + { CDC_TX1_TX_PATH_CFG0, 0x10}, + { CDC_TX1_TX_PATH_CFG1, 0x0B}, + { CDC_TX1_TX_VOL_CTL, 0x00}, + { CDC_TX1_TX_PATH_SEC0, 0x00}, + { CDC_TX1_TX_PATH_SEC1, 0x00}, + { CDC_TX1_TX_PATH_SEC2, 0x01}, + { CDC_TX1_TX_PATH_SEC3, 0x3C}, + { CDC_TX1_TX_PATH_SEC4, 0x20}, + { CDC_TX1_TX_PATH_SEC5, 0x00}, + { CDC_TX1_TX_PATH_SEC6, 0x00}, + { CDC_TX2_TX_PATH_CTL, 0x04}, + { CDC_TX2_TX_PATH_CFG0, 0x10}, + { CDC_TX2_TX_PATH_CFG1, 0x0B}, + { CDC_TX2_TX_VOL_CTL, 0x00}, + { CDC_TX2_TX_PATH_SEC0, 0x00}, + { CDC_TX2_TX_PATH_SEC1, 0x00}, + { CDC_TX2_TX_PATH_SEC2, 0x01}, + { CDC_TX2_TX_PATH_SEC3, 0x3C}, + { CDC_TX2_TX_PATH_SEC4, 0x20}, + { CDC_TX2_TX_PATH_SEC5, 0x00}, + { CDC_TX2_TX_PATH_SEC6, 0x00}, + { CDC_TX3_TX_PATH_CTL, 0x04}, + { CDC_TX3_TX_PATH_CFG0, 0x10}, + { CDC_TX3_TX_PATH_CFG1, 0x0B}, + { CDC_TX3_TX_VOL_CTL, 0x00}, + { CDC_TX3_TX_PATH_SEC0, 0x00}, + { CDC_TX3_TX_PATH_SEC1, 0x00}, + { CDC_TX3_TX_PATH_SEC2, 0x01}, + { CDC_TX3_TX_PATH_SEC3, 0x3C}, + { CDC_TX3_TX_PATH_SEC4, 0x20}, + { CDC_TX3_TX_PATH_SEC5, 0x00}, + { CDC_TX3_TX_PATH_SEC6, 0x00}, + { CDC_TX4_TX_PATH_CTL, 0x04}, + { CDC_TX4_TX_PATH_CFG0, 0x10}, + { CDC_TX4_TX_PATH_CFG1, 0x0B}, + { CDC_TX4_TX_VOL_CTL, 0x00}, + { CDC_TX4_TX_PATH_SEC0, 0x00}, + { CDC_TX4_TX_PATH_SEC1, 0x00}, + { CDC_TX4_TX_PATH_SEC2, 0x01}, + { CDC_TX4_TX_PATH_SEC3, 0x3C}, + { CDC_TX4_TX_PATH_SEC4, 0x20}, + { CDC_TX4_TX_PATH_SEC5, 0x00}, + { CDC_TX4_TX_PATH_SEC6, 0x00}, + { CDC_TX5_TX_PATH_CTL, 0x04}, + { CDC_TX5_TX_PATH_CFG0, 0x10}, + { CDC_TX5_TX_PATH_CFG1, 0x0B}, + { CDC_TX5_TX_VOL_CTL, 0x00}, + { CDC_TX5_TX_PATH_SEC0, 0x00}, + { CDC_TX5_TX_PATH_SEC1, 0x00}, + { CDC_TX5_TX_PATH_SEC2, 0x01}, + { CDC_TX5_TX_PATH_SEC3, 0x3C}, + { CDC_TX5_TX_PATH_SEC4, 0x20}, + { CDC_TX5_TX_PATH_SEC5, 0x00}, + { CDC_TX5_TX_PATH_SEC6, 0x00}, + { CDC_TX6_TX_PATH_CTL, 0x04}, + { CDC_TX6_TX_PATH_CFG0, 0x10}, + { CDC_TX6_TX_PATH_CFG1, 0x0B}, + { CDC_TX6_TX_VOL_CTL, 0x00}, + { CDC_TX6_TX_PATH_SEC0, 0x00}, + { CDC_TX6_TX_PATH_SEC1, 0x00}, + { CDC_TX6_TX_PATH_SEC2, 0x01}, + { CDC_TX6_TX_PATH_SEC3, 0x3C}, + { CDC_TX6_TX_PATH_SEC4, 0x20}, + { CDC_TX6_TX_PATH_SEC5, 0x00}, + { CDC_TX6_TX_PATH_SEC6, 0x00}, + { CDC_TX7_TX_PATH_CTL, 0x04}, + { CDC_TX7_TX_PATH_CFG0, 0x10}, + { CDC_TX7_TX_PATH_CFG1, 0x0B}, + { CDC_TX7_TX_VOL_CTL, 0x00}, + { CDC_TX7_TX_PATH_SEC0, 0x00}, + { CDC_TX7_TX_PATH_SEC1, 0x00}, + { CDC_TX7_TX_PATH_SEC2, 0x01}, + { CDC_TX7_TX_PATH_SEC3, 0x3C}, + { CDC_TX7_TX_PATH_SEC4, 0x20}, + { CDC_TX7_TX_PATH_SEC5, 0x00}, + { CDC_TX7_TX_PATH_SEC6, 0x00}, +}; + +static bool tx_is_volatile_register(struct device *dev, unsigned int reg) +{ + /* Update volatile list for tx/tx macros */ + switch (reg) { + case CDC_TX_TOP_CSR_SWR_DMIC0_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC1_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC2_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC3_CTL: + return true; + } + return false; +} + +static bool tx_is_rw_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CDC_TX_CLK_RST_CTRL_MCLK_CONTROL: + case CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL: + case CDC_TX_CLK_RST_CTRL_SWR_CONTROL: + case CDC_TX_TOP_CSR_TOP_CFG0: + case CDC_TX_TOP_CSR_ANC_CFG: + case CDC_TX_TOP_CSR_SWR_CTRL: + case CDC_TX_TOP_CSR_FREQ_MCLK: + case CDC_TX_TOP_CSR_DEBUG_BUS: + case CDC_TX_TOP_CSR_DEBUG_EN: + case CDC_TX_TOP_CSR_TX_I2S_CTL: + case CDC_TX_TOP_CSR_I2S_CLK: + case CDC_TX_TOP_CSR_I2S_RESET: + case CDC_TX_TOP_CSR_SWR_DMIC0_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC1_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC2_CTL: + case CDC_TX_TOP_CSR_SWR_DMIC3_CTL: + case CDC_TX_TOP_CSR_SWR_AMIC0_CTL: + case CDC_TX_TOP_CSR_SWR_AMIC1_CTL: + case CDC_TX_ANC0_CLK_RESET_CTL: + case CDC_TX_ANC0_MODE_1_CTL: + case CDC_TX_ANC0_MODE_2_CTL: + case CDC_TX_ANC0_FF_SHIFT: + case CDC_TX_ANC0_FB_SHIFT: + case CDC_TX_ANC0_LPF_FF_A_CTL: + case CDC_TX_ANC0_LPF_FF_B_CTL: + case CDC_TX_ANC0_LPF_FB_CTL: + case CDC_TX_ANC0_SMLPF_CTL: + case CDC_TX_ANC0_DCFLT_SHIFT_CTL: + case CDC_TX_ANC0_IIR_ADAPT_CTL: + case CDC_TX_ANC0_IIR_COEFF_1_CTL: + case CDC_TX_ANC0_IIR_COEFF_2_CTL: + case CDC_TX_ANC0_FF_A_GAIN_CTL: + case CDC_TX_ANC0_FF_B_GAIN_CTL: + case CDC_TX_ANC0_FB_GAIN_CTL: + case CDC_TX_INP_MUX_ADC_MUX0_CFG0: + case CDC_TX_INP_MUX_ADC_MUX0_CFG1: + case CDC_TX_INP_MUX_ADC_MUX1_CFG0: + case CDC_TX_INP_MUX_ADC_MUX1_CFG1: + case CDC_TX_INP_MUX_ADC_MUX2_CFG0: + case CDC_TX_INP_MUX_ADC_MUX2_CFG1: + case CDC_TX_INP_MUX_ADC_MUX3_CFG0: + case CDC_TX_INP_MUX_ADC_MUX3_CFG1: + case CDC_TX_INP_MUX_ADC_MUX4_CFG0: + case CDC_TX_INP_MUX_ADC_MUX4_CFG1: + case CDC_TX_INP_MUX_ADC_MUX5_CFG0: + case CDC_TX_INP_MUX_ADC_MUX5_CFG1: + case CDC_TX_INP_MUX_ADC_MUX6_CFG0: + case CDC_TX_INP_MUX_ADC_MUX6_CFG1: + case CDC_TX_INP_MUX_ADC_MUX7_CFG0: + case CDC_TX_INP_MUX_ADC_MUX7_CFG1: + case CDC_TX0_TX_PATH_CTL: + case CDC_TX0_TX_PATH_CFG0: + case CDC_TX0_TX_PATH_CFG1: + case CDC_TX0_TX_VOL_CTL: + case CDC_TX0_TX_PATH_SEC0: + case CDC_TX0_TX_PATH_SEC1: + case CDC_TX0_TX_PATH_SEC2: + case CDC_TX0_TX_PATH_SEC3: + case CDC_TX0_TX_PATH_SEC4: + case CDC_TX0_TX_PATH_SEC5: + case CDC_TX0_TX_PATH_SEC6: + case CDC_TX0_TX_PATH_SEC7: + case CDC_TX1_TX_PATH_CTL: + case CDC_TX1_TX_PATH_CFG0: + case CDC_TX1_TX_PATH_CFG1: + case CDC_TX1_TX_VOL_CTL: + case CDC_TX1_TX_PATH_SEC0: + case CDC_TX1_TX_PATH_SEC1: + case CDC_TX1_TX_PATH_SEC2: + case CDC_TX1_TX_PATH_SEC3: + case CDC_TX1_TX_PATH_SEC4: + case CDC_TX1_TX_PATH_SEC5: + case CDC_TX1_TX_PATH_SEC6: + case CDC_TX2_TX_PATH_CTL: + case CDC_TX2_TX_PATH_CFG0: + case CDC_TX2_TX_PATH_CFG1: + case CDC_TX2_TX_VOL_CTL: + case CDC_TX2_TX_PATH_SEC0: + case CDC_TX2_TX_PATH_SEC1: + case CDC_TX2_TX_PATH_SEC2: + case CDC_TX2_TX_PATH_SEC3: + case CDC_TX2_TX_PATH_SEC4: + case CDC_TX2_TX_PATH_SEC5: + case CDC_TX2_TX_PATH_SEC6: + case CDC_TX3_TX_PATH_CTL: + case CDC_TX3_TX_PATH_CFG0: + case CDC_TX3_TX_PATH_CFG1: + case CDC_TX3_TX_VOL_CTL: + case CDC_TX3_TX_PATH_SEC0: + case CDC_TX3_TX_PATH_SEC1: + case CDC_TX3_TX_PATH_SEC2: + case CDC_TX3_TX_PATH_SEC3: + case CDC_TX3_TX_PATH_SEC4: + case CDC_TX3_TX_PATH_SEC5: + case CDC_TX3_TX_PATH_SEC6: + case CDC_TX4_TX_PATH_CTL: + case CDC_TX4_TX_PATH_CFG0: + case CDC_TX4_TX_PATH_CFG1: + case CDC_TX4_TX_VOL_CTL: + case CDC_TX4_TX_PATH_SEC0: + case CDC_TX4_TX_PATH_SEC1: + case CDC_TX4_TX_PATH_SEC2: + case CDC_TX4_TX_PATH_SEC3: + case CDC_TX4_TX_PATH_SEC4: + case CDC_TX4_TX_PATH_SEC5: + case CDC_TX4_TX_PATH_SEC6: + case CDC_TX5_TX_PATH_CTL: + case CDC_TX5_TX_PATH_CFG0: + case CDC_TX5_TX_PATH_CFG1: + case CDC_TX5_TX_VOL_CTL: + case CDC_TX5_TX_PATH_SEC0: + case CDC_TX5_TX_PATH_SEC1: + case CDC_TX5_TX_PATH_SEC2: + case CDC_TX5_TX_PATH_SEC3: + case CDC_TX5_TX_PATH_SEC4: + case CDC_TX5_TX_PATH_SEC5: + case CDC_TX5_TX_PATH_SEC6: + case CDC_TX6_TX_PATH_CTL: + case CDC_TX6_TX_PATH_CFG0: + case CDC_TX6_TX_PATH_CFG1: + case CDC_TX6_TX_VOL_CTL: + case CDC_TX6_TX_PATH_SEC0: + case CDC_TX6_TX_PATH_SEC1: + case CDC_TX6_TX_PATH_SEC2: + case CDC_TX6_TX_PATH_SEC3: + case CDC_TX6_TX_PATH_SEC4: + case CDC_TX6_TX_PATH_SEC5: + case CDC_TX6_TX_PATH_SEC6: + case CDC_TX7_TX_PATH_CTL: + case CDC_TX7_TX_PATH_CFG0: + case CDC_TX7_TX_PATH_CFG1: + case CDC_TX7_TX_VOL_CTL: + case CDC_TX7_TX_PATH_SEC0: + case CDC_TX7_TX_PATH_SEC1: + case CDC_TX7_TX_PATH_SEC2: + case CDC_TX7_TX_PATH_SEC3: + case CDC_TX7_TX_PATH_SEC4: + case CDC_TX7_TX_PATH_SEC5: + case CDC_TX7_TX_PATH_SEC6: + return true; + } + + return false; +} + +static const struct regmap_config tx_regmap_config = { + .name = "tx_macro", + .reg_bits = 16, + .val_bits = 32, + .reg_stride = 4, + .cache_type = REGCACHE_FLAT, + .max_register = TX_MAX_OFFSET, + .reg_defaults = tx_defaults, + .num_reg_defaults = ARRAY_SIZE(tx_defaults), + .writeable_reg = tx_is_rw_register, + .volatile_reg = tx_is_volatile_register, + .readable_reg = tx_is_rw_register, +}; + +static int tx_macro_mclk_enable(struct tx_macro *tx, + bool mclk_enable) +{ + struct regmap *regmap = tx->regmap; + + if (mclk_enable) { + if (tx->tx_mclk_users == 0) { + regcache_mark_dirty(regmap); + regcache_sync(regmap); + /* 9.6MHz MCLK, set value 0x00 if other frequency */ + regmap_update_bits(regmap, CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01); + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + CDC_TX_MCLK_EN_MASK, + CDC_TX_MCLK_ENABLE); + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_TX_FS_CNT_EN_MASK, + CDC_TX_FS_CNT_ENABLE); + } + tx->tx_mclk_users++; + } else { + if (tx->tx_mclk_users <= 0) { + dev_err(tx->dev, "clock already disabled\n"); + tx->tx_mclk_users = 0; + goto exit; + } + tx->tx_mclk_users--; + if (tx->tx_mclk_users == 0) { + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + CDC_TX_FS_CNT_EN_MASK, 0x0); + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + CDC_TX_MCLK_EN_MASK, 0x0); + } + } +exit: + return 0; +} + +static bool is_amic_enabled(struct snd_soc_component *component, int decimator) +{ + u16 adc_mux_reg, adc_reg, adc_n; + + adc_mux_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG1(decimator); + + if (snd_soc_component_read(component, adc_mux_reg) & SWR_MIC) { + adc_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG0(decimator); + adc_n = snd_soc_component_read_field(component, adc_reg, + CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK); + if (adc_n < TX_ADC_MAX) + return true; + } + + return false; +} + +static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct tx_macro *tx; + struct snd_soc_component *component; + u16 dec_cfg_reg, hpf_gate_reg; + u8 hpf_cut_off_freq; + u16 adc_reg, adc_n; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + tx = hpf_work->tx; + component = tx->component; + hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; + + dec_cfg_reg = CDC_TXn_TX_PATH_CFG0(hpf_work->decimator); + hpf_gate_reg = CDC_TXn_TX_PATH_SEC2(hpf_work->decimator); + + if (is_amic_enabled(component, hpf_work->decimator)) { + adc_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG0(hpf_work->decimator); + adc_n = snd_soc_component_read(component, adc_reg) & + CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK; + /* analog mic clear TX hold */ + snd_soc_component_write_field(component, + dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK, + hpf_cut_off_freq); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x02); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x01); + } else { + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK, + hpf_cut_off_freq); + snd_soc_component_write_field(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK, 0x1); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_component_write_field(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK, 0x0); + } +} + +static void tx_macro_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork; + struct snd_soc_component *component; + struct tx_macro *tx; + struct delayed_work *delayed_work; + u8 decimator; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + tx = tx_mute_dwork->tx; + component = tx->component; + decimator = tx_mute_dwork->decimator; + + snd_soc_component_write_field(component, CDC_TXn_TX_PATH_CTL(decimator), + CDC_TXn_PGA_MUTE_MASK, 0x0); +} + +static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int path = e->shift_l; + + ucontrol->value.integer.value[0] = tx->dec_mode[path]; + + return 0; +} + +static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + int value = ucontrol->value.integer.value[0]; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int path = e->shift_l; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + tx->dec_mode[path] = value; + + return 0; +} + +static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = tx->bcs_enable; + + return 0; +} + +static int tx_macro_set_bcs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + int value = ucontrol->value.integer.value[0]; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + tx->bcs_enable = value; + + return 0; +} + +static int tx_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + u32 decimator, sample_rate; + int tx_fs_rate; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + sample_rate = params_rate(params); + switch (sample_rate) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 3; + break; + case 48000: + tx_fs_rate = 4; + break; + case 96000: + tx_fs_rate = 5; + break; + case 192000: + tx_fs_rate = 6; + break; + case 384000: + tx_fs_rate = 7; + break; + default: + dev_err(component->dev, "%s: Invalid TX sample rate: %d\n", + __func__, params_rate(params)); + return -EINVAL; + } + + for_each_set_bit(decimator, &tx->active_ch_mask[dai->id], + TX_MACRO_DEC_MAX) { + if (decimator >= 0) { + snd_soc_component_update_bits(component, + CDC_TXn_TX_PATH_CTL(decimator), + CDC_TXn_PCM_RATE_MASK, + tx_fs_rate); + } else { + dev_err(component->dev, "%s: ERROR: Invalid decimator: %d\n", + __func__, decimator); + return -EINVAL; + } + } + return 0; +} + +static int tx_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct snd_soc_component *component = dai->component; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + switch (dai->id) { + case TX_MACRO_AIF1_CAP: + case TX_MACRO_AIF2_CAP: + case TX_MACRO_AIF3_CAP: + *tx_slot = tx->active_ch_mask[dai->id]; + *tx_num = tx->active_ch_cnt[dai->id]; + break; + default: + break; + } + return 0; +} + +static int tx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_component *component = dai->component; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + u16 decimator; + + decimator = tx->active_decimator[dai->id]; + + if (mute) + snd_soc_component_write_field(component, + CDC_TXn_TX_PATH_CTL(decimator), + CDC_TXn_PGA_MUTE_MASK, 0x1); + else + snd_soc_component_update_bits(component, + CDC_TXn_TX_PATH_CTL(decimator), + CDC_TXn_PGA_MUTE_MASK, 0x0); + + return 0; +} + +static struct snd_soc_dai_ops tx_macro_dai_ops = { + .hw_params = tx_macro_hw_params, + .get_channel_map = tx_macro_get_channel_map, + .mute_stream = tx_macro_digital_mute, +}; + +static struct snd_soc_dai_driver tx_macro_dai[] = { + { + .name = "tx_macro_tx1", + .id = TX_MACRO_AIF1_CAP, + .capture = { + .stream_name = "TX_AIF1 Capture", + .rates = TX_MACRO_RATES, + .formats = TX_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tx_macro_dai_ops, + }, + { + .name = "tx_macro_tx2", + .id = TX_MACRO_AIF2_CAP, + .capture = { + .stream_name = "TX_AIF2 Capture", + .rates = TX_MACRO_RATES, + .formats = TX_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tx_macro_dai_ops, + }, + { + .name = "tx_macro_tx3", + .id = TX_MACRO_AIF3_CAP, + .capture = { + .stream_name = "TX_AIF3 Capture", + .rates = TX_MACRO_RATES, + .formats = TX_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tx_macro_dai_ops, + }, +}; + +static const char * const dec_mode_mux_text[] = { + "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", +}; + +static const struct soc_enum dec_mode_mux_enum[] = { + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 4, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 5, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 6, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 7, ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text), +}; + +static const struct snd_kcontrol_new tx_macro_snd_controls[] = { + SOC_SINGLE_S8_TLV("TX_DEC0 Volume", + CDC_TX0_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC1 Volume", + CDC_TX1_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC2 Volume", + CDC_TX2_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC3 Volume", + CDC_TX3_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC4 Volume", + CDC_TX4_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC5 Volume", + CDC_TX5_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC6 Volume", + CDC_TX6_TX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("TX_DEC7 Volume", + CDC_TX7_TX_VOL_CTL, + -84, 40, digital_gain), + + SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum[0], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum[1], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum[2], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum[3], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum[4], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum[5], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum[6], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum[7], + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0, + tx_macro_get_bcs, tx_macro_set_bcs), +}; + +static int tx_macro_swrm_clock(void *handle, bool enable) +{ + struct tx_macro *tx = (struct tx_macro *) handle; + struct regmap *regmap = tx->regmap; + + if (enable) { + tx_macro_mclk_enable(tx, true); + if (tx->reset_swr) + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_RESET_MASK, + CDC_TX_SWR_RESET_ENABLE); + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_CLK_EN_MASK, + CDC_TX_SWR_CLK_ENABLE); + if (tx->reset_swr) + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_RESET_MASK, 0x0); + tx->reset_swr = false; + } else { + regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + CDC_TX_SWR_CLK_EN_MASK, 0x0); + + tx_macro_mclk_enable(tx, false); + } + return 0; +} + +static int tx_macro_component_probe(struct snd_soc_component *comp) +{ + struct tx_macro *tx = snd_soc_component_get_drvdata(comp); + int i; + + snd_soc_component_init_regmap(comp, tx->regmap); + + for (i = 0; i < NUM_DECIMATORS; i++) { + tx->tx_hpf_work[i].tx = tx; + tx->tx_hpf_work[i].decimator = i; + INIT_DELAYED_WORK(&tx->tx_hpf_work[i].dwork, + tx_macro_tx_hpf_corner_freq_callback); + } + + for (i = 0; i < NUM_DECIMATORS; i++) { + tx->tx_mute_dwork[i].tx = tx; + tx->tx_mute_dwork[i].decimator = i; + INIT_DELAYED_WORK(&tx->tx_mute_dwork[i].dwork, + tx_macro_mute_update_callback); + } + tx->component = comp; + + snd_soc_component_update_bits(comp, CDC_TX0_TX_PATH_SEC7, 0x3F, + 0x0A); + + return 0; +} + +static int swclk_gate_enable(struct clk_hw *hw) +{ + return tx_macro_swrm_clock(to_tx_macro(hw), true); +} + +static void swclk_gate_disable(struct clk_hw *hw) +{ + tx_macro_swrm_clock(to_tx_macro(hw), false); +} + +static int swclk_gate_is_enabled(struct clk_hw *hw) +{ + struct tx_macro *tx = to_tx_macro(hw); + int ret, val; + + regmap_read(tx->regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, &val); + ret = val & BIT(0); + + return ret; +} + +static unsigned long swclk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate / 2; +} + +static const struct clk_ops swclk_gate_ops = { + .prepare = swclk_gate_enable, + .unprepare = swclk_gate_disable, + .is_enabled = swclk_gate_is_enabled, + .recalc_rate = swclk_recalc_rate, + +}; + +static struct clk *tx_macro_register_mclk_output(struct tx_macro *tx) +{ + struct device *dev = tx->dev; + struct device_node *np = dev->of_node; + const char *parent_clk_name = NULL; + const char *clk_name = "lpass-tx-mclk"; + struct clk_hw *hw; + struct clk_init_data init; + int ret; + + parent_clk_name = __clk_get_name(tx->clks[2].clk); + + init.name = clk_name; + init.ops = &swclk_gate_ops; + init.flags = 0; + init.parent_names = &parent_clk_name; + init.num_parents = 1; + tx->hw.init = &init; + hw = &tx->hw; + ret = clk_hw_register(tx->dev, hw); + if (ret) + return ERR_PTR(ret); + + of_clk_add_provider(np, of_clk_src_simple_get, hw->clk); + + return NULL; +} + +static const struct snd_soc_component_driver tx_macro_component_drv = { + .name = "RX-MACRO", + .probe = tx_macro_component_probe, + .controls = tx_macro_snd_controls, + .num_controls = ARRAY_SIZE(tx_macro_snd_controls), +}; + +static int tx_macro_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tx_macro *tx; + void __iomem *base; + int ret; + + tx = devm_kzalloc(dev, sizeof(*tx), GFP_KERNEL); + if (!tx) + return -ENOMEM; + + tx->clks[0].id = "macro"; + tx->clks[1].id = "dcodec"; + tx->clks[2].id = "mclk"; + tx->clks[3].id = "npl"; + tx->clks[4].id = "fsgen"; + + ret = devm_clk_bulk_get(dev, TX_NUM_CLKS_MAX, tx->clks); + if (ret) { + dev_err(dev, "Error getting RX Clocks (%d)\n", ret); + return ret; + } + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + tx->regmap = devm_regmap_init_mmio(dev, base, &tx_regmap_config); + + dev_set_drvdata(dev, tx); + + tx->reset_swr = true; + tx->dev = dev; + + /* set MCLK and NPL rates */ + clk_set_rate(tx->clks[2].clk, MCLK_FREQ); + clk_set_rate(tx->clks[3].clk, MCLK_FREQ); + + ret = clk_bulk_prepare_enable(TX_NUM_CLKS_MAX, tx->clks); + if (ret) + return ret; + + tx_macro_register_mclk_output(tx); + + ret = devm_snd_soc_register_component(dev, &tx_macro_component_drv, + tx_macro_dai, + ARRAY_SIZE(tx_macro_dai)); + if (ret) + goto err; + return ret; +err: + clk_bulk_disable_unprepare(TX_NUM_CLKS_MAX, tx->clks); + + return ret; +} + +static int tx_macro_remove(struct platform_device *pdev) +{ + struct tx_macro *tx = dev_get_drvdata(&pdev->dev); + + of_clk_del_provider(pdev->dev.of_node); + + clk_bulk_disable_unprepare(TX_NUM_CLKS_MAX, tx->clks); + + return 0; +} + +static const struct of_device_id tx_macro_dt_match[] = { + { .compatible = "qcom,sm8250-lpass-tx-macro" }, + { } +}; +static struct platform_driver tx_macro_driver = { + .driver = { + .name = "tx_macro", + .of_match_table = tx_macro_dt_match, + .suppress_bind_attrs = true, + }, + .probe = tx_macro_probe, + .remove = tx_macro_remove, +}; + +module_platform_driver(tx_macro_driver); + +MODULE_DESCRIPTION("TX macro driver"); +MODULE_LICENSE("GPL"); From patchwork Thu Jan 28 14:19:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 372613 Delivered-To: patch@linaro.org Received: by 2002:a02:a60d:0:0:0:0:0 with SMTP id c13csp1299688jam; Thu, 28 Jan 2021 06:25:27 -0800 (PST) X-Google-Smtp-Source: ABdhPJx4W/PymKB8ngP0REkAuKwi9nb+uj4SWcLjB91mZlw8KUhg0Fek+V+o7vfs/75xkHCFLXqr X-Received: by 2002:a05:6402:d05:: with SMTP id eb5mr14058224edb.143.1611843927428; Thu, 28 Jan 2021 06:25:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611843927; cv=none; d=google.com; s=arc-20160816; b=Ey2C76meUHPMsCZO6AHMIdyGakP5ksXSFuChPg6FAbZepz1bUwPau7B8RYJwtAdqzW P6mfkjpmRLFMMMVfB3vdN2n8ls7+eGbYkomvNki2dJ+X3srReh3WqwrIINTO7izpolPZ xKrbZ6wypTCZi4zhsLRhOH0eS94PC+SxhA3L+rLQOhFzkDKIlBghzEWDe8KBgDL9OM9l +raeP0vKgQ6QtXXVyuP5C0nchrThaSQh3k2/6i9i2fu249vfu8njcwWbMmmuePID3G1E Y9FdFsEy45gmuiEQQp/VZxzU5EuEF1FSHVrZF7Yt/06i+zCI1+Iwqlu2tYstSeI+OZvt V4yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=C2C4SZf56eBXFa1NaDkZ7qGrx+cPeuV29t21rQaXPIY=; b=OHJ/LYWEcgeMMKj+D/BKof8M9ALRhG0El6pVnEee3t3b3ILHxPif2G0ZfasDhc/Lgy Widqc8euTstdI2TNnGYFElc+dUpZh31En/4JrAfq8KA4tgRFdASwIHsIiXFdYet5f2cf DIWorzrD3cG/vB7nkPB8HButf57FsgQOv2GT3x4Qy4mclvxmZwhL2FlbGpirPx0ILEgn WnnL/7iPlhh1fKWd5iQzt2Et2njNSZK+JPxwUOjCFASvdqgA8JtavaViANxvMIbLK4ty fnM0wZY6eHmfJYSZ91U4oRosy9lYF9ZOv679U7fCHEgjvzHQ1V5Cu0A8ErvntO9NkJnU IsRg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RisX8Mia; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d14si2496304ejc.30.2021.01.28.06.25.26; Thu, 28 Jan 2021 06:25:27 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RisX8Mia; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231439AbhA1OYI (ORCPT + 6 others); Thu, 28 Jan 2021 09:24:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41224 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231586AbhA1OVn (ORCPT ); Thu, 28 Jan 2021 09:21:43 -0500 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76A5DC0617AA for ; Thu, 28 Jan 2021 06:20:05 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id g10so5585106wrx.1 for ; Thu, 28 Jan 2021 06:20:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=C2C4SZf56eBXFa1NaDkZ7qGrx+cPeuV29t21rQaXPIY=; b=RisX8MiaLOaiNgy+zNBOW2lVvLr388lV5AL2oCPDi/oYedR9Cja0EjIGdXIbmI3B6O AegSkqMgIRXck07W3eM0GTCHWktHwZMjKLudrWTXXMckZC3Nq/lWAlBdeZhVi3Z0cGqo vOi+C2pUL1BhZaqMQ5no4I478V2QwzJIeD5ySRpc6GnJvjSkDre9GGiSRt+YPge74LS8 k/rlb9XFvEbpm79FZjjUqHjzWvQUf0PLUAPO0qV2LK8YoGZG2Sx61E3otan3vI5lHpZ/ wswjNHSmZxESdHeL8dZm5+b7ojOoJvWZG3+hQoaY8bID3wqLprxuwD7x77G8QQ6XMuWj kOFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=C2C4SZf56eBXFa1NaDkZ7qGrx+cPeuV29t21rQaXPIY=; b=UvPzL7a0S4IXQwIuusB89zLLiA9t4l2f7KO19vxD+ebNrQ8QTp5T4bSL1uejBDedcj vlljx9X6h4K3Tsw0taqnG1LPaLvM1Sp0JT+q1Uve0OH3K2AUbhKVZ5RfVwYfI3B2nieP mCt6wzuxhCQZz8eUSqncmIM7BeOi8lZoFjA+0oSe10hHUIeRPbDQ/UMN1lfyCNLRh4th 0IuP6yOBkWZU1jQ0ENybUdmaMpbH6LYdB3Bay9uYNBud/JqKQKfbQVMJBTHfi6jzcTsF b9KqCxwis881fh5b/8FBRKcXfVyzTOg/TDFrGALH0sYsUsFwH21F1RzVVbzIe0pzyeuX tWuA== X-Gm-Message-State: AOAM531ZRrnGg9LJJ2HBSr/NFRsrMF3LcYp/zGc0SHJKdfClljtwbQHe nf7gpi12HjBQ7At/Y4vXv+34KQ== X-Received: by 2002:adf:f183:: with SMTP id h3mr16897862wro.30.1611843604128; Thu, 28 Jan 2021 06:20:04 -0800 (PST) Received: from srini-hackbox.lan (cpc86377-aztw32-2-0-cust226.18-1.cable.virginm.net. [92.233.226.227]) by smtp.gmail.com with ESMTPSA id d9sm7257096wrq.74.2021.01.28.06.20.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 06:20:03 -0800 (PST) From: Srinivas Kandagatla To: broonie@kernel.org Cc: perex@perex.cz, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, devicetree@vger.kernel.org, robh+dt@kernel.org, Srinivas Kandagatla Subject: [PATCH 7/7] ASoC: codec: lpass-tx-macro: add dapm widgets and route Date: Thu, 28 Jan 2021 14:19:29 +0000 Message-Id: <20210128141929.26573-8-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> References: <20210128141929.26573-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds dapm widgets and routes on this codec Signed-off-by: Srinivas Kandagatla --- sound/soc/codecs/lpass-tx-macro.c | 685 ++++++++++++++++++++++++++++++ 1 file changed, 685 insertions(+) -- 2.21.0 diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index 604bd14860a3..06f4ff82d6f8 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -712,6 +712,289 @@ static void tx_macro_mute_update_callback(struct work_struct *work) CDC_TXn_PGA_MUTE_MASK, 0x0); } +static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tx_macro_mclk_enable(tx, true); + break; + case SND_SOC_DAPM_POST_PMD: + tx_macro_mclk_enable(tx, false); + break; + default: + break; + } + + return 0; +} + +static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val, dmic; + u16 mic_sel_reg; + u16 dmic_clk_reg; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + val = ucontrol->value.enumerated.item[0]; + + switch (e->reg) { + case CDC_TX_INP_MUX_ADC_MUX0_CFG0: + mic_sel_reg = CDC_TX0_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX1_CFG0: + mic_sel_reg = CDC_TX1_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX2_CFG0: + mic_sel_reg = CDC_TX2_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX3_CFG0: + mic_sel_reg = CDC_TX3_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX4_CFG0: + mic_sel_reg = CDC_TX4_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX5_CFG0: + mic_sel_reg = CDC_TX5_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX6_CFG0: + mic_sel_reg = CDC_TX6_TX_PATH_CFG0; + break; + case CDC_TX_INP_MUX_ADC_MUX7_CFG0: + mic_sel_reg = CDC_TX7_TX_PATH_CFG0; + break; + } + + if (val != 0) { + if (val < 5) { + snd_soc_component_write_field(component, mic_sel_reg, + CDC_TXn_ADC_DMIC_SEL_MASK, 0); + } else { + snd_soc_component_write_field(component, mic_sel_reg, + CDC_TXn_ADC_DMIC_SEL_MASK, 1); + dmic = TX_ADC_TO_DMIC(val); + dmic_clk_reg = CDC_TX_TOP_CSR_SWR_DMICn_CTL(dmic); + snd_soc_component_write_field(component, dmic_clk_reg, + CDC_TX_SWR_DMIC_CLK_SEL_MASK, + tx->dmic_clk_div); + } + } + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + u32 dai_id = widget->shift; + u32 dec_id = mc->shift; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + if (test_bit(dec_id, &tx->active_ch_mask[dai_id])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + return 0; +} + +static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct snd_soc_dapm_update *update = NULL; + struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + u32 dai_id = widget->shift; + u32 dec_id = mc->shift; + u32 enable = ucontrol->value.integer.value[0]; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + if (enable) { + set_bit(dec_id, &tx->active_ch_mask[dai_id]); + tx->active_ch_cnt[dai_id]++; + tx->active_decimator[dai_id] = dec_id; + } else { + tx->active_ch_cnt[dai_id]--; + clear_bit(dec_id, &tx->active_ch_mask[dai_id]); + tx->active_decimator[dai_id] = -1; + } + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); + + return 0; +} + +static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + unsigned int decimator; + u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg, tx_gain_ctl_reg; + u8 hpf_cut_off_freq; + int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS; + int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS; + u16 adc_mux_reg, adc_reg, adc_n, dmic; + u16 dmic_clk_reg; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + decimator = w->shift; + tx_vol_ctl_reg = CDC_TXn_TX_PATH_CTL(decimator); + hpf_gate_reg = CDC_TXn_TX_PATH_SEC2(decimator); + dec_cfg_reg = CDC_TXn_TX_PATH_CFG0(decimator); + tx_gain_ctl_reg = CDC_TXn_TX_VOL_CTL(decimator); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + adc_mux_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG1(decimator); + if (snd_soc_component_read(component, adc_mux_reg) & SWR_MIC) { + adc_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG0(decimator); + adc_n = snd_soc_component_read(component, adc_reg) & + CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK; + if (adc_n >= TX_ADC_MAX) { + dmic = TX_ADC_TO_DMIC(adc_n); + dmic_clk_reg = CDC_TX_TOP_CSR_SWR_DMICn_CTL(dmic); + + snd_soc_component_write_field(component, dmic_clk_reg, + CDC_TX_SWR_DMIC_CLK_SEL_MASK, + tx->dmic_clk_div); + } + } + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_ADC_MODE_MASK, + tx->dec_mode[decimator]); + /* Enable TX PGA Mute */ + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_PGA_MUTE_MASK, 0x1); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_CLK_EN_MASK, 0x1); + if (!is_amic_enabled(component, decimator)) { + snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x00); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + } + hpf_cut_off_freq = snd_soc_component_read_field(component, dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK); + + tx->tx_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK, + CF_MIN_3DB_150HZ); + + if (is_amic_enabled(component, decimator)) { + hpf_delay = TX_MACRO_AMIC_HPF_DELAY_MS; + unmute_delay = TX_MACRO_AMIC_UNMUTE_DELAY_MS; + } + /* schedule work queue to Remove Mute */ + queue_delayed_work(system_freezable_wq, + &tx->tx_mute_dwork[decimator].dwork, + msecs_to_jiffies(unmute_delay)); + if (tx->tx_hpf_work[decimator].hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + queue_delayed_work(system_freezable_wq, + &tx->tx_hpf_work[decimator].dwork, + msecs_to_jiffies(hpf_delay)); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x02); + if (!is_amic_enabled(component, decimator)) + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x00); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x01); + + /* + * 6ms delay is required as per HW spec + */ + usleep_range(6000, 6010); + } + /* apply gain after decimator is enabled */ + snd_soc_component_write(component, tx_gain_ctl_reg, + snd_soc_component_read(component, + tx_gain_ctl_reg)); + if (tx->bcs_enable) { + snd_soc_component_update_bits(component, dec_cfg_reg, + 0x01, 0x01); + tx->bcs_clk_en = true; + } + break; + case SND_SOC_DAPM_PRE_PMD: + hpf_cut_off_freq = + tx->tx_hpf_work[decimator].hpf_cut_off_freq; + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_PGA_MUTE_MASK, 0x1); + if (cancel_delayed_work_sync( + &tx->tx_hpf_work[decimator].dwork)) { + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_component_write_field( + component, dec_cfg_reg, + CDC_TXn_HPF_CUT_FREQ_MASK, + hpf_cut_off_freq); + if (is_amic_enabled(component, decimator)) + snd_soc_component_update_bits(component, + hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x02); + else + snd_soc_component_update_bits(component, + hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x03); + + /* + * Minimum 1 clk cycle delay is required + * as per HW spec + */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, hpf_gate_reg, + CDC_TXn_HPF_F_CHANGE_MASK | + CDC_TXn_HPF_ZERO_GATE_MASK, + 0x1); + } + } + cancel_delayed_work_sync(&tx->tx_mute_dwork[decimator].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_CLK_EN_MASK, 0x0); + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_ADC_MODE_MASK, 0x0); + snd_soc_component_write_field(component, tx_vol_ctl_reg, + CDC_TXn_PGA_MUTE_MASK, 0x0); + if (tx->bcs_enable) { + snd_soc_component_write_field(component, dec_cfg_reg, + CDC_TXn_PH_EN_MASK, 0x0); + snd_soc_component_write_field(component, + CDC_TX0_TX_PATH_SEC7, + CDC_TX0_MBHC_CTL_EN_MASK, + 0x0); + tx->bcs_clk_en = false; + } + break; + } + return 0; +} + static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -907,6 +1190,83 @@ static struct snd_soc_dai_driver tx_macro_dai[] = { }, }; +static const char * const adc_mux_text[] = { + "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1" +}; + +static SOC_ENUM_SINGLE_DECL(tx_dec0_enum, CDC_TX_INP_MUX_ADC_MUX0_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec1_enum, CDC_TX_INP_MUX_ADC_MUX1_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec2_enum, CDC_TX_INP_MUX_ADC_MUX2_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec3_enum, CDC_TX_INP_MUX_ADC_MUX3_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec4_enum, CDC_TX_INP_MUX_ADC_MUX4_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec5_enum, CDC_TX_INP_MUX_ADC_MUX5_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec6_enum, CDC_TX_INP_MUX_ADC_MUX6_CFG1, + 0, adc_mux_text); +static SOC_ENUM_SINGLE_DECL(tx_dec7_enum, CDC_TX_INP_MUX_ADC_MUX7_CFG1, + 0, adc_mux_text); + +static const struct snd_kcontrol_new tx_dec0_mux = SOC_DAPM_ENUM("tx_dec0", tx_dec0_enum); +static const struct snd_kcontrol_new tx_dec1_mux = SOC_DAPM_ENUM("tx_dec1", tx_dec1_enum); +static const struct snd_kcontrol_new tx_dec2_mux = SOC_DAPM_ENUM("tx_dec2", tx_dec2_enum); +static const struct snd_kcontrol_new tx_dec3_mux = SOC_DAPM_ENUM("tx_dec3", tx_dec3_enum); +static const struct snd_kcontrol_new tx_dec4_mux = SOC_DAPM_ENUM("tx_dec4", tx_dec4_enum); +static const struct snd_kcontrol_new tx_dec5_mux = SOC_DAPM_ENUM("tx_dec5", tx_dec5_enum); +static const struct snd_kcontrol_new tx_dec6_mux = SOC_DAPM_ENUM("tx_dec6", tx_dec6_enum); +static const struct snd_kcontrol_new tx_dec7_mux = SOC_DAPM_ENUM("tx_dec7", tx_dec7_enum); + +static const char * const smic_mux_text[] = { + "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_DMIC0", + "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4", + "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7" +}; + +static SOC_ENUM_SINGLE_DECL(tx_smic0_enum, CDC_TX_INP_MUX_ADC_MUX0_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic1_enum, CDC_TX_INP_MUX_ADC_MUX1_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic2_enum, CDC_TX_INP_MUX_ADC_MUX2_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic3_enum, CDC_TX_INP_MUX_ADC_MUX3_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic4_enum, CDC_TX_INP_MUX_ADC_MUX4_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic5_enum, CDC_TX_INP_MUX_ADC_MUX5_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic6_enum, CDC_TX_INP_MUX_ADC_MUX6_CFG0, + 0, smic_mux_text); + +static SOC_ENUM_SINGLE_DECL(tx_smic7_enum, CDC_TX_INP_MUX_ADC_MUX7_CFG0, + 0, smic_mux_text); + +static const struct snd_kcontrol_new tx_smic0_mux = SOC_DAPM_ENUM_EXT("tx_smic0", tx_smic0_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic1_mux = SOC_DAPM_ENUM_EXT("tx_smic1", tx_smic1_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic2_mux = SOC_DAPM_ENUM_EXT("tx_smic2", tx_smic2_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic3_mux = SOC_DAPM_ENUM_EXT("tx_smic3", tx_smic3_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic4_mux = SOC_DAPM_ENUM_EXT("tx_smic4", tx_smic4_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic5_mux = SOC_DAPM_ENUM_EXT("tx_smic5", tx_smic5_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic6_mux = SOC_DAPM_ENUM_EXT("tx_smic6", tx_smic6_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const struct snd_kcontrol_new tx_smic7_mux = SOC_DAPM_ENUM_EXT("tx_smic7", tx_smic7_enum, + snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); + static const char * const dec_mode_mux_text[] = { "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", }; @@ -930,6 +1290,327 @@ static const struct soc_enum dec_mode_mux_enum[] = { dec_mode_mux_text), }; +static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { + SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0), + + SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0), + + SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0), + + SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0, + tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)), + + SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0, + tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)), + + SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0, + tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)), + + SND_SOC_DAPM_MUX("TX SMIC MUX0", SND_SOC_NOPM, 0, 0, &tx_smic0_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX1", SND_SOC_NOPM, 0, 0, &tx_smic1_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX2", SND_SOC_NOPM, 0, 0, &tx_smic2_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX3", SND_SOC_NOPM, 0, 0, &tx_smic3_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX4", SND_SOC_NOPM, 0, 0, &tx_smic4_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX5", SND_SOC_NOPM, 0, 0, &tx_smic5_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX6", SND_SOC_NOPM, 0, 0, &tx_smic6_mux), + SND_SOC_DAPM_MUX("TX SMIC MUX7", SND_SOC_NOPM, 0, 0, &tx_smic7_mux), + + SND_SOC_DAPM_INPUT("TX SWR_ADC0"), + SND_SOC_DAPM_INPUT("TX SWR_ADC1"), + SND_SOC_DAPM_INPUT("TX SWR_ADC2"), + SND_SOC_DAPM_INPUT("TX SWR_ADC3"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC0"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC1"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC2"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC3"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC4"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC5"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC6"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC7"), + + SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM, + TX_MACRO_DEC0, 0, + &tx_dec0_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM, + TX_MACRO_DEC1, 0, + &tx_dec1_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM, + TX_MACRO_DEC2, 0, + &tx_dec2_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM, + TX_MACRO_DEC3, 0, + &tx_dec3_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM, + TX_MACRO_DEC4, 0, + &tx_dec4_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM, + TX_MACRO_DEC5, 0, + &tx_dec5_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM, + TX_MACRO_DEC6, 0, + &tx_dec6_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM, + TX_MACRO_DEC7, 0, + &tx_dec7_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0, + tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + NULL, 0), +}; + +static const struct snd_soc_dapm_route tx_audio_map[] = { + {"TX_AIF1 CAP", NULL, "TX_MCLK"}, + {"TX_AIF2 CAP", NULL, "TX_MCLK"}, + {"TX_AIF3 CAP", NULL, "TX_MCLK"}, + + {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"}, + {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"}, + {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"}, + + {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX DEC0 MUX", NULL, "TX_MCLK"}, + {"TX DEC1 MUX", NULL, "TX_MCLK"}, + {"TX DEC2 MUX", NULL, "TX_MCLK"}, + {"TX DEC3 MUX", NULL, "TX_MCLK"}, + {"TX DEC4 MUX", NULL, "TX_MCLK"}, + {"TX DEC5 MUX", NULL, "TX_MCLK"}, + {"TX DEC6 MUX", NULL, "TX_MCLK"}, + {"TX DEC7 MUX", NULL, "TX_MCLK"}, + + {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"}, + {"TX SMIC MUX0", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"}, + {"TX SMIC MUX1", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"}, + {"TX SMIC MUX2", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"}, + {"TX SMIC MUX3", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"}, + {"TX SMIC MUX4", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"}, + {"TX SMIC MUX5", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"}, + {"TX SMIC MUX6", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"}, + {"TX SMIC MUX7", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"}, +}; + static const struct snd_kcontrol_new tx_macro_snd_controls[] = { SOC_SINGLE_S8_TLV("TX_DEC0 Volume", CDC_TX0_TX_VOL_CTL, @@ -1107,6 +1788,10 @@ static const struct snd_soc_component_driver tx_macro_component_drv = { .probe = tx_macro_component_probe, .controls = tx_macro_snd_controls, .num_controls = ARRAY_SIZE(tx_macro_snd_controls), + .dapm_widgets = tx_macro_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tx_macro_dapm_widgets), + .dapm_routes = tx_audio_map, + .num_dapm_routes = ARRAY_SIZE(tx_audio_map), }; static int tx_macro_probe(struct platform_device *pdev)