From patchwork Wed May 9 12:56:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 135285 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp5618108lji; Wed, 9 May 2018 06:06:54 -0700 (PDT) X-Google-Smtp-Source: AB8JxZr5zGaK8lsJwIuKjNNi1zA637TMmUehiZ2qoUP1VyUl6Wud29DapCP+LBvXO71lCTj4H9Bw X-Received: by 2002:a63:b70b:: with SMTP id t11-v6mr34972902pgf.193.1525871214611; Wed, 09 May 2018 06:06:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525871214; cv=none; d=google.com; s=arc-20160816; b=t5xSPLWMlnthkwXgWXIFY12VL+OqYL3K54+PfP6YPfZ0JK/i2VGKpQCT1QkmSOCfVU cTte+NSGJIXFUnKB2fCzzz1hS1313R8iuXW+IPfFU9Ejxa8CYflBWzQ9ZQNM3A61wRG+ GNYG3HP9bKXYqrZMsA9E5jXSATxBnFljgHUxHTDmnZn7/3NxTEh+xKB4dSOaBpE8oWGR OsWuWzx+58VQFjc+voQkMDYxsn0WS0yNIjKKeFnW1BAiPGN3T6ybxYeye3RcaE259fJx 5L1gesUUlhDzCMYgrGCzExB78phRVcgToDsIvw3/U+0xl2g6ThJeURvrJhfE9t8IXNXJ UIpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=9G4F1QDZdFbjgEwPPkl/jVHgo4EMxa/TE3JTwT2bMok=; b=USk47UZFY7jmxi7YCkJ8va6THJoh/k8DVGQhBN/SSvvGiMcEza/hdvBQ6hE8aXCV3x fUnVZgcM63drhxyfQS7x3kdOwO8FEHBxvwIvF1BXanImO+HwL6R/zNffDnO8PPlG0pG/ lV8dZv0oaV0hqbNBkoRIBOvp8s0lQNx0o8qns7RJwnwMhlfkWJsdx2S62kj851XMQx3Q 9NdraaeS3enNP4cjGAI5Q2uKl1QSzIUoQ3OxuQ3BYwe/emQnlS04eZ7v9/6/lNHvUEI2 x1xF+FUqhtJNxXIyIoePxnydM/QqcnSF5hSgayPAxbQP4P5PG+ahfdwEqNQHlpi/+b9i ktzw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=HRBVs0Fw; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t22-v6si1389531pgo.686.2018.05.09.06.06.54; Wed, 09 May 2018 06:06:54 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=HRBVs0Fw; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934898AbeEINGv (ORCPT + 6 others); Wed, 9 May 2018 09:06:51 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:35102 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935032AbeEINAo (ORCPT ); Wed, 9 May 2018 09:00:44 -0400 Received: by mail-wm0-f67.google.com with SMTP id o78-v6so27743266wmg.0 for ; Wed, 09 May 2018 06:00:43 -0700 (PDT) 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; bh=4f6YO5GHuZ0NuZbxLgAZ0h3DTM6BWNJ2ZQMExu7+H4M=; b=HRBVs0FwWDNNn4IEHLipSXhkf2p+9mkL7nROuLhaQz4elai3g5bcUxGTvRvlcXaCJm nZXxZ0s93iCbgYSI9sq4MCDClVRtnCqkW811AEkZuJ8St2Oq4QhvFHjLiFrDBKqmQzo6 XDdIzEe19CPUXqAOVm6Utu+OmAfDss0+8IiSE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4f6YO5GHuZ0NuZbxLgAZ0h3DTM6BWNJ2ZQMExu7+H4M=; b=mOBFj0eB2bFbgA5981H+khXIiArYBYwPzxzGndsYhyEScPzVHWhSx9MpICXe06Ukdt D7c6M8paaH/eVIOaQgJn+5ioKESHMQdAPdX0cMYiEG/VnuuVzVNO3EL5PB8t+8a+zP+s Zobez1AufUu6rEYhv3i4ZnbuKJpaDTyytIfoOKxS31jieGN6Z9XooSYPNGQ81wiIjCmI HTEid7LqQKTaSE5YGlfZkp95w01BPpU/Skl3e4CLreQQOdLHGTC+ykPXmPF1uTImzxSx +kaf/6lIgsqtqqDJ8VX/aNqDWZAqgMFcW3KhVHBTD3C9dUVRDpn39N8viDDf6yC6JD/l j7qg== X-Gm-Message-State: ALKqPwenuW03cQ0RU5K9p17Isfuwg7zMnfundqrIdPLsYNzX5+L/6Fgx kfsnQ++xNFqDBwH9++JiSbu5WQ== X-Received: by 10.28.184.7 with SMTP id i7mr5725263wmf.126.1525870842573; Wed, 09 May 2018 06:00:42 -0700 (PDT) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id q2-v6sm29422963wrj.57.2018.05.09.06.00.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 May 2018 06:00:41 -0700 (PDT) From: Srinivas Kandagatla To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org, bgoswami@codeaurora.org Cc: gregkh@linuxfoundation.org, david.brown@linaro.org, mark.rutland@arm.com, lgirdwood@gmail.com, plai@codeaurora.org, tiwai@suse.com, perex@perex.cz, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, rohkumar@qti.qualcomm.com, spatakok@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v8 04/24] ASoC: qdsp6: dt-bindings: Add q6afe dt bindings Date: Wed, 9 May 2018 13:56:15 +0100 Message-Id: <20180509125635.5653-5-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> References: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch add DT bindings for AFE (Audio Frontend) DSP module. Signed-off-by: Srinivas Kandagatla Reviewed-and-tested-by: Rohit kumar Reviewed-by: Rob Herring Reviewed-by: Banajit Goswami --- .../devicetree/bindings/sound/qcom,q6afe.txt | 104 +++++++++++++++++++++ include/dt-bindings/sound/qcom,q6afe.h | 31 ++++++ 2 files changed, 135 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,q6afe.txt create mode 100644 include/dt-bindings/sound/qcom,q6afe.h -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/sound/qcom,q6afe.txt b/Documentation/devicetree/bindings/sound/qcom,q6afe.txt new file mode 100644 index 000000000000..14335a08b963 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,q6afe.txt @@ -0,0 +1,104 @@ +Qualcomm Audio Front End (Q6AFE) binding + +AFE is one of the APR audio service on Q6DSP +Please refer to qcom,apr.txt for details of the common apr service bindings +used by all apr services. Must contain the following properties. + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,q6afe-v." + Or "qcom,q6afe" where the version number can be queried + from DSP. + example "qcom,q6afe" + += AFE DAIs (Digial Audio Interface) +"dais" subnode of the AFE node. It represents afe dais, each afe dai is a +subnode of "dais" representing board specific dai setup. +"dais" node should have following properties followed by dai children. + +- #sound-dai-cells + Usage: required + Value type: + Definition: Must be 1 + +- #address-cells + Usage: required + Value type: + Definition: Must be 1 + +- #size-cells + Usage: required + Value type: + Definition: Must be 0 + +== AFE DAI is subnode of "dais" and represent a dai, it includes board specific +configuration of each dai. Must contain the following properties. + +- reg + Usage: required + Value type: + Definition: Must be dai id + +- qcom,sd-lines + Usage: required for mi2s interface + Value type: + Definition: Must be list of serial data lines used by this dai. + should be one or more of the 1-4 sd lines. + += EXAMPLE + +q6afe@4 { + compatible = "qcom,q6afe"; + reg = ; + + dais { + #sound-dai-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + hdmi@1 { + reg = <1>; + }; + + prim-mi2s-rx@16 { + reg = <16>; + qcom,sd-lines = <1 3>; + }; + + prim-mi2s-tx@17 { + reg = <17>; + qcom,sd-lines = <2>; + }; + + sec-mi2s-rx@18 { + reg = <18>; + qcom,sd-lines = <1 4>; + }; + + sec-mi2s-tx@19 { + reg = <19>; + qcom,sd-lines = <2>; + }; + + tert-mi2s-rx@20 { + reg = <20>; + qcom,sd-lines = <2 4>; + }; + + tert-mi2s-tx@21 { + reg = <21>; + qcom,sd-lines = <1>; + }; + + quat-mi2s-rx@22 { + reg = <22>; + qcom,sd-lines = <1>; + }; + + quat-mi2s-tx@23 { + reg = <23>; + qcom,sd-lines = <2>; + }; + }; +}; diff --git a/include/dt-bindings/sound/qcom,q6afe.h b/include/dt-bindings/sound/qcom,q6afe.h new file mode 100644 index 000000000000..e162045f5dc9 --- /dev/null +++ b/include/dt-bindings/sound/qcom,q6afe.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __DT_BINDINGS_Q6_AFE_H__ +#define __DT_BINDINGS_Q6_AFE_H__ + +/* Audio Front End (AFE) virtual ports IDs */ +#define HDMI_RX 1 +#define SLIMBUS_0_RX 2 +#define SLIMBUS_0_TX 3 +#define SLIMBUS_1_RX 4 +#define SLIMBUS_1_TX 5 +#define SLIMBUS_2_RX 6 +#define SLIMBUS_2_TX 7 +#define SLIMBUS_3_RX 8 +#define SLIMBUS_3_TX 9 +#define SLIMBUS_4_RX 10 +#define SLIMBUS_4_TX 11 +#define SLIMBUS_5_RX 12 +#define SLIMBUS_5_TX 13 +#define SLIMBUS_6_RX 14 +#define SLIMBUS_6_TX 15 +#define PRIMARY_MI2S_RX 16 +#define PRIMARY_MI2S_TX 17 +#define SECONDARY_MI2S_RX 18 +#define SECONDARY_MI2S_TX 19 +#define TERTIARY_MI2S_RX 20 +#define TERTIARY_MI2S_TX 21 +#define QUATERNARY_MI2S_RX 22 +#define QUATERNARY_MI2S_TX 23 + +#endif /* __DT_BINDINGS_Q6_AFE_H__ */ + From patchwork Wed May 9 12:56:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 135282 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp5617211lji; Wed, 9 May 2018 06:06:12 -0700 (PDT) X-Google-Smtp-Source: AB8JxZoly1HLifuejKvMQndCcDvWJnLoXORMcm+q5ZAywD7fneWhJQlV8QviZdqndGN6dRT44XrK X-Received: by 2002:a17:902:b949:: with SMTP id h9-v6mr45005444pls.146.1525871172773; Wed, 09 May 2018 06:06:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525871172; cv=none; d=google.com; s=arc-20160816; b=lzs6rA4RRFEtcNAQq2Q/jUWH4y6TtH4jhqL6A7jtrzMi9OziQo3LM+e0AaYFpyM4XC 78C//ts2Cay5Is0CqtfwPfziBFjgi7MuGMfwttA2MmOcRfcxCUy9ago7y5P4lR0KiXdp VVZzz3TbUx931OcngCBzvGLe5m28TDMtflIpNSkqIiXJlU9HdQLRAOvhSWvBxz79h4wJ +VUaNbfw0x8QGJYYbAel073oz9tObeOsoLwoJ7vaVA5f4Nw9I5sQdwyPxLzmc7ZyMeC4 JQGs41qklvOwVv5hN9l7nEla8iqBYNWWxlhp77S2tXGABZVgFZbZL8uEWd7FhRSwHTNo a0IQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=cjjH3Y4X2ggtNI9N+6NKDcE9SOItjRJaJoDuvBuaf/0=; b=fpjSoqTtpQ5U0XnkY7mUnODAdd/B0WlKirCoPSu9IAbvhpI/pKp4RCtjlgDq4dBxWy /+VwbR5D4jINUIBX9y6oFyhkQ/bllTT55kStUuDkzke44Vj82RhD7lPMFgGfCW1nDMOu kXw4akfbja4gVLr4yV68xg9te7+3Rgth9K/jyzxnsd89BjHZ4tYUNjhOgluloAqwg/Z7 4WPsIwHYOhjLfl8O8d/aVIT9PXgNl1+m1TthLWyOo2dNQgX98luONeVwV5vmjORSnN0z 9oNwU6dgpk2+qcju/G7MOnXmntceVPMPk2IJ2lxoa+8iK2X+86MqF4ss9ZwJHB02d7tN w7Ow== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=KXPrJwFu; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s5-v6si3064238pgo.12.2018.05.09.06.06.12; Wed, 09 May 2018 06:06:12 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=KXPrJwFu; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934801AbeEINGK (ORCPT + 6 others); Wed, 9 May 2018 09:06:10 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:53410 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935076AbeEINAq (ORCPT ); Wed, 9 May 2018 09:00:46 -0400 Received: by mail-wm0-f68.google.com with SMTP id a67so24469169wmf.3 for ; Wed, 09 May 2018 06:00:46 -0700 (PDT) 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; bh=TonztnZFUfzr96dQ6USPYmlNzO7FCoMzce/zgXpMmwg=; b=KXPrJwFul1zTkqThgjCW95nWSpIZTW2BuyGpNe3JihZZsF7g3aQPcXGO9HB+v8Y3RU 0aDwa7Q3ptlY7iH+EZCwEEX73LJhx5RLebPixQAEMA6eLq3v7JfkUoSN6Soqk64/+aMh qkxedSdy00TgknqfW+n+3Q9HRjKnsh3n4tya4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TonztnZFUfzr96dQ6USPYmlNzO7FCoMzce/zgXpMmwg=; b=P3D5mVzAYFqOSXoH53lPydutJrc4zUWXc5zd1PTJhhWS+bpuR8tvLkA3UBNWiYhVDp FQgHdrj70JdYKdBaI69E/RL7d5J2xchBHdnoNy8hFnLZJg3ZwYRK1BYhkhJNLSWQez6M g6zw6bmaIdumqpNnKLcogy0m2BiLP5+4gWxWU7vFN/7ZjH7jfwhWYFlIvN6gFT2lusud bXCmtLrxcrwgsQWniwY1WXVC5CNPcipgk9SaE0YORfoRUGxKN7nKcakcB+UoXaxuSVGk mQZnIWhUsnJlK1DLtgIKGBQkpUzTWWY7q0a/hQ71XgKywjPZjLIv/wWVZKSqc3VJXaJh 1c8A== X-Gm-Message-State: ALQs6tBCR3xtxIFJJa0Nt3Rm/2/erTOpmrYFkRnGp4hqNBENbL0k4YbE D8z9NLM4bkYYEMFZyyogyL30pw== X-Received: by 2002:a1c:c1c9:: with SMTP id r192-v6mr5511413wmf.120.1525870845596; Wed, 09 May 2018 06:00:45 -0700 (PDT) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id q2-v6sm29422963wrj.57.2018.05.09.06.00.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 May 2018 06:00:44 -0700 (PDT) From: Srinivas Kandagatla To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org, bgoswami@codeaurora.org Cc: gregkh@linuxfoundation.org, david.brown@linaro.org, mark.rutland@arm.com, lgirdwood@gmail.com, plai@codeaurora.org, tiwai@suse.com, perex@perex.cz, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, rohkumar@qti.qualcomm.com, spatakok@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v8 06/24] ASoC: qdsp6: dt-bindings: Add q6asm dt bindings Date: Wed, 9 May 2018 13:56:17 +0100 Message-Id: <20180509125635.5653-7-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> References: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch add DT bindings for ASM (Audio Stream Manager) DSP module. Signed-off-by: Srinivas Kandagatla Reviewed-and-tested-by: Rohit kumar Reviewed-by: Rob Herring Reviewed-by: Banajit Goswami --- .../devicetree/bindings/sound/qcom,q6asm.txt | 33 ++++++++++++++++++++++ include/dt-bindings/sound/qcom,q6asm.h | 22 +++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,q6asm.txt create mode 100644 include/dt-bindings/sound/qcom,q6asm.h -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/sound/qcom,q6asm.txt b/Documentation/devicetree/bindings/sound/qcom,q6asm.txt new file mode 100644 index 000000000000..2178eb91146f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,q6asm.txt @@ -0,0 +1,33 @@ +Qualcomm Audio Stream Manager (Q6ASM) binding + +Q6ASM is one of the APR audio service on Q6DSP. +Please refer to qcom,apr.txt for details of the common apr service bindings +used by the apr service device. + +- but must contain the following property: + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,q6asm-v.". + Or "qcom,q6asm" where the version number can be queried + from DSP. + example "qcom,q6asm-v2.0" + += ASM DAIs (Digial Audio Interface) +"dais" subnode of the ASM node represents dai specific configuration + +- #sound-dai-cells + Usage: required + Value type: + Definition: Must be 1 + += EXAMPLE + +q6asm@7 { + compatible = "qcom,q6asm"; + reg = ; + q6asmdai: dais { + #sound-dai-cells = <1>; + }; +}; diff --git a/include/dt-bindings/sound/qcom,q6asm.h b/include/dt-bindings/sound/qcom,q6asm.h new file mode 100644 index 000000000000..1eb77d87c2e8 --- /dev/null +++ b/include/dt-bindings/sound/qcom,q6asm.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __DT_BINDINGS_Q6_ASM_H__ +#define __DT_BINDINGS_Q6_ASM_H__ + +#define MSM_FRONTEND_DAI_MULTIMEDIA1 0 +#define MSM_FRONTEND_DAI_MULTIMEDIA2 1 +#define MSM_FRONTEND_DAI_MULTIMEDIA3 2 +#define MSM_FRONTEND_DAI_MULTIMEDIA4 3 +#define MSM_FRONTEND_DAI_MULTIMEDIA5 4 +#define MSM_FRONTEND_DAI_MULTIMEDIA6 5 +#define MSM_FRONTEND_DAI_MULTIMEDIA7 6 +#define MSM_FRONTEND_DAI_MULTIMEDIA8 7 +#define MSM_FRONTEND_DAI_MULTIMEDIA9 8 +#define MSM_FRONTEND_DAI_MULTIMEDIA10 9 +#define MSM_FRONTEND_DAI_MULTIMEDIA11 10 +#define MSM_FRONTEND_DAI_MULTIMEDIA12 11 +#define MSM_FRONTEND_DAI_MULTIMEDIA13 12 +#define MSM_FRONTEND_DAI_MULTIMEDIA14 13 +#define MSM_FRONTEND_DAI_MULTIMEDIA15 14 +#define MSM_FRONTEND_DAI_MULTIMEDIA16 15 + +#endif /* __DT_BINDINGS_Q6_ASM_H__ */ From patchwork Wed May 9 12:56:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 135280 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp5616164lji; Wed, 9 May 2018 06:05:22 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpBGr3tEqjBir414RarMlyg2LLTrQXD/bnd/mpB3ULxRkVoSSwxbKOTOwOO9urZTypxjQ5t X-Received: by 2002:a17:902:887:: with SMTP id 7-v6mr46670746pll.319.1525871122278; Wed, 09 May 2018 06:05:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525871122; cv=none; d=google.com; s=arc-20160816; b=lygrNHuYu9sU3FvW1osS9gcwExprL3ViEmbIh+vgMbfiuZZflep7xYyAIuHqC39rru 2wsiT0GcZzAlefHyVkyFfbN2wW9aqoNCBg/fIaHRL1CYNO0vWIINfJS9sLHfiRdiIFwG 3o/h6F5kcWBQtzArAMUhRUO7NWsilUMrPdwrhw1MEanT4kLSvuDAP5zH5miX4fSf4SFQ Yj1cGkDPXt+KdcxoGUGtU4bveevQFhjRx61tt64LCZ56QdgmfWjSFrUS4y/VqjiDBj1Z 9ausWIRDZl4SnLr10BpyBr9I1vS1C/HaZZcq2Y4JQQE4d36+lhxoRbgHZxCzKDW5PW61 CC/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=d4UV3nxesIDaDzP62X7FGwWohlaw32XKNmXuamyrDOw=; b=zqLMXUCYG7D/nPNJy8NpIrL9EXgriLFucqK5ebzLV7QeRck//4iILVX23RLS8mBLIv D/jblyYuvM93zzTfr6GYdql39oMqZJoSLDwYGYNy7LRF4kVLVP4qt0Tz1l/Q7CZNNfp3 WhvoCDWxtWXWNWtSsci+GlyC+UZjE8LIugudHJedhl6PI0JLQUJtgGOVwskJQ3/u8aeY 8BTYBPjdpf4c9gQo6tktKnW9TkCVrfkf5nFp/8y8RtS71iQUThPjLvfo5lMREVCRJ/HZ 3VQ1xTQRUvE77VYDcDKEixFExJN2/XuikRj7aFeLptS+h+UPG++xUjz7SfoDEFSw4tNz GEqQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=K94fmiXF; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 203si25091636pfa.60.2018.05.09.06.05.22; Wed, 09 May 2018 06:05:22 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=K94fmiXF; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935258AbeEINFU (ORCPT + 6 others); Wed, 9 May 2018 09:05:20 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:54852 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934947AbeEINAv (ORCPT ); Wed, 9 May 2018 09:00:51 -0400 Received: by mail-wm0-f67.google.com with SMTP id f6so24586144wmc.4 for ; Wed, 09 May 2018 06:00:51 -0700 (PDT) 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; bh=81L4iuB9dIy8Q9rQfXMv7/IXr0S26lAn6O5lqufAqtI=; b=K94fmiXFBHgrLmkaGRtxxRNdRGA62SC5ftdwKp0nYK89n2uOk5yhKIoa57AuNh2RTN eclZls/cd41GJxL28o9EVeQ33bwyZ0zmJkPHQZGSoYLfY0Ttv7leQxGpu1bCHVJvtKVO lDkKHeFuv5m9jdOSADaBXGAV7dZDIdGhh9+YA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=81L4iuB9dIy8Q9rQfXMv7/IXr0S26lAn6O5lqufAqtI=; b=W3X3GmJagaYRnM1DB9wM+Qdpy99WUnh0DM1qK1s07zBnacbSpCuz4PHB/ZQO+L0ZPK GGICFeoWMePeVNQ7Wuh6NTiZSp1HgLCeEsk1GGetDyMKTo7OZZ8EfJm+9YrQOpJW42BO DgXFvh1coR6t98+1XgS73SDxzoBDFik6Ok4zH4H27KYabFNXMcHX3zhfVzOnMMD2YSCw uZkI3Yxm09tlbIwkIZO/v1o4Rwpvsxo+vJZWU90UnLGsiUjyx+W8b32+4DMj1IicKmiK Brl946TG+Fs2fvMuJkfq6g8iHhziengQopLLZhvT29RgnzJ5EMp9+dgu9f+aPCBHYc+n nt9g== X-Gm-Message-State: ALKqPwe4RDKzn/fefw0FUYXtmC+TvU1oWcidDic2EPBdD3zD7LVaK6JV 9NWiToMNS1hX5xtLxefFFmHufQ== X-Received: by 10.28.166.23 with SMTP id p23mr5304444wme.152.1525870849864; Wed, 09 May 2018 06:00:49 -0700 (PDT) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id q2-v6sm29422963wrj.57.2018.05.09.06.00.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 May 2018 06:00:49 -0700 (PDT) From: Srinivas Kandagatla To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org, bgoswami@codeaurora.org Cc: gregkh@linuxfoundation.org, david.brown@linaro.org, mark.rutland@arm.com, lgirdwood@gmail.com, plai@codeaurora.org, tiwai@suse.com, perex@perex.cz, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, rohkumar@qti.qualcomm.com, spatakok@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v8 09/24] ASoC: qdsp6: q6afe: Add q6afe driver Date: Wed, 9 May 2018 13:56:20 +0100 Message-Id: <20180509125635.5653-10-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> References: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds support to Q6AFE (Audio Front End) module on Q6DSP. AFE module sits right at the other end of cpu where the codec/audio devices are connected. AFE provides abstraced interfaces to both hardware and virtual devices. Each AFE tx/rx port can be configured to connect to one of the hardware devices like codec, hdmi, slimbus, i2s and so on. AFE services include starting, stopping, and if needed, any configurations of the ports. Signed-off-by: Srinivas Kandagatla Reviewed-and-tested-by: Rohit kumar Reviewed-by: Banajit Goswami --- sound/soc/qcom/Kconfig | 4 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6afe.c | 529 ++++++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6afe.h | 35 +++ 4 files changed, 569 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6afe.c create mode 100644 sound/soc/qcom/qdsp6/q6afe.h -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 37ee0d958145..bb0a2afb0563 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -47,11 +47,15 @@ config SND_SOC_QDSP6_COMMON config SND_SOC_QDSP6_CORE tristate +config SND_SOC_QDSP6_AFE + tristate + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" depends on QCOM_APR && HAS_DMA select SND_SOC_QDSP6_COMMON select SND_SOC_QDSP6_CORE + select SND_SOC_QDSP6_AFE help To add support for MSM QDSP6 Soc Audio. This will enable sound soc platform specific diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile index 03b8e89c9731..7ff666bd10ca 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o +obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c new file mode 100644 index 000000000000..ec35ed1ffede --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -0,0 +1,529 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +// Copyright (c) 2018, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6dsp-errno.h" +#include "q6core.h" +#include "q6afe.h" + +/* AFE CMDs */ +#define AFE_PORT_CMD_DEVICE_START 0x000100E5 +#define AFE_PORT_CMD_DEVICE_STOP 0x000100E6 +#define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF +#define AFE_SVC_CMD_SET_PARAM 0x000100f3 +#define AFE_PORT_CMDRSP_GET_PARAM_V2 0x00010106 +#define AFE_PARAM_ID_HDMI_CONFIG 0x00010210 +#define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C + +/* Port IDs */ +#define AFE_API_VERSION_HDMI_CONFIG 0x1 +#define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E +#define TIMEOUT_MS 1000 +#define AFE_CMD_RESP_AVAIL 0 +#define AFE_CMD_RESP_NONE 1 + +struct q6afe { + struct apr_device *apr; + struct device *dev; + struct q6core_svc_api_info ainfo; + struct mutex lock; + struct list_head port_list; + spinlock_t port_list_lock; + struct list_head node; + struct platform_device *pdev_dais; +}; + +struct afe_port_cmd_device_start { + u16 port_id; + u16 reserved; +} __packed; + +struct afe_port_cmd_device_stop { + u16 port_id; + u16 reserved; +/* Reserved for 32-bit alignment. This field must be set to 0.*/ +} __packed; + +struct afe_port_param_data_v2 { + u32 module_id; + u32 param_id; + u16 param_size; + u16 reserved; +} __packed; + +struct afe_port_cmd_set_param_v2 { + u16 port_id; + u16 payload_size; + u32 payload_address_lsw; + u32 payload_address_msw; + u32 mem_map_handle; +} __packed; + +struct afe_param_id_hdmi_multi_chan_audio_cfg { + u32 hdmi_cfg_minor_version; + u16 datatype; + u16 channel_allocation; + u32 sample_rate; + u16 bit_width; + u16 reserved; +} __packed; + +union afe_port_config { + struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch; +} __packed; + +struct q6afe_port { + wait_queue_head_t wait; + union afe_port_config port_cfg; + struct aprv2_ibasic_rsp_result_t result; + int token; + int id; + int cfg_type; + struct q6afe *afe; + struct list_head node; +}; + +struct afe_port_map { + int port_id; + int token; + int is_rx; + int is_dig_pcm; +}; + +/* + * Mapping between Virtual Port IDs to DSP AFE Port ID + * On B Family SoCs DSP Port IDs are consistent across multiple SoCs + * on A Family SoCs DSP port IDs are same as virtual Port IDs. + */ + +static struct afe_port_map port_maps[AFE_PORT_MAX] = { + [HDMI_RX] = { AFE_PORT_ID_MULTICHAN_HDMI_RX, HDMI_RX, 1, 1}, +}; + +static struct q6afe_port *afe_find_port(struct q6afe *afe, int token) +{ + struct q6afe_port *p = NULL; + struct q6afe_port *ret = NULL; + unsigned long flags; + + spin_lock_irqsave(&afe->port_list_lock, flags); + list_for_each_entry(p, &afe->port_list, node) + if (p->token == token) { + ret = p; + break; + } + + spin_unlock_irqrestore(&afe->port_list_lock, flags); + return ret; +} + +static int q6afe_callback(struct apr_device *adev, struct apr_resp_pkt *data) +{ + struct q6afe *afe = dev_get_drvdata(&adev->dev); + struct aprv2_ibasic_rsp_result_t *res; + struct apr_hdr *hdr = &data->hdr; + struct q6afe_port *port; + + if (!data->payload_size) + return 0; + + res = data->payload; + switch (hdr->opcode) { + case APR_BASIC_RSP_RESULT: { + if (res->status) { + dev_err(afe->dev, "cmd = 0x%x returned error = 0x%x\n", + res->opcode, res->status); + } + switch (res->opcode) { + case AFE_PORT_CMD_SET_PARAM_V2: + case AFE_PORT_CMD_DEVICE_STOP: + case AFE_PORT_CMD_DEVICE_START: + case AFE_SVC_CMD_SET_PARAM: + port = afe_find_port(afe, hdr->token); + if (port) { + port->result = *res; + wake_up(&port->wait); + } + break; + default: + dev_err(afe->dev, "Unknown cmd 0x%x\n", res->opcode); + break; + } + } + break; + default: + break; + } + + return 0; +} + +/** + * q6afe_get_port_id() - Get port id from a given port index + * + * @index: port index + * + * Return: Will be an negative on error or valid port_id on success + */ +int q6afe_get_port_id(int index) +{ + if (index < 0 || index > AFE_PORT_MAX) + return -EINVAL; + + return port_maps[index].port_id; +} +EXPORT_SYMBOL_GPL(q6afe_get_port_id); + +static int afe_apr_send_pkt(struct q6afe *afe, struct apr_pkt *pkt, + struct q6afe_port *port) +{ + wait_queue_head_t *wait = &port->wait; + struct apr_hdr *hdr = &pkt->hdr; + int ret; + + mutex_lock(&afe->lock); + port->result.opcode = 0; + port->result.status = 0; + + ret = apr_send_pkt(afe->apr, pkt); + if (ret < 0) { + dev_err(afe->dev, "packet not transmitted (%d)\n", ret); + ret = -EINVAL; + goto err; + } + + ret = wait_event_timeout(*wait, (port->result.opcode == hdr->opcode), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + ret = -ETIMEDOUT; + } else if (port->result.status > 0) { + dev_err(afe->dev, "DSP returned error[%x]\n", + port->result.status); + ret = -EINVAL; + } else { + ret = 0; + } + +err: + mutex_unlock(&afe->lock); + + return ret; +} + +static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data, + int param_id, int psize) +{ + struct afe_port_cmd_set_param_v2 *param; + struct afe_port_param_data_v2 *pdata; + struct q6afe *afe = port->afe; + struct apr_pkt *pkt; + u16 port_id = port->id; + int ret, pkt_size; + void *p, *pl; + + pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize; + p = kzalloc(pkt_size, GFP_KERNEL); + if (!p) + return -ENOMEM; + + pkt = p; + param = p + APR_HDR_SIZE; + pdata = p + APR_HDR_SIZE + sizeof(*param); + pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata); + memcpy(pl, data, psize); + + pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + pkt->hdr.pkt_size = pkt_size; + pkt->hdr.src_port = 0; + pkt->hdr.dest_port = 0; + pkt->hdr.token = port->token; + pkt->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + + param->port_id = port_id; + param->payload_size = sizeof(*pdata) + psize; + param->payload_address_lsw = 0x00; + param->payload_address_msw = 0x00; + param->mem_map_handle = 0x00; + pdata->module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + pdata->param_id = param_id; + pdata->param_size = psize; + + ret = afe_apr_send_pkt(afe, pkt, port); + if (ret) + dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", + port_id, ret); + + kfree(pkt); + return ret; +} + +/** + * q6afe_port_stop() - Stop a afe port + * + * @port: Instance of port to stop + * + * Return: Will be an negative on packet size on success. + */ +int q6afe_port_stop(struct q6afe_port *port) +{ + struct afe_port_cmd_device_stop *stop; + struct q6afe *afe = port->afe; + struct apr_pkt *pkt; + int port_id = port->id; + int ret = 0; + int index, pkt_size; + void *p; + + port_id = port->id; + index = port->token; + if (index < 0 || index > AFE_PORT_MAX) { + dev_err(afe->dev, "AFE port index[%d] invalid!\n", index); + return -EINVAL; + } + + pkt_size = APR_HDR_SIZE + sizeof(*stop); + p = kzalloc(pkt_size, GFP_KERNEL); + if (!p) + return -ENOMEM; + + pkt = p; + stop = p + APR_HDR_SIZE; + + pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + pkt->hdr.pkt_size = pkt_size; + pkt->hdr.src_port = 0; + pkt->hdr.dest_port = 0; + pkt->hdr.token = index; + pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_STOP; + stop->port_id = port_id; + stop->reserved = 0; + + ret = afe_apr_send_pkt(afe, pkt, port); + if (ret) + dev_err(afe->dev, "AFE close failed %d\n", ret); + + kfree(pkt); + return ret; +} +EXPORT_SYMBOL_GPL(q6afe_port_stop); + +/** + * q6afe_hdmi_port_prepare() - Prepare hdmi afe port. + * + * @port: Instance of afe port + * @cfg: HDMI configuration for the afe port + * + */ +void q6afe_hdmi_port_prepare(struct q6afe_port *port, + struct q6afe_hdmi_cfg *cfg) +{ + union afe_port_config *pcfg = &port->port_cfg; + + pcfg->hdmi_multi_ch.hdmi_cfg_minor_version = + AFE_API_VERSION_HDMI_CONFIG; + pcfg->hdmi_multi_ch.datatype = cfg->datatype; + pcfg->hdmi_multi_ch.channel_allocation = cfg->channel_allocation; + pcfg->hdmi_multi_ch.sample_rate = cfg->sample_rate; + pcfg->hdmi_multi_ch.bit_width = cfg->bit_width; +} +EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare); + +/** + * q6afe_port_start() - Start a afe port + * + * @port: Instance of port to start + * + * Return: Will be an negative on packet size on success. + */ +int q6afe_port_start(struct q6afe_port *port) +{ + struct afe_port_cmd_device_start *start; + struct q6afe *afe = port->afe; + int port_id = port->id; + int ret, param_id = port->cfg_type; + struct apr_pkt *pkt; + int pkt_size; + void *p; + + ret = q6afe_port_set_param_v2(port, &port->port_cfg, param_id, + sizeof(port->port_cfg)); + if (ret) { + dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", + port_id, ret); + return ret; + } + + pkt_size = APR_HDR_SIZE + sizeof(*start); + p = kzalloc(pkt_size, GFP_KERNEL); + if (!p) + return -ENOMEM; + + pkt = p; + start = p + APR_HDR_SIZE; + + pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + pkt->hdr.pkt_size = pkt_size; + pkt->hdr.src_port = 0; + pkt->hdr.dest_port = 0; + pkt->hdr.token = port->token; + pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_START; + + start->port_id = port_id; + + ret = afe_apr_send_pkt(afe, pkt, port); + if (ret) + dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", + port_id, ret); + + kfree(pkt); + return ret; +} +EXPORT_SYMBOL_GPL(q6afe_port_start); + +/** + * q6afe_port_get_from_id() - Get port instance from a port id + * + * @dev: Pointer to afe child device. + * @id: port id + * + * Return: Will be an error pointer on error or a valid afe port + * on success. + */ +struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id) +{ + int port_id; + struct q6afe *afe = dev_get_drvdata(dev->parent); + struct q6afe_port *port; + unsigned long flags; + int cfg_type; + + if (id < 0 || id > AFE_PORT_MAX) { + dev_err(dev, "AFE port token[%d] invalid!\n", id); + return ERR_PTR(-EINVAL); + } + + port_id = port_maps[id].port_id; + + switch (port_id) { + case AFE_PORT_ID_MULTICHAN_HDMI_RX: + cfg_type = AFE_PARAM_ID_HDMI_CONFIG; + break; + default: + dev_err(dev, "Invalid port id 0x%x\n", port_id); + return ERR_PTR(-EINVAL); + } + + port = kzalloc(sizeof(*port), GFP_KERNEL); + if (!port) + return ERR_PTR(-ENOMEM); + + init_waitqueue_head(&port->wait); + + port->token = id; + port->id = port_id; + port->afe = afe; + port->cfg_type = cfg_type; + + spin_lock_irqsave(&afe->port_list_lock, flags); + list_add_tail(&port->node, &afe->port_list); + spin_unlock_irqrestore(&afe->port_list_lock, flags); + + return port; + +} +EXPORT_SYMBOL_GPL(q6afe_port_get_from_id); + +/** + * q6afe_port_put() - Release port reference + * + * @port: Instance of port to put + */ +void q6afe_port_put(struct q6afe_port *port) +{ + struct q6afe *afe = port->afe; + unsigned long flags; + + spin_lock_irqsave(&afe->port_list_lock, flags); + list_del(&port->node); + spin_unlock_irqrestore(&afe->port_list_lock, flags); + kfree(port); +} +EXPORT_SYMBOL_GPL(q6afe_port_put); + +static int q6afe_probe(struct apr_device *adev) +{ + struct q6afe *afe; + struct device *dev = &adev->dev; + struct device_node *dais_np; + + afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL); + if (!afe) + return -ENOMEM; + + q6core_get_svc_api_info(adev->svc_id, &afe->ainfo); + afe->apr = adev; + mutex_init(&afe->lock); + afe->dev = dev; + INIT_LIST_HEAD(&afe->port_list); + spin_lock_init(&afe->port_list_lock); + + dev_set_drvdata(dev, afe); + + dais_np = of_get_child_by_name(dev->of_node, "dais"); + if (dais_np) { + afe->pdev_dais = of_platform_device_create(dais_np, + "q6afe-dai", dev); + of_node_put(dais_np); + } + + return 0; +} + +static int q6afe_remove(struct apr_device *adev) +{ + struct q6afe *afe = dev_get_drvdata(&adev->dev); + + if (afe->pdev_dais) + of_platform_device_destroy(&afe->pdev_dais->dev, NULL); + + return 0; +} + +static const struct of_device_id q6afe_device_id[] = { + { .compatible = "qcom,q6afe" }, + {}, +}; +MODULE_DEVICE_TABLE(of, q6afe_device_id); + +static struct apr_driver qcom_q6afe_driver = { + .probe = q6afe_probe, + .remove = q6afe_remove, + .callback = q6afe_callback, + .driver = { + .name = "qcom-q6afe", + .of_match_table = of_match_ptr(q6afe_device_id), + + }, +}; + +module_apr_driver(qcom_q6afe_driver); +MODULE_DESCRIPTION("Q6 Audio Front End"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h new file mode 100644 index 000000000000..3bd991a7c42d --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6afe.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __Q6AFE_H__ +#define __Q6AFE_H__ + +#include + +#define AFE_PORT_MAX 48 + +#define MSM_AFE_PORT_TYPE_RX 0 +#define MSM_AFE_PORT_TYPE_TX 1 +#define AFE_MAX_PORTS AFE_PORT_MAX + +struct q6afe_hdmi_cfg { + u16 datatype; + u16 channel_allocation; + u32 sample_rate; + u16 bit_width; +}; + +struct q6afe_port_config { + struct q6afe_hdmi_cfg hdmi; +}; + +struct q6afe_port; + +struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id); +int q6afe_port_start(struct q6afe_port *port); +int q6afe_port_stop(struct q6afe_port *port); +void q6afe_port_put(struct q6afe_port *port); +int q6afe_get_port_id(int index); +void q6afe_hdmi_port_prepare(struct q6afe_port *port, + struct q6afe_hdmi_cfg *cfg); + +#endif /* __Q6AFE_H__ */ From patchwork Wed May 9 12:56:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 135277 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp5615522lji; Wed, 9 May 2018 06:04:54 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrrsACd+x0Njq4FsRGQsn2VgI9CkjRNtPmiBGR77gyVgH175Z4D+nw7avSYkdKMLT8KpfAO X-Received: by 2002:a17:902:8c95:: with SMTP id t21-v6mr41163143plo.306.1525871093894; Wed, 09 May 2018 06:04:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525871093; cv=none; d=google.com; s=arc-20160816; b=HYniwwMCKC4OgpOIqqII2NcNApj0qGo2NIQ9kW44Gc3hIbr8OFw4o0KHk7lkHCWvl/ SBq54cOacQp0+I1r3CDNYJ9+pBDAMeVHV6IsXJBH6saJ/eS8FaG7xrZOJ52727vUeBYL liYmniqLQKdMho7my3n8p1wkw0u/4umotzdOTterqeN92P0Z4HPbEr7kQb9fj9i4UWDr gPDGVDMjEYGfYN25s89L5hJnX6aA8EAVG3t0bEdpiolcJGP/990FQ7GhqHT/OkqVOEA3 4wbuJyMNkosg9kiLlUUxAb6wz02H5O63y/IT8RZDDCrgCEyZHLnrAxPDVZu8lkPYWV9d LuIg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=DLMPIksFKYZRkmDsAQG/JYWE1LqLeMgoKXVIt7e/SLY=; b=p/hR4J7ljVtPdDH5/mVMmaEg04ltBfBBOolKB9w9hhMynpj6V+zUnbIFKO6cVGdpH8 0AQJpamLp6lY0mtHPqts6gtczl06uH1rF4AYj+xguWOxJhkLtlcnCNzLezXSO+eSGqPz JRZO8oy0h7nYFpF+7A0GLJ45NawvGYoS1ibzKgvNYmISbmmzYr7Cw3yrdc5jFLQRHRAr khal2DD0yILOPNEOwSGHbtoJtEgtJCQwFUjG6/q1GWUxm3z8lMqFroBfJGJ4DD0Fm+w2 hFw0YPNBcKzpFLaP0vVQByXCuaQeANoTXKYz+jU2QB6hqswqYVmNBkNKuuSNM7vf2CzK Fwvg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=MnoOITD+; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a12-v6si6769619pgq.652.2018.05.09.06.04.53; Wed, 09 May 2018 06:04:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=MnoOITD+; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934909AbeEINEt (ORCPT + 6 others); Wed, 9 May 2018 09:04:49 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:37454 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935104AbeEINA4 (ORCPT ); Wed, 9 May 2018 09:00:56 -0400 Received: by mail-wr0-f193.google.com with SMTP id h5-v6so11641113wrm.4 for ; Wed, 09 May 2018 06:00:55 -0700 (PDT) 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; bh=sbPWrWiCGiDY2QirDIQ3A1DQWd4TmU+91n/s1B0/4pA=; b=MnoOITD+v4hRKv/Bs3K2Gj5SdTEDfkw99bNERX3XU865pnpyRxCJ7oO/LcUmEm2/MH 0cIR4oi+QDulyxEnVZ+ijrA3QwqBopzJrCMC21QQ4FmYw6SqWuKw15VkbpDlJaMFa3J3 vUNKuz/Pt4DfVFg0R1Mktr9oOJcEw49y2KfXM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=sbPWrWiCGiDY2QirDIQ3A1DQWd4TmU+91n/s1B0/4pA=; b=Fi7QeBRA6Du7tBuGQKdcnBs+PQTc6/138pgkH1U2spon+w2g78jr5UABkKgwJrRFeH dK3enxvk6CDiJBGZoq2fy2fHDh/KF2t9uz9FbQj21ehDg7Cy+jwGvZ9mwJRrfXRdmqY5 sUd3Cg7k17JOoBdueLoQ7ivYgQUFccUdW5OQ79x2BYdJGY5yTTJwdf2oPQV8Yyc/sGkE 6igZRMvhPaN7dsIKc32dDI0qOQvRDSK1HIzJwMwVyUHGgB+J5r+c3IvN0Bj9AIjWliLS Unx03tll98eNv8MkBg11Y6a/YxPfaxQed7ryt0O+KsWIETCVj8IYeoOJbZnFbNHoYEt2 ok+g== X-Gm-Message-State: ALQs6tABtlkWNsNgbQRhK668wd+qxYK4bsiGdh6l4tDrD9B2pgjodrkq xcFutPXBxDLfbpuPWOURpQbrvg== X-Received: by 2002:adf:e749:: with SMTP id c9-v6mr38691736wrn.203.1525870854350; Wed, 09 May 2018 06:00:54 -0700 (PDT) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id q2-v6sm29422963wrj.57.2018.05.09.06.00.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 May 2018 06:00:53 -0700 (PDT) From: Srinivas Kandagatla To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org, bgoswami@codeaurora.org Cc: gregkh@linuxfoundation.org, david.brown@linaro.org, mark.rutland@arm.com, lgirdwood@gmail.com, plai@codeaurora.org, tiwai@suse.com, perex@perex.cz, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, rohkumar@qti.qualcomm.com, spatakok@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v8 12/24] ASoC: qdsp6: q6afe: Add support to MI2S sysclks Date: Wed, 9 May 2018 13:56:23 +0100 Message-Id: <20180509125635.5653-13-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> References: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds support to LPASS Bit clock, LPASS Digital core clock and OSR clock. These clocks are required for both MI2S and PCM setup. Signed-off-by: Srinivas Kandagatla Reviewed-and-tested-by: Rohit kumar Reviewed-by: Banajit Goswami --- sound/soc/qcom/qdsp6/q6afe.c | 164 +++++++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6afe.h | 131 ++++++++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+) -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c index 6808b7bae5d5..11525a25db13 100644 --- a/sound/soc/qcom/qdsp6/q6afe.c +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -33,6 +33,9 @@ #define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG 0x00010235 +#define AFE_PARAM_ID_LPAIF_CLK_CONFIG 0x00010238 +#define AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG 0x00010239 + #define AFE_PARAM_ID_SLIMBUS_CONFIG 0x00010212 #define AFE_PARAM_ID_I2S_CONFIG 0x0001020D @@ -66,6 +69,11 @@ #define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E #define AFE_API_VERSION_SLIMBUS_CONFIG 0x1 +/* Clock set API version */ +#define AFE_API_VERSION_CLOCK_SET 1 +#define Q6AFE_LPASS_CLK_CONFIG_API_VERSION 0x1 +#define AFE_MODULE_CLOCK_SET 0x0001028F +#define AFE_PARAM_ID_CLOCK_SET 0x00010290 /* SLIMbus Rx port on channel 0. */ #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX 0x4000 @@ -142,6 +150,13 @@ struct afe_port_param_data_v2 { u16 reserved; } __packed; +struct afe_svc_cmd_set_param { + uint32_t payload_size; + uint32_t payload_address_lsw; + uint32_t payload_address_msw; + uint32_t mem_map_handle; +} __packed; + struct afe_port_cmd_set_param_v2 { u16 port_id; u16 payload_size; @@ -202,6 +217,23 @@ struct afe_param_id_slimbus_cfg { */ } __packed; +struct afe_clk_cfg { + u32 i2s_cfg_minor_version; + u32 clk_val1; + u32 clk_val2; + u16 clk_src; + u16 clk_root; + u16 clk_set_mode; + u16 reserved; +} __packed; + +struct afe_digital_clk_cfg { + u32 i2s_cfg_minor_version; + u32 clk_val; + u16 clk_root; + u16 reserved; +} __packed; + struct afe_param_id_i2s_cfg { u32 i2s_cfg_minor_version; u16 bit_width; @@ -219,6 +251,16 @@ union afe_port_config { struct afe_param_id_i2s_cfg i2s_cfg; } __packed; + +struct afe_clk_set { + uint32_t clk_set_minor_version; + uint32_t clk_id; + uint32_t clk_freq_in_hz; + uint16_t clk_attri; + uint16_t clk_root; + uint32_t enable; +}; + struct q6afe_port { wait_queue_head_t wait; union afe_port_config port_cfg; @@ -387,6 +429,54 @@ static int afe_apr_send_pkt(struct q6afe *afe, struct apr_pkt *pkt, return ret; } +static int q6afe_port_set_param(struct q6afe_port *port, void *data, + int param_id, int module_id, int psize) +{ + struct afe_svc_cmd_set_param *param; + struct afe_port_param_data_v2 *pdata; + struct q6afe *afe = port->afe; + struct apr_pkt *pkt; + u16 port_id = port->id; + int ret, pkt_size; + void *p, *pl; + + pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize; + p = kzalloc(pkt_size, GFP_KERNEL); + if (!p) + return -ENOMEM; + + pkt = p; + param = p + APR_HDR_SIZE; + pdata = p + APR_HDR_SIZE + sizeof(*param); + pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata); + memcpy(pl, data, psize); + + pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + pkt->hdr.pkt_size = pkt_size; + pkt->hdr.src_port = 0; + pkt->hdr.dest_port = 0; + pkt->hdr.token = port->token; + pkt->hdr.opcode = AFE_SVC_CMD_SET_PARAM; + + param->payload_size = sizeof(*pdata) + psize; + param->payload_address_lsw = 0x00; + param->payload_address_msw = 0x00; + param->mem_map_handle = 0x00; + pdata->module_id = module_id; + pdata->param_id = param_id; + pdata->param_size = psize; + + ret = afe_apr_send_pkt(afe, pkt, port); + if (ret) + dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", + port_id, ret); + + kfree(pkt); + return ret; +} + static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data, int param_id, int psize) { @@ -436,6 +526,80 @@ static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data, return ret; } +static int q6afe_set_lpass_clock(struct q6afe_port *port, + struct afe_clk_cfg *cfg) +{ + return q6afe_port_set_param_v2(port, cfg, + AFE_PARAM_ID_LPAIF_CLK_CONFIG, + sizeof(*cfg)); +} + +static int q6afe_set_lpass_clock_v2(struct q6afe_port *port, + struct afe_clk_set *cfg) +{ + return q6afe_port_set_param(port, cfg, AFE_PARAM_ID_CLOCK_SET, + AFE_MODULE_CLOCK_SET, sizeof(*cfg)); +} + +static int q6afe_set_digital_codec_core_clock(struct q6afe_port *port, + struct afe_digital_clk_cfg *cfg) +{ + return q6afe_port_set_param_v2(port, cfg, + AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG, + sizeof(*cfg)); +} + +int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id, + int clk_src, int clk_root, + unsigned int freq, int dir) +{ + struct afe_clk_cfg ccfg = {0,}; + struct afe_clk_set cset = {0,}; + struct afe_digital_clk_cfg dcfg = {0,}; + int ret; + + switch (clk_id) { + case LPAIF_DIG_CLK: + dcfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; + dcfg.clk_val = freq; + dcfg.clk_root = clk_root; + ret = q6afe_set_digital_codec_core_clock(port, &dcfg); + break; + case LPAIF_BIT_CLK: + ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; + ccfg.clk_val1 = freq; + ccfg.clk_src = clk_src; + ccfg.clk_root = clk_root; + ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; + ret = q6afe_set_lpass_clock(port, &ccfg); + break; + + case LPAIF_OSR_CLK: + ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; + ccfg.clk_val2 = freq; + ccfg.clk_src = clk_src; + ccfg.clk_root = clk_root; + ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID; + ret = q6afe_set_lpass_clock(port, &ccfg); + break; + case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1: + cset.clk_set_minor_version = AFE_API_VERSION_CLOCK_SET; + cset.clk_id = clk_id; + cset.clk_freq_in_hz = freq; + cset.clk_attri = clk_src; + cset.clk_root = clk_root; + cset.enable = !!freq; + ret = q6afe_set_lpass_clock_v2(port, &cset); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} +EXPORT_SYMBOL_GPL(q6afe_port_set_sysclk); + /** * q6afe_port_stop() - Stop a afe port * diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h index 3cb3bb4985a9..5ca54a9bdfd5 100644 --- a/sound/soc/qcom/qdsp6/q6afe.h +++ b/sound/soc/qcom/qdsp6/q6afe.h @@ -16,6 +16,134 @@ #define AFE_MAX_CHAN_COUNT 8 #define AFE_PORT_MAX_AUDIO_CHAN_CNT 0x8 +#define Q6AFE_LPASS_CLK_SRC_INTERNAL 1 +#define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0 + +#define LPAIF_DIG_CLK 1 +#define LPAIF_BIT_CLK 2 +#define LPAIF_OSR_CLK 3 + +/* Clock ID for Primary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT 0x100 +/* Clock ID for Primary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT 0x101 +/* Clock ID for Secondary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT 0x102 +/* Clock ID for Secondary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT 0x103 +/* Clock ID for Tertiary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT 0x104 +/* Clock ID for Tertiary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT 0x105 +/* Clock ID for Quartnery I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT 0x106 +/* Clock ID for Quartnery I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT 0x107 +/* Clock ID for Speaker I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_IBIT 0x108 +/* Clock ID for Speaker I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_EBIT 0x109 +/* Clock ID for Speaker I2S OSR */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR 0x10A + +/* Clock ID for QUINARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT 0x10B +/* Clock ID for QUINARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT 0x10C +/* Clock ID for SENARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT 0x10D +/* Clock ID for SENARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT 0x10E +/* Clock ID for INT0 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT 0x10F +/* Clock ID for INT1 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT 0x110 +/* Clock ID for INT2 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT 0x111 +/* Clock ID for INT3 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT 0x112 +/* Clock ID for INT4 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT 0x113 +/* Clock ID for INT5 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT 0x114 +/* Clock ID for INT6 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT 0x115 + +/* Clock ID for QUINARY MI2S OSR CLK */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR 0x116 + +/* Clock ID for Primary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT 0x200 +/* Clock ID for Primary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_EBIT 0x201 +/* Clock ID for Secondary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT 0x202 +/* Clock ID for Secondary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_EBIT 0x203 +/* Clock ID for Tertiary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT 0x204 +/* Clock ID for Tertiary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_EBIT 0x205 +/* Clock ID for Quartery PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT 0x206 +/* Clock ID for Quartery PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT 0x207 +/* Clock ID for Quinary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT 0x208 +/* Clock ID for Quinary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_PCM_EBIT 0x209 +/* Clock ID for QUINARY PCM OSR */ +#define Q6AFE_LPASS_CLK_ID_QUI_PCM_OSR 0x20A + +/** Clock ID for Primary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT 0x200 +/** Clock ID for Primary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT 0x201 +/** Clock ID for Secondary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT 0x202 +/** Clock ID for Secondary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT 0x203 +/** Clock ID for Tertiary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT 0x204 +/** Clock ID for Tertiary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT 0x205 +/** Clock ID for Quartery TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT 0x206 +/** Clock ID for Quartery TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT 0x207 +/** Clock ID for Quinary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT 0x208 +/** Clock ID for Quinary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT 0x209 +/** Clock ID for Quinary TDM OSR */ +#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_OSR 0x20A + +/* Clock ID for MCLK1 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_1 0x300 +/* Clock ID for MCLK2 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_2 0x301 +/* Clock ID for MCLK3 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_3 0x302 +/* Clock ID for MCLK4 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_4 0x304 +/* Clock ID for Internal Digital Codec Core */ +#define Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 0x303 +/* Clock ID for INT MCLK0 */ +#define Q6AFE_LPASS_CLK_ID_INT_MCLK_0 0x305 +/* Clock ID for INT MCLK1 */ +#define Q6AFE_LPASS_CLK_ID_INT_MCLK_1 0x306 + +/* Clock attribute for invalid use (reserved for internal usage) */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVALID 0x0 +/* Clock attribute for no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1 +/* Clock attribute for dividend couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND 0x2 +/* Clock attribute for divisor couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR 0x3 +/* Clock attribute for invert and no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO 0x4 + struct q6afe_hdmi_cfg { u16 datatype; u16 channel_allocation; @@ -59,4 +187,7 @@ void q6afe_slim_port_prepare(struct q6afe_port *port, struct q6afe_slim_cfg *cfg); int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg); +int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id, + int clk_src, int clk_root, + unsigned int freq, int dir); #endif /* __Q6AFE_H__ */ From patchwork Wed May 9 12:56:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 135272 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp5613515lji; Wed, 9 May 2018 06:03:24 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqy7uBYAbNrlZ06jAC0l+qcCI1PJ94rRj+Te7KLaY4z7jXKFcWgjlNRjIOzlLx3LBl7/7Q9 X-Received: by 2002:a63:69c3:: with SMTP id e186-v6mr35873883pgc.353.1525871004504; Wed, 09 May 2018 06:03:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525871004; cv=none; d=google.com; s=arc-20160816; b=ElP4cWfcXT+b73ElLt7KxJwco+7l4gU5CnCV9K7Qoms7J0gEM4QIQHOTvYUPqZ2Ajw 2EgEVycZhwOkEhxwzUg0QuBnX6mR5L7+Dd/mZqbVkio/y0T8C02fbK4AXyeFOibgkIeK 60RiRgzUCjqA+Mad73Gs5nrEMXGQ5FySU5OI78K20c1DbnfwG2nGWPqOp+Y2xGmKTlYO BfvZuiBBipRW3w2IqICnyNRVbhohb2kpgpMTUkgcTwwRXCNwAzOsDqmjcdd0i1skxsXQ SQlFUUFGJan2Br8umN32UMl37SU89JWKpbxXKNeCSAIfoDf2P/2W5YBLgQIdUu4a7sfR 0MwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=rLT6FvLaLBW8X+HXxmcCBD2MfpFuYv7kCTA5Q9hq0ZE=; b=elV6Mo0JYCHeSt9pggp42qPImpO3v9z4plzjxLZs8NblKXjJl/PRSP68m8R21ngEHL aiLeKDt94o3yrKa8SjgiKkX8WZQC7YapBjAkJhXZ8UCjBooZYFhITo90QhMJP11a/oO5 JmVkubzF67OmK9UqvLXQ7l/2MJG7WZpzIyZr+Qw47pRfMeTecLbVdd6LZtLBGXQoBYhb WZdcsUs5UYBnML6I5vJzMn0Kc5my6i8OyBRw5NCoiH8/dLwI4RTuNKAi4G1Z6KKpWPr5 7LoyJU1692tPOBhBdVDJtXAHZypsfEooy2kIp6NR2o5VS1txtr7nSiHCLTmB+eOZUz2M pLWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=dXdD9xV4; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n34-v6si26314365pld.91.2018.05.09.06.03.24; Wed, 09 May 2018 06:03:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=dXdD9xV4; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934840AbeEINDW (ORCPT + 6 others); Wed, 9 May 2018 09:03:22 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:34773 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934876AbeEINBH (ORCPT ); Wed, 9 May 2018 09:01:07 -0400 Received: by mail-wr0-f195.google.com with SMTP id p18-v6so35611819wrm.1 for ; Wed, 09 May 2018 06:01:06 -0700 (PDT) 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; bh=Pp7J4FmzUj2D+rZQ3AjZL89N94ikWxLJSU1oLbB/Oqk=; b=dXdD9xV4/AzRv21Iq23rCC2ASMUpbTZno0HNA7Ddga8x8Zj1a9GkvmNS78QxR1l9pJ cybzTBJc/1wouUE5cHj8HQpqr9lWL3zgkrxoQnyEdEEFdYdTG7TTOv3UNS4wI/vdnT8u 4/8kwtdopffk2H8KLRinp17t9ismuwJ738h/U= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Pp7J4FmzUj2D+rZQ3AjZL89N94ikWxLJSU1oLbB/Oqk=; b=pQ29jv0HAIM1GedwjzAM8xjwEmavxn/LkHzzw7wPcpzYjY+GX7aUzOBQ+YMir+P5kD 3tNH9ppEi+cPSvS+zrkuCP16RQw7T4GvlO3cnFZ7Km1WmVWHPtmXHtyWDOrS51iSeJvb Gln3wM+TftN+xrfeCnMOFafbr1/7zD9SUslHgJdk4QacZPgclv8Aj/41sHoNrDYvU3Vq iDRJznv/9p3ei18O/ONQySjCYwveiz3pRUrAGkdLREY3so7H82mZr9uv3sRhj8p+gEJk CsZLlcP2JOSfNpbeO8e0Tlo+UfitFcaDWEPpoiEcsMVY6Kgj376sc55p3XxA1KxtCoyZ Qt3A== X-Gm-Message-State: ALKqPwfD0w/ItSTYfk9eix08Ko1U08enFl6Ru+pwj8z89VzzDes+SWcA nRQL8VCYZOPB0AwlPaQQm6aMQg== X-Received: by 2002:adf:9a8e:: with SMTP id a14-v6mr5405391wrc.50.1525870865826; Wed, 09 May 2018 06:01:05 -0700 (PDT) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id q2-v6sm29422963wrj.57.2018.05.09.06.01.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 May 2018 06:01:05 -0700 (PDT) From: Srinivas Kandagatla To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org, bgoswami@codeaurora.org Cc: gregkh@linuxfoundation.org, david.brown@linaro.org, mark.rutland@arm.com, lgirdwood@gmail.com, plai@codeaurora.org, tiwai@suse.com, perex@perex.cz, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, rohkumar@qti.qualcomm.com, spatakok@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v8 18/24] ASoC: qdsp6: q6routing: Add support to all SLIMBus Mixers Date: Wed, 9 May 2018 13:56:29 +0100 Message-Id: <20180509125635.5653-19-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> References: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds support to SLIMBus related mixers to control mux between ASM stream and AFE port. Signed-off-by: Srinivas Kandagatla Reviewed-and-tested-by: Rohit kumar Reviewed-by: Banajit Goswami --- sound/soc/qcom/qdsp6/q6routing.c | 261 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c index f7ee9a1a29b2..97204f2d1894 100644 --- a/sound/soc/qcom/qdsp6/q6routing.c +++ b/sound/soc/qcom/qdsp6/q6routing.c @@ -233,6 +233,180 @@ static const struct snd_kcontrol_new hdmi_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_1_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_1_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_1_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_1_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_1_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_1_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_1_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_1_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_3_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_3_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_3_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_3_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_3_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_3_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_3_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_3_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_4_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { /* Frontend AIF */ SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), @@ -256,6 +430,28 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)), + + SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_rx_mixer_controls, + ARRAY_SIZE(slimbus_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_1_rx_mixer_controls, + ARRAY_SIZE(slimbus_1_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_2_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_2_rx_mixer_controls, + ARRAY_SIZE(slimbus_2_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_3_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_3_rx_mixer_controls, + ARRAY_SIZE(slimbus_3_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_4_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_4_rx_mixer_controls, + ARRAY_SIZE(slimbus_4_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_5_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_5_rx_mixer_controls, + ARRAY_SIZE(slimbus_5_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_6_rx_mixer_controls, + ARRAY_SIZE(slimbus_6_rx_mixer_controls)), }; static const struct snd_soc_dapm_route intercon[] = { @@ -268,6 +464,71 @@ static const struct snd_soc_dapm_route intercon[] = { {"HDMI Mixer", "MultiMedia7", "MM_DL7"}, {"HDMI Mixer", "MultiMedia8", "MM_DL8"}, {"HDMI_RX", NULL, "HDMI Mixer"}, + + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"}, + + {"SLIMBUS_1_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_1_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_1_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_1_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_1_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_1_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_1_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_1_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Audio Mixer"}, + + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_2_RX", NULL, "SLIMBUS_2_RX Audio Mixer"}, + + {"SLIMBUS_3_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_3_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_3_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_3_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_3_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_3_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_3_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_3_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX Audio Mixer"}, + + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_4_RX", NULL, "SLIMBUS_4_RX Audio Mixer"}, + + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_5_RX", NULL, "SLIMBUS_5_RX Audio Mixer"}, + + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"}, }; static int routing_hw_params(struct snd_pcm_substream *substream, From patchwork Wed May 9 12:56:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 135271 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp5612694lji; Wed, 9 May 2018 06:02:47 -0700 (PDT) X-Google-Smtp-Source: AB8JxZp6a3Y9vDMiYoKvTCQKtpX3B0mmVsBBpB/SXmjFiAy58P/hkQlDrswalowPmTGKROv+sKfn X-Received: by 2002:a17:902:6b45:: with SMTP id g5-v6mr31411805plt.67.1525870967838; Wed, 09 May 2018 06:02:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525870967; cv=none; d=google.com; s=arc-20160816; b=Hs3iY2smJ8h6EQVnBL9ACKLbgWxqQDQIGWRRX2TUi8CawFgzYE3Xev+AzORveJ3THN 9ADcC2WdBvYD6rchlfTBjxo0C0FC80fiwelkh5Uu2s71/iLTBj7Xg47Ri3wuiuoWA5Vi Sm+e4+01wv2kl5WCNpZI0nuanJHhWFJuUxpN3An4mBW9LsFGOwLmMr7xpmj1tdNukO4L poANFt2pWF5DnRwRYJJZEk8ANpc80oegNos9v1LdfROhqMUGrFt+f4e4E4jnszewS8RW PHFt2KXqNiibIN6Lwrrb+A2Hfx/+h4zwa9C6JSceO8NWZmO9GmAtTwtSOV0eCWBGTnGW 2UMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=ZhPl/3J05aAz05lNk+rIQKxgNt4xk+ELOreMep5YDc4=; b=naTBO0EpAOEsQBR5b7i9SIGolOvrNNHE09bpOVp2T2RlCejOh/hgBiOaq/nKcmCqBm YhCWzElLk6PcVwWU+mMK/qvJk8jBrzMJCth1UGlVUOzZwulJ90/9OfLnXg9Z4aJrW4bE JRS31/KkpeS+wiljkuTv8RljEGNt5ybY9anLUjDQXLBqgb6nZwDacfrI+EJsevK6V4E0 xXjDRlGy11Q462FevnPgw9lvJnE7qyLnBTcrv7vKRxLdxBLbI69RkJvO9akuEcOaoAw/ soII2DbpLKtBlzraDtKczrIenzROz1NXVHccBi+BYSm6hNkLMYy72KbLHgKDuH6u5n00 vO8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=FxWId18j; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 24si13482002pfj.6.2018.05.09.06.02.47; Wed, 09 May 2018 06:02:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=FxWId18j; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935146AbeEINCq (ORCPT + 6 others); Wed, 9 May 2018 09:02:46 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:54902 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935145AbeEINBI (ORCPT ); Wed, 9 May 2018 09:01:08 -0400 Received: by mail-wm0-f66.google.com with SMTP id f6so24587891wmc.4 for ; Wed, 09 May 2018 06:01:08 -0700 (PDT) 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; bh=XCYL1w9GGBm32yTT9KlPVAqCUS/+7Ln99cDRiwc6tqE=; b=FxWId18jzsacZc+3hlWuTYUhvN51nQtrLSeQwCocDyp0CExLZOa7Wo0kZ0mFzGW2fY E2/bipDbeBfkk2CO1RGqpVdsCrKFAqlEEU4+za65x3/59zA6KTPfQZNAtlW+DNXnKUZD 94ehN7vrW5z1eFdBw7A8+ITJjpds4eEuQN0x8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=XCYL1w9GGBm32yTT9KlPVAqCUS/+7Ln99cDRiwc6tqE=; b=UJ/gGy2syrD6rlC5qgGJW18Er3bPaLtHPYgo2+68896BcuEVIN+r8szI1YQ/ko19Mh m8UOmh3xjNZzRT97aTlHMInBrduETEB7E8Peqi+mi3kkwi7NE0NfTEb661KVN2dPFmKJ 2gSuts1YNGSQSo8uALpCM4y6gTLYCrMjItI4OVDUOqi6e8GC2Q4k9ZvlPRrQgn4pP6Ji JKxTrWHPcPsyzBF4BumLAdjp931yfgoLG37FdEgYrk0SKX1Qc4k3bhxXMWV5/xO6up7r a8FhnvSu0FHqxfj3PU9cR9lewIb/hYQuz8bDKzAB3LL+NmfS2VYFzYVQEL3MxklMslKp Ga5g== X-Gm-Message-State: ALKqPwcK3Z3aAzmkzLNT5+bdpdoNiZ2uQdNIEqd6hvdzBRcxscAjzatg r9C2fdBJ2KGFpAVokMZBX8Rq0w== X-Received: by 10.28.74.219 with SMTP id n88mr6289531wmi.31.1525870867257; Wed, 09 May 2018 06:01:07 -0700 (PDT) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id q2-v6sm29422963wrj.57.2018.05.09.06.01.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 May 2018 06:01:06 -0700 (PDT) From: Srinivas Kandagatla To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org, bgoswami@codeaurora.org Cc: gregkh@linuxfoundation.org, david.brown@linaro.org, mark.rutland@arm.com, lgirdwood@gmail.com, plai@codeaurora.org, tiwai@suse.com, perex@perex.cz, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, rohkumar@qti.qualcomm.com, spatakok@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v8 19/24] ASoC: qdsp6: q6routing: Add support to MI2S Mixers Date: Wed, 9 May 2018 13:56:30 +0100 Message-Id: <20180509125635.5653-20-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> References: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch add support to MI2S mixers required to select path between ASM stream and AFE ports. Signed-off-by: Srinivas Kandagatla Reviewed-and-tested-by: Rohit kumar Reviewed-by: Banajit Goswami --- sound/soc/qcom/qdsp6/q6routing.c | 329 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c index 97204f2d1894..604a29f7101c 100644 --- a/sound/soc/qcom/qdsp6/q6routing.c +++ b/sound/soc/qcom/qdsp6/q6routing.c @@ -233,6 +233,103 @@ static const struct snd_kcontrol_new hdmi_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", PRIMARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", PRIMARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", PRIMARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", PRIMARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", PRIMARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", PRIMARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", PRIMARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", PRIMARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + + static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -407,6 +504,126 @@ static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul1_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul2_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul3_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul4_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul5_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul6_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul7_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul8_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { /* Frontend AIF */ SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), @@ -452,6 +669,35 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0, slimbus_6_rx_mixer_controls, ARRAY_SIZE(slimbus_6_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + primary_mi2s_rx_mixer_controls, + ARRAY_SIZE(primary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + secondary_mi2s_rx_mixer_controls, + ARRAY_SIZE(secondary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + quaternary_mi2s_rx_mixer_controls, + ARRAY_SIZE(quaternary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + tertiary_mi2s_rx_mixer_controls, + ARRAY_SIZE(tertiary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0, + mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0, + mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia3 Mixer", SND_SOC_NOPM, 0, 0, + mmul3_mixer_controls, ARRAY_SIZE(mmul3_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia4 Mixer", SND_SOC_NOPM, 0, 0, + mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0, + mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia6 Mixer", SND_SOC_NOPM, 0, 0, + mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia7 Mixer", SND_SOC_NOPM, 0, 0, + mmul7_mixer_controls, ARRAY_SIZE(mmul7_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0, + mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), + }; static const struct snd_soc_dapm_route intercon[] = { @@ -529,6 +775,89 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_6_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, {"SLIMBUS_6_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"}, + + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"}, + + {"TERT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Audio Mixer"}, + + {"SEC_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL5"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL7"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"}, + + {"PRI_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"}, + + {"MultiMedia1 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia1 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + + {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia2 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + + {"MultiMedia3 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia3 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + + {"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia4 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + + {"MultiMedia5 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia5 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + + {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + + {"MultiMedia7 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia7 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia7 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + + {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia8 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia8 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + + {"MM_UL1", NULL, "MultiMedia1 Mixer"}, + {"MM_UL2", NULL, "MultiMedia2 Mixer"}, + {"MM_UL3", NULL, "MultiMedia3 Mixer"}, + {"MM_UL4", NULL, "MultiMedia4 Mixer"}, + {"MM_UL5", NULL, "MultiMedia5 Mixer"}, + {"MM_UL6", NULL, "MultiMedia6 Mixer"}, + {"MM_UL7", NULL, "MultiMedia7 Mixer"}, + {"MM_UL8", NULL, "MultiMedia8 Mixer"}, }; static int routing_hw_params(struct snd_pcm_substream *substream, From patchwork Wed May 9 12:56:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 135267 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp5610311lji; Wed, 9 May 2018 06:01:24 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrpYTRSUzYBHim+MW57R9U825isZRFol53BtllDhJkON0Xq++wTZw+A553VoUfZclXYy0nn X-Received: by 10.98.232.1 with SMTP id c1mr43950849pfi.184.1525870884851; Wed, 09 May 2018 06:01:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525870884; cv=none; d=google.com; s=arc-20160816; b=pN1C0OnSk6zhBASzJkbI3rtHNgutrfTmlpmlxH4p77LP5KQWtL3+TlJ043kfqR7NhI ABUGuafeWTZveiwuGkZyohVPJPc2YHWeM+LnZPMqBVlQb3P9NWf+02HJLbfNfDFZl2WZ LLvJ/0CPRGaKXlnrmeSVvixIIdljXVsJo6FurqoICxehx1YqYxP5UjNPuWSBdiWxy/e7 luLQ5j+eNOJmk0S5w1wFkgzdjbtyCRGAKiE3542LyG3bRJN8EFJHJmaMjdkq40vnQMXv ncC2rIF6J4kiiAuvVU50TTHvDRYwl2IqFcTiccTnDl2kVq2XDfQjLuPCXBwsgWbht+b7 9C2A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=mNDgEWvzWsxzY03ACMJO6hHIry10dhD0GRmmLKT6KA4=; b=fVKb37WXNltc3mA5Ait3mq/QPGmtfUkuuh6Q51Z+O6a+UyEsCh1DwYMtFA0ybCtfjI B/s6/yIwOZKp/syz+Z0IZyIak8J944dFlvfO1cKsoq/DHxCOCiW+0eBctqSDiPrS3qLk bTaV9wMG3a98hlkvDFwDSqxBA1u2gSBb5ORoBXFl3wr+nJC9vR2qUHYd0Gae/rQ7roQq 7qsrFdvEgrvnOEgcMR2ytXGMm7uQu+AcOwtGocuqHkk2sdxzqMcQYAJZsa97lBXO5xYb ZoNlPdObEaqmIJ5RRoxtEw2PK0eFZPki8AE0zm6tboVFVY/CReEcVezkcVB3Fi4SY8/E B4hg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=cmx/D0CF; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s5-v6si3057920pgo.12.2018.05.09.06.01.24; Wed, 09 May 2018 06:01:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=cmx/D0CF; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935177AbeEINBQ (ORCPT + 6 others); Wed, 9 May 2018 09:01:16 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:32993 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935159AbeEINBM (ORCPT ); Wed, 9 May 2018 09:01:12 -0400 Received: by mail-wm0-f68.google.com with SMTP id x12-v6so23280847wmc.0 for ; Wed, 09 May 2018 06:01:11 -0700 (PDT) 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; bh=PYFMgkui2Zy9dtj/0Tk2aYhc6DaDjPxlBARwa2XCGJ4=; b=cmx/D0CF7qlkrAFVyfe8EGB1vmfRcrxuYkBa+dNTPuldl06heR0O7IJ7Nesw1ofv8B R6SlJzabgVAXUy9VkcBRbtnKwJHNpgIqdPZIsqVl4uMTDQK88l/Xm2Pmiplx86xhCL73 SI7bqxkuI3t/q1McB1+wGz1pGrcu7IczLkks4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PYFMgkui2Zy9dtj/0Tk2aYhc6DaDjPxlBARwa2XCGJ4=; b=cHz4WXHYPzHV+nKW+H6LrvZgAqMD9uVz+K7anZX/HpiucrW2Brab/NjDGayq4LyzOk FIAkUBitLhy5aKKmnsJDbABdIFyd53DRylfmb4ebCpkGp+YiFIZUPyItaevz2SYQyrag QdmeUHTMWnOiVzfBi5xuF5ozb729cndFTRnhXb9Q6q9KHytD7eFARzeJ0r78wmObWHbM TrI2/MX6jOzgPawjt0hRAdAlp2iDB1+EE53x4lVqrdNzv14mdnmyERZ7aCFyndTHzbqe ilJlBM2WUiB9zEnFtd1fvcawQzpnZDGu4hj59Gnpt1Ea1MFiDxNjy/Y6Jy5emyC6zV72 2jMg== X-Gm-Message-State: ALKqPweuU8QwJHYJQLZF9Ni5jj7TaVcsJCa/HsxvZ5FDisDPGGBhXjs0 GxfEhxVneG6L111eaxoDK2ddKw== X-Received: by 2002:a1c:c702:: with SMTP id x2-v6mr6217229wmf.57.1525870870300; Wed, 09 May 2018 06:01:10 -0700 (PDT) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id q2-v6sm29422963wrj.57.2018.05.09.06.01.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 May 2018 06:01:09 -0700 (PDT) From: Srinivas Kandagatla To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org, bgoswami@codeaurora.org Cc: gregkh@linuxfoundation.org, david.brown@linaro.org, mark.rutland@arm.com, lgirdwood@gmail.com, plai@codeaurora.org, tiwai@suse.com, perex@perex.cz, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, rohkumar@qti.qualcomm.com, spatakok@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v8 21/24] ASoC: qdsp6: q6asm: Add q6asm dai driver Date: Wed, 9 May 2018 13:56:32 +0100 Message-Id: <20180509125635.5653-22-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> References: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds support to q6asm dai driver which configures Q6ASM streams to pass pcm data. Signed-off-by: Srinivas Kandagatla Reviewed-and-tested-by: Rohit kumar Reviewed-by: Banajit Goswami --- sound/soc/qcom/Kconfig | 4 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6asm-dai.c | 624 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 629 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6asm-dai.c -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index d3523a30d942..85bb7dd11fd9 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -62,6 +62,9 @@ config SND_SOC_QDSP6_ROUTING config SND_SOC_QDSP6_ASM tristate +config SND_SOC_QDSP6_ASM_DAI + tristate + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" depends on QCOM_APR && HAS_DMA @@ -72,6 +75,7 @@ config SND_SOC_QDSP6 select SND_SOC_QDSP6_ADM select SND_SOC_QDSP6_ROUTING select SND_SOC_QDSP6_ASM + select SND_SOC_QDSP6_ASM_DAI help To add support for MSM QDSP6 Soc Audio. This will enable sound soc platform specific diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile index bada1aa303c2..c33b3cacbea1 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_SND_SOC_QDSP6_AFE_DAI) += q6afe-dai.o obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o +obj-$(CONFIG_SND_SOC_QDSP6_ASM_DAI) += q6asm-dai.o diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c new file mode 100644 index 000000000000..349c6a883c63 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -0,0 +1,624 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +// Copyright (c) 2018, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6asm.h" +#include "q6routing.h" +#include "q6dsp-errno.h" + +#define DRV_NAME "q6asm-fe-dai" + +#define PLAYBACK_MIN_NUM_PERIODS 2 +#define PLAYBACK_MAX_NUM_PERIODS 8 +#define PLAYBACK_MAX_PERIOD_SIZE 65536 +#define PLAYBACK_MIN_PERIOD_SIZE 128 +#define CAPTURE_MIN_NUM_PERIODS 2 +#define CAPTURE_MAX_NUM_PERIODS 8 +#define CAPTURE_MAX_PERIOD_SIZE 4096 +#define CAPTURE_MIN_PERIOD_SIZE 320 +#define SID_MASK_DEFAULT 0xF + +enum stream_state { + Q6ASM_STREAM_IDLE = 0, + Q6ASM_STREAM_STOPPED, + Q6ASM_STREAM_RUNNING, +}; + +struct q6asm_dai_rtd { + struct snd_pcm_substream *substream; + phys_addr_t phys; + unsigned int pcm_size; + unsigned int pcm_count; + unsigned int pcm_irq_pos; /* IRQ position */ + unsigned int periods; + uint16_t bits_per_sample; + uint16_t source; /* Encoding source bit mask */ + struct audio_client *audio_client; + uint16_t session_id; + enum stream_state state; +}; + +struct q6asm_dai_data { + long long int sid; +}; + +static struct snd_pcm_hardware q6asm_dai_hardware_capture = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 4, + .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * + CAPTURE_MAX_PERIOD_SIZE, + .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, + .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, + .periods_min = CAPTURE_MIN_NUM_PERIODS, + .periods_max = CAPTURE_MAX_NUM_PERIODS, + .fifo_size = 0, +}; + +static struct snd_pcm_hardware q6asm_dai_hardware_playback = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .rates = SNDRV_PCM_RATE_8000_192000, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = (PLAYBACK_MAX_NUM_PERIODS * + PLAYBACK_MAX_PERIOD_SIZE), + .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE, + .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE, + .periods_min = PLAYBACK_MIN_NUM_PERIODS, + .periods_max = PLAYBACK_MAX_NUM_PERIODS, + .fifo_size = 0, +}; + +#define Q6ASM_FEDAI_DRIVER(num) { \ + .playback = { \ + .stream_name = "MultiMedia"#num" Playback", \ + .rates = (SNDRV_PCM_RATE_8000_192000| \ + SNDRV_PCM_RATE_KNOT), \ + .formats = (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE), \ + .channels_min = 1, \ + .channels_max = 8, \ + .rate_min = 8000, \ + .rate_max = 192000, \ + }, \ + .capture = { \ + .stream_name = "MultiMedia"#num" Capture", \ + .rates = (SNDRV_PCM_RATE_8000_48000| \ + SNDRV_PCM_RATE_KNOT), \ + .formats = (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE), \ + .channels_min = 1, \ + .channels_max = 4, \ + .rate_min = 8000, \ + .rate_max = 48000, \ + }, \ + .name = "MultiMedia"#num, \ + .probe = fe_dai_probe, \ + .id = MSM_FRONTEND_DAI_MULTIMEDIA##num, \ + } + +/* Conventional and unconventional sample rate supported */ +static unsigned int supported_sample_rates[] = { + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, + 88200, 96000, 176400, 192000 +}; + +static struct snd_pcm_hw_constraint_list constraints_sample_rates = { + .count = ARRAY_SIZE(supported_sample_rates), + .list = supported_sample_rates, + .mask = 0, +}; + +static void event_handler(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv) +{ + struct q6asm_dai_rtd *prtd = priv; + struct snd_pcm_substream *substream = prtd->substream; + + switch (opcode) { + case ASM_CLIENT_EVENT_CMD_RUN_DONE: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + q6asm_write_async(prtd->audio_client, + prtd->pcm_count, 0, 0, NO_TIMESTAMP); + break; + case ASM_CLIENT_EVENT_CMD_EOS_DONE: + prtd->state = Q6ASM_STREAM_STOPPED; + break; + case ASM_CLIENT_EVENT_DATA_WRITE_DONE: { + prtd->pcm_irq_pos += prtd->pcm_count; + snd_pcm_period_elapsed(substream); + if (prtd->state == Q6ASM_STREAM_RUNNING) + q6asm_write_async(prtd->audio_client, + prtd->pcm_count, 0, 0, NO_TIMESTAMP); + + break; + } + case ASM_CLIENT_EVENT_DATA_READ_DONE: + prtd->pcm_irq_pos += prtd->pcm_count; + snd_pcm_period_elapsed(substream); + if (prtd->state == Q6ASM_STREAM_RUNNING) + q6asm_read(prtd->audio_client); + + break; + default: + break; + } +} + +static int q6asm_dai_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct q6asm_dai_rtd *prtd = runtime->private_data; + struct snd_soc_component *c = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + struct q6asm_dai_data *pdata; + int ret, i; + + pdata = snd_soc_component_get_drvdata(c); + if (!pdata) + return -EINVAL; + + if (!prtd || !prtd->audio_client) { + pr_err("%s: private data null or audio client freed\n", + __func__); + return -EINVAL; + } + + prtd->pcm_count = snd_pcm_lib_period_bytes(substream); + prtd->pcm_irq_pos = 0; + /* rate and channels are sent to audio driver */ + if (prtd->state) { + /* clear the previous setup if any */ + q6asm_cmd(prtd->audio_client, CMD_CLOSE); + q6asm_unmap_memory_regions(substream->stream, + prtd->audio_client); + q6routing_stream_close(soc_prtd->dai_link->id, + substream->stream); + } + + ret = q6asm_map_memory_regions(substream->stream, prtd->audio_client, + prtd->phys, + (prtd->pcm_size / prtd->periods), + prtd->periods); + + if (ret < 0) { + pr_err("Audio Start: Buffer Allocation failed rc = %d\n", + ret); + return -ENOMEM; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = q6asm_open_write(prtd->audio_client, FORMAT_LINEAR_PCM, + prtd->bits_per_sample); + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = q6asm_open_read(prtd->audio_client, FORMAT_LINEAR_PCM, + prtd->bits_per_sample); + } + + if (ret < 0) { + pr_err("%s: q6asm_open_write failed\n", __func__); + q6asm_audio_client_free(prtd->audio_client); + prtd->audio_client = NULL; + return -ENOMEM; + } + + prtd->session_id = q6asm_get_session_id(prtd->audio_client); + ret = q6routing_stream_open(soc_prtd->dai_link->id, LEGACY_PCM_MODE, + prtd->session_id, substream->stream); + if (ret) { + pr_err("%s: stream reg failed ret:%d\n", __func__, ret); + return ret; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = q6asm_media_format_block_multi_ch_pcm( + prtd->audio_client, runtime->rate, + runtime->channels, NULL, + prtd->bits_per_sample); + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = q6asm_enc_cfg_blk_pcm_format_support(prtd->audio_client, + runtime->rate, runtime->channels, + prtd->bits_per_sample); + + /* Queue the buffers */ + for (i = 0; i < runtime->periods; i++) + q6asm_read(prtd->audio_client); + + } + if (ret < 0) + pr_info("%s: CMD Format block failed\n", __func__); + + prtd->state = Q6ASM_STREAM_RUNNING; + + return 0; +} + +static int q6asm_dai_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct q6asm_dai_rtd *prtd = runtime->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0); + break; + case SNDRV_PCM_TRIGGER_STOP: + prtd->state = Q6ASM_STREAM_STOPPED; + ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int q6asm_dai_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct snd_soc_dai *cpu_dai = soc_prtd->cpu_dai; + struct snd_soc_component *c = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + struct q6asm_dai_rtd *prtd; + struct q6asm_dai_data *pdata; + struct device *dev = c->dev; + int ret = 0; + int stream_id; + + stream_id = cpu_dai->driver->id; + + pdata = snd_soc_component_get_drvdata(c); + if (!pdata) { + pr_err("Drv data not found ..\n"); + return -EINVAL; + } + + prtd = kzalloc(sizeof(struct q6asm_dai_rtd), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + + prtd->substream = substream; + prtd->audio_client = q6asm_audio_client_alloc(dev, + (q6asm_cb)event_handler, prtd, stream_id, + LEGACY_PCM_MODE); + if (!prtd->audio_client) { + pr_info("%s: Could not allocate memory\n", __func__); + kfree(prtd); + return -ENOMEM; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + runtime->hw = q6asm_dai_hardware_playback; + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + runtime->hw = q6asm_dai_hardware_capture; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_sample_rates); + if (ret < 0) + pr_info("snd_pcm_hw_constraint_list failed\n"); + /* Ensure that buffer size is a multiple of period size */ + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + pr_info("snd_pcm_hw_constraint_integer failed\n"); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE, + PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE); + if (ret < 0) { + pr_err("constraint for buffer bytes min max ret = %d\n", + ret); + } + } + + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); + if (ret < 0) { + pr_err("constraint for period bytes step ret = %d\n", + ret); + } + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); + if (ret < 0) { + pr_err("constraint for buffer bytes step ret = %d\n", + ret); + } + + runtime->private_data = prtd; + + snd_soc_set_runtime_hwparams(substream, &q6asm_dai_hardware_playback); + + runtime->dma_bytes = q6asm_dai_hardware_playback.buffer_bytes_max; + + + if (pdata->sid < 0) + prtd->phys = substream->dma_buffer.addr; + else + prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + return 0; +} + +static int q6asm_dai_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct q6asm_dai_rtd *prtd = runtime->private_data; + + if (prtd->audio_client) { + q6asm_cmd(prtd->audio_client, CMD_CLOSE); + q6asm_unmap_memory_regions(substream->stream, + prtd->audio_client); + q6asm_audio_client_free(prtd->audio_client); + prtd->audio_client = NULL; + } + q6routing_stream_close(soc_prtd->dai_link->id, + substream->stream); + kfree(prtd); + return 0; +} + +static snd_pcm_uframes_t q6asm_dai_pointer(struct snd_pcm_substream *substream) +{ + + struct snd_pcm_runtime *runtime = substream->runtime; + struct q6asm_dai_rtd *prtd = runtime->private_data; + + if (prtd->pcm_irq_pos >= prtd->pcm_size) + prtd->pcm_irq_pos = 0; + + return bytes_to_frames(runtime, (prtd->pcm_irq_pos)); +} + +static int q6asm_dai_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct snd_soc_component *c = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + struct device *dev = c->dev; + + return dma_mmap_coherent(dev, vma, + runtime->dma_area, runtime->dma_addr, + runtime->dma_bytes); +} + +static int q6asm_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct q6asm_dai_rtd *prtd = runtime->private_data; + + prtd->pcm_size = params_buffer_bytes(params); + prtd->periods = params_periods(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + prtd->bits_per_sample = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + prtd->bits_per_sample = 24; + break; + } + + return 0; +} + +static struct snd_pcm_ops q6asm_dai_ops = { + .open = q6asm_dai_open, + .hw_params = q6asm_dai_hw_params, + .close = q6asm_dai_close, + .ioctl = snd_pcm_lib_ioctl, + .prepare = q6asm_dai_prepare, + .trigger = q6asm_dai_trigger, + .pointer = q6asm_dai_pointer, + .mmap = q6asm_dai_mmap, +}; + +static int q6asm_dai_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm_substream *psubstream, *csubstream; + struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + struct snd_pcm *pcm = rtd->pcm; + struct device *dev; + int size, ret; + + dev = c->dev; + size = q6asm_dai_hardware_playback.buffer_bytes_max; + psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (psubstream) { + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, + &psubstream->dma_buffer); + if (ret) { + dev_err(dev, "Cannot allocate buffer(s)\n"); + return ret; + } + } + + csubstream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; + if (csubstream) { + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, + &csubstream->dma_buffer); + if (ret) { + dev_err(dev, "Cannot allocate buffer(s)\n"); + if (psubstream) + snd_dma_free_pages(&psubstream->dma_buffer); + return ret; + } + } + + return ret; +} + +static void q6asm_dai_pcm_free(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + int i; + + for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) { + substream = pcm->streams[i].substream; + if (substream) { + snd_dma_free_pages(&substream->dma_buffer); + substream->dma_buffer.area = NULL; + substream->dma_buffer.addr = 0; + } + } +} + +static const struct snd_soc_dapm_route afe_pcm_routes[] = { + {"MM_DL1", NULL, "MultiMedia1 Playback" }, + {"MM_DL2", NULL, "MultiMedia2 Playback" }, + {"MM_DL3", NULL, "MultiMedia3 Playback" }, + {"MM_DL4", NULL, "MultiMedia4 Playback" }, + {"MM_DL5", NULL, "MultiMedia5 Playback" }, + {"MM_DL6", NULL, "MultiMedia6 Playback" }, + {"MM_DL7", NULL, "MultiMedia7 Playback" }, + {"MM_DL7", NULL, "MultiMedia8 Playback" }, + {"MultiMedia1 Capture", NULL, "MM_UL1"}, + {"MultiMedia2 Capture", NULL, "MM_UL2"}, + {"MultiMedia3 Capture", NULL, "MM_UL3"}, + {"MultiMedia4 Capture", NULL, "MM_UL4"}, + {"MultiMedia5 Capture", NULL, "MM_UL5"}, + {"MultiMedia6 Capture", NULL, "MM_UL6"}, + {"MultiMedia7 Capture", NULL, "MM_UL7"}, + {"MultiMedia8 Capture", NULL, "MM_UL8"}, + +}; + +static int fe_dai_probe(struct snd_soc_dai *dai) +{ + struct snd_soc_dapm_context *dapm; + + dapm = snd_soc_component_get_dapm(dai->component); + snd_soc_dapm_add_routes(dapm, afe_pcm_routes, + ARRAY_SIZE(afe_pcm_routes)); + + return 0; +} + + +static const struct snd_soc_component_driver q6asm_fe_dai_component = { + .name = DRV_NAME, + .ops = &q6asm_dai_ops, + .pcm_new = q6asm_dai_pcm_new, + .pcm_free = q6asm_dai_pcm_free, + +}; + +static struct snd_soc_dai_driver q6asm_fe_dais[] = { + Q6ASM_FEDAI_DRIVER(1), + Q6ASM_FEDAI_DRIVER(2), + Q6ASM_FEDAI_DRIVER(3), + Q6ASM_FEDAI_DRIVER(4), + Q6ASM_FEDAI_DRIVER(5), + Q6ASM_FEDAI_DRIVER(6), + Q6ASM_FEDAI_DRIVER(7), + Q6ASM_FEDAI_DRIVER(8), +}; + +static int q6asm_dai_bind(struct device *dev, struct device *master, void *data) +{ + struct device_node *node = dev->of_node; + struct of_phandle_args args; + struct q6asm_dai_data *pdata; + int rc; + + pdata = kzalloc(sizeof(struct q6asm_dai_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + rc = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args); + if (rc < 0) + pdata->sid = -1; + else + pdata->sid = args.args[0] & SID_MASK_DEFAULT; + + dev_set_drvdata(dev, pdata); + + return snd_soc_register_component(dev, &q6asm_fe_dai_component, + q6asm_fe_dais, + ARRAY_SIZE(q6asm_fe_dais)); +} +static void q6asm_dai_unbind(struct device *dev, struct device *master, + void *data) +{ + struct q6asm_dai_data *pdata = dev_get_drvdata(dev); + + snd_soc_unregister_component(dev); + + kfree(pdata); + +} + +static const struct component_ops q6asm_dai_comp_ops = { + .bind = q6asm_dai_bind, + .unbind = q6asm_dai_unbind, +}; + +static int q6asm_dai_probe(struct platform_device *pdev) +{ + return component_add(&pdev->dev, &q6asm_dai_comp_ops); +} + +static int q6asm_dai_dev_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &q6asm_dai_comp_ops); + return 0; +} + +static struct platform_driver q6asm_dai_platform_driver = { + .driver = { + .name = "q6asm-dai", + }, + .probe = q6asm_dai_probe, + .remove = q6asm_dai_dev_remove, +}; +module_platform_driver(q6asm_dai_platform_driver); + +MODULE_DESCRIPTION("Q6ASM dai driver"); +MODULE_LICENSE("GPL v2"); From patchwork Wed May 9 12:56:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 135268 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp5610449lji; Wed, 9 May 2018 06:01:28 -0700 (PDT) X-Google-Smtp-Source: AB8JxZon+QU9SeXmlKhK4Iq6s9cVNDcrKbTjCgjTHTLoN5paIHCy9eUzYesxoUZRfUcg9jvEuF2k X-Received: by 2002:a17:902:8f94:: with SMTP id z20-v6mr31300654plo.391.1525870888786; Wed, 09 May 2018 06:01:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525870888; cv=none; d=google.com; s=arc-20160816; b=OuzxsupbOb9Ywp/9e8VYKSRizuiuycz5DFM5oguCMigQUpFcrUc9We0eWoKCWr92dh GjgOevs4oEfUeJAZbHS/YVvury8zYonDCxZgHYKDlL8Fdn7lWCMvNnWhx49TPoK6sLzV hD5KbXPVnL1W+7e68/cus3RPKIH2eMp6DHTM1ejfkixVrAj9J4oq035GRK8akmx3SMR4 flyzKmNHIW+fGnZFkfKOobljWr+cAi/wW3NVtRcLsD26dUtAbpNxudt8e1s6wfYbMMLw Ou7LVOqiWEcSni9EkyPLAYeM66aP5AeIJQlAgKgiBZ4jBYCiYXJVBmsyc7kFmqyKf3rI UB3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=Z/2csrV2PQ1LEx8AIYoFE30nS+9wyxxTxAibNEDzuCI=; b=ID1IPXPeaU9EljlN52QckqrS1SL9tKFv7Bp7PCEhtd2JApcRVcqEU72+0L/s4anNQ3 wmsOTxHcrpm4uINMOxuX6uUx4QKK6horzaY0NmNBCwKsAY/Raa35I6bRg7pOEk+tMkcA 34Gj07ZKDF68rWoKg7yw5v8EuajBf83EK0vJBjE9qOcRidaGPtmcSpVS2WBoGjt6/aQt eqIBwJKAtdc9+ntkQl7QmTJJu6i8cN8SDGSXNyAIl/Zqi1dMkmztV8xF8ZJcg5sau9Qk LKr1JznRKp0SgOf9KRN6R5mHdxDKX/o46oo5Li/O7cs3g/u0AwXT8fWvMEBww38UWhBA 1n3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=HcQtlcLm; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s5-v6si3057920pgo.12.2018.05.09.06.01.28; Wed, 09 May 2018 06:01:28 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=HcQtlcLm; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935169AbeEINB1 (ORCPT + 6 others); Wed, 9 May 2018 09:01:27 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:44570 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935166AbeEINBP (ORCPT ); Wed, 9 May 2018 09:01:15 -0400 Received: by mail-wr0-f194.google.com with SMTP id y15-v6so23846880wrg.11 for ; Wed, 09 May 2018 06:01:14 -0700 (PDT) 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; bh=b6KNRmgBNX1F/vt0UTkBKE7cHLPTGGkXc0Y/LbvjVlU=; b=HcQtlcLmKg8VdAA1dp3tKD/M8ZN5HaNc/XwDYo6vcUvXWsAoXH0KSxRifOgPK0+EC6 CgZ5yT4unKD1MFOowJZAJrTm18NKFfAuOstQB3BwBidc5LSIGCSIZZdJMrr9ZnAJmuQS Y25fP8+/FLqTjptTNtywmy2s389CWJ19binDk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=b6KNRmgBNX1F/vt0UTkBKE7cHLPTGGkXc0Y/LbvjVlU=; b=Wq7/Cu8/BKz62qwUzWRkDLXobSamzIQIpSgA2MfC2JlPw38gKxsN68yjuyfvbfAG1T fiNTMYIkNRTsrWuRX//nqmtMJL9LiKP0HCmawC68INlG+f5nrX8Tz1uCCZspTYqeLrhi LlKtpsQxqaG9Nl1wepRfhUwRYI2s+/vzEsZQ08reBtYOOETcWBTR754gecm4sKJwtEj4 /B7tEbYHuvOZWxtCljXvKU0Oa5BAf/+UJD5X6prXUvbrsSo+ZAgyzzinymfRgS3R+rzm CDAlbLi4I6U2cEDH4s8pWWjnapspdFFU/Gk7slmY5mP4qrYMen7tFeyIXgbOFZeb6EO5 aoyg== X-Gm-Message-State: ALQs6tCCCuSUZlmstUOM6GMVyyQt4CiW3ceAjD9bgOgDIW9PabvteTiV Yw5OAi4YYDV52s9LcyqJodI/rg== X-Received: by 2002:adf:8e27:: with SMTP id n36-v6mr34525098wrb.27.1525870873030; Wed, 09 May 2018 06:01:13 -0700 (PDT) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id q2-v6sm29422963wrj.57.2018.05.09.06.01.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 May 2018 06:01:12 -0700 (PDT) From: Srinivas Kandagatla To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org, bgoswami@codeaurora.org Cc: gregkh@linuxfoundation.org, david.brown@linaro.org, mark.rutland@arm.com, lgirdwood@gmail.com, plai@codeaurora.org, tiwai@suse.com, perex@perex.cz, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, rohkumar@qti.qualcomm.com, spatakok@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v8 23/24] ASoC: qcom: apq8096: Add db820c machine driver Date: Wed, 9 May 2018 13:56:34 +0100 Message-Id: <20180509125635.5653-24-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> References: <20180509125635.5653-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds support to DB820c machine driver. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/Kconfig | 9 ++ sound/soc/qcom/Makefile | 2 + sound/soc/qcom/apq8096.c | 255 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 sound/soc/qcom/apq8096.c -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 85bb7dd11fd9..87838fa27997 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -81,3 +81,12 @@ config SND_SOC_QDSP6 This will enable sound soc platform specific audio drivers. This includes q6asm, q6adm, q6afe interfaces to DSP using apr. + +config SND_SOC_MSM8996 + tristate "SoC Machine driver for MSM8996 and APQ8096 boards" + depends on QCOM_APR + select SND_SOC_QDSP6 + help + Support for Qualcomm Technologies LPASS audio block in + APQ8096 SoC-based systems. + Say Y if you want to use audio device on this SoCs diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile index 0276717917c0..206945bb9ba1 100644 --- a/sound/soc/qcom/Makefile +++ b/sound/soc/qcom/Makefile @@ -13,9 +13,11 @@ obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += snd-soc-lpass-apq8016.o # Machine snd-soc-storm-objs := storm.o snd-soc-apq8016-sbc-objs := apq8016_sbc.o +snd-soc-apq8096-objs := apq8096.o obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o +obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-apq8096.o #DSP lib obj-$(CONFIG_SND_SOC_QDSP6) += qdsp6/ diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c new file mode 100644 index 000000000000..561cd429e6f2 --- /dev/null +++ b/sound/soc/qcom/apq8096.c @@ -0,0 +1,255 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include + +static int apq8096_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + return 0; +} + +static int apq8096_sbc_parse_of(struct snd_soc_card *card) +{ + struct device_node *np; + struct device_node *codec = NULL; + struct device_node *platform = NULL; + struct device_node *cpu = NULL; + struct device *dev = card->dev; + struct snd_soc_dai_link *link; + int ret, num_links; + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(dev, "Error parsing card name: %d\n", ret); + return ret; + } + + /* DAPM routes */ + if (of_property_read_bool(dev->of_node, "qcom,audio-routing")) { + ret = snd_soc_of_parse_audio_routing(card, + "qcom,audio-routing"); + if (ret) + return ret; + } + + /* Populate links */ + num_links = of_get_child_count(dev->of_node); + + /* Allocate the DAI link array */ + card->dai_link = kcalloc(num_links, sizeof(*link), GFP_KERNEL); + if (!card->dai_link) + return -ENOMEM; + + card->num_links = num_links; + link = card->dai_link; + + for_each_child_of_node(dev->of_node, np) { + cpu = of_get_child_by_name(np, "cpu"); + if (!cpu) { + dev_err(dev, "Can't find cpu DT node\n"); + ret = -EINVAL; + goto err; + } + + link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0); + if (!link->cpu_of_node) { + dev_err(card->dev, "error getting cpu phandle\n"); + ret = -EINVAL; + goto err; + } + + ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name); + if (ret) { + dev_err(card->dev, "error getting cpu dai name\n"); + goto err; + } + + platform = of_get_child_by_name(np, "platform"); + codec = of_get_child_by_name(np, "codec"); + if (codec && platform) { + link->platform_of_node = of_parse_phandle(platform, + "sound-dai", + 0); + if (!link->platform_of_node) { + dev_err(card->dev, "platform dai not found\n"); + ret = -EINVAL; + goto err; + } + + ret = snd_soc_of_get_dai_link_codecs(dev, codec, link); + if (ret < 0) { + dev_err(card->dev, "codec dai not found\n"); + goto err; + } + link->no_pcm = 1; + link->ignore_pmdown_time = 1; + link->be_hw_params_fixup = apq8096_be_hw_params_fixup; + } else { + link->platform_of_node = link->cpu_of_node; + link->codec_dai_name = "snd-soc-dummy-dai"; + link->codec_name = "snd-soc-dummy"; + link->dynamic = 1; + } + + link->ignore_suspend = 1; + ret = of_property_read_string(np, "link-name", &link->name); + if (ret) { + dev_err(card->dev, "error getting codec dai_link name\n"); + goto err; + } + + link->dpcm_playback = 1; + link->dpcm_capture = 1; + link->stream_name = link->name; + link++; + } + + return 0; +err: + of_node_put(cpu); + of_node_put(codec); + of_node_put(platform); + kfree(card->dai_link); + return ret; +} + +static int apq8096_bind(struct device *dev) +{ + struct snd_soc_card *card; + int ret; + + card = kzalloc(sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + component_bind_all(dev, card); + card->dev = dev; + ret = apq8096_sbc_parse_of(card); + if (ret) { + dev_err(dev, "Error parsing OF data\n"); + goto err; + } + + ret = snd_soc_register_card(card); + if (ret) + goto err; + + return 0; + +err: + component_unbind_all(dev, card); + kfree(card); + return ret; +} + +static void apq8096_unbind(struct device *dev) +{ + struct snd_soc_card *card = dev_get_drvdata(dev); + + snd_soc_unregister_card(card); + component_unbind_all(dev, card); + kfree(card->dai_link); + kfree(card); +} + +static const struct component_master_ops apq8096_ops = { + .bind = apq8096_bind, + .unbind = apq8096_unbind, +}; + +static int apq8016_compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static void apq8016_release_of(struct device *dev, void *data) +{ + of_node_put(data); +} + +static int add_audio_components(struct device *dev, + struct component_match **matchptr) +{ + struct device_node *np, *platform, *cpu, *node, *dai_node; + + node = dev->of_node; + + for_each_child_of_node(node, np) { + cpu = of_get_child_by_name(np, "cpu"); + if (cpu) { + dai_node = of_parse_phandle(cpu, "sound-dai", 0); + of_node_get(dai_node); + component_match_add_release(dev, matchptr, + apq8016_release_of, + apq8016_compare_of, + dai_node); + } + + platform = of_get_child_by_name(np, "platform"); + if (platform) { + dai_node = of_parse_phandle(platform, "sound-dai", 0); + component_match_add_release(dev, matchptr, + apq8016_release_of, + apq8016_compare_of, + dai_node); + } + } + + return 0; +} + +static int apq8096_platform_probe(struct platform_device *pdev) +{ + struct component_match *match = NULL; + int ret; + + ret = add_audio_components(&pdev->dev, &match); + if (ret) + return ret; + + return component_master_add_with_match(&pdev->dev, &apq8096_ops, match); +} + +static int apq8096_platform_remove(struct platform_device *pdev) +{ + component_master_del(&pdev->dev, &apq8096_ops); + + return 0; +} + +static const struct of_device_id msm_snd_apq8096_dt_match[] = { + {.compatible = "qcom,apq8096-sndcard"}, + {} +}; + +MODULE_DEVICE_TABLE(of, msm_snd_apq8096_dt_match); + +static struct platform_driver msm_snd_apq8096_driver = { + .probe = apq8096_platform_probe, + .remove = apq8096_platform_remove, + .driver = { + .name = "msm-snd-apq8096", + .owner = THIS_MODULE, + .of_match_table = msm_snd_apq8096_dt_match, + }, +}; +module_platform_driver(msm_snd_apq8096_driver); +MODULE_AUTHOR("Srinivas Kandagatla