From patchwork Tue Dec 5 22:17:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 120760 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6311415qgn; Tue, 5 Dec 2017 14:20:35 -0800 (PST) X-Google-Smtp-Source: AGs4zMY2NOL1XNJwXB+7KP3LhMjt6aO7kNFcgikVp5R8GBFvMm0NU2TkJbMLb0jRuBf7akWB275O X-Received: by 10.84.244.138 with SMTP id h10mr6557393pll.289.1512512435340; Tue, 05 Dec 2017 14:20:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512512435; cv=none; d=google.com; s=arc-20160816; b=Lbm7nNt1GiWUfeITEj8Bul3SUskH1LwzlaHNQG6kAXSUkGHtX0OMjtmKw2DAcT2Rrp ugcToEY39cqGg6qNIxd6rlxuneVdhgg/3Ra9YJ9zQ0/VD16D/15/6SIhrepVolTWHutu spf3rw1J6uPetYH412VvIGD+cy4B6pghhdxn01MFtQzwZhIKHHb49aj9YlCHIfwYrBiM GWJTFid3qSQBSyPOGf/1nHZ/Mif92DbDvL6CZI7auA/3rPKz6hb1Ux/wKzlj3zn53918 53UfS2CJcW0+dOJuZHPzFKs8c97BqKWvxgI9SA5tbRBpH5aeQ2KNC6UKffyJ37gnFXmT 4Brw== 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=Nzk9Z2TN009fUVkx64V8wL3ol2JKcDmveSGMED4kSK4=; b=GQLE7uK6o2j5xdTGdp3Z6OnGUaWt5Ia9p9iZ0eqhJb+ndB4uHfvWxaHP9oqLFH+oGu GcmdEa8fJTuG/lIbSHA9tkdK76BS7Ld/ZPi4lAZXjHbw67embkJcLlIt9gMi7rSctIpv CMtp4a0Qr6oqOS0KmhYWD8uYojwbVxJkR9EwF5UTFYq1AbvGzzKT97cIrL9I4YXaKnAa +vjdUykJjqmjVA8+6hv5lr+31GnlQktNVhdbrMX9Ci+nPlQ+IS0+/BlNZCJG/NZuOrDV 6NDW4EP6HIunkaYCvzggrMLmwVwYqQDxRy2po+a3PZk7URkwDXauaU1M6DLIAp8Gifxg TKPw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jVhf6TPL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p14si718664pgd.651.2017.12.05.14.20.34; Tue, 05 Dec 2017 14:20:35 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jVhf6TPL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752565AbdLEWUb (ORCPT + 28 others); Tue, 5 Dec 2017 17:20:31 -0500 Received: from mail-wm0-f68.google.com ([74.125.82.68]:46180 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752062AbdLEWUV (ORCPT ); Tue, 5 Dec 2017 17:20:21 -0500 Received: by mail-wm0-f68.google.com with SMTP id r78so4048641wme.5 for ; Tue, 05 Dec 2017 14:20:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Nzk9Z2TN009fUVkx64V8wL3ol2JKcDmveSGMED4kSK4=; b=jVhf6TPL2W6B4YPSEPOsG9pA0Evup3RMSQNb7Y/xQ3i6jjFaNyv2HoNjHm41YBpVZX WIyNGzsJJpzM+4wbJ6igITxcjQh27RZi8tH8hRRAqj3OJVWF4tbv74Pr1C+RAiBHJZAU pzUMWUvmfxZaInMO11wJevtnlMAO4FH6Jh04s= 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=Nzk9Z2TN009fUVkx64V8wL3ol2JKcDmveSGMED4kSK4=; b=ax/ltCWgdkQU3z7Gp2v7dkIZUGzvdsLoCuAgNo2V+7fEfOZP1wmuMBP9gxzA65jgSu u+En5GfNSZR9MNgV9VEG2CXn7X9+rHeNmj/QB526Z0YU60GG72czDQUKRUMssBJB0ai7 QlW4917Bx8QItSTUBA5VDVEVV3KZV9NUxhNkcqtyPuE3hA+8wrIpPmtWOSiU6ZiDv+hX +b+OHQ4GsxA2Iuu2P6PhArq6MXBlrM31N7ZtPYrUI12dN6TAEUzdFM9YHklDS2t8gD94 4B3fegxjl25/x0U7z1V/1Exxa0qF9PR2sa7ELQC91OO4dqnNVHGGb8yhNFD8zi/xaQN9 cPKw== X-Gm-Message-State: AKGB3mJIMAvGqcyIh6u7sAtSGiWdYXFJMyJ8ugnKqHf+hh3O5M68OzpJ afXcWN29Y93u/TIhZHP+iL+zhA== X-Received: by 10.28.120.2 with SMTP id t2mr10128000wmc.5.1512512420394; Tue, 05 Dec 2017 14:20:20 -0800 (PST) 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 t138sm1633154wme.16.2017.12.05.14.20.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Dec 2017 14:20:19 -0800 (PST) From: srinivas.kandagatla@linaro.org To: broonie@kernel.org, bgoswami@codeaurora.org Cc: alsa-devel@alsa-project.org, tiwai@suse.com, plai@codeaurora.org, kwestfie@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, lkasam@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v2 01/15] dt-bindings: soc: qcom: Add bindings for APR bus Date: Tue, 5 Dec 2017 22:17:58 +0000 Message-Id: <20171205221812.25641-2-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> References: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla This patch add dt bindings for Qualcomm APR bus driver Signed-off-by: Srinivas Kandagatla --- .../devicetree/bindings/soc/qcom/qcom,apr.txt | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt -- 2.15.0 diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt new file mode 100644 index 000000000000..4e93213ae98d --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt @@ -0,0 +1,28 @@ +Qualcomm APR (Asynchronous Packet Router) binding + +This binding describes the Qualcomm APR. APR is a IPC protocol for +communication between Application processor and QDSP. APR is mainly +used for audio/voice services on the QDSP. + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,apr-" example: "qcom,apr-msm8996" + + +- qcom,smd-channel: + Usage: required + Value type: + Definition: standard SMD property specifying the SMD channel used for + communication with the APR on QDSP. + Should be "apr_audio_svc". + Described in soc/qcom/qcom,smd.txt + += EXAMPLE +The following example represents a QDSP based sound card on a MSM8996 device +which uses apr as communication between Apps and QDSP. + + apr { + compatible = "qcom,apr-msm8996"; + qcom,smd-channels = "apr_audio_svc"; + }; From patchwork Tue Dec 5 22:18:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 120774 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6315437qgn; Tue, 5 Dec 2017 14:25:37 -0800 (PST) X-Google-Smtp-Source: AGs4zMaUfWoXgMw0igDmoxT9ldAhXVdH7Lb8vNAP0fmXCSXaUGGiEKBcJYuVCxelCEppRY5Z+XWS X-Received: by 10.98.178.17 with SMTP id x17mr158623pfe.239.1512512737361; Tue, 05 Dec 2017 14:25:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512512737; cv=none; d=google.com; s=arc-20160816; b=s5ZlILHIb7VgtGtjZTo3DqMWiLl9YZW5HmCbX4BqkseiOXwmYN+24rwq74wfYcqWtm v8EiaWk7cjFnGq//xh3UW0HU56hFOvsQpScSx89+pUofZqIMcKosI6tTDFYl/qJbp6bd FHcP3DAZEp+VIU2GMFpVXBQTJ86UuYkExMu42g/LyQdwPyHFpV8s6RU1HON477lAg7i6 s+MGaJpJC8s8tAEV+AKow5AOA84edKlDGrvFXpZT5JHUTvU4JDilBkdYv+8Zv5tnDGri +bwWzpeMXi4KKwcgw0Kfbn3+nTMLWp0Gm+3iM5QXl6+Ig3qivcYie0GBYwlVr6KoWB0O woWA== 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=qv1fUBlz1SkIfoply7mtU0EdtHdqkqeOE+eq/Dp1P2Y=; b=QGW2/L66O0fFhjw2w12va0VD6rAc8PWc8hmV4i8EtlCBTOfoWfEXtLFHaY8amYcdr1 kxNE7Nc40/rhwxyT/xn9QLIjdpHe+7JnajL8nAfdc70NYitCJmG0ONGVHkUiOhMjF4Zi VS99sZdFqUkQF8LsQUJHuvEWVyN3g6irTqoSJ3sB+DHTbfMakhzbL7vE4jfsv+Z+2m0g 9ynUD7XXnA9f63NAg8AZuJBPz0tN3NQRPvjzeT68jJYDazWAn6A1lrramobveAXVmFeV bS7y9OIfNH3AYqih0veSv7i/ClLN2DxcCpHwnUmb6llEoGXoobW9oyBs3VOTBDS8r2rQ Xfmg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SZd66MsO; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o76si824574pfg.10.2017.12.05.14.25.37; Tue, 05 Dec 2017 14:25:37 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SZd66MsO; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752875AbdLEWZf (ORCPT + 28 others); Tue, 5 Dec 2017 17:25:35 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:40411 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752376AbdLEWUX (ORCPT ); Tue, 5 Dec 2017 17:20:23 -0500 Received: by mail-wm0-f67.google.com with SMTP id f206so3934158wmf.5 for ; Tue, 05 Dec 2017 14:20:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qv1fUBlz1SkIfoply7mtU0EdtHdqkqeOE+eq/Dp1P2Y=; b=SZd66MsOK+wH7iHnMA9WBUb4JRhS6pdC/H1AMovQolWBDF+cjAiDVXC7m6CoJrUMZT VqMbbZLta1SAtwGxKYFeUfOYFfS2+bAo8A/Ft+XlcUebigZHUkELyRmaQmzVmJUjZC/T bu6ZD2I47pNos2mqjjmQSZ/OpAA5tqPPNdHYw= 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=qv1fUBlz1SkIfoply7mtU0EdtHdqkqeOE+eq/Dp1P2Y=; b=pJdAlABZPuNS1BwtvKfPXkowsV4PhX4NDDaojnS3Nw2bfAPJ80OSRR31Hl5JuxOh6H DB8Vm1QXMqa1bld0aTAohsnw7g85pp71Mpu5+aroa4EKrhT/NdrjSwvdI5rFYp5I4Xwj V7J573fNMM2g8M/bW8dsEVw5ILcA+sJzPyvIN4jKG14wtaAzFqZNcDHdIBmd4VKyZ0iT r+hUy2ZUU9mOQa2UX9+oHtPKuuF/5RU3ueLj457uBcUxGwxJKCGY1qLBpCArVV+7x/Y6 aYpDqwlWbAnmH+jG3YEN4TuOiA3hj8/5ubmqrmH6ybcOfpjdRFhQdppyUhnx+rB+Tjwq YoBA== X-Gm-Message-State: AKGB3mKRYuH8xNpVJv+6Or5dDtwLHX6725MrL67nANRt683mLIMNp+Tk CcnppXcjIjjtWDlI1Z1OF4fWJg== X-Received: by 10.28.17.77 with SMTP id 74mr6800203wmr.66.1512512422478; Tue, 05 Dec 2017 14:20:22 -0800 (PST) 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 t138sm1633154wme.16.2017.12.05.14.20.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Dec 2017 14:20:21 -0800 (PST) From: srinivas.kandagatla@linaro.org To: broonie@kernel.org, bgoswami@codeaurora.org Cc: alsa-devel@alsa-project.org, tiwai@suse.com, plai@codeaurora.org, kwestfie@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, lkasam@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v2 03/15] ASoC: qcom: qdsp6: Add common qdsp6 helper functions Date: Tue, 5 Dec 2017 22:18:00 +0000 Message-Id: <20171205221812.25641-4-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> References: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla This patch adds some common helper functions like translating dsp error to linux error codes and channel mappings etc. These functions are used in all the following qdsp6 drivers. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/qdsp6/common.h | 225 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/common.h -- 2.15.0 diff --git a/sound/soc/qcom/qdsp6/common.h b/sound/soc/qcom/qdsp6/common.h new file mode 100644 index 000000000000..cbd6e009ef4b --- /dev/null +++ b/sound/soc/qcom/qdsp6/common.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __Q6DSP_COMMON_H__ +#define __Q6DSP_COMMON_H__ + +/* ERROR CODES */ +/* Success. The operation completed with no errors. */ +#define ADSP_EOK 0x00000000 +/* General failure. */ +#define ADSP_EFAILED 0x00000001 +/* Bad operation parameter. */ +#define ADSP_EBADPARAM 0x00000002 +/* Unsupported routine or operation. */ +#define ADSP_EUNSUPPORTED 0x00000003 +/* Unsupported version. */ +#define ADSP_EVERSION 0x00000004 +/* Unexpected problem encountered. */ +#define ADSP_EUNEXPECTED 0x00000005 +/* Unhandled problem occurred. */ +#define ADSP_EPANIC 0x00000006 +/* Unable to allocate resource. */ +#define ADSP_ENORESOURCE 0x00000007 +/* Invalid handle. */ +#define ADSP_EHANDLE 0x00000008 +/* Operation is already processed. */ +#define ADSP_EALREADY 0x00000009 +/* Operation is not ready to be processed. */ +#define ADSP_ENOTREADY 0x0000000A +/* Operation is pending completion. */ +#define ADSP_EPENDING 0x0000000B +/* Operation could not be accepted or processed. */ +#define ADSP_EBUSY 0x0000000C +/* Operation aborted due to an error. */ +#define ADSP_EABORTED 0x0000000D +/* Operation preempted by a higher priority. */ +#define ADSP_EPREEMPTED 0x0000000E +/* Operation requests intervention to complete. */ +#define ADSP_ECONTINUE 0x0000000F +/* Operation requests immediate intervention to complete. */ +#define ADSP_EIMMEDIATE 0x00000010 +/* Operation is not implemented. */ +#define ADSP_ENOTIMPL 0x00000011 +/* Operation needs more data or resources. */ +#define ADSP_ENEEDMORE 0x00000012 +/* Operation does not have memory. */ +#define ADSP_ENOMEMORY 0x00000014 +/* Item does not exist. */ +#define ADSP_ENOTEXIST 0x00000015 +/* Max count for adsp error code sent to HLOS*/ +#define ADSP_ERR_MAX (ADSP_ENOTEXIST + 1) +/* Operation is finished. */ +#define ADSP_ETERMINATED 0x00011174 + +/* ERROR STRING */ +/* Success. The operation completed with no errors. */ +#define ADSP_EOK_STR "ADSP_EOK" +/* General failure. */ +#define ADSP_EFAILED_STR "ADSP_EFAILED" +/* Bad operation parameter. */ +#define ADSP_EBADPARAM_STR "ADSP_EBADPARAM" +/* Unsupported routine or operation. */ +#define ADSP_EUNSUPPORTED_STR "ADSP_EUNSUPPORTED" +/* Unsupported version. */ +#define ADSP_EVERSION_STR "ADSP_EVERSION" +/* Unexpected problem encountered. */ +#define ADSP_EUNEXPECTED_STR "ADSP_EUNEXPECTED" +/* Unhandled problem occurred. */ +#define ADSP_EPANIC_STR "ADSP_EPANIC" +/* Unable to allocate resource. */ +#define ADSP_ENORESOURCE_STR "ADSP_ENORESOURCE" +/* Invalid handle. */ +#define ADSP_EHANDLE_STR "ADSP_EHANDLE" +/* Operation is already processed. */ +#define ADSP_EALREADY_STR "ADSP_EALREADY" +/* Operation is not ready to be processed. */ +#define ADSP_ENOTREADY_STR "ADSP_ENOTREADY" +/* Operation is pending completion. */ +#define ADSP_EPENDING_STR "ADSP_EPENDING" +/* Operation could not be accepted or processed. */ +#define ADSP_EBUSY_STR "ADSP_EBUSY" +/* Operation aborted due to an error. */ +#define ADSP_EABORTED_STR "ADSP_EABORTED" +/* Operation preempted by a higher priority. */ +#define ADSP_EPREEMPTED_STR "ADSP_EPREEMPTED" +/* Operation requests intervention to complete. */ +#define ADSP_ECONTINUE_STR "ADSP_ECONTINUE" +/* Operation requests immediate intervention to complete. */ +#define ADSP_EIMMEDIATE_STR "ADSP_EIMMEDIATE" +/* Operation is not implemented. */ +#define ADSP_ENOTIMPL_STR "ADSP_ENOTIMPL" +/* Operation needs more data or resources. */ +#define ADSP_ENEEDMORE_STR "ADSP_ENEEDMORE" +/* Operation does not have memory. */ +#define ADSP_ENOMEMORY_STR "ADSP_ENOMEMORY" +/* Item does not exist. */ +#define ADSP_ENOTEXIST_STR "ADSP_ENOTEXIST" +/* Unexpected error code. */ +#define ADSP_ERR_MAX_STR "ADSP_ERR_MAX" + +#define PCM_FORMAT_MAX_NUM_CHANNEL 8 +#define PCM_CHANNEL_NULL 0 + +#define PCM_CHANNEL_FL 1 /* Front left channel. */ +#define PCM_CHANNEL_FR 2 /* Front right channel. */ +#define PCM_CHANNEL_FC 3 /* Front center channel. */ +#define PCM_CHANNEL_LS 4 /* Left surround channel. */ +#define PCM_CHANNEL_RS 5 /* Right surround channel. */ +#define PCM_CHANNEL_LFE 6 /* Low frequency effect channel. */ +#define PCM_CHANNEL_CS 7 /* Center surround channel; Rear center ch */ +#define PCM_CHANNEL_LB 8 /* Left back channel; Rear left channel. */ +#define PCM_CHANNEL_RB 9 /* Right back channel; Rear right channel. */ +#define PCM_CHANNELS 10 /* Top surround channel. */ + +static inline int q6dsp_map_channels(u8 *ch_map, int ch) +{ + memset(ch_map, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (ch == 1) { + ch_map[0] = PCM_CHANNEL_FC; + } else if (ch == 2) { + ch_map[0] = PCM_CHANNEL_FL; + ch_map[1] = PCM_CHANNEL_FR; + } else if (ch == 3) { + ch_map[0] = PCM_CHANNEL_FL; + ch_map[1] = PCM_CHANNEL_FR; + ch_map[2] = PCM_CHANNEL_FC; + } else if (ch == 4) { + ch_map[0] = PCM_CHANNEL_FL; + ch_map[1] = PCM_CHANNEL_FR; + ch_map[2] = PCM_CHANNEL_LS; + ch_map[3] = PCM_CHANNEL_RS; + } else if (ch == 5) { + ch_map[0] = PCM_CHANNEL_FL; + ch_map[1] = PCM_CHANNEL_FR; + ch_map[2] = PCM_CHANNEL_FC; + ch_map[3] = PCM_CHANNEL_LS; + ch_map[4] = PCM_CHANNEL_RS; + } else if (ch == 6) { + ch_map[0] = PCM_CHANNEL_FL; + ch_map[1] = PCM_CHANNEL_FR; + ch_map[2] = PCM_CHANNEL_LFE; + ch_map[3] = PCM_CHANNEL_FC; + ch_map[4] = PCM_CHANNEL_LS; + ch_map[5] = PCM_CHANNEL_RS; + } else if (ch == 8) { + ch_map[0] = PCM_CHANNEL_FL; + ch_map[1] = PCM_CHANNEL_FR; + ch_map[2] = PCM_CHANNEL_LFE; + ch_map[3] = PCM_CHANNEL_FC; + ch_map[4] = PCM_CHANNEL_LS; + ch_map[5] = PCM_CHANNEL_RS; + ch_map[6] = PCM_CHANNEL_LB; + ch_map[7] = PCM_CHANNEL_RB; + } else { + return -EINVAL; + } + + return 0; +} + +enum { + LEGACY_PCM_MODE = 0, + LOW_LATENCY_PCM_MODE, + ULTRA_LOW_LATENCY_PCM_MODE, + ULL_POST_PROCESSING_PCM_MODE, +}; + +struct adsp_err_code { + int lnx_err_code; + char *adsp_err_str; +}; + +static struct adsp_err_code adsp_err_code_info[ADSP_ERR_MAX+1] = { + { 0, ADSP_EOK_STR}, + { -ENOTRECOVERABLE, ADSP_EFAILED_STR}, + { -EINVAL, ADSP_EBADPARAM_STR}, + { -ENOSYS, ADSP_EUNSUPPORTED_STR}, + { -ENOPROTOOPT, ADSP_EVERSION_STR}, + { -ENOTRECOVERABLE, ADSP_EUNEXPECTED_STR}, + { -ENOTRECOVERABLE, ADSP_EPANIC_STR}, + { -ENOSPC, ADSP_ENORESOURCE_STR}, + { -EBADR, ADSP_EHANDLE_STR}, + { -EALREADY, ADSP_EALREADY_STR}, + { -EPERM, ADSP_ENOTREADY_STR}, + { -EINPROGRESS, ADSP_EPENDING_STR}, + { -EBUSY, ADSP_EBUSY_STR}, + { -ECANCELED, ADSP_EABORTED_STR}, + { -EAGAIN, ADSP_EPREEMPTED_STR}, + { -EAGAIN, ADSP_ECONTINUE_STR}, + { -EAGAIN, ADSP_EIMMEDIATE_STR}, + { -EAGAIN, ADSP_ENOTIMPL_STR}, + { -ENODATA, ADSP_ENEEDMORE_STR}, + { -EADV, ADSP_ERR_MAX_STR}, + { -ENOMEM, ADSP_ENOMEMORY_STR}, + { -ENODEV, ADSP_ENOTEXIST_STR}, + { -EADV, ADSP_ERR_MAX_STR}, +}; + +static inline int adsp_err_get_lnx_err_code(u32 adsp_error) +{ + if (adsp_error > ADSP_ERR_MAX) + return adsp_err_code_info[ADSP_ERR_MAX].lnx_err_code; + else + return adsp_err_code_info[adsp_error].lnx_err_code; +} + +static inline char *adsp_err_get_err_str(u32 adsp_error) +{ + if (adsp_error > ADSP_ERR_MAX) + return adsp_err_code_info[ADSP_ERR_MAX].adsp_err_str; + else + return adsp_err_code_info[adsp_error].adsp_err_str; +} + +#endif /* __Q6DSP_COMMON_H__ */ From patchwork Tue Dec 5 22:18:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 120773 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6314626qgn; Tue, 5 Dec 2017 14:24:37 -0800 (PST) X-Google-Smtp-Source: AGs4zMaXFhezCfNRUVbL4SCbLiT0+n4qmymGOTNJy9akeNLXpkC7V9rpskph/+F3YiWpccA71QFf X-Received: by 10.84.172.1 with SMTP id m1mr20226433plb.174.1512512677667; Tue, 05 Dec 2017 14:24:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512512677; cv=none; d=google.com; s=arc-20160816; b=xoq8FJtobibfNh7xX0pDePy6mysnnN8cN2/2vVJfHLZorDA00XKgMueWOIaeX96CZi R7+UTh7YKCW8q3SaULS7Kj3NRJ7qddlcsd2xZo1d+Kl8GgHMEnWLp9vgaUk8hSM8Q9XH 4+58ON6ESLaM7GlmF8jN89Ji5db1HZqWzM7GOaj0Z89otO9fj6yLKAiRAZaxncVzb99i d9tzntKNxyEw54Y0czas23d/c/aGCEvomioOTpT45KGe0hSAJxH5A3fGlVCoiY6yTHwk n1pRol+TQ9FuEZXdbMb6Vc/gPU93KNjUutP+u10xMljAhGLoQpp2P9qb550qQAuwjwbj Txtw== 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=5XW8G3AfUSX1oIB43MTJ4nDLnbzlV2SUCs0XIXzlsDY=; b=n0ODrmEFyV88Hamae5TCRB1FleiKpIq5CRBUitl1LD8mYkhRKe2iMfjCeH2UOX0Pwi 6geX6JujuylbB4j9V/G79+IlWzPS6NT6pEQOtUDh4w4soGNYnvoDn/qKMC4UMIhgr67c ijNiTDXQn8Bejr9cOZRgYo6J2sNUq2Sm2Rj/lNkp1wCzZtf6ZLaDYfF2RJ00gZk4692y T6yRdkUSDe7Vop0LOiKq7z5/0IO3Uk0inYfktDgHdlnBh7NclbV1Ep5vag7MPZAyicFM xMKAaa2IF6dIPkb8eERrZ+8F95/ENRPNsF1muqYmyl4sg7nrdWrB32Refu8e88SLQx1C ptrQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Ixyi0uJl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m8si797091pfi.343.2017.12.05.14.24.37; Tue, 05 Dec 2017 14:24:37 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Ixyi0uJl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752936AbdLEWYe (ORCPT + 28 others); Tue, 5 Dec 2017 17:24:34 -0500 Received: from mail-wr0-f195.google.com ([209.85.128.195]:40115 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751709AbdLEWU2 (ORCPT ); Tue, 5 Dec 2017 17:20:28 -0500 Received: by mail-wr0-f195.google.com with SMTP id q9so1912849wre.7 for ; Tue, 05 Dec 2017 14:20:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5XW8G3AfUSX1oIB43MTJ4nDLnbzlV2SUCs0XIXzlsDY=; b=Ixyi0uJlUk0OD1LzS45f30gUf1G2C8XtRSZUnK1hl0dskWdVZo455XcrsZ4hoFWkIU tll5DDBuWlofw/jwU19L43lCcKIyt2yw3IZ+hTvPuL4ZRhX3sv8tvcRrRcq/bmkQjGsG 9m2uPR5kBePW7YkvJ5NH9u9t/RLUkFcQbzfbw= 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=5XW8G3AfUSX1oIB43MTJ4nDLnbzlV2SUCs0XIXzlsDY=; b=OPKSl3kPeX7zgFGnaFfczO6Y4bYh5MfwGCxFL7Q6exXMkAUFiMxHTwDWgjFgXeVYfq LLkRVAn4IP7eJSAexdmY7vEofv4n5J7bEDVv7pCKR1/jgrtwa/KySiacz8SDZ0Ih98V+ 2pnyiGBB3Gk1BqJgaLDFUnNBi/9ecAoWT+gFYui52keW4HMgqfxKiwp94Q8POmVhxQBJ MXqZVItdmYQcoTqCLeNnnYunYi/pPu3ofHcS8UpMaOMQqmSXfZ9M9w8MknQzg8kXmEpq hC9+PBdsKAmQ4pqOSzv22YXlHuX+JpzcdEOkSqQOSWf2q3pspwsHV36PcXq55Bv+huXX s2JA== X-Gm-Message-State: AJaThX6qiBy8kVY1mVafVbMlESIIDPp8Lr/TCMmx4cDvqVktFc3+r33F 2aTgb6O4iV0omr4XG+mRQWTVRQ== X-Received: by 10.223.139.67 with SMTP id v3mr17201716wra.70.1512512426956; Tue, 05 Dec 2017 14:20:26 -0800 (PST) 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 t138sm1633154wme.16.2017.12.05.14.20.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Dec 2017 14:20:26 -0800 (PST) From: srinivas.kandagatla@linaro.org To: broonie@kernel.org, bgoswami@codeaurora.org Cc: alsa-devel@alsa-project.org, tiwai@suse.com, plai@codeaurora.org, kwestfie@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, lkasam@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v2 07/15] ASoC: qcom: q6asm: Add support to memory map and unmap Date: Tue, 5 Dec 2017 22:18:04 +0000 Message-Id: <20171205221812.25641-8-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> References: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla This patch adds support to memory map and unmap regions commands in q6asm module. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/qdsp6/q6asm.c | 343 ++++++++++++++++++++++++++++++++++++++++++- sound/soc/qcom/qdsp6/q6asm.h | 5 + 2 files changed, 347 insertions(+), 1 deletion(-) -- 2.15.0 diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c index 9cc583afef4d..4be92441f524 100644 --- a/sound/soc/qcom/qdsp6/q6asm.c +++ b/sound/soc/qcom/qdsp6/q6asm.c @@ -14,9 +14,46 @@ #include "q6asm.h" #include "common.h" +#define ASM_CMD_SHARED_MEM_MAP_REGIONS 0x00010D92 +#define ASM_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00010D93 +#define ASM_CMD_SHARED_MEM_UNMAP_REGIONS 0x00010D94 + #define TUN_READ_IO_MODE 0x0004 /* tunnel read write mode */ #define SYNC_IO_MODE 0x0001 #define ASYNC_IO_MODE 0x0002 +#define ASM_SHIFT_GAPLESS_MODE_FLAG 31 +#define ADSP_MEMORY_MAP_SHMEM8_4K_POOL 3 + +struct avs_cmd_shared_mem_map_regions { + struct apr_hdr hdr; + u16 mem_pool_id; + u16 num_regions; + u32 property_flag; +} __packed; + +struct avs_shared_map_region_payload { + u32 shm_addr_lsw; + u32 shm_addr_msw; + u32 mem_size_bytes; +} __packed; + +struct avs_cmd_shared_mem_unmap_regions { + struct apr_hdr hdr; + u32 mem_map_handle; +} __packed; + +struct audio_buffer { + dma_addr_t phys; + uint32_t used; + uint32_t size; /* size of buffer */ +}; + +struct audio_port_data { + struct audio_buffer *buf; + uint32_t max_buf_cnt; + uint32_t dsp_buf; + uint32_t mem_map_handle; +}; struct audio_client { int session; @@ -27,6 +64,8 @@ struct audio_client { uint64_t time_stamp; struct apr_device *adev; struct mutex cmd_lock; + /* idx:1 out port, 0: in port */ + struct audio_port_data port[2]; wait_queue_head_t cmd_wait; int perf_mode; int stream_id; @@ -86,6 +125,260 @@ static void q6asm_session_free(struct audio_client *ac) mutex_unlock(&a->session_lock); } +static inline void q6asm_add_mmaphdr(struct audio_client *ac, + struct apr_hdr *hdr, u32 pkt_size, + bool cmd_flg, u32 token) +{ + hdr->hdr_field = APR_SEQ_CMD_HDR_FIELD; + hdr->src_port = 0; + hdr->dest_port = 0; + hdr->pkt_size = pkt_size; + if (cmd_flg) + hdr->token = token; +} + +static inline void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, + uint32_t pkt_size, bool cmd_flg, + uint32_t stream_id) +{ + hdr->hdr_field = APR_SEQ_CMD_HDR_FIELD; + hdr->src_svc = ac->adev->svc_id; + hdr->src_domain = APR_DOMAIN_APPS; + hdr->dest_svc = APR_SVC_ASM; + hdr->dest_domain = APR_DOMAIN_ADSP; + hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id); + hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id); + hdr->pkt_size = pkt_size; + if (cmd_flg) + hdr->token = ac->session; +} + +static int __q6asm_memory_unmap(struct audio_client *ac, + phys_addr_t buf_add, int dir) +{ + struct avs_cmd_shared_mem_unmap_regions mem_unmap; + struct q6asm *a = dev_get_drvdata(ac->dev->parent); + int rc; + + if (!a) + return -ENODEV; + + q6asm_add_mmaphdr(ac, &mem_unmap.hdr, sizeof(mem_unmap), true, + ((ac->session << 8) | dir)); + a->mem_state = -1; + + mem_unmap.hdr.opcode = ASM_CMD_SHARED_MEM_UNMAP_REGIONS; + mem_unmap.mem_map_handle = ac->port[dir].mem_map_handle; + + if (mem_unmap.mem_map_handle == 0) { + dev_err(ac->dev, "invalid mem handle\n"); + return -EINVAL; + } + + rc = apr_send_pkt(a->adev, (uint32_t *) &mem_unmap); + if (rc < 0) + return rc; + + rc = wait_event_timeout(a->mem_wait, (a->mem_state >= 0), + 5 * HZ); + if (!rc) { + dev_err(ac->dev, "CMD timeout for memory_unmap 0x%x\n", + mem_unmap.mem_map_handle); + return -ETIMEDOUT; + } else if (a->mem_state > 0) { + return adsp_err_get_lnx_err_code(a->mem_state); + } + ac->port[dir].mem_map_handle = 0; + + return 0; +} + +/** + * q6asm_unmap_memory_regions() - unmap memory regions in the dsp. + * + * @dir: direction of audio stream + * @ac: audio client instanace + * + * Return: Will be an negative value on failure or zero on success + */ +int q6asm_unmap_memory_regions(unsigned int dir, struct audio_client *ac) +{ + struct audio_port_data *port; + int cnt = 0; + int rc = 0; + + mutex_lock(&ac->cmd_lock); + port = &ac->port[dir]; + if (!port->buf) { + mutex_unlock(&ac->cmd_lock); + return 0; + } + cnt = port->max_buf_cnt - 1; + if (cnt >= 0) { + rc = __q6asm_memory_unmap(ac, port->buf[dir].phys, dir); + if (rc < 0) { + dev_err(ac->dev, "%s: Memory_unmap_regions failed %d\n", + __func__, rc); + mutex_unlock(&ac->cmd_lock); + return rc; + } + } + + port->max_buf_cnt = 0; + kfree(port->buf); + port->buf = NULL; + mutex_unlock(&ac->cmd_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(q6asm_unmap_memory_regions); + +static int __q6asm_memory_map_regions(struct audio_client *ac, int dir, + uint32_t period_sz, uint32_t periods, + bool is_contiguous) +{ + struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + struct q6asm *a = dev_get_drvdata(ac->dev->parent); + struct audio_port_data *port = NULL; + struct audio_buffer *ab = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + int rc = 0; + int i = 0; + int cmd_size = 0; + uint32_t num_regions; + uint32_t buf_sz; + + if (!a) + return -ENODEV; + num_regions = is_contiguous ? 1 : periods; + buf_sz = is_contiguous ? (period_sz * periods) : period_sz; + buf_sz = PAGE_ALIGN(buf_sz); + + cmd_size = sizeof(*mmap_regions) + (sizeof(*mregions) * num_regions); + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (!mmap_region_cmd) + return -ENOMEM; + + mmap_regions = (struct avs_cmd_shared_mem_map_regions *)mmap_region_cmd; + q6asm_add_mmaphdr(ac, &mmap_regions->hdr, cmd_size, true, + ((ac->session << 8) | dir)); + a->mem_state = -1; + + mmap_regions->hdr.opcode = ASM_CMD_SHARED_MEM_MAP_REGIONS; + mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + mmap_regions->num_regions = num_regions; + mmap_regions->property_flag = 0x00; + + payload = ((u8 *) mmap_region_cmd + + sizeof(struct avs_cmd_shared_mem_map_regions)); + + mregions = (struct avs_shared_map_region_payload *)payload; + + ac->port[dir].mem_map_handle = 0; + port = &ac->port[dir]; + + for (i = 0; i < num_regions; i++) { + ab = &port->buf[i]; + mregions->shm_addr_lsw = lower_32_bits(ab->phys); + mregions->shm_addr_msw = upper_32_bits(ab->phys); + mregions->mem_size_bytes = buf_sz; + ++mregions; + } + + rc = apr_send_pkt(a->adev, (uint32_t *) mmap_region_cmd); + if (rc < 0) + goto fail_cmd; + + rc = wait_event_timeout(a->mem_wait, (a->mem_state >= 0), + 5 * HZ); + if (!rc) { + dev_err(ac->dev, "timeout. waited for memory_map\n"); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (a->mem_state > 0) { + rc = adsp_err_get_lnx_err_code(a->mem_state); + goto fail_cmd; + } + rc = 0; +fail_cmd: + kfree(mmap_region_cmd); + return rc; +} + +/** + * q6asm_map_memory_regions() - map memory regions in the dsp. + * + * @dir: direction of audio stream + * @ac: audio client instanace + * @phys: physcial address that needs mapping. + * @period_sz: audio period size + * @periods: number of periods + * + * Return: Will be an negative value on failure or zero on success + */ +int q6asm_map_memory_regions(unsigned int dir, struct audio_client *ac, + dma_addr_t phys, + unsigned int period_sz, unsigned int periods) +{ + struct audio_buffer *buf; + int cnt; + int rc; + + if (ac->port[dir].buf) { + dev_err(ac->dev, "Buffer already allocated\n"); + return 0; + } + + mutex_lock(&ac->cmd_lock); + + buf = kzalloc(((sizeof(struct audio_buffer)) * periods), GFP_KERNEL); + if (!buf) { + mutex_unlock(&ac->cmd_lock); + return -ENOMEM; + } + + + ac->port[dir].buf = buf; + + buf[0].phys = phys; + buf[0].used = dir ^ 1; + buf[0].size = period_sz; + cnt = 1; + while (cnt < periods) { + if (period_sz > 0) { + buf[cnt].phys = buf[0].phys + (cnt * period_sz); + buf[cnt].used = dir ^ 1; + buf[cnt].size = period_sz; + } + cnt++; + } + + ac->port[dir].max_buf_cnt = periods; + mutex_unlock(&ac->cmd_lock); + + rc = __q6asm_memory_map_regions(ac, dir, period_sz, periods, 1); + if (rc < 0) { + dev_err(ac->dev, + "CMD Memory_map_regions failed %d for size %d\n", rc, + period_sz); + + + ac->port[dir].max_buf_cnt = 0; + kfree(buf); + ac->port[dir].buf = NULL; + + return rc; + } + + return 0; +} +EXPORT_SYMBOL_GPL(q6asm_map_memory_regions); + /** * q6asm_audio_client_free() - Freee allocated audio client * @@ -117,8 +410,10 @@ static struct audio_client *q6asm_get_audio_client(struct q6asm *a, static int q6asm_srvc_callback(struct apr_device *adev, struct apr_client_data *data) { - struct q6asm *q6asm = dev_get_drvdata(&adev->dev); + struct q6asm *a, *q6asm = dev_get_drvdata(&adev->dev); struct audio_client *ac = NULL; + struct audio_port_data *port; + uint32_t dir = 0; uint32_t sid = 0; uint32_t *payload; @@ -135,6 +430,52 @@ static int q6asm_srvc_callback(struct apr_device *adev, struct apr_client_data * return 0; } + a = dev_get_drvdata(ac->dev->parent); + if (data->opcode == APR_BASIC_RSP_RESULT) { + switch (payload[0]) { + case ASM_CMD_SHARED_MEM_MAP_REGIONS: + case ASM_CMD_SHARED_MEM_UNMAP_REGIONS: + if (payload[1] != 0) { + dev_err(ac->dev, + "cmd = 0x%x returned error = 0x%x sid:%d\n", + payload[0], payload[1], sid); + a->mem_state = payload[1]; + } else { + a->mem_state = 0; + } + + wake_up(&a->mem_wait); + break; + default: + dev_err(&adev->dev, "command[0x%x] not expecting rsp\n", + payload[0]); + break; + } + return 0; + } + + dir = (data->token & 0x0F); + port = &ac->port[dir]; + + switch (data->opcode) { + case ASM_CMDRSP_SHARED_MEM_MAP_REGIONS:{ + a->mem_state = 0; + ac->port[dir].mem_map_handle = payload[0]; + wake_up(&a->mem_wait); + break; + } + case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:{ + a->mem_state = 0; + ac->port[dir].mem_map_handle = 0; + wake_up(&a->mem_wait); + + break; + } + default: + dev_dbg(&adev->dev, "command[0x%x]success [0x%x]\n", + payload[0], payload[1]); + break; + } if (ac->cb) ac->cb(data->opcode, data->token, data->payload, ac->priv); return 0; diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h index 7a8a9039fd89..e1409c368600 100644 --- a/sound/soc/qcom/qdsp6/q6asm.h +++ b/sound/soc/qcom/qdsp6/q6asm.h @@ -11,4 +11,9 @@ struct audio_client *q6asm_audio_client_alloc(struct device *dev, app_cb cb, void *priv); void q6asm_audio_client_free(struct audio_client *ac); int q6asm_get_session_id(struct audio_client *ac); +int q6asm_map_memory_regions(unsigned int dir, + struct audio_client *ac, + dma_addr_t phys, + unsigned int bufsz, unsigned int bufcnt); +int q6asm_unmap_memory_regions(unsigned int dir, struct audio_client *ac); #endif /* __Q6_ASM_H__ */ From patchwork Tue Dec 5 22:18:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 120762 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6311543qgn; Tue, 5 Dec 2017 14:20:45 -0800 (PST) X-Google-Smtp-Source: AGs4zMZD5wfuWLKsIAarh59isqfABuUH51r4uS72tLOqaOEKeXBTKvrP6D1fSt877BT9WTZifiPY X-Received: by 10.99.176.76 with SMTP id z12mr18790560pgo.358.1512512445428; Tue, 05 Dec 2017 14:20:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512512445; cv=none; d=google.com; s=arc-20160816; b=T1hxEWMffHjVTvLcZ0t1qXxo+eDSQla2QoOxH1s0IM0qUAfvSVd/iKbWa+CEscsC+5 7ppZ3vgZ8Jgolmp1Xh3gI4CeAXNiXMQWmamZP94sb68XuWO9PJpgoGEVIrf7Kn5QxyWJ eY91RG+qZGJiXC2w545KpXJMgF6LsVSfbmNqHSz6i5+Ai/87mItiY5f1kqnR+Z0YCmLb /oJKRQ6Nz54sVHfLFI6cF9bt0Ih/0qxe2RWAzR0XEDRRBwipphkfifccaFE+cnjmIzTF uot1Ryga31VlCU7z0cS0c4CTeroUjjBYH9VexiH5HbdDbw4BRLH+9O3urb88P/JU+ICq jVgw== 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=lyDSytykL6/GEF2GBqE/UFmRdNv9oB4GeJrqQrtV21I=; b=lViLWUkl/Yf5ijD8SKdJYGajrK1xsRdOzMwWdioDbrFb7QD3Yj1NCYbs7kAhwBJzYd WMB2qK9dJhcLzn6TBOBu1uHqGVSogKY/kLmakDSo8OfRSK/VtGwHS4bP5UYvls+JxrqI 699HXPzik4cboYSXLFHjhYNTif/KH65rS/Kh+UNsSNF+JaH3MKTqXXLZP4hLn/kGVFkR /ET5wjzBYLe0md8aLrgAoBphWycad01JazS5P6hNaA5DUijYJ3JLLI9mfPiutHTU9H4s b4yfhOceeRobxLnaqE6uhIyrZRaK+QNjag8YW+/zGBg9RlhDAGaACFIK1B2ZlFCEvhMQ JI7w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dA68Y0mk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a90si754625plc.137.2017.12.05.14.20.44; Tue, 05 Dec 2017 14:20:45 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dA68Y0mk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752653AbdLEWUn (ORCPT + 28 others); Tue, 5 Dec 2017 17:20:43 -0500 Received: from mail-wr0-f196.google.com ([209.85.128.196]:41623 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752500AbdLEWUa (ORCPT ); Tue, 5 Dec 2017 17:20:30 -0500 Received: by mail-wr0-f196.google.com with SMTP id z18so1906481wrb.8 for ; Tue, 05 Dec 2017 14:20:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lyDSytykL6/GEF2GBqE/UFmRdNv9oB4GeJrqQrtV21I=; b=dA68Y0mkbD2pq+HvXyq4jgsZot1rppGFhEg17x7DkBq8Ljozg8bRsB/uCpCtr4BRQt X03430kH5+vWxEZddhlMKD+tHi+ReyxUudypM813RLmzVQT2W10e8v6KNqZWisYBJq94 J0Vk+3A27tQ2UFl84aIsnwrxAZsq5hxKShiBM= 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=lyDSytykL6/GEF2GBqE/UFmRdNv9oB4GeJrqQrtV21I=; b=T4V3zAMHY0agegjLLGm4XGYZkGCxTMEp9wH6bFZabVijDq7cYiLmj/lO739cesNrMc YBSnx3Am2uDcctm0ZMS23jusf3vJzsIxsPDwmtKHPUM1d8TgUKmOnHUoBI5n0BOg7rfx rz7fkTbgNau1d24Bv45F9iIX6XqWfhHTdxOne/HP+Jbh8b84oh16UxFCEsHXainbLDyN A2bQn4rUg51AEHaVSn/3vd+Ws1PCBmD34tSE/5M4hi7rJuRyPI/oqAO1Oe3qFITskZOV AjwP5Hf+rWh8HXjJruV+TTirtblb35k9FJAdSBhrYErfbQqWs5BmJPBkocnqAVLcebWI Sucg== X-Gm-Message-State: AJaThX4lTQ093Tj6jQOIoDaNkZ9Zbt3n5SQqQNsjYOKtLrwpv5d1ZgC5 P9BTBQNqbI54F3VDiO6/9GjIU44IjMU= X-Received: by 10.223.139.196 with SMTP id w4mr16769201wra.51.1512512428192; Tue, 05 Dec 2017 14:20:28 -0800 (PST) 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 t138sm1633154wme.16.2017.12.05.14.20.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Dec 2017 14:20:27 -0800 (PST) From: srinivas.kandagatla@linaro.org To: broonie@kernel.org, bgoswami@codeaurora.org Cc: alsa-devel@alsa-project.org, tiwai@suse.com, plai@codeaurora.org, kwestfie@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, lkasam@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v2 08/15] ASoC: qcom: q6asm: add support to audio stream apis Date: Tue, 5 Dec 2017 22:18:05 +0000 Message-Id: <20171205221812.25641-9-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> References: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla This patch adds support to open, write and media format commands in the q6asm module. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/qdsp6/q6asm.c | 530 ++++++++++++++++++++++++++++++++++++++++++- sound/soc/qcom/qdsp6/q6asm.h | 42 ++++ 2 files changed, 571 insertions(+), 1 deletion(-) -- 2.15.0 diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c index 4be92441f524..dabd6509ef99 100644 --- a/sound/soc/qcom/qdsp6/q6asm.c +++ b/sound/soc/qcom/qdsp6/q6asm.c @@ -8,16 +8,34 @@ #include #include #include +#include #include #include #include #include "q6asm.h" #include "common.h" +#define ASM_STREAM_CMD_CLOSE 0x00010BCD +#define ASM_STREAM_CMD_FLUSH 0x00010BCE +#define ASM_SESSION_CMD_PAUSE 0x00010BD3 +#define ASM_DATA_CMD_EOS 0x00010BDB +#define DEFAULT_POPP_TOPOLOGY 0x00010BE4 +#define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09 #define ASM_CMD_SHARED_MEM_MAP_REGIONS 0x00010D92 #define ASM_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00010D93 #define ASM_CMD_SHARED_MEM_UNMAP_REGIONS 0x00010D94 - +#define ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2 0x00010D98 +#define ASM_DATA_EVENT_WRITE_DONE_V2 0x00010D99 +#define ASM_SESSION_CMD_RUN_V2 0x00010DAA +#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5 +#define ASM_DATA_CMD_WRITE_V2 0x00010DAB +#define ASM_SESSION_CMD_SUSPEND 0x00010DEC +#define ASM_STREAM_CMD_OPEN_WRITE_V3 0x00010DB3 + +#define ASM_LEGACY_STREAM_SESSION 0 +#define ASM_END_POINT_DEVICE_MATRIX 0 +#define DEFAULT_APP_TYPE 0 +#define TUN_WRITE_IO_MODE 0x0008 /* tunnel read write mode */ #define TUN_READ_IO_MODE 0x0004 /* tunnel read write mode */ #define SYNC_IO_MODE 0x0001 #define ASYNC_IO_MODE 0x0002 @@ -42,6 +60,49 @@ struct avs_cmd_shared_mem_unmap_regions { u32 mem_map_handle; } __packed; +struct asm_data_cmd_media_fmt_update_v2 { + u32 fmt_blk_size; +} __packed; + +struct asm_multi_channel_pcm_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; + u16 num_channels; + u16 bits_per_sample; + u32 sample_rate; + u16 is_signed; + u16 reserved; + u8 channel_mapping[8]; +} __packed; + +struct asm_data_cmd_write_v2 { + struct apr_hdr hdr; + u32 buf_addr_lsw; + u32 buf_addr_msw; + u32 mem_map_handle; + u32 buf_size; + u32 seq_id; + u32 timestamp_lsw; + u32 timestamp_msw; + u32 flags; +} __packed; + +struct asm_stream_cmd_open_write_v3 { + struct apr_hdr hdr; + uint32_t mode_flags; + uint16_t sink_endpointype; + uint16_t bits_per_sample; + uint32_t postprocopo_id; + uint32_t dec_fmt_id; +} __packed; + +struct asm_session_cmd_run_v2 { + struct apr_hdr hdr; + u32 flags; + u32 time_lsw; + u32 time_msw; +} __packed; + struct audio_buffer { dma_addr_t phys; uint32_t used; @@ -408,6 +469,111 @@ static struct audio_client *q6asm_get_audio_client(struct q6asm *a, return NULL; } +static int32_t q6asm_callback(struct apr_device *adev, + struct apr_client_data *data, int session_id) +{ + struct audio_client *ac;// = (struct audio_client *)priv; + uint32_t token; + uint32_t *payload; + uint32_t wakeup_flag = 1; + uint32_t client_event = 0; + struct q6asm *q6asm = dev_get_drvdata(&adev->dev); + + if (data == NULL) + return -EINVAL; + + ac = q6asm_get_audio_client(q6asm, session_id); + if (!q6asm_is_valid_audio_client(ac)) + return -EINVAL; + + payload = data->payload; + + if (data->opcode == APR_BASIC_RSP_RESULT) { + token = data->token; + switch (payload[0]) { + case ASM_SESSION_CMD_PAUSE: + client_event = ASM_CLIENT_EVENT_CMD_PAUSE_DONE; + break; + case ASM_SESSION_CMD_SUSPEND: + client_event = ASM_CLIENT_EVENT_CMD_SUSPEND_DONE; + break; + case ASM_DATA_CMD_EOS: + client_event = ASM_CLIENT_EVENT_CMD_EOS_DONE; + break; + break; + case ASM_STREAM_CMD_FLUSH: + client_event = ASM_CLIENT_EVENT_CMD_FLUSH_DONE; + break; + case ASM_SESSION_CMD_RUN_V2: + client_event = ASM_CLIENT_EVENT_CMD_RUN_DONE; + break; + + case ASM_STREAM_CMD_FLUSH_READBUFS: + if (token != ac->session) { + dev_err(ac->dev, "session invalid\n"); + return -EINVAL; + } + case ASM_STREAM_CMD_CLOSE: + client_event = ASM_CLIENT_EVENT_CMD_CLOSE_DONE; + break; + case ASM_STREAM_CMD_OPEN_WRITE_V3: + case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2: + if (payload[1] != 0) { + dev_err(ac->dev, + "cmd = 0x%x returned error = 0x%x\n", + payload[0], payload[1]); + if (wakeup_flag) { + ac->cmd_state = payload[1]; + wake_up(&ac->cmd_wait); + } + return 0; + } + break; + default: + dev_err(ac->dev, "command[0x%x] not expecting rsp\n", + payload[0]); + break; + } + + if (ac->cmd_state && wakeup_flag) { + ac->cmd_state = 0; + wake_up(&ac->cmd_wait); + } + if (ac->cb) + ac->cb(client_event, data->token, + data->payload, ac->priv); + + return 0; + } + + switch (data->opcode) { + case ASM_DATA_EVENT_WRITE_DONE_V2:{ + struct audio_port_data *port = + &ac->port[SNDRV_PCM_STREAM_PLAYBACK]; + + client_event = ASM_CLIENT_EVENT_DATA_WRITE_DONE; + + if (ac->io_mode & SYNC_IO_MODE) { + dma_addr_t phys = port->buf[data->token].phys; + + if (lower_32_bits(phys) != payload[0] || + upper_32_bits(phys) != payload[1]) { + dev_err(ac->dev, "Expected addr %pa\n", + &port->buf[data->token].phys); + return -EINVAL; + } + token = data->token; + port->buf[token].used = 1; + } + break; + } + } + if (ac->cb) + ac->cb(client_event, data->token, data->payload, ac->priv); + + return 0; +} + static int q6asm_srvc_callback(struct apr_device *adev, struct apr_client_data *data) { struct q6asm *a, *q6asm = dev_get_drvdata(&adev->dev); @@ -415,12 +581,16 @@ static int q6asm_srvc_callback(struct apr_device *adev, struct apr_client_data * struct audio_port_data *port; uint32_t dir = 0; uint32_t sid = 0; + int dest_port; uint32_t *payload; if (!data) { dev_err(&adev->dev, "%s: Invalid CB\n", __func__); return 0; } + dest_port = (data->dest_port >> 8) & 0xFF; + if (dest_port) + return q6asm_callback(adev, data, dest_port); payload = data->payload; sid = (data->token >> 8) & 0x0F; @@ -540,6 +710,364 @@ struct audio_client *q6asm_audio_client_alloc(struct device *dev, } EXPORT_SYMBOL_GPL(q6asm_audio_client_alloc); +static int __q6asm_open_write(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, uint32_t stream_id, + bool is_gapless_mode) +{ + struct asm_stream_cmd_open_write_v3 open; + int rc; + + q6asm_add_hdr(ac, &open.hdr, sizeof(open), true, stream_id); + ac->cmd_state = -1; + + open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V3; + open.mode_flags = 0x00; + open.mode_flags |= ASM_LEGACY_STREAM_SESSION; + if (is_gapless_mode) + open.mode_flags |= 1 << ASM_SHIFT_GAPLESS_MODE_FLAG; + + /* source endpoint : matrix */ + open.sink_endpointype = ASM_END_POINT_DEVICE_MATRIX; + open.bits_per_sample = bits_per_sample; + open.postprocopo_id = DEFAULT_POPP_TOPOLOGY; + + switch (format) { + case FORMAT_LINEAR_PCM: + open.dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2; + break; + default: + dev_err(ac->dev, "Invalid format 0x%x\n", format); + return -EINVAL; + } + rc = apr_send_pkt(ac->adev, (uint32_t *) &open); + if (rc < 0) + return rc; + + rc = wait_event_timeout(ac->cmd_wait, (ac->cmd_state >= 0), 5 * HZ); + if (!rc) { + dev_err(ac->dev, "timeout on open write\n"); + return -ETIMEDOUT; + } + + if (ac->cmd_state > 0) + return adsp_err_get_lnx_err_code(ac->cmd_state); + + ac->io_mode |= TUN_WRITE_IO_MODE; + + return 0; +} + +/** + * q6asm_open_write() - Open audio client for writing + * + * @ac: audio client pointer + * @format: audio sample format + * @bits_per_sample: bits per sample + * + * Return: Will be an negative value on error or zero on success + */ +int q6asm_open_write(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample) +{ + return __q6asm_open_write(ac, format, bits_per_sample, + ac->stream_id, false); +} +EXPORT_SYMBOL_GPL(q6asm_open_write); + +static int __q6asm_run(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts, bool wait) +{ + struct asm_session_cmd_run_v2 run; + int rc; + + q6asm_add_hdr(ac, &run.hdr, sizeof(run), true, ac->stream_id); + ac->cmd_state = -1; + + run.hdr.opcode = ASM_SESSION_CMD_RUN_V2; + run.flags = flags; + run.time_lsw = lsw_ts; + run.time_msw = msw_ts; + + rc = apr_send_pkt(ac->adev, (uint32_t *) &run); + if (rc < 0) + return rc; + + if (wait) { + rc = wait_event_timeout(ac->cmd_wait, (ac->cmd_state >= 0), + 5 * HZ); + if (!rc) { + dev_err(ac->dev, "timeout on run cmd\n"); + return -ETIMEDOUT; + } + if (ac->cmd_state > 0) + return adsp_err_get_lnx_err_code(ac->cmd_state); + } + + return 0; +} + +/** + * q6asm_run() - start the audio client + * + * @ac: audio client pointer + * @flags: flags associated with write + * @msw_ts: timestamp msw + * @lsw_ts: timestamp lsw + * + * Return: Will be an negative value on error or zero on success + */ +int q6asm_run(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts) +{ + return __q6asm_run(ac, flags, msw_ts, lsw_ts, true); +} +EXPORT_SYMBOL_GPL(q6asm_run); + +/** + * q6asm_run_nowait() - start the audio client withou blocking + * + * @ac: audio client pointer + * @flags: flags associated with write + * @msw_ts: timestamp msw + * @lsw_ts: timestamp lsw + * + * Return: Will be an negative value on error or zero on success + */ +int q6asm_run_nowait(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts) +{ + return __q6asm_run(ac, flags, msw_ts, lsw_ts, false); +} +EXPORT_SYMBOL_GPL(q6asm_run_nowait); + +/** + * q6asm_media_format_block_multi_ch_pcm() - setup pcm configuration + * + * @ac: audio client pointer + * @rate: audio sample rate + * @channels: number of audio channels. + * @use_default_chmap: flag to use default ch map. + * @channel_map: channel map pointer + * @bits_per_sample: bits per sample + * + * Return: Will be an negative value on error or zero on success + */ +int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample) +{ + struct asm_multi_channel_pcm_fmt_blk_v2 fmt; + u8 *channel_mapping; + int rc = 0; + + q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), true, ac->stream_id); + ac->cmd_state = -1; + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.num_channels = channels; + fmt.bits_per_sample = bits_per_sample; + fmt.sample_rate = rate; + fmt.is_signed = 1; + + channel_mapping = fmt.channel_mapping; + + if (use_default_chmap) { + if (q6dsp_map_channels(channel_mapping, channels)) { + dev_err(ac->dev, " map channels failed %d\n", channels); + return -EINVAL; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->adev, (uint32_t *) &fmt); + if (rc < 0) + goto fail_cmd; + + rc = wait_event_timeout(ac->cmd_wait, (ac->cmd_state >= 0), 5 * HZ); + if (!rc) { + dev_err(ac->dev, "timeout on format update\n"); + return -ETIMEDOUT; + } + if (ac->cmd_state > 0) + return adsp_err_get_lnx_err_code(ac->cmd_state); + + return 0; +fail_cmd: + return rc; +} +EXPORT_SYMBOL_GPL(q6asm_media_format_block_multi_ch_pcm); + +/** + * q6asm_write_nolock() - non blocking write + * + * @ac: audio client pointer + * @len: lenght in bytes + * @msw_ts: timestamp msw + * @lsw_ts: timestamp lsw + * @flags: flags associated with write + * + * Return: Will be an negative value on error or zero on success + */ +int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, + uint32_t lsw_ts, uint32_t flags) +{ + struct asm_data_cmd_write_v2 write; + struct audio_port_data *port; + struct audio_buffer *ab; + int dsp_buf = 0; + int rc = 0; + + if (ac->io_mode & SYNC_IO_MODE) { + port = &ac->port[SNDRV_PCM_STREAM_PLAYBACK]; + q6asm_add_hdr(ac, &write.hdr, sizeof(write), false, + ac->stream_id); + + dsp_buf = port->dsp_buf; + ab = &port->buf[dsp_buf]; + + write.hdr.token = port->dsp_buf; + write.hdr.opcode = ASM_DATA_CMD_WRITE_V2; + write.buf_addr_lsw = lower_32_bits(ab->phys); + write.buf_addr_msw = upper_32_bits(ab->phys); + write.buf_size = len; + write.seq_id = port->dsp_buf; + write.timestamp_lsw = lsw_ts; + write.timestamp_msw = msw_ts; + write.mem_map_handle = + ac->port[SNDRV_PCM_STREAM_PLAYBACK].mem_map_handle; + + if (flags == NO_TIMESTAMP) + write.flags = (flags & 0x800000FF); + else + write.flags = (0x80000000 | flags); + + port->dsp_buf++; + + if (port->dsp_buf >= port->max_buf_cnt) + port->dsp_buf = 0; + + rc = apr_send_pkt(ac->adev, (uint32_t *) &write); + if (rc < 0) + return rc; + } + + return 0; +} +EXPORT_SYMBOL_GPL(q6asm_write_nolock); + +static void q6asm_reset_buf_state(struct audio_client *ac) +{ + int cnt = 0; + int loopcnt = 0; + int used; + struct audio_port_data *port = NULL; + + if (ac->io_mode & SYNC_IO_MODE) { + used = (ac->io_mode & TUN_WRITE_IO_MODE ? 1 : 0); + mutex_lock(&ac->cmd_lock); + for (loopcnt = 0; loopcnt <= SNDRV_PCM_STREAM_CAPTURE; + loopcnt++) { + port = &ac->port[loopcnt]; + cnt = port->max_buf_cnt - 1; + port->dsp_buf = 0; + while (cnt >= 0) { + if (!port->buf) + continue; + port->buf[cnt].used = used; + cnt--; + } + } + mutex_unlock(&ac->cmd_lock); + } +} + +static int __q6asm_cmd(struct audio_client *ac, int cmd, bool wait) +{ + int stream_id = ac->stream_id; + struct apr_hdr hdr; + int rc; + + q6asm_add_hdr(ac, &hdr, sizeof(hdr), true, stream_id); + ac->cmd_state = -1; + switch (cmd) { + case CMD_PAUSE: + hdr.opcode = ASM_SESSION_CMD_PAUSE; + break; + case CMD_SUSPEND: + hdr.opcode = ASM_SESSION_CMD_SUSPEND; + break; + case CMD_FLUSH: + hdr.opcode = ASM_STREAM_CMD_FLUSH; + break; + case CMD_OUT_FLUSH: + hdr.opcode = ASM_STREAM_CMD_FLUSH_READBUFS; + break; + case CMD_EOS: + hdr.opcode = ASM_DATA_CMD_EOS; + ac->cmd_state = 0; + break; + case CMD_CLOSE: + hdr.opcode = ASM_STREAM_CMD_CLOSE; + break; + default: + return -EINVAL; + } + + rc = apr_send_pkt(ac->adev, (uint32_t *) &hdr); + if (rc < 0) + return rc; + + if (!wait) + return 0; + + rc = wait_event_timeout(ac->cmd_wait, (ac->cmd_state >= 0), 5 * HZ); + if (!rc) { + dev_err(ac->dev, "timeout response for opcode[0x%x]\n", + hdr.opcode); + return -ETIMEDOUT; + } + if (ac->cmd_state > 0) + return adsp_err_get_lnx_err_code(ac->cmd_state); + + if (cmd == CMD_FLUSH) + q6asm_reset_buf_state(ac); + + return 0; +} + +/** + * q6asm_cmd() - run cmd on audio client + * + * @ac: audio client pointer + * @cmd: command to run on audio client. + * + * Return: Will be an negative value on error or zero on success + */ +int q6asm_cmd(struct audio_client *ac, int cmd) +{ + return __q6asm_cmd(ac, cmd, true); +} +EXPORT_SYMBOL_GPL(q6asm_cmd); + +/** + * q6asm_cmd_nowait() - non blocking, run cmd on audio client + * + * @ac: audio client pointer + * @cmd: command to run on audio client. + * + * Return: Will be an negative value on error or zero on success + */ +int q6asm_cmd_nowait(struct audio_client *ac, int cmd) +{ + return __q6asm_cmd(ac, cmd, false); +} +EXPORT_SYMBOL_GPL(q6asm_cmd_nowait); static int q6asm_probe(struct apr_device *adev) { diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h index e1409c368600..b4896059da79 100644 --- a/sound/soc/qcom/qdsp6/q6asm.h +++ b/sound/soc/qcom/qdsp6/q6asm.h @@ -2,7 +2,34 @@ #ifndef __Q6_ASM_H__ #define __Q6_ASM_H__ +/* ASM client callback events */ +#define CMD_PAUSE 0x0001 +#define ASM_CLIENT_EVENT_CMD_PAUSE_DONE 0x1001 +#define CMD_FLUSH 0x0002 +#define ASM_CLIENT_EVENT_CMD_FLUSH_DONE 0x1002 +#define CMD_EOS 0x0003 +#define ASM_CLIENT_EVENT_CMD_EOS_DONE 0x1003 +#define CMD_CLOSE 0x0004 +#define ASM_CLIENT_EVENT_CMD_CLOSE_DONE 0x1004 +#define CMD_OUT_FLUSH 0x0005 +#define ASM_CLIENT_EVENT_CMD_OUT_FLUSH_DONE 0x1005 +#define CMD_SUSPEND 0x0006 +#define ASM_CLIENT_EVENT_CMD_SUSPEND_DONE 0x1006 +#define ASM_CLIENT_EVENT_CMD_RUN_DONE 0x1008 +#define ASM_CLIENT_EVENT_DATA_WRITE_DONE 0x1009 + +#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 MAX_SESSIONS 16 +#define NO_TIMESTAMP 0xFF00 +#define FORMAT_LINEAR_PCM 0x0000 typedef void (*app_cb) (uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); @@ -10,6 +37,21 @@ struct audio_client; struct audio_client *q6asm_audio_client_alloc(struct device *dev, app_cb cb, void *priv); void q6asm_audio_client_free(struct audio_client *ac); +int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, + uint32_t lsw_ts, uint32_t flags); +int q6asm_open_write(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample); +int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample); +int q6asm_run(struct audio_client *ac, uint32_t flags, uint32_t msw_ts, + uint32_t lsw_ts); +int q6asm_run_nowait(struct audio_client *ac, uint32_t flags, uint32_t msw_ts, + uint32_t lsw_ts); +int q6asm_cmd(struct audio_client *ac, int cmd); +int q6asm_cmd_nowait(struct audio_client *ac, int cmd); int q6asm_get_session_id(struct audio_client *ac); int q6asm_map_memory_regions(unsigned int dir, struct audio_client *ac, From patchwork Tue Dec 5 22:18:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 120761 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6311522qgn; Tue, 5 Dec 2017 14:20:43 -0800 (PST) X-Google-Smtp-Source: AGs4zMawRSXMrzWzX+dlWXuzAplWTMHymJEtQzBVacVF3vJzPjd50k8w1fytQzDZV91ey9hoTcDX X-Received: by 10.84.129.47 with SMTP id 44mr19735195plb.442.1512512443602; Tue, 05 Dec 2017 14:20:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512512443; cv=none; d=google.com; s=arc-20160816; b=VMfGADlvFblg1x0+61ifSENjdAhH0N/GsIE/bBsnMwlx+7N9FvYpEyjr9UUsTV4mab O3/Vpo3+ft+aUPnvzXzsNBo1z3EF5jVw7IlF1W+otLmZ4zo/j4YXEpPjNb+bWOu8t1HG bk7Os3b3m3BQQSl7DH69BahqoOi6+crv3eOBh6IKdxEkUQNUKhLg5TyelH3xtOjtk3pb Cjq07/gwBbx+3Os1rcyTWt74qblgAvl2UWYp1e3gLZmglSoTpP83vrQok1k5stTQ2a71 Y2QE1naZQHCf8TVMR0kLXwBmBVcyhDlxpuctC9ooFn9Mo4PdU4/s4Q4G6CtAs84eaTqj bdoA== 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=cPZtQqR0yiseM2a32yfW3rRraXfHOAS2FUKLHWw3kvY=; b=l4WZaCcTtw7h4ajvKdWgjfbRquScAWu9AYpQgn2wTsHup82ZyuTirbarbKbzxotkNS 2SADXI6FpTobWN2Qi35QzLAnyl+Dzl7qqZvPGK3L97TV9aiJpjb0AZVo1KL6QvtJKeId Xl/09n3nAkmg1rwS68VF/FPJXzxpV+RtlJhbsGVdkdA/S2f9GGaGzYChOYc3fPBEgPmN gQ5DLP5ONU5W3DtdA0c8ZHjzMqVQOJ6Q7xjILiVyQKji57ZXHqXw+G9RMMcusNFY9Cos Yj8AFfpK4mQY+OEKjC9o3E7MvMFwQ6MQEH8utGgZzi/y+X05JEftHVU1iAByy9P4QMPu MxeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=clC+q61G; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a90si754625plc.137.2017.12.05.14.20.43; Tue, 05 Dec 2017 14:20:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=clC+q61G; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752638AbdLEWUl (ORCPT + 28 others); Tue, 5 Dec 2017 17:20:41 -0500 Received: from mail-wr0-f193.google.com ([209.85.128.193]:32849 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752540AbdLEWUb (ORCPT ); Tue, 5 Dec 2017 17:20:31 -0500 Received: by mail-wr0-f193.google.com with SMTP id v22so1935010wrb.0 for ; Tue, 05 Dec 2017 14:20:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cPZtQqR0yiseM2a32yfW3rRraXfHOAS2FUKLHWw3kvY=; b=clC+q61GGMkwCMxwt8zxbBU1IMmHB677xAIcth7G9N1cKBvT5H6ADQ97lDRcLSlB7C P/HPSrqHv0ygyOUJeL1IIfAvlGqraxRYeeFQeBk6oHkzZxucoT50PtZsgePo8Smv9fm6 pJ1iDdEXW7t9sSKeCdNzvvyz5CZ1ypXKH0zNA= 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=cPZtQqR0yiseM2a32yfW3rRraXfHOAS2FUKLHWw3kvY=; b=hAlr0nI/Tt0inbwgP/fVkAoYt6djUhIc3DDIusNll+MGY8CmfxEpjt43g6QzN+y0N/ cqlGrGv5/akdteGYJxCNyESoaIETLZewz2XebTQhsu1jPO0M6Vkl/5xAaIpwMTj7WqV6 panCbY43ZcPdtZbHA96wjWV7Mo7sqB7qKSOfdKzIoVHCxR/I4eoxvK7B/EfY3nlqtCUX Rm3vj/81Psvo8Wa0dHKTp2Fwl8auFB9zeuXdLVMYA1XzhH6pkpFYsqcR/5oF93rJ2IU6 ggBvCj8qE9CKsYQoNSI8SEtjGeys6vEwuEll3qF3khn1Sj946L/j/Ac1pAzqXPe42ys4 FthA== X-Gm-Message-State: AJaThX4w4DA7Ui0yL3KY8hqufh2gtEWPnz7HWyvtWMGnHEJThcJSnVdp DE3+RWIMA0shaDHsAKV4EqjYyQ== X-Received: by 10.223.136.164 with SMTP id f33mr17181240wrf.162.1512512429126; Tue, 05 Dec 2017 14:20:29 -0800 (PST) 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 t138sm1633154wme.16.2017.12.05.14.20.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Dec 2017 14:20:28 -0800 (PST) From: srinivas.kandagatla@linaro.org To: broonie@kernel.org, bgoswami@codeaurora.org Cc: alsa-devel@alsa-project.org, tiwai@suse.com, plai@codeaurora.org, kwestfie@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, lkasam@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v2 09/15] ASoC: qcom: qdsp6: Add support to Q6CORE Date: Tue, 5 Dec 2017 22:18:06 +0000 Message-Id: <20171205221812.25641-10-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> References: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla This patch adds support to core apr service, which is used to query status of other static and dynamic services on the dsp. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/Kconfig | 5 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6core.c | 227 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6core.c -- 2.15.0 diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 7ebdb879a8a3..121b9c957024 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -56,11 +56,16 @@ config SND_SOC_QDSP6_ASM tristate default n +config SND_SOC_QDSP6_CORE + tristate + default n + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" select SND_SOC_QDSP6_AFE select SND_SOC_QDSP6_ADM select SND_SOC_QDSP6_ASM + select SND_SOC_QDSP6_CORE 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 49dd3ccab27b..ad7f10691e54 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o +obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o diff --git a/sound/soc/qcom/qdsp6/q6core.c b/sound/soc/qcom/qdsp6/q6core.c new file mode 100644 index 000000000000..d4e2dbc62489 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6core.c @@ -0,0 +1,227 @@ +/* SPDX-License-Identifier: GPL-2.0 +* Copyright (c) 2017, Linaro Limited +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define Q6_READY_TIMEOUT_MS 100 +#define AVCS_CMD_ADSP_EVENT_GET_STATE 0x0001290C +#define AVCS_CMDRSP_ADSP_EVENT_GET_STATE 0x0001290D +#define AVCS_GET_VERSIONS 0x00012905 +#define AVCS_GET_VERSIONS_RSP 0x00012906 + +struct avcs_svc_info { + uint32_t service_id; + uint32_t version; +} __packed; + +struct q6core { + struct apr_device *adev; + wait_queue_head_t wait; + uint32_t avcs_state; + int resp_received; + uint32_t num_services; + struct avcs_svc_info *svcs_info; +}; + +static struct apr_device_id static_services[] = { + ADSP_AUDIO_APR_DEV("AFE", APR_SVC_AFE), + ADSP_AUDIO_APR_DEV("ASM", APR_SVC_ASM), + ADSP_AUDIO_APR_DEV("ADM", APR_SVC_ADM), + ADSP_AUDIO_APR_DEV("TEST", APR_SVC_TEST_CLIENT), + ADSP_AUDIO_APR_DEV("MVM", APR_SVC_ADSP_MVM), + ADSP_AUDIO_APR_DEV("CVS", APR_SVC_ADSP_CVS), + ADSP_AUDIO_APR_DEV("CVP", APR_SVC_ADSP_CVP), + ADSP_AUDIO_APR_DEV("USM", APR_SVC_USM), + ADSP_AUDIO_APR_DEV("VIDC", APR_SVC_VIDC), + ADSP_AUDIO_APR_DEV("LSM", APR_SVC_LSM), +}; + +static int core_callback(struct apr_device *adev, struct apr_client_data *data) +{ + struct q6core *core = dev_get_drvdata(&adev->dev); + uint32_t *payload; + + switch (data->opcode) { + case AVCS_GET_VERSIONS_RSP: + payload = data->payload; + core->num_services = payload[1]; + + if (!core->svcs_info) + core->svcs_info = kcalloc(core->num_services, + sizeof(*core->svcs_info), + GFP_ATOMIC); + if (!core->svcs_info) + return -ENOMEM; + + /* svc info is after 8 bytes */ + memcpy(core->svcs_info, payload + 2, + core->num_services * sizeof(*core->svcs_info)); + + core->resp_received = 1; + wake_up(&core->wait); + + break; + case AVCS_CMDRSP_ADSP_EVENT_GET_STATE: + payload = data->payload; + core->avcs_state = payload[0]; + + core->resp_received = 1; + wake_up(&core->wait); + break; + default: + dev_err(&adev->dev, "Message id from adsp core svc: 0x%x\n", + data->opcode); + break; + } + + return 0; +} + +void q6core_add_service(struct device *dev, uint32_t svc_id, uint32_t version) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(static_services); i++) { + if (static_services[i].svc_id == svc_id) { + static_services[i].svc_version = version; + apr_add_device(dev->parent, &static_services[i]); + dev_info(dev, + "Adding SVC: %s: id 0x%x API Ver 0x%x:0x%x\n", + static_services[i].name, svc_id, + APR_SVC_MAJOR_VERSION(version), + APR_SVC_MINOR_VERSION(version)); + } + } +} + +static void q6core_add_static_services(struct q6core *core) +{ + int i; + struct apr_device *adev = core->adev; + struct avcs_svc_info *svcs_info = core->svcs_info; + + for (i = 0; i < core->num_services; i++) + q6core_add_service(&adev->dev, svcs_info[i].service_id, + svcs_info[i].version); +} + +static int q6core_get_svc_versions(struct q6core *core) +{ + struct apr_device *adev = core->adev; + struct apr_hdr hdr = {0}; + int rc; + + hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, 0); + hdr.opcode = AVCS_GET_VERSIONS; + + rc = apr_send_pkt(adev, (uint32_t *)&hdr); + if (rc < 0) + return rc; + + rc = wait_event_timeout(core->wait, (core->resp_received == 1), + msecs_to_jiffies(Q6_READY_TIMEOUT_MS)); + if (rc > 0 && core->resp_received) { + core->resp_received = 0; + return 0; + } + + return rc; +} + +static bool q6core_is_adsp_ready(struct q6core *core) +{ + struct apr_device *adev = core->adev; + struct apr_hdr hdr = {0}; + int rc; + + hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, 0); + hdr.opcode = AVCS_CMD_ADSP_EVENT_GET_STATE; + + rc = apr_send_pkt(adev, (uint32_t *)&hdr); + if (rc < 0) + return false; + + rc = wait_event_timeout(core->wait, (core->resp_received == 1), + msecs_to_jiffies(Q6_READY_TIMEOUT_MS)); + if (rc > 0 && core->resp_received) { + core->resp_received = 0; + if (core->avcs_state == 0x1) + return true; + } + + return false; +} + +static int q6core_probe(struct apr_device *adev) +{ + struct q6core *core; + unsigned long timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + int ret = 0; + + core = devm_kzalloc(&adev->dev, sizeof(*core), GFP_KERNEL); + if (!core) + return -ENOMEM; + + dev_set_drvdata(&adev->dev, core); + + core->adev = adev; + init_waitqueue_head(&core->wait); + + do { + if (!q6core_is_adsp_ready(core)) { + dev_info(&adev->dev, "ADSP Audio isn't ready\n"); + } else { + dev_info(&adev->dev, "ADSP Audio is ready\n"); + + ret = q6core_get_svc_versions(core); + if (!ret) + q6core_add_static_services(core); + + break; + } + } while (time_after(timeout, jiffies)); + + return ret; +} + +static int q6core_exit(struct apr_device *adev) +{ + return 0; +} + +static const struct apr_device_id core_id[] = { + {"Q6CORE", APR_DOMAIN_ADSP, APR_SVC_ADSP_CORE, APR_CLIENT_AUDIO}, + { }, +}; + +static struct apr_driver qcom_q6core_driver = { + .probe = q6core_probe, + .remove = q6core_exit, + .callback = core_callback, + .id_table = core_id, + .driver = { + .name = "qcom-q6core", + }, +}; + +module_apr_driver(qcom_q6core_driver); + +MODULE_AUTHOR("Srinivas Kandagatla X-Patchwork-Id: 120768 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6313473qgn; Tue, 5 Dec 2017 14:23:07 -0800 (PST) X-Google-Smtp-Source: AGs4zMaaGICZip73NbiWWEI/4LmQvnNIvch/96nrE2un5vQxX3BrFpxsuxlhna6ks3n2Ok61jhTn X-Received: by 10.99.5.200 with SMTP id 191mr19285973pgf.450.1512512587712; Tue, 05 Dec 2017 14:23:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512512587; cv=none; d=google.com; s=arc-20160816; b=LBjc4vAxSyCHvx+dXyEYk7S6grKxc/t9S2i+WvpBRLoob/CTdRiurqXHk7bkHs9Q2m QGlla3AlfQmxb/L9zd+AGsU9FCLdhEw6c188LWgg9OHFQzN3tnMMRhQRfqw08JiLN3zM 1/OSvve6rNiimPoZEGgs3KI7DIM908jpK+20j5311XK8WCiDOr9Rs+20rsQH/bLGeNVL h4zP4MGRcm3zNdWAcab08jDb38/HEJH/azCBn1lX5DBe6WUymo1OzGeJJzIq61QRAThI Vwf32INEeV4BY7oM4rX2aQRMGRYWCpxkVCKhxhz8235w9tq6fazyV/05rBmQRPSSmCb3 u/TQ== 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=YF29kSvkkTFI/EITT+oLSPbAKuiEdfsC9uRjYX9htTI=; b=jfEhiWpjceOkQkkv+8BlUloKoMmxAEjc2VzFVIJhZ5DfuvoRViM6/zZoM42RiJAkLw M/j2oZ7FYcpBd7etlBgTj8VraREIkzUzQvXFoeAfHVnBuAATDkiymzpXZd8RYaCGDONu DFvJ/B15jrgBELs92cbWdfL7zRzy10s8cSGv8zKKn80337aoqu+GzEhsG24ePiUYZ6Ha YRaG4EfrvZ88Yl9uU8W5xxntpHV7CxWiKAJpStA+82kI/NEfQHNjfv6G0e2T3IwK6w9D Gws3B1MoYQmouEsF+a2mLHb/DiH44edeA2Ny4uqLN6MP5ywpf3hQHO803QIQQUak42P2 asaQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WuzAUEsE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u13si723136pgc.615.2017.12.05.14.23.07; Tue, 05 Dec 2017 14:23:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WuzAUEsE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752882AbdLEWXG (ORCPT + 28 others); Tue, 5 Dec 2017 17:23:06 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:45658 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752550AbdLEWUb (ORCPT ); Tue, 5 Dec 2017 17:20:31 -0500 Received: by mail-wm0-f65.google.com with SMTP id 9so4030977wme.4 for ; Tue, 05 Dec 2017 14:20:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YF29kSvkkTFI/EITT+oLSPbAKuiEdfsC9uRjYX9htTI=; b=WuzAUEsEF9WtYIfRqvj6PJAjYCOwmc/JN7TtGSRoFVZI0vbErx7QmsVrUXfFlfz0p3 zDeKlRTAcuOAkuX6B7mizPfHD9gSjmS4GEC55cF2WOtO0kjujSmq+/uND7Th/tgVyYkD 1b4xIRLsQSsF1osTAUV8zynTaUieI4tVcjZtg= 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=YF29kSvkkTFI/EITT+oLSPbAKuiEdfsC9uRjYX9htTI=; b=hFDPgB/RnLIEi9EFWLQwOPKuzTT3XVe72A1YgtKdiCdBClfheEcpVM0qZ2bDvn/bR4 JlyXHJWKvfxCw3LznhI4K37W8a1hEfzQwcCoF29ZnqSKPULitmscetb9LdEUPfHAmBDw gTXr9WcBT+f2X2nDtfwW0UiTsio/OuQTTKwIuWoGGf2g0c/hFqGFas/Ee8mmG1N3ENYy ocbpHe6n6upNIsxRbaMSXY0DyZgiZCt09Eu+F2YmzNd7ny2Xtzhi9f4AbJmj7ePyySz8 5jiG/wPCzQRrR2HR6X7tVCBWMgnZbwdR0EOL/NJCmDIzBuR1MRAPVDfrdcnN9OPPNtLt EW/w== X-Gm-Message-State: AKGB3mKBx7GKsFPgCMEDPPsZB61imfg64X0IvKI7yStSQZRqq9qapMxq oVSFKTplVS73CenvzyuzsI8beg== X-Received: by 10.28.65.136 with SMTP id o130mr1246416wma.33.1512512430276; Tue, 05 Dec 2017 14:20:30 -0800 (PST) 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 t138sm1633154wme.16.2017.12.05.14.20.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Dec 2017 14:20:29 -0800 (PST) From: srinivas.kandagatla@linaro.org To: broonie@kernel.org, bgoswami@codeaurora.org Cc: alsa-devel@alsa-project.org, tiwai@suse.com, plai@codeaurora.org, kwestfie@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, lkasam@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v2 10/15] ASoC: qcom: qdsp6: Add support to q6routing driver Date: Tue, 5 Dec 2017 22:18:07 +0000 Message-Id: <20171205221812.25641-11-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> References: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla This patch adds support to q6 routing driver which configures route between ASM and AFE module using ADM apis. This driver uses dapm widgets to setup the matrix between AFE ports and ASM streams. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/Kconfig | 5 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6routing.c | 386 +++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6routing.h | 9 + 4 files changed, 401 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6routing.c create mode 100644 sound/soc/qcom/qdsp6/q6routing.h -- 2.15.0 diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 121b9c957024..dd8fb0cde614 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -60,12 +60,17 @@ config SND_SOC_QDSP6_CORE tristate default n +config SND_SOC_QDSP6_ROUTING + tristate + default n + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" select SND_SOC_QDSP6_AFE select SND_SOC_QDSP6_ADM select SND_SOC_QDSP6_ASM select SND_SOC_QDSP6_CORE + select SND_SOC_QDSP6_ROUTING 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 ad7f10691e54..c1ad060a2341 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o +obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c new file mode 100644 index 000000000000..f5f12d61a1ee --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6routing.c @@ -0,0 +1,386 @@ +/* SPDX-License-Identifier: GPL-2.0 +* Copyright (c) 2011-2016, The Linux Foundation +* Copyright (c) 2017, Linaro Limited +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6afe.h" +#include "q6asm.h" +#include "q6adm.h" +#include "q6routing.h" + +struct session_data { + int state; + int port_id; + int path_type; + int app_type; + int acdb_id; + int sample_rate; + int bits_per_sample; + int channels; + int format; + int perf_mode; + int numcopps; + int fedai_id; + unsigned long copp_map; +}; + +struct msm_routing_data { + struct session_data sessions[MAX_SESSIONS]; + struct device *dev; + struct mutex lock; +}; + +static struct msm_routing_data *routing_data; + +/** + * q6routing_reg_phy_stream() - Register a new stream for route setup + * + * @fedai_id: Frontend dai id. + * @perf_mode: Performace mode. + * @stream_id: ASM stream id to map. + * @stream_type: Direction of stream + * + * Return: Will be an negative on error or a zero on success. + */ +int q6routing_reg_phy_stream(int fedai_id, int perf_mode, + int stream_id, int stream_type) +{ + int j, topology, num_copps = 0; + struct route_payload payload; + int copp_idx; + struct session_data *session; + + if (!routing_data) { + pr_err("Routing driver not yet ready\n"); + return -EINVAL; + } + + session = &routing_data->sessions[stream_id - 1]; + mutex_lock(&routing_data->lock); + session->fedai_id = fedai_id; + payload.num_copps = 0; /* only RX needs to use payload */ + topology = NULL_COPP_TOPOLOGY; + copp_idx = q6adm_open(routing_data->dev, session->port_id, + session->path_type, session->sample_rate, + session->channels, topology, perf_mode, + session->bits_per_sample, 0, 0); + if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { + mutex_unlock(&routing_data->lock); + return -EINVAL; + } + + set_bit(copp_idx, &session->copp_map); + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + unsigned long copp = session->copp_map; + + if (test_bit(j, &copp)) { + payload.port_id[num_copps] = session->port_id; + payload.copp_idx[num_copps] = j; + num_copps++; + } + } + + if (num_copps) { + payload.num_copps = num_copps; + payload.session_id = stream_id; + q6adm_matrix_map(routing_data->dev, session->path_type, + payload, perf_mode); + } + mutex_unlock(&routing_data->lock); + + return 0; +} +EXPORT_SYMBOL_GPL(q6routing_reg_phy_stream); + +static struct session_data *routing_get_session(struct msm_routing_data *data, + int port_id, int port_type) +{ + int i; + + for (i = 0; i < MAX_SESSIONS; i++) + if (port_id == data->sessions[i].port_id) + return &data->sessions[i]; + + return NULL; +} + +static struct session_data *get_session_from_id(struct msm_routing_data *data, + int fedai_id) +{ + int i; + + for (i = 0; i < MAX_SESSIONS; i++) { + if (fedai_id == data->sessions[i].fedai_id) + return &data->sessions[i]; + } + + return NULL; +} +/** + * q6routing_dereg_phy_stream() - Deregister a stream + * + * @fedai_id: Frontend dai id. + * @stream_type: Direction of stream + * + * Return: Will be an negative on error or a zero on success. + */ +void q6routing_dereg_phy_stream(int fedai_id, int stream_type) +{ + struct session_data *session; + int idx; + + session = get_session_from_id(routing_data, fedai_id); + if (!session) + return; + + for_each_set_bit(idx, &session->copp_map, MAX_COPPS_PER_PORT) + q6adm_close(routing_data->dev, session->port_id, + session->perf_mode, idx); + + session->fedai_id = -1; + session->copp_map = 0; +} +EXPORT_SYMBOL_GPL(q6routing_dereg_phy_stream); + +static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_context *dapm = + snd_soc_dapm_kcontrol_dapm(kcontrol); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int session_id = mc->shift; + struct snd_soc_platform *platform = snd_soc_dapm_to_platform(dapm); + struct msm_routing_data *priv = snd_soc_platform_get_drvdata(platform); + struct session_data *session = &priv->sessions[session_id]; + + if (session->port_id != -1) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + return 0; +} + +static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_context *dapm = + snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_platform *platform = snd_soc_dapm_to_platform(dapm); + struct msm_routing_data *data = snd_soc_platform_get_drvdata(platform); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + int be_id = mc->reg; + int session_id = mc->shift; + struct session_data *session = &data->sessions[session_id]; + + if (ucontrol->value.integer.value[0]) { + session->port_id = be_id; + snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, update); + } else { + session->port_id = -1; + snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, update); + } + + return 1; +} + +static const struct snd_kcontrol_new hdmi_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", AFE_PORT_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", AFE_PORT_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", AFE_PORT_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", AFE_PORT_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", AFE_PORT_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", AFE_PORT_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", AFE_PORT_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", AFE_PORT_HDMI_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 */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0), + + /* Mixer definitions */ + SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, + hdmi_mixer_controls, + ARRAY_SIZE(hdmi_mixer_controls)), +}; + +static const struct snd_soc_dapm_route intercon[] = { + {"HDMI Mixer", "MultiMedia1", "MM_DL1"}, + {"HDMI Mixer", "MultiMedia2", "MM_DL2"}, + {"HDMI Mixer", "MultiMedia3", "MM_DL3"}, + {"HDMI Mixer", "MultiMedia4", "MM_DL4"}, + {"HDMI Mixer", "MultiMedia5", "MM_DL5"}, + {"HDMI Mixer", "MultiMedia6", "MM_DL6"}, + {"HDMI Mixer", "MultiMedia7", "MM_DL7"}, + {"HDMI Mixer", "MultiMedia8", "MM_DL8"}, + {"HDMI", NULL, "HDMI Mixer"}, + {"HDMI-RX", NULL, "HDMI"}, +}; + +static int routing_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int be_id = rtd->cpu_dai->id; + struct snd_soc_platform *platform = rtd->platform; + struct msm_routing_data *data = snd_soc_platform_get_drvdata(platform); + struct session_data *session; + int port_id, port_type, path_type, bits_per_sample; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + path_type = ADM_PATH_PLAYBACK; + port_type = MSM_AFE_PORT_TYPE_RX; + } + + port_id = be_id; + + session = routing_get_session(data, port_id, port_type); + + if (!session) { + pr_err("No session matrix setup yet..\n"); + return -EINVAL; + } + + mutex_lock(&data->lock); + + session->path_type = path_type; + session->sample_rate = params_rate(params); + session->channels = params_channels(params); + session->format = params_format(params); + + if (session->format == SNDRV_PCM_FORMAT_S16_LE) + session->bits_per_sample = 16; + else if (session->format == SNDRV_PCM_FORMAT_S24_LE) + bits_per_sample = 24; + + mutex_unlock(&data->lock); + return 0; +} + +static int routing_close(struct snd_pcm_substream *substream) +{ + return 0; +} + +static int routing_prepare(struct snd_pcm_substream *substream) +{ + return 0; +} + +static struct snd_pcm_ops q6pcm_routing_ops = { + .hw_params = routing_hw_params, + .close = routing_close, + .prepare = routing_prepare, +}; + +/* Not used but frame seems to require it */ +static int msm_routing_probe(struct snd_soc_platform *platform) +{ + int i; + + for (i = 0; i < MAX_SESSIONS; i++) + routing_data->sessions[i].port_id = -1; + + snd_soc_platform_set_drvdata(platform, routing_data); + + return 0; +} + +static struct snd_soc_platform_driver msm_soc_routing_platform = { + .ops = &q6pcm_routing_ops, + .probe = msm_routing_probe, + .component_driver = { + .dapm_widgets = msm_qdsp6_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm_qdsp6_widgets), + .dapm_routes = intercon, + .num_dapm_routes = ARRAY_SIZE(intercon), + }, +}; + +static int q6pcm_routing_probe(struct platform_device *pdev) +{ + + routing_data = devm_kzalloc(&pdev->dev, + sizeof(*routing_data), GFP_KERNEL); + if (!routing_data) + return -ENOMEM; + + routing_data->dev = &pdev->dev; + + mutex_init(&routing_data->lock); + dev_set_drvdata(&pdev->dev, routing_data); + + return devm_snd_soc_register_platform(&pdev->dev, + &msm_soc_routing_platform); +} + +static int q6pcm_routing_remove(struct platform_device *pdev) +{ + return 0; +} + +static struct platform_driver q6pcm_routing_driver = { + .driver = { + .name = "q6routing", + .owner = THIS_MODULE, + }, + .probe = q6pcm_routing_probe, + .remove = q6pcm_routing_remove, +}; + +module_platform_driver(q6pcm_routing_driver); + +MODULE_DESCRIPTION("Q6 Routing platform"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/qcom/qdsp6/q6routing.h b/sound/soc/qcom/qdsp6/q6routing.h new file mode 100644 index 000000000000..7f0feb196acc --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6routing.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _Q6_PCM_ROUTING_H +#define _Q6_PCM_ROUTING_H + +int q6routing_reg_phy_stream(int fedai_id, int perf_mode, + int stream_id, int stream_type); +void q6routing_dereg_phy_stream(int fedai_id, int stream_type); + +#endif /*_Q6_PCM_ROUTING_H */ From patchwork Tue Dec 5 22:18:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 120766 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6313333qgn; Tue, 5 Dec 2017 14:22:57 -0800 (PST) X-Google-Smtp-Source: AGs4zMbnAwz2g9+jr2TAacHHiKkhrI2RYFnocOHHX0MjWMGDXZ5ySZPSiF2wFssDem8G9jrU1lxu X-Received: by 10.99.119.67 with SMTP id s64mr18570622pgc.390.1512512577823; Tue, 05 Dec 2017 14:22:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512512577; cv=none; d=google.com; s=arc-20160816; b=qsnvhxIfkYpB57NnfyVQcUk2CNw8p2hhSaDIfP/108putltLx0Z/wheQuJjQ4E3fRI hh1vAjOUmadDP8s2dD/W9Ssc90wvSqacptltBzHPAFkpt15KKJetSZN7JgXaVyHH3ULF ItxmQTtbCpu0p+nC6A5V6xNkYaCRxtZz5rc8VeClstfLIKY5YJZmsm6+UwzDxwXUHQ2m 7G5TiMDBetR+xrCjDD0HtEc0bypDkyBLfLpEUWOjV4306HOhYjnC6jW8o+RyAvv4RrBz BzMeWx/YLFd/qrMW2Rgu8Qhp8/YQlkGL93levTwLdYCIKk2rbmm+eWPtiOqAvrHC39l5 QBag== 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=a4Nye70Z/4V59BxT5yqwQWB6aMjM38xOlv74JwyTt7A=; b=0EYpTsl+ljHein8noOfJdITtRDzrBOjEh/Rq0CbQ55fW2NEhr1PLv5oWdPxvz+SanG kokF1z3DHVfVc+XRj4eJhfkJADZSGoJEIfgscK0vr4aX94xQ5sID7qxS8F22AMsulc6Q z3O/Pk1q5eimprUsnm1YFaoNOmVWUL7DTMbeWgG9Mn6gfkbS7OtnrBdbSx0VxJU1zWoI 9WBB2RDeqkMYyu/UKGo8pnW5tqvL8vgFhehB7ubqONpTe1sLZPKxD3FdokPQXBdrmNhz 7n7vFBtka6odBEGU6A9ngmmVfMcu449rEvn1UuiB051/trDZMThThP6rvemPtzLgOm2n swEA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NPZ90mL9; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g9si797302pfg.327.2017.12.05.14.22.57; Tue, 05 Dec 2017 14:22:57 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NPZ90mL9; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752847AbdLEWW4 (ORCPT + 28 others); Tue, 5 Dec 2017 17:22:56 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:45672 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752586AbdLEWUe (ORCPT ); Tue, 5 Dec 2017 17:20:34 -0500 Received: by mail-wm0-f65.google.com with SMTP id 9so4031133wme.4 for ; Tue, 05 Dec 2017 14:20:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=a4Nye70Z/4V59BxT5yqwQWB6aMjM38xOlv74JwyTt7A=; b=NPZ90mL9uNSPml26ztxHQqo17dnhx3L3Q4vjluSTkbY6K0pfKKrSjSiEKDS79q5raA cAmdEn0z8buWPqKLjYj14LTjbuJ7ZSwV8PEPMSxlvGsKqqAsiRTTjQ5aIImTJEiO5PYW FCCoFZ8XJE20+ep1HNYxvhDvuV3DGFddw7fCQ= 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=a4Nye70Z/4V59BxT5yqwQWB6aMjM38xOlv74JwyTt7A=; b=qp1VTHvXMxj6/G3yjZgRjzlpdux0qJMFWBYDXF0EMyjpkkLmuYDRnuR8s2Y8xuN4wj DHZTVF/ObnI5TEde6IqZfS2unTSq9t0gZ0YjPHz1N4OEMfzAyqjTSE5oAGrzuyhRZrML JZZM6IO61GIf56D2BJSOGPD0PWxPkN1AcIESzHqCzzYJMQv5AszViFG3LQVb6HknOZ40 UWm0cPqxqFdElAUUBiNF9mWP1eKFOQYsjXBikhk9WUGUHP8OSy2RmJd2CKUPMppz2X7d VdQb5KKk5RybBMnrPMPYZubJEEzQs6bt0QZssQUGoDtwG04GnB5l/GTF5pEvgfsG9zTR jPbQ== X-Gm-Message-State: AKGB3mKHbv0L9q3oJE/3vdGsuK5JNPsz4xM463AW/hhIcmJC+gbz1FZ3 oxnEQ8qCbAWWPUPfb5DQ+zKXTQ== X-Received: by 10.28.120.19 with SMTP id t19mr7586888wmc.64.1512512432356; Tue, 05 Dec 2017 14:20:32 -0800 (PST) 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 t138sm1633154wme.16.2017.12.05.14.20.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Dec 2017 14:20:31 -0800 (PST) From: srinivas.kandagatla@linaro.org To: broonie@kernel.org, bgoswami@codeaurora.org Cc: alsa-devel@alsa-project.org, tiwai@suse.com, plai@codeaurora.org, kwestfie@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, lkasam@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v2 12/15] ASoC: qcom: qdsp6: Add support to q6asm dai driver Date: Tue, 5 Dec 2017 22:18:09 +0000 Message-Id: <20171205221812.25641-13-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> References: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla This patch adds support to q6asm dai driver which configures Q6ASM streams to pass pcm data. Currently the driver only exposes 2 playback streams for hdmi playback support, it can be easily extended to add all 8 streams. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/Kconfig | 6 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6asm-dai.c | 534 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 541 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6asm-dai.c -- 2.15.0 diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 003ce182691c..ecd1e4ba834d 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -68,6 +68,11 @@ config SND_SOC_QDSP6_AFE_DAI tristate default n +config SND_SOC_QDSP6_ASM_DAI + tristate + default n + + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" select SND_SOC_QDSP6_AFE @@ -76,6 +81,7 @@ config SND_SOC_QDSP6 select SND_SOC_QDSP6_CORE select SND_SOC_QDSP6_ROUTING select SND_SOC_QDSP6_AFE_DAI + 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 bd8bd02bf09e..03576a442fb5 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o obj-$(CONFIG_SND_SOC_QDSP6_AFE_DAI) += q6afe-dai.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..709c5de230fa --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -0,0 +1,534 @@ +/* SPDX-License-Identifier: GPL-2.0 +* Copyright (c) 2011-2016, The Linux Foundation +* Copyright (c) 2017, Linaro Limited +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6asm.h" +#include "q6routing.h" +#include "common.h" + +#define PLAYBACK_MIN_NUM_PERIODS 2 +#define PLAYBACK_MAX_NUM_PERIODS 8 +#define PLAYBACK_MAX_PERIOD_SIZE 65536 +#define PLAYBACK_MIN_PERIOD_SIZE 128 + +enum stream_state { + IDLE = 0, + STOPPED, + RUNNING, +}; + +struct q6asm_dai_rtd { + struct snd_pcm_substream *substream; + dma_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; + bool set_channel_map; + char channel_map[8]; +}; + +struct q6asm_dai_data { + u64 sid; +}; + +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, +}; + +/* 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: + q6asm_write_nolock(prtd->audio_client, + prtd->pcm_count, 0, 0, NO_TIMESTAMP); + break; + case ASM_CLIENT_EVENT_CMD_EOS_DONE: + prtd->state = STOPPED; + break; + case ASM_CLIENT_EVENT_DATA_WRITE_DONE: { + prtd->pcm_irq_pos += prtd->pcm_count; + snd_pcm_period_elapsed(substream); + if (prtd->state == RUNNING) + q6asm_write_nolock(prtd->audio_client, + prtd->pcm_count, 0, 0, NO_TIMESTAMP); + + 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 q6asm_dai_data *pdata; + int ret; + + pdata = dev_get_drvdata(soc_prtd->platform->dev); + 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_dereg_phy_stream(soc_prtd->dai_link->id, + SNDRV_PCM_STREAM_PLAYBACK); + } + + 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; + } + + ret = q6asm_open_write(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_reg_phy_stream(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; + } + + ret = q6asm_media_format_block_multi_ch_pcm( + prtd->audio_client, runtime->rate, + runtime->channels, !prtd->set_channel_map, + prtd->channel_map, prtd->bits_per_sample); + if (ret < 0) + pr_info("%s: CMD Format block failed\n", __func__); + + prtd->state = 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: + ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0); + break; + 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 = 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 q6asm_dai_rtd *prtd; + struct q6asm_dai_data *pdata; + struct device *dev = soc_prtd->platform->dev; + int ret = 0; + + pdata = dev_get_drvdata(dev); + if (!pdata) { + pr_err("Platform 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, + (app_cb)event_handler, prtd); + if (!prtd->audio_client) { + pr_info("%s: Could not allocate memory\n", __func__); + kfree(prtd); + return -ENOMEM; + } + +// prtd->audio_client->dev = dev; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + runtime->hw = q6asm_dai_hardware_playback; + + 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); + } + + prtd->set_channel_map = false; + 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); + } + q6routing_dereg_phy_stream(soc_prtd->dai_link->id, + SNDRV_PCM_STREAM_PLAYBACK); + 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_card *card = soc_prtd->card->snd_card; + + return dma_mmap_coherent(card->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 *pcm = rtd->pcm; + struct snd_pcm_substream *substream; + struct snd_card *card = rtd->card->snd_card; + struct device *dev = card->dev; + struct device_node *node = dev->of_node; + struct q6asm_dai_data *pdata = dev_get_drvdata(rtd->platform->dev); + struct of_phandle_args args; + + int size, ret = 0; + + ret = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args); + if (ret < 0) + pdata->sid = -1; + else + pdata->sid = args.args[0]; + + + + substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + size = q6asm_dai_hardware_playback.buffer_bytes_max; + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, + &substream->dma_buffer); + if (ret) { + dev_err(dev, "Cannot allocate buffer(s)\n"); + 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 struct snd_soc_platform_driver q6asm_soc_platform = { + .ops = &q6asm_dai_ops, + .pcm_new = q6asm_dai_pcm_new, + .pcm_free = q6asm_dai_pcm_free, + +}; + +static const struct snd_soc_dapm_route afe_pcm_routes[] = { + {"MM_DL1", NULL, "MultiMedia1 Playback" }, + {"MM_DL2", NULL, "MultiMedia2 Playback" }, + +}; + +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 = "q6asm-fe-dai", +}; + +static struct snd_soc_dai_driver q6asm_fe_dais[] = { + { + .playback = { + .stream_name = "MultiMedia1 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, + }, + .name = "MM_DL1", + .probe = fe_dai_probe, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1, + }, + { + .playback = { + .stream_name = "MultiMedia2 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, + }, + .name = "MM_DL2", + .probe = fe_dai_probe, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, +}; + +static int q6asm_dai_probe(struct platform_device *pdev) +{ + struct q6asm_dai_data *pdata; + struct device *dev = &pdev->dev; + int rc; + + pdata = devm_kzalloc(dev, sizeof(struct q6asm_dai_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + + dev_set_drvdata(dev, pdata); + + rc = snd_soc_register_platform(dev, &q6asm_soc_platform); + if (rc) { + dev_err(&pdev->dev, "err_dai_platform\n"); + return rc; + } + + rc = snd_soc_register_component(dev, &q6asm_fe_dai_component, + q6asm_fe_dais, + ARRAY_SIZE(q6asm_fe_dais)); + if (rc) + dev_err(dev, "err_dai_component\n"); + + return rc; + +} + +static int q6asm_dai_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static struct platform_driver q6asm_dai_driver = { + .driver = { + .name = "q6asm_dai", + .owner = THIS_MODULE, + }, + .probe = q6asm_dai_probe, + .remove = q6asm_dai_remove, +}; + +module_platform_driver(q6asm_dai_driver); + +MODULE_DESCRIPTION("PCM module platform driver"); +MODULE_LICENSE("GPL v2"); From patchwork Tue Dec 5 22:18:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 120765 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6312093qgn; Tue, 5 Dec 2017 14:21:28 -0800 (PST) X-Google-Smtp-Source: AGs4zMbrcw/I50kE2SAdR0gfEkqjyMwMcGisJZ71Foh83Q2b5zNLmlT4lbF0FCt56KpqmeGDJsJ9 X-Received: by 10.84.224.5 with SMTP id r5mr19929071plj.341.1512512488420; Tue, 05 Dec 2017 14:21:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512512488; cv=none; d=google.com; s=arc-20160816; b=HQEHB/Kp+/N6GbV3DoJL/km0rkBgBfLZML1j7KbwpEP4RIe4BnfjctxaYl1JJXrj7S GImrqGpC9gn/tMTjR/oKDDX8PhCz/RCudeWdi7ie/x0E6N9o4Ycl4kQcKeMXuIqmGFka vm3FO3njJio3OpWfTHzUB3+SJVz/BIKt20+/KJLeg66BWSO8tIrLbOU2WajV5klpmwFM uy9TeLoQT3kZMiOl63r3BK2aS0Wk8v7hm9+JHRfmrpJsCxiEbJIcmopuZT41FlH3n+Zu GtQtbzwkY2HFvaQaKx9Xdj/OJ/7uncQKo2IN/FEJRqA5vORNspJAI5vUSFlu3Utwl5n2 YIhQ== 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=5P11H62b4xPELhart8WGy+syC64k2uY5O2WNEbio21c=; b=n+ALcF+wo3r0dtJQNMBigPTvD9ilc+EdwViIvZt/+Qfc6ddv2G91gGCfCZnfuDBwZX M0BwAvzKOqq+OMphnceoympd+k5OVKGiNMImO0cImZJhPCL/BZAv0ujsMWmIaBzIDYA/ fyYPcBitNskzG+75/CMnfCQ1K1OzZUkvk7RYBthmQq/i8AjEs1J4UpTm+s0RGA4+SErf NoZJ1p+1GiDIp5Xgqa/sSsk0JTf8RTZZ2ZeiC4mrBq5D2xh13j37x5al3zMP+TYCz/BI Rv6gpzh98rZljLFrQDwU6Ts0dXUVyeZbQl3VWMfP5dm6kSrdvuXpPg7v38YtrsGzVlWN z+4Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MIkitO4H; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 20si791469pft.356.2017.12.05.14.21.28; Tue, 05 Dec 2017 14:21:28 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MIkitO4H; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752751AbdLEWV0 (ORCPT + 28 others); Tue, 5 Dec 2017 17:21:26 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:36883 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752598AbdLEWUf (ORCPT ); Tue, 5 Dec 2017 17:20:35 -0500 Received: by mail-wm0-f67.google.com with SMTP id f140so3950844wmd.2 for ; Tue, 05 Dec 2017 14:20:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5P11H62b4xPELhart8WGy+syC64k2uY5O2WNEbio21c=; b=MIkitO4HhmsKWXEQ7pWYUaSBSOIyZYezWZYnA/n8MIEGFqNpiuuym+R4IE/nHtCwAK WbHjc8NdinkJZ0Efq1gp0A7VuqbdAW8bDEWlZfG762Lr9j0Z8UFra9eOS6Lau7+db0FF 2zHoaoPr+wUO0mfbRm7atV37BiI73/4vKCJGs= 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=5P11H62b4xPELhart8WGy+syC64k2uY5O2WNEbio21c=; b=DoV5o9swVOk70sz3zu5rlVcqWjb6xGpl1HL8gLYrdhxT3xcS8JAReB6YjG3csQgPrm tcvgiRLgg4dCjdLOnRVAqHlIi/jE1PaLtEFJm2Yt7u3YbhsBoUFDKh3oml/ZlO/w3aH1 2E8RgVARrw7AnXYdXmtSiB35FQpRvLAz2Fskfj4Wcr7SyLmXcbyvifcZWZVK3wNdm7gO hTitSwmd6yrDIEj/JEjGjNyzcqiA0ReALX3jPj83tNEl/wmyugtQrlG2Rxahxhv4iUKD 5n4JlxSqgFCI7rHW+BloSISrdaDY+EH/xQty/YMwrG4kKyys5AcJKEveYaQLaYnGIkHb 3sJw== X-Gm-Message-State: AKGB3mLwTGLsaZmPcz6MMPrjMu84Of9BOCqqBuJmgR7YFdFEipLtfwFM t4buleKg29z7CelKZWmGURGUKQ== X-Received: by 10.28.218.70 with SMTP id r67mr6773422wmg.14.1512512434188; Tue, 05 Dec 2017 14:20:34 -0800 (PST) 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 t138sm1633154wme.16.2017.12.05.14.20.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Dec 2017 14:20:33 -0800 (PST) From: srinivas.kandagatla@linaro.org To: broonie@kernel.org, bgoswami@codeaurora.org Cc: alsa-devel@alsa-project.org, tiwai@suse.com, plai@codeaurora.org, kwestfie@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, lkasam@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v2 14/15] ASoC: qcom: apq8096: Add db820c machine driver Date: Tue, 5 Dec 2017 22:18:11 +0000 Message-Id: <20171205221812.25641-15-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> References: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla uThis patch adds support to DB820c machine driver. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/Kconfig | 9 +++- sound/soc/qcom/apq8096.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 sound/soc/qcom/apq8096.c -- 2.15.0 diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index ecd1e4ba834d..748ccc3edefa 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -72,7 +72,6 @@ config SND_SOC_QDSP6_ASM_DAI tristate default n - config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" select SND_SOC_QDSP6_AFE @@ -87,3 +86,11 @@ 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" + select SND_SOC_QDSP6V2 + default n + help + To add support for SoC audio on MSM8996 and APQ8096 boards + diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c new file mode 100644 index 000000000000..5b2036317f71 --- /dev/null +++ b/sound/soc/qcom/apq8096.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +int msm8996_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 struct snd_soc_dai_link msm8996_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = "MultiMedia1 Playback", + .stream_name = "MultiMedia1", + .cpu_dai_name = "MM_DL1", + .platform_name = "q6asm_dai", + .dynamic = 1, + .dpcm_playback = 1, + + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* Backend DAI Links */ + { + .name = "HDMI Playback", + .stream_name = "q6afe_dai", + .cpu_dai_name = "HDMI", + .platform_name = "q6routing", + .no_pcm = 1, + .dpcm_playback = 1, + .be_hw_params_fixup = msm8996_be_hw_params_fixup, + .codec_dai_name = "i2s-hifi", + .codec_name = "hdmi-audio-codec.0.auto", + }, +}; + +static int apq8096_sbc_parse_of(struct snd_soc_card *card) +{ + struct device *dev = card->dev; + int ret; + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) + dev_err(dev, "Error parsing card name: %d\n", ret); + + return ret; +} + +static int msm_snd_apq8096_probe(struct platform_device *pdev) +{ + int ret; + struct snd_soc_card *card; + + card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->dev = &pdev->dev; + + ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + card->dai_link = msm8996_dai_links; + card->num_links = ARRAY_SIZE(msm8996_dai_links); + + ret = apq8096_sbc_parse_of(card); + if (ret) { + dev_err(&pdev->dev, "Error parsing OF data\n"); + return ret; + } + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) + dev_err(&pdev->dev, "sound card register failed (%d)!\n", ret); + else + dev_err(&pdev->dev, "sound card register Sucessfull\n"); + + return ret; +} + +static const struct of_device_id msm_snd_apq8096_dt_match[] = { + {.compatible = "qcom,apq8096-sndcard"}, + {} +}; + +static struct platform_driver msm_snd_apq8096_driver = { + .probe = msm_snd_apq8096_probe, + .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 X-Patchwork-Id: 120763 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6312052qgn; Tue, 5 Dec 2017 14:21:25 -0800 (PST) X-Google-Smtp-Source: AGs4zMby4DZXrca8hVullsoGMI/plj5OXEx0k8Lu6iFVpmRWQ0qxskuy6LWtogxGcGoVCNKU70z3 X-Received: by 10.84.252.23 with SMTP id x23mr20023213pll.54.1512512485339; Tue, 05 Dec 2017 14:21:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512512485; cv=none; d=google.com; s=arc-20160816; b=UgmYwBvSQoVH/wQjbhBz9wNXia4UkoltF+N/499T2t+VE3kLu6CCTqn3LsuztMYBPi 7aO+a6DZTk82dA11hV0J5EaA3SdeCWY27pIfKHFp1cPPih+XEEw8+ymB5IxcXLmdf/GF Nb4sqEw7W62yIMOPNJPyGuiq2rPypZ4xCmkOlzFbFOu91TyR2IjVjAF2XyfZQgG0tmUE yXOPCcOqQPv8Qdgf0OhBzvakYlMIbz+4DO2bWm7Xiz9bvpDWMH2o1dsilnkV60yoGos6 pEFhB0qlHDQRWgZAX5pSqw6yvFnIreL8WomGLAzl3RM1Rt3khGxlUNJ+E7zYvVvAAENL 8AYw== 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=ULUUZ5WmFHLaZcT68KslFCqjJW9uzV3bA4f/Y48ULGw=; b=AZgDcjXqQxSRaW9TtblgQcrmP0fXZzrpcANGUeepZ475c0BbznDOdItfflOsKzPQL8 AR9zKO3k4cBOnGohoCOSrvNLHhJ+Jv+guIVHCC/J1IGN6ukEbFlN9EWN/Brfav/2DEQc K6+qpNJoPAANtGSri59QSIhE0N2ScBH8L3gkxXeYt6Cs3pAczcauayv5gabBmtV1U+7X pntIzCgpb+xkfYeUdBWP+uDTyvMf9HVC0ZHAv+yaCyxCQ5vg4YmM0YP6Az0TXttccliP zkV5WWyQB+yJCZwQSy7hivmimhd1tEX5X+AhofgQUyxDN6UD1QWlrSZUJgg7toKbsZzj zoEA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UwHHvjaN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 20si791469pft.356.2017.12.05.14.21.25; Tue, 05 Dec 2017 14:21:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UwHHvjaN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752719AbdLEWVY (ORCPT + 28 others); Tue, 5 Dec 2017 17:21:24 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:41684 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752602AbdLEWUg (ORCPT ); Tue, 5 Dec 2017 17:20:36 -0500 Received: by mail-wm0-f65.google.com with SMTP id g75so4103177wme.0 for ; Tue, 05 Dec 2017 14:20:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ULUUZ5WmFHLaZcT68KslFCqjJW9uzV3bA4f/Y48ULGw=; b=UwHHvjaNRGCdrculUzPoeRv/JeFnrmtsZza2FO86VTAoAjn7GI26Lfd6dEcFZyJgcz tmSlaqRZw3bgenx+6df/44/6FUD1LY5865swuZACWZOu+/1fixBsW3H3pXATGDJWRv2e WvIrLpV54lj+mL8jZ/D08BXn4NotC1g4sJ3cs= 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=ULUUZ5WmFHLaZcT68KslFCqjJW9uzV3bA4f/Y48ULGw=; b=MRNeUdS7VUX1tTx0OEUs6/s1epaTjWPUBLrung8+zh+aCPJsboEXgRbAYbwCSbUQzH ynZudHpFL4Fl7nU421h2bLzCsiQ3bT1hs55RRrCQH2CE9RfT01LhX7TORfG5X1cDbkVJ qORBZ4GVkqFXaUEvOLow83maayRWvY5204KGaKa0BrjIbenTIXhJfh7cbVEG7RVqhHGU XOnYpwMij/w6Mbs+1m06IWpLAvLg0btBKGDuigMcFaMVEGoQ60e2tZNZNRTzqYUJYpXo xH6hfESVYj7oT0Dzg6RLB4xPopJIqsneZVrxYBBzNTFmnKtjVdPyh/TPSSvube35A+w7 25Vw== X-Gm-Message-State: AKGB3mIqCn8gP7rVKuBByyC7iX2IKX+sSbfhNkBb9SPrFSoL4tVlyHvZ XPqL1mrwecgXU6YsrJ/K5kEU9Q== X-Received: by 10.28.62.5 with SMTP id l5mr6921395wma.47.1512512435244; Tue, 05 Dec 2017 14:20:35 -0800 (PST) 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 t138sm1633154wme.16.2017.12.05.14.20.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Dec 2017 14:20:34 -0800 (PST) From: srinivas.kandagatla@linaro.org To: broonie@kernel.org, bgoswami@codeaurora.org Cc: alsa-devel@alsa-project.org, tiwai@suse.com, plai@codeaurora.org, kwestfie@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, lkasam@qti.qualcomm.com, Srinivas Kandagatla Subject: [PATCH v2 15/15] arm64: dts: msm8996: db820c: Add sound card support Date: Tue, 5 Dec 2017 22:18:12 +0000 Message-Id: <20171205221812.25641-16-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> References: <20171205221812.25641-1-srinivas.kandagatla@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla This patch adds hdmi sound card support to db820c via qdsp. Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 5 +++++ arch/arm64/boot/dts/qcom/msm8996.dtsi | 33 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) -- 2.15.0 diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi index 9769053957af..b955769b100d 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi @@ -190,6 +190,11 @@ }; }; + snd { + compatible = "qcom,apq8096-sndcard"; + qcom,model = "DB820c"; + iommus = <&lpass_q6_smmu 1>; + }; gpio_keys { compatible = "gpio-keys"; diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index a144cec7bb71..25c43fb8ab49 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -1262,6 +1262,7 @@ phys = <&hdmi_phy>; phy-names = "hdmi_phy"; + #sound-dai-cells = <0>; ports { #address-cells = <1>; @@ -1297,6 +1298,33 @@ "ref_clk"; }; }; + + lpass_q6_smmu: arm,smmu-lpass_q6@1600000 { + compatible = "qcom,msm8996-smmu-v2"; + reg = <0x1600000 0x20000>; + #iommu-cells = <1>; + power-domains = <&gcc HLOS1_VOTE_LPASS_CORE_GDSC>; + + #global-interrupts = <1>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + ; + + clocks = <&gcc GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK>, + <&gcc GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK>; + clock-names = "iface", "bus"; + status = "okay"; + }; }; adsp-pil { @@ -1325,6 +1353,11 @@ qcom,ipc = <&apcs 16 8>; qcom,smd-edge = <1>; qcom,remote-pid = <2>; + + apr { + compatible = "qcom,apr-msm8996"; + qcom,smd-channels = "apr_audio_svc"; + }; }; };