From patchwork Sat Mar 10 02:24:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131261 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1690498lja; Fri, 9 Mar 2018 18:28:15 -0800 (PST) X-Google-Smtp-Source: AG47ELtZsLg6f0elJS5qJ2YIVdyQVOJFz2BW99keOvqTZfEaNVJOyy+eCsUNJzOMUzaj6NUlpksE X-Received: by 10.28.197.205 with SMTP id v196mr51960wmf.141.1520648895038; Fri, 09 Mar 2018 18:28:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648895; cv=none; d=google.com; s=arc-20160816; b=DMHeLwXjfagtYqx56GdYxYoztcSutdKt9yDkgeNAyRtgYzOUkqeNP+tpl6GTkcBS1B yINrZ+H8alhMZrlrDVOtGG+c941JiBFDQdzkOr+gZwIpOk3qEPxwwxoUctdDNT6mWt/p AwimXun7XN5+P3enp4UyAql27kTGVZaZ8jAjQVo06ewkifWn1uoklRj/lJRAbDjoZibq aCaIHqklfgc52lxKGsV+w/XdmEYJ2MHjyAvgV+XjVCQTjhCf5pWnbB05GqZb/lf8f5nd zcA9pHB8wgD6+qW4pOfmjYFbq2NNxLV/QSJD/fZOaDutCtwvqe7I7K97EXTpw5A4vmra 00FQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=ck9HWXJi/D/M6ecjhMNNj0Ee9OYDTIl3fXmJ9tNr2Oo=; b=bekf2AoB6VaxPuiXx+AMTU3tCiQUEpUCWBwl7SE2enKnz6wnlVRZGURYAQwHCDUMpp jGvCORuOcmlfXra+qFXlyGy77nfcKZnjiGcdAwTSe+oypYKFxl2nKVgQ3xxNimulG7ZH 7DDz7NeHugEu0OGU0ZeLD6wl7eCWU4aJIFSw9TH7YNPgg4nhln+wkYnlSTybM2tJtxIb mlwGcaFukKyZmOcuKVufVdHbsbXx6HZgg2ohqAtdSNJ1KOHxryORfr1bqyWFqle8u6Sl fsyTDOonuIBawWblb4t1h88oOgC8LXLYwJDeI2psumqlPIqQx13UTMzNj9EGFK0+su73 tC7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Yp82MUdd; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id v45si1317408wrc.492.2018.03.09.18.28.14; Fri, 09 Mar 2018 18:28:15 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Yp82MUdd; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 7EB3F267673; Sat, 10 Mar 2018 03:27:59 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 90970267657; Sat, 10 Mar 2018 03:27:49 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wr0-f194.google.com (mail-wr0-f194.google.com [209.85.128.194]) by alsa0.perex.cz (Postfix) with ESMTP id AA643267657 for ; Sat, 10 Mar 2018 03:27:45 +0100 (CET) Received: by mail-wr0-f194.google.com with SMTP id a27so3018643wra.2 for ; Fri, 09 Mar 2018 18:27:45 -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=ilP90eHaJXeYp6vICJe+A6YWCWp+N5+KT8I8sFYNtac=; b=Yp82MUddWH32xjcnmUBCPhHRbP4KU+fGNwfeWbwJDOrkV4qPUc65Fx0IiglZvd7p1D SDEpcQNxWIsuAqPnloKSgKm/9xOEcV1g8oupmXqxbcxtKtd1VGzGr8AmJtPLMctLpF36 z+MUgox+DQSXurvHvwN/3gO1gMLVHhrPITcdQ= 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=ilP90eHaJXeYp6vICJe+A6YWCWp+N5+KT8I8sFYNtac=; b=irr++efVxJJOeaXdRIhANWvdhCJXehhQG5Qnfk6andt3Ka4yj3hZP5tT4FU9Pzln+y 4shlREB0MLvS1gMzaoUynxTBFk3oT0qZq/QPuAeEA0Yqi5cyMx9iKznSBo5YncrDbTvZ bV6tiRFboURgO7OCXqpd6NAGwImNBv6sF+IG1pQp0XI+RNVBgG/pbA/d7lLLHx+1JbwW f0P32jV9Zr2uGHibMSwFqZYzE/0mVV7jD+q8dij+XdeIDPDqGuhdUb5Q7UtPjVTEbRsH xTR6uvoWzE+EpoIRagnVJbv0vyEikmu8K7QTIOxYz2zZ/c1UURsSf+9UzWgVoEWsRy+W M6Qw== X-Gm-Message-State: AElRT7HBp1Q47XtruljNckBmLElfxDrZM7fVOYjRrHugnd1Ii2eEbVU2 mAUAxPlrxuMlkE96Vf6P6w49OA== X-Received: by 10.223.192.74 with SMTP id c10mr426314wrf.145.1520648864858; Fri, 09 Mar 2018 18:27:44 -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 g78sm21489wmc.31.2018.03.09.18.27.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:44 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:34 +0000 Message-Id: <20180310022456.26739-3-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 02/24] soc: qcom: Add APR bus driver X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org From: Srinivas Kandagatla This patch adds support toi APR bus (Asynchronous Packet Router) driver. ARP driver is made as a bus driver so that the apr devices can added removed more dynamically depending on the state of the services on the dsp. APR is used for communication between application processor and QDSP to use services on QDSP like Audio and others. Signed-off-by: Srinivas Kandagatla --- drivers/soc/qcom/Kconfig | 9 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/apr.c | 379 ++++++++++++++++++++++++++++++++++++++++ include/linux/mod_devicetable.h | 11 ++ include/linux/soc/qcom/apr.h | 131 ++++++++++++++ 5 files changed, 531 insertions(+) create mode 100644 drivers/soc/qcom/apr.c create mode 100644 include/linux/soc/qcom/apr.h -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 7a729eee13a0..26a8332276e6 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -115,4 +115,13 @@ config QCOM_WCNSS_CTRL Client driver for the WCNSS_CTRL SMD channel, used to download nv firmware to a newly booted WCNSS chip. +config QCOM_APR + tristate "Qualcomm APR Bus (Asynchronous Packet Router)" + depends on ARCH_QCOM + depends on RPMSG + help + Enable APR IPC protocol support between + application processor and QDSP6. APR is + used by audio driver to configure QDSP6 + ASM, ADM and AFE modules. endmenu diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 7620b1416ee1..043da96e3b79 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_QCOM_SMP2P) += smp2p.o obj-$(CONFIG_QCOM_SMSM) += smsm.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o obj-$(CONFIG_ARCH_MSM8996) += kryo-l2-accessors.o +obj-$(CONFIG_QCOM_APR) += apr.o diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c new file mode 100644 index 000000000000..56ed3fb1f2f9 --- /dev/null +++ b/drivers/soc/qcom/apr.c @@ -0,0 +1,379 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2011-2017, The Linux Foundation +// Copyright (c) 2018, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct apr { + struct rpmsg_endpoint *ch; + struct device *dev; + spinlock_t svcs_lock; + struct list_head svcs; + int dest_domain_id; +}; + +/** + * apr_send_pkt() - Send a apr message from apr device + * + * @adev: Pointer to previously registered apr device. + * @buf: Pointer to buffer to send + * + * Return: Will be an negative on packet size on success. + */ +int apr_send_pkt(struct apr_device *adev, void *buf) +{ + struct apr *apr = dev_get_drvdata(adev->dev.parent); + struct apr_hdr *hdr; + unsigned long flags; + int ret; + + spin_lock_irqsave(&adev->lock, flags); + + hdr = (struct apr_hdr *)buf; + hdr->src_domain = APR_DOMAIN_APPS; + hdr->src_svc = adev->svc_id; + hdr->dest_domain = adev->domain_id; + hdr->dest_svc = adev->svc_id; + + ret = rpmsg_send(apr->ch, buf, hdr->pkt_size); + if (ret) { + dev_err(&adev->dev, "Unable to send APR pkt %d\n", + hdr->pkt_size); + } else { + ret = hdr->pkt_size; + } + + spin_unlock_irqrestore(&adev->lock, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(apr_send_pkt); + +static void apr_dev_release(struct device *dev) +{ + struct apr_device *adev = to_apr_device(dev); + + kfree(adev); +} + +static int apr_callback(struct rpmsg_device *rpdev, void *buf, + int len, void *priv, u32 addr) +{ + struct apr *apr = dev_get_drvdata(&rpdev->dev); + struct apr_client_message data; + struct apr_device *p, *c_svc = NULL; + struct apr_driver *adrv = NULL; + struct apr_hdr *hdr; + uint16_t hdr_size; + uint16_t msg_type; + uint16_t ver; + uint16_t svc; + + if (len <= APR_HDR_SIZE) { + dev_err(apr->dev, "APR: Improper apr pkt received:%p %d\n", + buf, len); + return -EINVAL; + } + + hdr = buf; + ver = APR_HDR_FIELD_VER(hdr->hdr_field); + if (ver > APR_PKT_VER + 1) + return -EINVAL; + + hdr_size = APR_HDR_FIELD_SIZE_BYTES(hdr->hdr_field); + if (hdr_size < APR_HDR_SIZE) { + dev_err(apr->dev, "APR: Wrong hdr size:%d\n", hdr_size); + return -EINVAL; + } + + if (hdr->pkt_size < APR_HDR_SIZE) { + dev_err(apr->dev, "APR: Wrong paket size\n"); + return -EINVAL; + } + + msg_type = APR_HDR_FIELD_MT(hdr->hdr_field); + if (msg_type >= APR_MSG_TYPE_MAX && msg_type != APR_BASIC_RSP_RESULT) { + dev_err(apr->dev, "APR: Wrong message type: %d\n", msg_type); + return -EINVAL; + } + + if (hdr->src_domain >= APR_DOMAIN_MAX || + hdr->dest_domain >= APR_DOMAIN_MAX || + hdr->src_svc >= APR_SVC_MAX || + hdr->dest_svc >= APR_SVC_MAX) { + dev_err(apr->dev, "APR: Wrong APR header\n"); + return -EINVAL; + } + + svc = hdr->dest_svc; + spin_lock(&apr->svcs_lock); + list_for_each_entry(p, &apr->svcs, node) { + if (svc == p->svc_id) { + c_svc = p; + if (c_svc->dev.driver) + adrv = to_apr_driver(c_svc->dev.driver); + break; + } + } + spin_unlock(&apr->svcs_lock); + + if (!adrv) { + dev_err(apr->dev, "APR: service is not registered\n"); + return -EINVAL; + } + + data.payload_size = hdr->pkt_size - hdr_size; + data.opcode = hdr->opcode; + data.src_port = hdr->src_port; + data.dest_port = hdr->dest_port; + data.token = hdr->token; + data.msg_type = msg_type; + + if (data.payload_size > 0) + data.payload = buf + hdr_size; + + adrv->callback(c_svc, &data); + + return 0; +} + +static int apr_device_match(struct device *dev, struct device_driver *drv) +{ + struct apr_device *adev = to_apr_device(dev); + struct apr_driver *adrv = to_apr_driver(drv); + const struct apr_device_id *id = adrv->id_table; + + /* Attempt an OF style match first */ + if (of_driver_match_device(dev, drv)) + return 1; + + if (!id) + return 0; + + while (id->domain_id != 0 || id->svc_id != 0) { + if (id->domain_id == adev->domain_id && + id->svc_id == adev->svc_id) + return 1; + id++; + } + + return 0; +} + +static int apr_device_probe(struct device *dev) +{ + struct apr_device *adev = to_apr_device(dev); + struct apr_driver *adrv = to_apr_driver(dev->driver); + + return adrv->probe(adev); +} + +static int apr_device_remove(struct device *dev) +{ + struct apr_device *adev = to_apr_device(dev); + struct apr_driver *adrv; + struct apr *apr = dev_get_drvdata(adev->dev.parent); + + if (dev->driver) { + adrv = to_apr_driver(dev->driver); + if (adrv->remove) + adrv->remove(adev); + spin_lock(&apr->svcs_lock); + list_del(&adev->node); + spin_unlock(&apr->svcs_lock); + } + + return 0; +} + +struct bus_type aprbus_type = { + .name = "aprbus", + .match = apr_device_match, + .probe = apr_device_probe, + .remove = apr_device_remove, + .force_dma = true, +}; +EXPORT_SYMBOL_GPL(aprbus_type); + +static int apr_add_device(struct device *dev, struct device_node *np, + const struct apr_device_id *id, bool is_svc) +{ + struct apr *apr = dev_get_drvdata(dev); + struct apr_device *adev = NULL; + + adev = kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) + return -ENOMEM; + + spin_lock_init(&adev->lock); + + if (is_svc) { + adev->svc_id = id->svc_id; + adev->domain_id = id->domain_id; + adev->version = id->svc_version; + dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", id->name, + id->domain_id, id->svc_id); + } else { + dev_set_name(&adev->dev, "%s:%s", dev_name(dev), np->name); + } + + adev->dev.bus = &aprbus_type; + adev->dev.parent = dev; + adev->dev.of_node = np; + adev->dev.release = apr_dev_release; + adev->dev.driver = NULL; + + spin_lock(&apr->svcs_lock); + list_add_tail(&adev->node, &apr->svcs); + spin_unlock(&apr->svcs_lock); + + dev_info(dev, "Adding APR dev: %s\n", dev_name(&adev->dev)); + + return device_register(&adev->dev); +} + +static void of_register_apr_devices(struct device *dev) +{ + struct apr *apr = dev_get_drvdata(dev); + struct device_node *node; + + for_each_child_of_node(dev->of_node, node) { + struct apr_device_id id = {0}; + const char *svc_name; + bool is_svc = false; + + if (of_find_property(node, "qcom,apr-svc-id", NULL) && + of_find_property(node, "qcom,apr-svc-name", NULL)) { + /* svc node */ + of_property_read_u32(node, "qcom,apr-svc-id", + &id.svc_id); + of_property_read_string(node, "qcom,apr-svc-name", + &svc_name); + id.domain_id = apr->dest_domain_id; + + memcpy(id.name, svc_name, strlen(svc_name) + 1); + is_svc = true; + } + + if (apr_add_device(dev, node, &id, is_svc)) + dev_err(dev, "Failed to add arp %s svc\n", svc_name); + } +} + +static int apr_probe(struct rpmsg_device *rpdev) +{ + struct device *dev = &rpdev->dev; + struct apr *apr; + int ret; + + apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL); + if (!apr) + return -ENOMEM; + + ret = of_property_read_u32(dev->of_node, "qcom,apr-dest-domain-id", + &apr->dest_domain_id); + if (ret) { + dev_err(dev, "APR Domain ID not specified in DT\n"); + return ret; + } + + dev_set_drvdata(dev, apr); + apr->ch = rpdev->ept; + apr->dev = dev; + INIT_LIST_HEAD(&apr->svcs); + + of_register_apr_devices(dev); + + return 0; +} + +static int apr_remove_device(struct device *dev, void *null) +{ + struct apr_device *adev = to_apr_device(dev); + + device_unregister(&adev->dev); + + return 0; +} + +static void apr_remove(struct rpmsg_device *rpdev) +{ + device_for_each_child(&rpdev->dev, NULL, apr_remove_device); +} + +/* + * __apr_driver_register() - Client driver registration with aprbus + * + * @drv:Client driver to be associated with client-device. + * @owner: owning module/driver + * + * This API will register the client driver with the aprbus + * It is called from the driver's module-init function. + */ +int __apr_driver_register(struct apr_driver *drv, struct module *owner) +{ + drv->driver.bus = &aprbus_type; + drv->driver.owner = owner; + + return driver_register(&drv->driver); +} +EXPORT_SYMBOL_GPL(__apr_driver_register); + +/* + * apr_driver_unregister() - Undo effect of apr_driver_register + * + * @drv: Client driver to be unregistered + */ +void apr_driver_unregister(struct apr_driver *drv) +{ + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL_GPL(apr_driver_unregister); + +static const struct of_device_id apr_of_match[] = { + { .compatible = "qcom,apr"}, + { .compatible = "qcom,apr-v2"}, + {} +}; + +static struct rpmsg_driver apr_driver = { + .probe = apr_probe, + .remove = apr_remove, + .callback = apr_callback, + .drv = { + .name = "qcom,apr", + .of_match_table = apr_of_match, + }, +}; + +static int __init apr_init(void) +{ + int ret; + + ret = bus_register(&aprbus_type); + if (!ret) + ret = register_rpmsg_driver(&apr_driver); + + return ret; +} + +static void __exit apr_exit(void) +{ + bus_unregister(&aprbus_type); + unregister_rpmsg_driver(&apr_driver); +} + +subsys_initcall(apr_init); +module_exit(apr_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Qualcomm APR Bus"); diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 48fb2b43c35a..c05c89b5a99e 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -471,6 +471,17 @@ struct slim_device_id { kernel_ulong_t driver_data; }; +#define APR_NAME_SIZE 32 +#define APR_MODULE_PREFIX "apr:" + +struct apr_device_id { + char name[APR_NAME_SIZE]; + __u32 domain_id; + __u32 svc_id; + __u32 svc_version; + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + #define SPMI_NAME_SIZE 32 #define SPMI_MODULE_PREFIX "spmi:" diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h new file mode 100644 index 000000000000..dbc9efe185d1 --- /dev/null +++ b/include/linux/soc/qcom/apr.h @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2011-2017, The Linux Foundation + * Copyright (c) 2018, Linaro Limited + */ + +#ifndef __QCOM_APR_H_ +#define __QCOM_APR_H_ + +#include +#include +#include +#include + +#define APR_HDR_LEN(hdr_len) ((hdr_len)/4) + +/* + * HEADER field + * version:0:3 + * header_size : 4:7 + * message_type : 8:9 + * reserved: 10:15 + */ +#define APR_HDR_FIELD(msg_type, hdr_len, ver)\ + (((msg_type & 0x3) << 8) | ((hdr_len & 0xF) << 4) | (ver & 0xF)) + +#define APR_HDR_SIZE sizeof(struct apr_hdr) +#define APR_SEQ_CMD_HDR_FIELD APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \ + APR_HDR_LEN(APR_HDR_SIZE), \ + APR_PKT_VER) +/* Version */ +#define APR_PKT_VER 0x0 + +/* Command and Response Types */ +#define APR_MSG_TYPE_EVENT 0x0 +#define APR_MSG_TYPE_CMD_RSP 0x1 +#define APR_MSG_TYPE_SEQ_CMD 0x2 +#define APR_MSG_TYPE_NSEQ_CMD 0x3 +#define APR_MSG_TYPE_MAX 0x04 + +/* APR Basic Response Message */ +#define APR_BASIC_RSP_RESULT 0x000110E8 +#define APR_RSP_ACCEPTED 0x000100BE + +struct aprv2_ibasic_rsp_result_t { + uint32_t opcode; + uint32_t status; +}; + +/* hdr field Ver [0:3], Size [4:7], Message type [8:10] */ +#define APR_HDR_FIELD_VER(h) (h & 0x000F) +#define APR_HDR_FIELD_SIZE(h) ((h & 0x00F0) >> 4) +#define APR_HDR_FIELD_SIZE_BYTES(h) (((h & 0x00F0) >> 4) * 4) +#define APR_HDR_FIELD_MT(h) ((h & 0x0300) >> 8) + +struct apr_hdr { + uint16_t hdr_field; + uint16_t pkt_size; + uint8_t src_svc; + uint8_t src_domain; + uint16_t src_port; + uint8_t dest_svc; + uint8_t dest_domain; + uint16_t dest_port; + uint32_t token; + uint32_t opcode; +}; + +struct apr_client_message { + uint16_t payload_size; + uint16_t hdr_len; + uint16_t msg_type; + uint16_t src; + uint16_t dest_svc; + uint16_t src_port; + uint16_t dest_port; + uint32_t token; + uint32_t opcode; + void *payload; +}; + +/* Bits 0 to 15 -- Minor version, Bits 16 to 31 -- Major version */ +#define APR_SVC_MAJOR_VERSION(v) ((v >> 16) & 0xFF) +#define APR_SVC_MINOR_VERSION(v) (v & 0xFF) + +struct apr_device { + struct device dev; + uint16_t svc_id; + uint16_t domain_id; + uint32_t version; + spinlock_t lock; + struct list_head node; +}; + +#define to_apr_device(d) container_of(d, struct apr_device, dev) + +struct apr_driver { + int (*probe)(struct apr_device *sl); + int (*remove)(struct apr_device *sl); + int (*callback)(struct apr_device *a, + struct apr_client_message *d); + struct device_driver driver; + const struct apr_device_id *id_table; +}; + +#define to_apr_driver(d) container_of(d, struct apr_driver, driver) + +/* + * use a macro to avoid include chaining to get THIS_MODULE + */ +#define apr_driver_register(drv) __apr_driver_register(drv, THIS_MODULE) + +int __apr_driver_register(struct apr_driver *drv, struct module *owner); +void apr_driver_unregister(struct apr_driver *drv); + +/** + * module_apr_driver() - Helper macro for registering a aprbus driver + * @__aprbus_driver: aprbus_driver struct + * + * Helper macro for aprbus drivers which do not do anything special in + * module init/exit. This eliminates a lot of boilerplate. Each module + * may only use this macro once, and calling it replaces module_init() + * and module_exit() + */ +#define module_apr_driver(__apr_driver) \ + module_driver(__apr_driver, apr_driver_register, \ + apr_driver_unregister) + +int apr_send_pkt(struct apr_device *adev, void *buf); + +#endif /* __QCOM_APR_H_ */ From patchwork Sat Mar 10 02:24:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131265 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1690636lja; Fri, 9 Mar 2018 18:28:26 -0800 (PST) X-Google-Smtp-Source: AG47ELvYpdV6pP9VC5J1cAL8YLNOCdWQS4nSg2F6PUgow3Fbpp9vdxma6vTdSooeME5xMJ42S9co X-Received: by 10.28.190.18 with SMTP id o18mr72986wmf.86.1520648906097; Fri, 09 Mar 2018 18:28:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648906; cv=none; d=google.com; s=arc-20160816; b=x7RO5dU8YkRc4oXLr4O5hvgW5NzB5wwRMiC2yIz0Yd9csEwjxey0/HPzjbhbgLCYLx O1bHu39zTkJuV9Eik6TDF/Y55v1DWfK2tuvGtWzPSZS6VHhHw05blOSseU8F5VwRM4QH 7mLp3RI7hYLdhq5zXKNrSl7MoBFM5jpC7yrYInAVXqj+GDrA9GvpJQO8PwnjstKmObQV qJ+OdQytlMkUTGFpfCGuLjpgeLXB/0XSuazhcv7IjWkb3AqrbDmn4JmSWKHyYSYjV2lF sQjwKRnWetyN/ZkHJFTUfl9O9GZ24VVjaKOKESLX/52ma7qtpEipcaNmLT+jYCkLcFMK 4n0A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=yR0ih/kqTFVZ005AMN0TYdW86ENPiIK2krfTMrMTCoA=; b=kGq3RuMmxM7eq9E1tzdjIP69ET4CDJZ+kJM9XbYIUfWX9mEVaoa0j5I2RPYUPUm7MD TnrUeYWp4j/9dhzFgY8n+jgGTjX8+BIOx2gRr/Ay4x9KrJX0i/lAFs2jGWaAm7siRFkx RvSTkXlYf8HC9UN4miKuU6+aGZ0bnohEi+fxdiHorLv/nmDmwer4Wl9Cb8r8VsZDeC7d WbGN1tHNbQVLk4x0NN+qGn5VW4iO/yowoXiFfT5xVQB6ky1CQuVsvtHyg8+x0G69z15j HdlhJn/EFTHqoQRQr/BS4RhuNXSvd5We0+pcaZqP0zxYcqQ9B5D0xCzlMMQnldzPhv7w Tl0A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=TQ/YSvEj; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id o123si51947wmd.41.2018.03.09.18.28.25; Fri, 09 Mar 2018 18:28:26 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=TQ/YSvEj; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 46349267671; Sat, 10 Mar 2018 03:28:02 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 227A0267661; Sat, 10 Mar 2018 03:27:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wr0-f196.google.com (mail-wr0-f196.google.com [209.85.128.196]) by alsa0.perex.cz (Postfix) with ESMTP id 8387E2675EE for ; Sat, 10 Mar 2018 03:27:46 +0100 (CET) Received: by mail-wr0-f196.google.com with SMTP id h2so3395330wre.12 for ; Fri, 09 Mar 2018 18:27:46 -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=wBeB8vX6L3AY/WzQ4cZv+e9QJKsD/Nw83cRKht3kMCg=; b=TQ/YSvEj1uJ6QKRqEuk+DlafcOMJhO4blbz11dvevAYI5lCvQQOckWyPlJ2Z4HgVKn lYt1/mq7D809zY047SC7cZDsQRnhPEXc3Vu//hJUuSu3XzQvXET+bE11so9biYhzWhO6 PvEauE7x5lUYtm7Y7siXpQJyf6IZXJavZYKZw= 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=wBeB8vX6L3AY/WzQ4cZv+e9QJKsD/Nw83cRKht3kMCg=; b=atgAcNzBXQnvp94silqPuMsqgjwZCURMpS0ZFMDjt4YL3kz2MEDHbKPEDRpD4I2XFn 4rnUL27c+PB576otteSDdAyeebnCS6yMy1wYI6Mp3xjQxKFUTGRIeelEHy8u9m3hcoHc vgyVUM7uVGI0zIA3PIzkLYrChxowKHoG27/xPKm75aSh3LdG5boZiFlKyYLc3LNPdhJ9 +CBTUcGSuy1QLNcg+FuFMIUUG45PptToGMrgD85+t2WgmkpzIYjW+U1oT+VKQQLx4DEY hhCfaSAj9JfbwIE3D2HYO8qT2SwBJREN62DLC6TEfzOEoE5kCB2gFcfAU8IQf4u/rXOM cbxg== X-Gm-Message-State: AElRT7FxU4c5AaTcuwZ1fw9TOMBj/9JfypKwHEr0sVG/FSIl0NZnhm0z mm81vwXewC/luh3sxrBtojGWyw== X-Received: by 10.223.189.136 with SMTP id l8mr432770wrh.69.1520648866173; Fri, 09 Mar 2018 18:27:46 -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 g78sm21489wmc.31.2018.03.09.18.27.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:45 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:35 +0000 Message-Id: <20180310022456.26739-4-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 03/24] ASoC: qdsp6: q6common: Add qdsp6 helper functions X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.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/Kconfig | 13 ++++++++ sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6dsp-common.c | 66 +++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6dsp-common.h | 24 ++++++++++++++ sound/soc/qcom/qdsp6/q6dsp-errno.h | 51 ++++++++++++++++++++++++++++ 5 files changed, 155 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/Makefile create mode 100644 sound/soc/qcom/qdsp6/q6dsp-common.c create mode 100644 sound/soc/qcom/qdsp6/q6dsp-common.h create mode 100644 sound/soc/qcom/qdsp6/q6dsp-errno.h -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 8ec9a074b38b..8247ade16dbe 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -43,3 +43,16 @@ config SND_SOC_APQ8016_SBC Support for Qualcomm Technologies LPASS audio block in APQ8016 SOC-based systems. Say Y if you want to use audio devices on MI2S. + +config SND_SOC_QDSP6_COMMON + tristate + +config SND_SOC_QDSP6 + tristate "SoC ALSA audio driver for QDSP6" + depends on QCOM_APR && HAS_DMA + select SND_SOC_QDSP6_COMMON + help + To add support for MSM QDSP6 Soc Audio. + This will enable sound soc platform specific + audio drivers. This includes q6asm, q6adm, + q6afe interfaces to DSP using apr. diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile new file mode 100644 index 000000000000..accebdb49306 --- /dev/null +++ b/sound/soc/qcom/qdsp6/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o diff --git a/sound/soc/qcom/qdsp6/q6dsp-common.c b/sound/soc/qcom/qdsp6/q6dsp-common.c new file mode 100644 index 000000000000..c342a073144c --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6dsp-common.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2011-2017, The Linux Foundation +// Copyright (c) 2018, Linaro Limited + +#include "q6dsp-common.h" +#include +#include +#include +#include + +int q6dsp_map_channels(u8 ch_map[PCM_FORMAT_MAX_NUM_CHANNEL], int ch) +{ + memset(ch_map, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + switch (ch) { + case 1: + ch_map[0] = PCM_CHANNEL_FC; + break; + case 2: + ch_map[0] = PCM_CHANNEL_FL; + ch_map[1] = PCM_CHANNEL_FR; + break; + case 3: + ch_map[0] = PCM_CHANNEL_FL; + ch_map[1] = PCM_CHANNEL_FR; + ch_map[2] = PCM_CHANNEL_FC; + break; + case 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; + break; + case 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; + break; + case 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; + break; + case 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; + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(q6dsp_map_channels); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/qcom/qdsp6/q6dsp-common.h b/sound/soc/qcom/qdsp6/q6dsp-common.h new file mode 100644 index 000000000000..32386f4a6432 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6dsp-common.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef __Q6DSP_COMMON_H__ +#define __Q6DSP_COMMON_H__ + +#include + +#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. */ + +int q6dsp_map_channels(u8 ch_map[PCM_FORMAT_MAX_NUM_CHANNEL], int ch); + +#endif /* __Q6DSP_COMMON_H__ */ diff --git a/sound/soc/qcom/qdsp6/q6dsp-errno.h b/sound/soc/qcom/qdsp6/q6dsp-errno.h new file mode 100644 index 000000000000..6285e1782824 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6dsp-errno.h @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef __Q6DSP_ERR_NO_H__ +#define __Q6DSP_ERR_NO_H__ +#include + +/* 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*/ + +#endif /*__Q6DSP_ERR_NO_H__ */ From patchwork Sat Mar 10 02:24:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131266 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1690855lja; Fri, 9 Mar 2018 18:28:43 -0800 (PST) X-Google-Smtp-Source: AG47ELubUZXvAYE9kZ81Zfo8JUqNYVCjUy1xMjfdnKbQFyMxtLnDGdeFsmo/3x5/0VCt+wycpBP/ X-Received: by 10.223.150.194 with SMTP id u60mr385805wrb.47.1520648923883; Fri, 09 Mar 2018 18:28:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648923; cv=none; d=google.com; s=arc-20160816; b=sn/qPXwd1GYqRZi0L38nRwzCnVOz9W5ANeLxHzCjN/MLLGT5Cj3MC/Q7djq3A+C8/5 vbMni21a4FC6BDv9ALKpSlJbS/w/ylYWYMiQS5KLN4HsKCxfp7YjuunwF7fxmJN4Ic2e XN/YR7Zq0AwznlMSlMGf3f9+iSZ0K2tnu1kID/yvctygiu20XyGdznXU0mgih9aDGczo 9NfcO7By4+oqwPP3WkciHcH7yKt1RkmshG4kLW3j6KYV0psH6s1uVOlPYLuPKs3UKbfH SUmaJEvsjFnTppIEKTV2uftVbxdBLbnxBBaEcXwxI/nRDya7EBpJwG+3rgj8jaShKMok siLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=Z1L2zxubE5rXCN8fRYk+UxmLW7LjXPvBidAnJEVFa+M=; b=VZKjgixKK5Bm4KSndZoibnpxlXKz0Ue26xmPTTUrT4cko2IxNKPC3SOciQVzYPT6R2 O3Dpcph9XQo4u3nr95P75umCk0v2bPtfs9AgU6k+9q5hp0MRz/f0bIQPyZ825efd0trA g1z4x998XsQaS7GoSs5AwxBEa01TThTRUrqXBgYFWBs4iBqEZSGLS3WZJuik+po61tR1 3ze8OQKrZeM0NMf52YSbGHF0zHYG1cZiZ7XK3b68zJVEQlApsN7GdGzB1cCFFjdi8SPf aECxsfbvV4Up6igPgr1N3ZxvmEb1wvyCC5zM2aNsmQlTzZh7uGebqtMA6G0QwLxRVnjM uc8g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=e2RuYP9c; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id u62si53323wma.100.2018.03.09.18.28.43; Fri, 09 Mar 2018 18:28:43 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=e2RuYP9c; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 20688267669; Sat, 10 Mar 2018 03:28:09 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 8E596267661; Sat, 10 Mar 2018 03:27:51 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by alsa0.perex.cz (Postfix) with ESMTP id 6BF9D267657 for ; Sat, 10 Mar 2018 03:27:49 +0100 (CET) Received: by mail-wm0-f67.google.com with SMTP id z81so7040818wmb.4 for ; Fri, 09 Mar 2018 18:27:49 -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=WlxlyTkOLwLXRt8sB2I1xqKKd2j4V9/sY8qBIz9W4yU=; b=e2RuYP9cfIS/JPtknxrrX5rxfNq5uT89m799QFW0/oz6YYu8ZIdjTmV1aj418TN02v n86ns2yxH0bohgfsHUcNT4cl7ymgjF4XJq0Sj4rkkjKh2mk7a2uPIHBn/dIAxfW5JZ+2 Bg8PRWr2RYyGzjj77dhCdMf/9OJ2BDWBjZhPA= 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=WlxlyTkOLwLXRt8sB2I1xqKKd2j4V9/sY8qBIz9W4yU=; b=g29hS9lRlLXHXSPphIJKyA2FV7Fxvpp2cjedNVB4sKI+GaL5wA8zrf5se4iYt5ZL4I IENBxxyzv9pXKSM6zdpvNgFQBwQlAzJ1Sz7dBHi8IdbHWoLAWAENwOKsupegYugFjUP/ mf1iI+fnxl8cb/D+jZziShNym3zDDFHYdR0pOMYUW9/2f5Bhl9hWAJAL4J9p+IwxrkYC xYf85wDU9NQDSSSi/QusOXXI+64pX1Kl6x496SAH26y9GpC30WqjSrivZVGIgCB0WUWf QtL9vSvwtxe9QWFKqh05QNcM92lBE6cPqoUp56Wsf2BdXrpef9/psGsc7aiM1rYIXQFJ JqCA== X-Gm-Message-State: AElRT7HZMAIjGcnufiU9hahL93UqEltiD3n1zUjLbZb8yQyHNknHRoi/ P2scSwXTyw7Gbv9gA9pqtSbmbA== X-Received: by 10.28.160.9 with SMTP id j9mr53717wme.103.1520648868689; Fri, 09 Mar 2018 18:27:48 -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 g78sm21489wmc.31.2018.03.09.18.27.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:48 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:37 +0000 Message-Id: <20180310022456.26739-6-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 05/24] ASoC: qdsp6: dt-bindings: Add q6adm dt bindings X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org From: Srinivas Kandagatla This patch add DT bindings for ADM (Audio Device Manager) DSP module. This module implements mixer controls to setup the connections between AFE ports and ASM streams. Signed-off-by: Srinivas Kandagatla --- .../devicetree/bindings/sound/qcom,q6adm.txt | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,q6adm.txt -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/Documentation/devicetree/bindings/sound/qcom,q6adm.txt b/Documentation/devicetree/bindings/sound/qcom,q6adm.txt new file mode 100644 index 000000000000..ddd93c80bd8a --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,q6adm.txt @@ -0,0 +1,34 @@ +Qualcomm Audio Device Manager (Q6ADM) binding + +Q6ADM is one of the APR audio service on Q6DSP. +Please refer to qcom,apr.txt for details of the coommon apr service bindings +used by the apr service device. + +- but must contain the following property: + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,adm-v.". + Or "qcom,adm" where the version number can be queried + from DSP. + example "qcom,adm-v2.0" + + += ADM routing +"routing" subnode of the ADM node represents adm routing specific configuration + +- #sound-dai-cells + Usage: required + Value type: + Definition: Must be 0 + += EXAMPLE +q6adm: q6adm { + compatible = "qcom,q6adm"; + qcom,apr-svc-name = "ADM"; + qcom,apr-svc-id = ; + q6routing: routing { + #sound-dai-cells = <0>; + }; +}; From patchwork Sat Mar 10 02:24:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131270 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1691078lja; Fri, 9 Mar 2018 18:29:03 -0800 (PST) X-Google-Smtp-Source: AG47ELs7oCqdKy64StVu8qH7IlANQ7gJcRmmJugCRQ/C9ywm+KbFj45TxqlbfGnIvcAT9sMjA/KP X-Received: by 10.223.138.203 with SMTP id z11mr381754wrz.199.1520648943368; Fri, 09 Mar 2018 18:29:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648943; cv=none; d=google.com; s=arc-20160816; b=zLeGnOk1n7UWCE7V4qHxWlQDtInkev29bnS04HZLco7yd8hH8+sJ+mFU5YI7jQ2LLS kFutDIvKRxJMLoSUJcZkK459LqRyrd0KfEYQ6qSH4n+S+yI58QWiS7aroLDd/auY3xt7 zGH1UnWCfbNXbcdrW4sI6NzNVuW/KzJJ1NputukyzkCdqWaUQp9Kd/xPZ5XvmCS0qt51 TbSJem3YEMGltuvApDwXoUAXXXWvWiiCK1j0q9lnyL1E+ouhjpi5nnIoGGlcrFC807xW SW8cPZ4N4ZRe8S2Hk0DUV09zgw4JHTKwwTc1qHJv3qvx8sfPCpZMAwyOjShNz7IlESkj 7MRQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=nVHXn9F0yIPHaYeoxa2eLG436tcEVAt2kVFUqmHrx6U=; b=vHSXnkXJe+O+9bGN+2ZOPf0ZKj/EwzkX+sru9wvBXcx1qkWwNZ70+Xrs7/QRVgUXYJ eQmwebrs9FgHkErvLE1Jwr+JRaQuK7VWH8FynqR0+RkvuxrfeQA8ppuZXpV5pwTZGjbV rtMYSLdVsJbUxeu/VieoPRidT6wQThtA8dukmXSug6gg2kvJ4zHoj5j/Z/FX9xv9x3y1 rtKE2YfuCoGoO/vioX9XNSt427PXMEKl1AFN5jcszZZAD5treqAi3+pCujB4R8l/jcFS WlVHHtzk2f9LksAjdzl4DtlwR01X0LF6lqDPVakBNyVaBMBkzrR9PBDZk1Wnn5ilaoXm 9+2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=h8lWMzSG; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id 33si1743448wrd.199.2018.03.09.18.29.03; Fri, 09 Mar 2018 18:29:03 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=h8lWMzSG; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 512FE2676B0; Sat, 10 Mar 2018 03:28:15 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 00DA726766C; Sat, 10 Mar 2018 03:27:54 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by alsa0.perex.cz (Postfix) with ESMTP id 6C3AA267666 for ; Sat, 10 Mar 2018 03:27:50 +0100 (CET) Received: by mail-wm0-f68.google.com with SMTP id t6so6971467wmt.5 for ; Fri, 09 Mar 2018 18:27:50 -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=5RoroAqka1QiRkDT0H3/wN8yePmLtx+aMNSdBlanLuo=; b=h8lWMzSGhaYPymeam4moGtHBZQp/1t91PoZabP7HhBHNpUlP4ViackL67llme/p2dM mOH18782YGT+zGNcHR6607MpE8aijD/kMYLl9D3Up7WDSXAGX2qY15w4E7nEqatI1K+a KpVPpUzQFj1+h7fD1Wf4JcjmbgByixkAPtlXg= 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=5RoroAqka1QiRkDT0H3/wN8yePmLtx+aMNSdBlanLuo=; b=VZXMsjyIxZ9X6UytVe9T6MmdyYqJfLorlOkWFwv+7lTmrMMLepZbFlx9a9gJftgUWO fjGc+0EpAX86lv/jZZ4zAKEGc3MzAZF9vALlcllX6HF/9CslU2r1dVq7/Vt9t13VLQhK Dcz2XCQWXmeRXkR+tqHukeyY7ojMezrLic17I0uGlP8ad2oKhgfQzoppv+SJFNORLLUw yRQzR+sxQmYuplinFWaWb8ox9BylQ9jxkQIXaHeQijetku3knsRox9rzsJ8Mh1eF3Plj jzyNQWabRnl2EvKlvN6VoyydHN6V7MMyubYBMyoSOCG3anhb4rOkJq9KS7jMbpYZwphf Bcdw== X-Gm-Message-State: AElRT7E2HUYs8nXAppA56yOdAYC+jQceXEGzyycOCbi+GZQq4JAd9QYh hHbL5N/mSEQ+Xc0y0wfgEeM12w== X-Received: by 10.28.62.16 with SMTP id l16mr77377wma.54.1520648869814; Fri, 09 Mar 2018 18:27:49 -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 g78sm21489wmc.31.2018.03.09.18.27.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:49 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:38 +0000 Message-Id: <20180310022456.26739-7-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 06/24] ASoC: qdsp6: dt-bindings: Add q6asm dt bindings X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org From: Srinivas Kandagatla This patch add DT bindings for ASM (Audio Stream Manager) DSP module. Signed-off-by: Srinivas Kandagatla --- .../devicetree/bindings/sound/qcom,q6asm.txt | 34 ++++++++++++++++++++++ include/dt-bindings/sound/qcom,q6asm.h | 22 ++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,q6asm.txt create mode 100644 include/dt-bindings/sound/qcom,q6asm.h -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/Documentation/devicetree/bindings/sound/qcom,q6asm.txt b/Documentation/devicetree/bindings/sound/qcom,q6asm.txt new file mode 100644 index 000000000000..84703747db3c --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,q6asm.txt @@ -0,0 +1,34 @@ +Qualcomm Audio Stream Manager (Q6ASM) binding + +Q6ASM is one of the APR audio service on Q6DSP. +Please refer to qcom,apr.txt for details of the coommon apr service bindings +used by the apr service device. + +- but must contain the following property: + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,asm-v.". + Or "qcom,asm" where the version number can be queried + from DSP. + example "qcom,asm-v2.0" + += ASM DAIs (Digial Audio Interface) +"dais" subnode of the ASM node represents dai specific configuration + +- #sound-dai-cells + Usage: required + Value type: + Definition: Must be 1 + += EXAMPLE + +q6asm: q6asm { + compatible = "qcom,q6asm"; + qcom,apr-svc-name = "ASM"; + qcom,apr-svc-id = ; + q6asmdai: dais { + #sound-dai-cells = <1>; + }; +}; diff --git a/include/dt-bindings/sound/qcom,q6asm.h b/include/dt-bindings/sound/qcom,q6asm.h new file mode 100644 index 000000000000..2e11b15d930d --- /dev/null +++ b/include/dt-bindings/sound/qcom,q6asm.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __DT_BINDINGS_Q6_ASM_H__ +#define __DT_BINDINGS_Q6_ASM_H__ + +#define MSM_FRONTEND_DAI_MULTIMEDIA1 0 +#define MSM_FRONTEND_DAI_MULTIMEDIA2 1 +#define MSM_FRONTEND_DAI_MULTIMEDIA3 2 +#define MSM_FRONTEND_DAI_MULTIMEDIA4 3 +#define MSM_FRONTEND_DAI_MULTIMEDIA5 4 +#define MSM_FRONTEND_DAI_MULTIMEDIA6 5 +#define MSM_FRONTEND_DAI_MULTIMEDIA7 6 +#define MSM_FRONTEND_DAI_MULTIMEDIA8 7 +#define MSM_FRONTEND_DAI_MULTIMEDIA9 8 +#define MSM_FRONTEND_DAI_MULTIMEDIA10 9 +#define MSM_FRONTEND_DAI_MULTIMEDIA11 10 +#define MSM_FRONTEND_DAI_MULTIMEDIA12 11 +#define MSM_FRONTEND_DAI_MULTIMEDIA13 12 +#define MSM_FRONTEND_DAI_MULTIMEDIA14 13 +#define MSM_FRONTEND_DAI_MULTIMEDIA15 14 +#define MSM_FRONTEND_DAI_MULTIMEDIA16 15 + +#endif /* __DT_BINDINGS_Q6_ASM_H__ */ From patchwork Sat Mar 10 02:24:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131269 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1690973lja; Fri, 9 Mar 2018 18:28:53 -0800 (PST) X-Google-Smtp-Source: AG47ELv2WhIJ3EqsF4hyvWygEGrblrbgXZe/Q7yBM+bzdqKb6rXqPIj9IAE5fA2L+ragKD0w35fX X-Received: by 10.223.164.215 with SMTP id h23mr416591wrb.38.1520648933065; Fri, 09 Mar 2018 18:28:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648933; cv=none; d=google.com; s=arc-20160816; b=PVZg1ZcDrvARqbdgGwR4hfH8LxJIMvl79ioJW9S3scBzfrK5PJDJHQYye+ELVHwgxL JazauIK9Nk6R0rET3RKeqQZPZyTDVXsRvZP9hSPprCRER83RnS3OZiOeoWBaWIXO5HM6 NsEwF+Q9kxQ8Zu8nTy5Ar0nUCmCfQEIM7YSX8+POBOCOzy9LlcLUqBkmLXusP7Y1Vz6C fcWSWVqAHPmyz8gN2B0xMNO6PBbTq0BZWT5mt4j1JygdThUoRMZWoNuA56KHw2a4mOEf SxEEoahD1dw5wYu1XHcvTEaDUhAcGR3QDhv/UFRXracDaz816Qta5wuL+dl+DQFUtMBA o4Cw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=OL/Aw90z+o0v2gipZzhLuEADAQv5FsKdEc9ZREVwLM4=; b=o7b5XcZzqSsbyQlkEtQ9JNawJCfd5Ls2sa15YN//jugTVyE+bF9To+Uk8Ge46FXKXO 2Y3QmgeChZTGTX2QmhpPvpsVHxaUX+M+gJqZwcdFnkIBKc3dZuyP1W7ddso2qlbtdk8P uzYW5PlY1ZHX1BLcWZUTZ+iCZd0iIbCLR61ltDBWPhWeWIgiozd5ScN+l/thTI89JsJ2 CTWIgz2VzMkW81o8GnO/VRbqSe33UNn5kdepsoL93vDEMmyoeEwj0KVP2v51yazvTq4X CyLZsDhOG6Nx2shCwP9Pfu8ijufjisGdy1upVkjiAKY4MQMzG+VpYRPneY97HjgG6Cwh ve9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=kwttTca6; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id p4si40451wmh.161.2018.03.09.18.28.52; Fri, 09 Mar 2018 18:28:53 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=kwttTca6; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id B01D326765C; Sat, 10 Mar 2018 03:28:11 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 3AFDD267669; Sat, 10 Mar 2018 03:27:54 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by alsa0.perex.cz (Postfix) with ESMTP id A87C726765E for ; Sat, 10 Mar 2018 03:27:51 +0100 (CET) Received: by mail-wm0-f67.google.com with SMTP id i3so6942807wmi.4 for ; Fri, 09 Mar 2018 18:27:51 -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=oziATVKecjbYAMw+g8nSqtbVNQIBytAYKwPySeHdBA4=; b=kwttTca6q3D815tlV6zKyv1qvFaQ+27zCmCnKvTf4xhkaO41RBjifON4lsyugxHhfY /wLmbrIJ8BXacslMCQ5uEwZ+ylCxV5myM1e+ucgeu/KH2TYlBuUZXnD++QzqJOPuhZ14 bQMU0cKwOtptRRm57TAgUQ4/FBYgsPjdwKngo= 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=oziATVKecjbYAMw+g8nSqtbVNQIBytAYKwPySeHdBA4=; b=AlAO7oAfJva9lFncy+OmkuBXq5Z/ynJXotpjC5uXyYKaTRQPkJBsvfxQeLFp9JuBJc yigrSkLJ5GNcV+M54SqiMeyjRqckUjppLi34bx2qA8w7ncVXtYXefnN2IP8qRVOZJ2QN KYAka15k4BQojKuQckADMjrMZkXpHAJhcuFJAlsbFgvdgSKzrvj0aXgyQJHAsVphqnEE oIr2gc+L+Kmyo4QFk9FCh6+FnvJGhR54o5s6KDmuWID/2prg3QKWHPqbvStUGYZsngjd BppuXfF+Iqx/qq/rlYpnngu/TjD4qVkzQHjy5ckpejNWxHkOLjeyNNXQpJ95R48NfNnn r53g== X-Gm-Message-State: AElRT7HPPvR9Y7e+dhRt7aw2CBUyBzF9EB/K0XlrH6SocbqbFa0BfboH ovZ2Ai+16GyoOd8Z2qdQ6MVmMw== X-Received: by 10.28.92.208 with SMTP id q199mr54252wmb.91.1520648871092; Fri, 09 Mar 2018 18:27:51 -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 g78sm21489wmc.31.2018.03.09.18.27.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:50 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:39 +0000 Message-Id: <20180310022456.26739-8-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 07/24] ASoC: qdsp6: q6afe: Add q6afe driver X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org From: Srinivas Kandagatla This patch adds support to Q6AFE (Audio Front End) module on Q6DSP. AFE module sits right at the other end of cpu where the codec/audio devices are connected. AFE provides abstraced interfaces to both hardware and virtual devices. Each AFE tx/rx port can be configured to connect to one of the hardware devices like codec, hdmi, slimbus, i2s and so on. AFE services include starting, stopping, and if needed, any configurations of the ports. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/Kconfig | 4 + sound/soc/qcom/Makefile | 3 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6afe.c | 503 ++++++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6afe.h | 35 +++ 5 files changed, 546 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6afe.c create mode 100644 sound/soc/qcom/qdsp6/q6afe.h -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 8247ade16dbe..f50c76d712c0 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -47,10 +47,14 @@ config SND_SOC_APQ8016_SBC config SND_SOC_QDSP6_COMMON tristate +config SND_SOC_QDSP6_AFE + tristate + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" depends on QCOM_APR && HAS_DMA select SND_SOC_QDSP6_COMMON + select SND_SOC_QDSP6_AFE help To add support for MSM QDSP6 Soc Audio. This will enable sound soc platform specific diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile index d5280355c24f..0276717917c0 100644 --- a/sound/soc/qcom/Makefile +++ b/sound/soc/qcom/Makefile @@ -16,3 +16,6 @@ snd-soc-apq8016-sbc-objs := apq8016_sbc.o obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o + +#DSP lib +obj-$(CONFIG_SND_SOC_QDSP6) += qdsp6/ diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile index accebdb49306..9ec951e0833b 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o +obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c new file mode 100644 index 000000000000..fd76f7296f36 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -0,0 +1,503 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2011-2017, The Linux Foundation +// Copyright (c) 2018, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6dsp-errno.h" +#include "q6core.h" +#include "q6afe.h" + +/* AFE CMDs */ +#define AFE_PORT_CMD_DEVICE_START 0x000100E5 +#define AFE_PORT_CMD_DEVICE_STOP 0x000100E6 +#define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF +#define AFE_PORT_CMDRSP_GET_PARAM_V2 0x00010106 +#define AFE_PARAM_ID_HDMI_CONFIG 0x00010210 +#define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C + +/* Port IDs */ +#define AFE_API_VERSION_HDMI_CONFIG 0x1 +#define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E +#define TIMEOUT_MS 1000 +#define AFE_CMD_RESP_AVAIL 0 +#define AFE_CMD_RESP_NONE 1 + +struct q6afe { + struct apr_device *apr; + struct device *dev; + struct q6core_svc_api_info ainfo; + struct mutex lock; + struct list_head port_list; + spinlock_t port_list_lock; + struct list_head node; + struct platform_device *pdev_dais; +}; + +struct afe_port_cmd_device_start { + struct apr_hdr hdr; + u16 port_id; + u16 reserved; +} __packed; + +struct afe_port_cmd_device_stop { + struct apr_hdr hdr; + u16 port_id; + u16 reserved; +/* Reserved for 32-bit alignment. This field must be set to 0.*/ +} __packed; + +struct afe_port_param_data_v2 { + u32 module_id; + u32 param_id; + u16 param_size; + u16 reserved; +} __packed; + +struct afe_port_cmd_set_param_v2 { + u16 port_id; + u16 payload_size; + u32 payload_address_lsw; + u32 payload_address_msw; + u32 mem_map_handle; +} __packed; + +struct afe_param_id_hdmi_multi_chan_audio_cfg { + u32 hdmi_cfg_minor_version; + u16 datatype; + u16 channel_allocation; + u32 sample_rate; + u16 bit_width; + u16 reserved; +} __packed; + +union afe_port_config { + struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch; +} __packed; + +struct q6afe_port { + wait_queue_head_t wait; + union afe_port_config port_cfg; + int token; + int id; + int cfg_type; + struct q6afe *afe; + struct list_head node; +}; + +struct afe_audioif_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + union afe_port_config pcfg; +} __packed; + +struct afe_port_map { + int port_id; + int token; + int is_rx; + int is_dig_pcm; +}; + +/** + * Mapping between Virtual Port IDs to DSP AFE Port ID + * On B Family SoCs DSP Port IDs are consistent across multiple SoCs + * on A Family SoCs DSP port IDs are same as virtual Port IDs. + **/ + +static struct afe_port_map port_maps[AFE_PORT_MAX] = { + [HDMI_RX] = { AFE_PORT_ID_MULTICHAN_HDMI_RX, HDMI_RX, 1, 1}, +}; + +static struct q6afe_port *afe_find_port(struct q6afe *afe, int token) +{ + struct q6afe_port *p = NULL; + unsigned long flags; + + spin_lock_irqsave(&afe->port_list_lock, flags); + list_for_each_entry(p, &afe->port_list, node) + if (p->token == token) + break; + + spin_unlock_irqrestore(&afe->port_list_lock, flags); + return p; +} + +static int q6afe_callback(struct apr_device *adev, + struct apr_client_message *data) +{ + struct q6afe *afe = dev_get_drvdata(&adev->dev); + struct aprv2_ibasic_rsp_result_t *res; + struct q6afe_port *port; + + if (!data->payload_size) + return 0; + + res = data->payload; + switch (data->opcode) { + case APR_BASIC_RSP_RESULT: { + if (res->status) { + dev_err(afe->dev, "cmd = 0x%x returned error = 0x%x\n", + res->opcode, res->status); + } + switch (res->opcode) { + case AFE_PORT_CMD_SET_PARAM_V2: + case AFE_PORT_CMD_DEVICE_STOP: + case AFE_PORT_CMD_DEVICE_START: + port = afe_find_port(afe, data->token); + if (port) { + port->result = *res; + wake_up(&port->wait); + } + break; + default: + dev_err(afe->dev, "Unknown cmd 0x%x\n", res->opcode); + break; + } + } + break; + default: + break; + } + + return 0; +} + +/** + * q6afe_get_port_id() - Get port id from a given port index + * + * @index: port index + * + * Return: Will be an negative on error or valid port_id on success + */ +int q6afe_get_port_id(int index) +{ + if (index < 0 || index > AFE_PORT_MAX) + return -EINVAL; + + return port_maps[index].port_id; +} +EXPORT_SYMBOL_GPL(q6afe_get_port_id); + +static int afe_apr_send_pkt(struct q6afe *afe, void *data, + struct q6afe_port *port) +{ + wait_queue_head_t *wait = &port->wait; + struct apr_hdr *hdr = data; + int ret; + + mutex_lock(&afe->lock); + port->result.opcode = 0; + port->result.status = 0; + + ret = apr_send_pkt(afe->apr, data); + if (ret < 0) { + dev_err(afe->dev, "packet not transmitted (%d)\n", ret); + ret = -EINVAL; + goto err; + } + + ret = wait_event_timeout(*wait, (port->result.opcode == hdr->opcode), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + ret = -ETIMEDOUT; + } else if (port->result.status > 0) { + dev_err(afe->dev, "DSP returned error[%x]\n", + port->result.status); + ret = -EINVAL; + } else { + ret = 0; + } + +err: + mutex_unlock(&afe->lock); + + return ret; +} + +static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data, + int param_id, int psize) +{ + struct apr_hdr *hdr; + struct afe_port_cmd_set_param_v2 *param; + struct afe_port_param_data_v2 *pdata; + struct q6afe *afe = port->afe; + u16 port_id = port->id; + int ret; + + hdr = data; + param = data + sizeof(*hdr); + pdata = data + sizeof(*hdr) + sizeof(*param); + + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + hdr->pkt_size = sizeof(*hdr) + sizeof(*param) + + sizeof(*pdata) + psize; + hdr->src_port = 0; + hdr->dest_port = 0; + hdr->token = port->token; + hdr->opcode = AFE_PORT_CMD_SET_PARAM_V2; + param->port_id = port_id; + param->payload_size = sizeof(*pdata) + psize; + param->payload_address_lsw = 0x00; + param->payload_address_msw = 0x00; + param->mem_map_handle = 0x00; + pdata->module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + pdata->param_id = param_id; + pdata->param_size = psize; + + ret = afe_apr_send_pkt(afe, data, port); + if (ret) + dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", + port_id, ret); + + + return ret; +} + +/** + * q6afe_port_stop() - Stop a afe port + * + * @port: Instance of port to stop + * + * Return: Will be an negative on packet size on success. + */ +int q6afe_port_stop(struct q6afe_port *port) +{ + int port_id = port->id; + struct afe_port_cmd_device_stop stop; + struct q6afe *afe = port->afe; + int ret = 0; + int index; + + port_id = port->id; + index = port->token; + if (index < 0 || index > AFE_PORT_MAX) { + dev_err(afe->dev, "AFE port index[%d] invalid!\n", index); + return -EINVAL; + } + + stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + stop.hdr.pkt_size = sizeof(stop); + stop.hdr.src_port = 0; + stop.hdr.dest_port = 0; + stop.hdr.token = index; + stop.hdr.opcode = AFE_PORT_CMD_DEVICE_STOP; + stop.port_id = port_id; + stop.reserved = 0; + + ret = afe_apr_send_pkt(afe, &stop, port); + if (ret) + dev_err(afe->dev, "AFE close failed %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(q6afe_port_stop); + +/** + * q6afe_hdmi_port_prepare() - Prepare hdmi afe port. + * + * @port: Instance of afe port + * @cfg: HDMI configuration for the afe port + * + */ +void q6afe_hdmi_port_prepare(struct q6afe_port *port, + struct q6afe_hdmi_cfg *cfg) +{ + union afe_port_config *pcfg = &port->port_cfg; + + pcfg->hdmi_multi_ch.hdmi_cfg_minor_version = + AFE_API_VERSION_HDMI_CONFIG; + pcfg->hdmi_multi_ch.datatype = cfg->datatype; + pcfg->hdmi_multi_ch.channel_allocation = cfg->channel_allocation; + pcfg->hdmi_multi_ch.sample_rate = cfg->sample_rate; + pcfg->hdmi_multi_ch.bit_width = cfg->bit_width; +} +EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare); + +/** + * q6afe_port_start() - Start a afe port + * + * @port: Instance of port to start + * + * Return: Will be an negative on packet size on success. + */ +int q6afe_port_start(struct q6afe_port *port) +{ + struct afe_audioif_config_command config = {0,}; + struct afe_port_cmd_device_start start; + struct q6afe *afe = port->afe; + int port_id = port->id; + int ret, param_id = port->cfg_type; + + config.pcfg = port->port_cfg; + + ret = q6afe_port_set_param_v2(port, &config, param_id, + sizeof(config.pcfg)); + if (ret) { + dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", + port_id, ret); + return ret; + } + + start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + start.hdr.pkt_size = sizeof(start); + start.hdr.src_port = 0; + start.hdr.dest_port = 0; + start.hdr.token = port->token; + start.hdr.opcode = AFE_PORT_CMD_DEVICE_START; + start.port_id = port_id; + + ret = afe_apr_send_pkt(afe, &start, port); + if (ret) + dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", + port_id, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(q6afe_port_start); + +/** + * q6afe_port_get_from_id() - Get port instance from a port id + * + * @dev: Pointer to afe child device. + * @id: port id + * + * Return: Will be an error pointer on error or a valid afe port + * on success. + */ +struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id) +{ + int port_id; + struct q6afe *afe = dev_get_drvdata(dev->parent); + struct q6afe_port *port; + unsigned long flags; + int cfg_type; + + if (id < 0 || id > AFE_PORT_MAX) { + dev_err(dev, "AFE port token[%d] invalid!\n", id); + return ERR_PTR(-EINVAL); + } + + port_id = port_maps[id].port_id; + + switch (port_id) { + case AFE_PORT_ID_MULTICHAN_HDMI_RX: + cfg_type = AFE_PARAM_ID_HDMI_CONFIG; + break; + default: + dev_err(dev, "Invalid port id 0x%x\n", port_id); + return ERR_PTR(-EINVAL); + } + + port = kzalloc(sizeof(*port), GFP_KERNEL); + if (!port) + return ERR_PTR(-ENOMEM); + + init_waitqueue_head(&port->wait); + + port->token = id; + port->id = port_id; + port->afe = afe; + port->cfg_type = cfg_type; + + spin_lock_irqsave(&afe->port_list_lock, flags); + list_add_tail(&port->node, &afe->port_list); + spin_unlock_irqrestore(&afe->port_list_lock, flags); + + return port; + +} +EXPORT_SYMBOL_GPL(q6afe_port_get_from_id); + +/** + * q6afe_port_put() - Release port reference + * + * @port: Instance of port to put + */ +void q6afe_port_put(struct q6afe_port *port) +{ + struct q6afe *afe = port->afe; + unsigned long flags; + + spin_lock_irqsave(&afe->port_list_lock, flags); + list_del(&port->node); + spin_unlock_irqrestore(&afe->port_list_lock, flags); + kfree(port); +} +EXPORT_SYMBOL_GPL(q6afe_port_put); + +static int q6afe_probe(struct apr_device *adev) +{ + struct q6afe *afe; + struct device *dev = &adev->dev; + struct device_node *dais_np; + + afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL); + if (!afe) + return -ENOMEM; + + q6core_get_svc_api_info(adev->svc_id, &afe->ainfo); + afe->apr = adev; + mutex_init(&afe->lock); + afe->dev = dev; + INIT_LIST_HEAD(&afe->port_list); + spin_lock_init(&afe->port_list_lock); + + dev_set_drvdata(dev, afe); + + dais_np = of_get_child_by_name(dev->of_node, "dais"); + if (dais_np) { + afe->pdev_dais = of_platform_device_create(dais_np, + "q6afe-dai", dev); + of_node_put(dais_np); + } + + return 0; +} + +static int q6afe_remove(struct apr_device *adev) +{ + struct q6afe *afe = dev_get_drvdata(&adev->dev); + + if (afe->pdev_dais) + of_platform_device_destroy(&afe->pdev_dais->dev, NULL); + + return 0; +} + +static const struct of_device_id q6afe_device_id[] = { + { .compatible = "qcom,q6afe" }, + {}, +}; +MODULE_DEVICE_TABLE(of, q6afe_device_id); + +static struct apr_driver qcom_q6afe_driver = { + .probe = q6afe_probe, + .remove = q6afe_remove, + .callback = q6afe_callback, + .driver = { + .name = "qcom-q6afe", + .of_match_table = of_match_ptr(q6afe_device_id), + + }, +}; + +module_apr_driver(qcom_q6afe_driver); +MODULE_DESCRIPTION("Q6 Audio Front End"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h new file mode 100644 index 000000000000..63250f118df8 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6afe.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef __Q6AFE_H__ +#define __Q6AFE_H__ + +#include + +#define AFE_PORT_MAX 48 + +#define MSM_AFE_PORT_TYPE_RX 0 +#define MSM_AFE_PORT_TYPE_TX 1 +#define AFE_MAX_PORTS AFE_PORT_MAX + +struct q6afe_hdmi_cfg { + u16 datatype; + u16 channel_allocation; + u32 sample_rate; + u16 bit_width; +}; + +struct q6afe_port_config { + struct q6afe_hdmi_cfg hdmi; +}; + +struct q6afe_port; + +struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id); +int q6afe_port_start(struct q6afe_port *port); +int q6afe_port_stop(struct q6afe_port *port); +void q6afe_port_put(struct q6afe_port *port); +int q6afe_get_port_id(int index); +void q6afe_hdmi_port_prepare(struct q6afe_port *port, + struct q6afe_hdmi_cfg *cfg); + +#endif /* __Q6AFE_H__ */ From patchwork Sat Mar 10 02:24:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131271 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1691222lja; Fri, 9 Mar 2018 18:29:15 -0800 (PST) X-Google-Smtp-Source: AG47ELupNrwLkcUorGKnV6NqBDFV+iP+P4wUB+6D+7Hzg9zu1Q6kqZcR/qxr/OSQouKjkV0490Z5 X-Received: by 10.28.62.211 with SMTP id l202mr63717wma.1.1520648955390; Fri, 09 Mar 2018 18:29:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648955; cv=none; d=google.com; s=arc-20160816; b=tMn51Wp+1FyAa9MLRXeoik3XzTSGGt2gRmXXUM0AIjWvBmGhIJEv66noneK/btwtvm Cx+OvIC8PszD2YXboQDZiu70k8yIfZPyzLfJJk5ClLZDWxmYntiM51jyaKs0TltLa00B A903vVAu8TMRLNTGAKocRIw5JaA4tMj5rssXSHkDrczuFS3/5sc7Y0nIMJs+rwgBmwpW EdaK/9cBYTZTUNqVTA1PAcuifhPJQVWAJ7e8b/K6VHnW5/Z1WnKwhdGi7WR4LQoH2DU5 HzYlebCcoNBRaRpo3fGZD6wwk8C9u76kc9T2LKfOkEtTpojpPwMmOWIS/DQD680hDtnf zUDw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=HScQ6kn3Lp0wLBFlO9LDaftjMWPloIKCSZN4a04JZWw=; b=0rEC4O7rQM9a/FssO7uNpBOXRdNGutkhWOkUfS7JJwEISvLSRt1rjM5P0yDhQ5j6Z4 sytEzkMqRvOPvPkSSRrgQHTQc4wKGrLDnGVTSB3tC6/9x2/nWSp0AGttJMc8xiGEepEj WRhwEFbZjHB3/kous+N9MVy+5khQhV4UL1cAkW34+Qh2BIOKFCe3huFf0am0hdD8YUin VfH8GUGbkCz4Rau/i1M/RjgEoHVCEyfAx8B0LkJwKE7aGcT3MavOHrcGm9XEZSOt+13H sDdXXtq1Jxt8bWWK+5dMLD4glTG3xhqx7psnuJ9pX9kuwtTz+CJDJvTR4ja76d78BAZK e0UA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=kAKe2s0h; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id u5si41498wmf.132.2018.03.09.18.29.15; Fri, 09 Mar 2018 18:29:15 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=kAKe2s0h; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 002902676CB; Sat, 10 Mar 2018 03:28:24 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 67667267673; Sat, 10 Mar 2018 03:27:57 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f65.google.com (mail-wm0-f65.google.com [74.125.82.65]) by alsa0.perex.cz (Postfix) with ESMTP id 2983E267661 for ; Sat, 10 Mar 2018 03:27:52 +0100 (CET) Received: by mail-wm0-f65.google.com with SMTP id h21so7054927wmd.1 for ; Fri, 09 Mar 2018 18:27:52 -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=8x1QcY9Ft0PCtXMM9g/h1C3XyDfksCEgIGpneEyd8JU=; b=kAKe2s0h4PkEbxCBCTGKk/dgsUf6kvDJyoemRQbGoft4FMQSaS0iM96yscDmfkJKum W3VqhTN2WtUoC9Vsh4h+rxaWchfi5MJB8T5TGE43jeI6XRHq/M5VVo2x6szfC5scXkhd 74ePgEkSAU9k6Q8Sdczec/3ubE89TjfjHTE9w= 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=8x1QcY9Ft0PCtXMM9g/h1C3XyDfksCEgIGpneEyd8JU=; b=CbTHry4c4lIlVAnFgL+f+686eV86IFNYuD1bRMAF7ZcTWq2mg+t6OBVvpwxTzhGBnb XCfxjeyofFN/5B02uTMhHcGlRf8Qg2jBab3ALxgkcV6HQwNoE6DTTVRIpNjgKrmEkWq+ uqJdBJEd2mkhRFwTxpsnuwlJdIZwHh3gOSDj8R18NxoIBLUckbJulzJrn8LzikP7JACW TwF0IPLCq3xCIYrQHp6CgWcCHz03C49Bpp4BpRABIzcdfa/63inMcNSV2TmbPoIXJi94 zMvk49qQjS/bAetY/F4tav008+slDI/Ex9CH7cxZZBC/af8Y3GFOIR8AmSnzhccn6wU+ DYOg== X-Gm-Message-State: AElRT7Emk8r9vvv8BpqHYAExrVjez0fBdQarOGWBrUZzUIZ94m+kFeUl L/8YSr5wMCOBJqEO29UkBePc4A== X-Received: by 10.28.66.65 with SMTP id p62mr68785wma.8.1520648872357; Fri, 09 Mar 2018 18:27:52 -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 g78sm21489wmc.31.2018.03.09.18.27.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:51 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:40 +0000 Message-Id: <20180310022456.26739-9-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 08/24] ASoC: qdsp6: qdafe: Add SLIMBus port Support X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org From: Srinivas Kandagatla This patch adds support to 6 SLIMBus AFE ports, which are used as backend dais. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/qdsp6/q6afe.c | 129 +++++++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6afe.h | 14 +++++ 2 files changed, 143 insertions(+) -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c index fd76f7296f36..de50ddd9faa4 100644 --- a/sound/soc/qcom/qdsp6/q6afe.c +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -26,9 +26,45 @@ #define AFE_PARAM_ID_HDMI_CONFIG 0x00010210 #define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C +#define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG 0x00010235 + +#define AFE_PARAM_ID_SLIMBUS_CONFIG 0x00010212 + /* Port IDs */ #define AFE_API_VERSION_HDMI_CONFIG 0x1 #define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E + +#define AFE_API_VERSION_SLIMBUS_CONFIG 0x1 + +/* SLIMbus Rx port on channel 0. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX 0x4000 +/* SLIMbus Tx port on channel 0. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX 0x4001 +/* SLIMbus Rx port on channel 1. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX 0x4002 +/* SLIMbus Tx port on channel 1. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX 0x4003 +/* SLIMbus Rx port on channel 2. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX 0x4004 +/* SLIMbus Tx port on channel 2. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX 0x4005 +/* SLIMbus Rx port on channel 3. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX 0x4006 +/* SLIMbus Tx port on channel 3. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX 0x4007 +/* SLIMbus Rx port on channel 4. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX 0x4008 +/* SLIMbus Tx port on channel 4. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX 0x4009 +/* SLIMbus Rx port on channel 5. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX 0x400a +/* SLIMbus Tx port on channel 5. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX 0x400b +/* SLIMbus Rx port on channel 6. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX 0x400c +/* SLIMbus Tx port on channel 6. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX 0x400d + #define TIMEOUT_MS 1000 #define AFE_CMD_RESP_AVAIL 0 #define AFE_CMD_RESP_NONE 1 @@ -81,8 +117,53 @@ struct afe_param_id_hdmi_multi_chan_audio_cfg { u16 reserved; } __packed; +struct afe_param_id_slimbus_cfg { + u32 sb_cfg_minor_version; +/* Minor version used for tracking the version of the SLIMBUS + * configuration interface. + * Supported values: #AFE_API_VERSION_SLIMBUS_CONFIG + */ + + u16 slimbus_dev_id; +/* SLIMbus hardware device ID, which is required to handle + * multiple SLIMbus hardware blocks. + * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2 + */ + u16 bit_width; +/* Bit width of the sample. + * Supported values: 16, 24 + */ + u16 data_format; +/* Data format supported by the SLIMbus hardware. The default is + * 0 (#AFE_SB_DATA_FORMAT_NOT_INDICATED), which indicates the + * hardware does not perform any format conversions before the data + * transfer. + */ + u16 num_channels; +/* Number of channels. + * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT + */ + u8 shared_ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT]; +/* Mapping of shared channel IDs (128 to 255) to which the + * master port is to be connected. + * Shared_channel_mapping[i] represents the shared channel assigned + * for audio channel i in multichannel audio data. + */ + u32 sample_rate; +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_96K + * - #AFE_PORT_SAMPLE_RATE_192K + */ +} __packed; + + union afe_port_config { struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch; + struct afe_param_id_slimbus_cfg slim_cfg; } __packed; struct q6afe_port { @@ -117,6 +198,20 @@ struct afe_port_map { static struct afe_port_map port_maps[AFE_PORT_MAX] = { [HDMI_RX] = { AFE_PORT_ID_MULTICHAN_HDMI_RX, HDMI_RX, 1, 1}, + [SLIMBUS_0_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX, + SLIMBUS_0_RX, 1, 1}, + [SLIMBUS_1_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX, + SLIMBUS_1_RX, 1, 1}, + [SLIMBUS_2_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX, + SLIMBUS_2_RX, 1, 1}, + [SLIMBUS_3_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX, + SLIMBUS_3_RX, 1, 1}, + [SLIMBUS_4_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX, + SLIMBUS_4_RX, 1, 1}, + [SLIMBUS_5_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX, + SLIMBUS_5_RX, 1, 1}, + [SLIMBUS_6_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX, + SLIMBUS_6_RX, 1, 1}, }; static struct q6afe_port *afe_find_port(struct q6afe *afe, int token) @@ -307,6 +402,31 @@ int q6afe_port_stop(struct q6afe_port *port) } EXPORT_SYMBOL_GPL(q6afe_port_stop); +/** + * q6afe_slim_port_prepare() - Prepare slim afe port. + * + * @port: Instance of afe port + * @cfg: SLIM configuration for the afe port + * + */ +void q6afe_slim_port_prepare(struct q6afe_port *port, + struct q6afe_slim_cfg *cfg) +{ + union afe_port_config *pcfg = &port->port_cfg; + + pcfg->slim_cfg.sb_cfg_minor_version = AFE_API_VERSION_SLIMBUS_CONFIG; + pcfg->slim_cfg.sample_rate = cfg->sample_rate; + pcfg->slim_cfg.bit_width = cfg->bit_width; + pcfg->slim_cfg.num_channels = cfg->num_channels; + pcfg->slim_cfg.data_format = cfg->data_format; + pcfg->slim_cfg.shared_ch_mapping[0] = cfg->ch_mapping[0]; + pcfg->slim_cfg.shared_ch_mapping[1] = cfg->ch_mapping[1]; + pcfg->slim_cfg.shared_ch_mapping[2] = cfg->ch_mapping[2]; + pcfg->slim_cfg.shared_ch_mapping[3] = cfg->ch_mapping[3]; + +} +EXPORT_SYMBOL_GPL(q6afe_slim_port_prepare); + /** * q6afe_hdmi_port_prepare() - Prepare hdmi afe port. * @@ -400,6 +520,15 @@ struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id) case AFE_PORT_ID_MULTICHAN_HDMI_RX: cfg_type = AFE_PARAM_ID_HDMI_CONFIG; break; + case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX: + case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX: + case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX: + case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX: + case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX: + case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX: + case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX: + cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG; + break; default: dev_err(dev, "Invalid port id 0x%x\n", port_id); return ERR_PTR(-EINVAL); diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h index 63250f118df8..155d6e47d7ce 100644 --- a/sound/soc/qcom/qdsp6/q6afe.h +++ b/sound/soc/qcom/qdsp6/q6afe.h @@ -11,6 +11,9 @@ #define MSM_AFE_PORT_TYPE_TX 1 #define AFE_MAX_PORTS AFE_PORT_MAX +#define AFE_MAX_CHAN_COUNT 8 +#define AFE_PORT_MAX_AUDIO_CHAN_CNT 0x8 + struct q6afe_hdmi_cfg { u16 datatype; u16 channel_allocation; @@ -18,8 +21,17 @@ struct q6afe_hdmi_cfg { u16 bit_width; }; +struct q6afe_slim_cfg { + u32 sample_rate; + u16 bit_width; + u16 data_format; + u16 num_channels; + u8 ch_mapping[AFE_MAX_CHAN_COUNT]; +}; + struct q6afe_port_config { struct q6afe_hdmi_cfg hdmi; + struct q6afe_slim_cfg slim; }; struct q6afe_port; @@ -31,5 +43,7 @@ void q6afe_port_put(struct q6afe_port *port); int q6afe_get_port_id(int index); void q6afe_hdmi_port_prepare(struct q6afe_port *port, struct q6afe_hdmi_cfg *cfg); +void q6afe_slim_port_prepare(struct q6afe_port *port, + struct q6afe_slim_cfg *cfg); #endif /* __Q6AFE_H__ */ From patchwork Sat Mar 10 02:24:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131272 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1691288lja; Fri, 9 Mar 2018 18:29:23 -0800 (PST) X-Google-Smtp-Source: AG47ELtwC60MtOYPnBJ7oqwjMSUCAv98YmabggKFKXG3EZ+BmE8SPpYDkPPxopTKZ7mn002O/ON4 X-Received: by 10.223.153.45 with SMTP id x42mr391743wrb.124.1520648963663; Fri, 09 Mar 2018 18:29:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648963; cv=none; d=google.com; s=arc-20160816; b=Vm75ae2aOQ7CINOofsgF+P9HqdJ+UxA64+YUa+/e+lsnVQaQcIsCj6b209vOSd5ny1 g2RhAtmG/TrBl2Cqmzcsu6V8qexZ22t14t25xBj9GonfH3FEzS4Uw2TdiZx5AUyvX1mL Vy6SeAAzHgiRJRUJnTfwJuIEUh077NzOImxDC6LyKnU+6sbNbQXblYxJuW0Ow4b7Fq5G EUXjr/LbJHQ7dD1ZdZfCFjg7ga9kQzwPabFlln0XuazFZ4bVojkTCS+1IPz00pHdMc53 peacwioeq5ZOmhheWStoTHSInXAMAOaO780ZLELRKRo5OfuMwxy+UkRlUnH2VnWwh5SY 0JSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=zO/chIE9vKJY0sX2N/2Fm/HgzsORhilWwr3zUnJcoBo=; b=O2EJJ3EzQit8+2fuZi6N9WwV6hXfCkjWpp01LkreYIniikJAHjkRXi6JbEaLkEqjYL y7pmbpU5mvPAqqQpig+0/g9/bPmqn7BvlywUAuaIDSbIR4V/9H3YyguPXSR7wS86I3Cp 71BsWtW6D4Ycn5aUIoZB+vl6cVfua3AxMOSwYLdpwoCCh83n/32F4j+pwM/KnMCTMI4l yztI2iafryAC5K9ZiNInX+wHmGNneM1/Xh+Ayd2PXlc5T8Ui1KUfZzF+g0OkccnjhIFv fFncL1qZPCmc0cMbtBOWrWleRZIjhFs4YVkjGwAE0PisC4gPRmnVs89G9QyBsgREOYOc OyTg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=hLeEMb8Y; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id f10si1671265wri.245.2018.03.09.18.29.23; Fri, 09 Mar 2018 18:29:23 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=hLeEMb8Y; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 528C826769C; Sat, 10 Mar 2018 03:28:28 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 32551267679; Sat, 10 Mar 2018 03:27:59 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f66.google.com (mail-wm0-f66.google.com [74.125.82.66]) by alsa0.perex.cz (Postfix) with ESMTP id 4471A267663 for ; Sat, 10 Mar 2018 03:27:53 +0100 (CET) Received: by mail-wm0-f66.google.com with SMTP id 188so6974020wme.1 for ; Fri, 09 Mar 2018 18:27:53 -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=uqyoUR1p/br/KvQtd8ktAuiag1iH6GTZoj54LXb4NC0=; b=hLeEMb8YIrFnKjcEUj0Nm8c//ecZibWVzxjc/RTynguDlWhTAVO9fLQFUv5BexS9h0 XTav1gaTjcwfUjcOAFwohO2x5qGqvj1G+qyhMMqxewjsK10ZRXD8VCkWyN19W4MZLFH9 ITNSM346IiHSIrThATwc6MXcnnbuSF1aYkQdo= 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=uqyoUR1p/br/KvQtd8ktAuiag1iH6GTZoj54LXb4NC0=; b=DWToGjmxGK7YtBhBnyErP5x71FP6gELTUKeHZUs0SI+qxDtyIAr0oGgXu1s8BRNsSl I6n3QhX1FMiKZ61FDIK96OVUL65braSgUBmt8gooIoOhMXchv5LGw8jpsVy8RtqV3+Oa EOTzPxZTTvI5JKnURcUYPzatID1a5ZUm0PGHEO0cjK2rcDE6KYKczN8HOrl+aBkYVmGv WfKuulY8q+bTUPi6uhI7k6Vnrv4tYuJTE3ASlVQ6NSKmr2+goK2dplreCZR+OFF/jIYV zQjpYgqGDKVBO6rFfIllabQMQpvClWTaY0t+0uy/xMDjRfxSuUh7p8yRddMtNj42R0Iy tuZQ== X-Gm-Message-State: AElRT7HGICo2tdJSzce/Itd3OwCoJWaBuCGtqdP2XMZdd8gP7TMvx8+g lORxvoH2zeQDjjP1qrlM5yK5+g== X-Received: by 10.28.236.89 with SMTP id k86mr74790wmh.82.1520648873569; Fri, 09 Mar 2018 18:27:53 -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 g78sm21489wmc.31.2018.03.09.18.27.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:53 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:41 +0000 Message-Id: <20180310022456.26739-10-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 09/24] ASoC: qdsp6: q6afe: Add support to MI2S ports X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org From: Srinivas Kandagatla This patch adds support to 4 MI2S ports on LPASS. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/qdsp6/q6afe.c | 228 +++++++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6afe.h | 13 +++ 2 files changed, 241 insertions(+) -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c index de50ddd9faa4..2da5e3b14e38 100644 --- a/sound/soc/qcom/qdsp6/q6afe.c +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -14,6 +14,10 @@ #include #include #include +#include +#include +#include +#include #include "q6dsp-errno.h" #include "q6core.h" #include "q6afe.h" @@ -28,7 +32,36 @@ #define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG 0x00010235 +#define AFE_PARAM_ID_LPAIF_CLK_CONFIG 0x00010238 +#define AFE_PARAM_ID_INTERNAL_DIGITAL_CDC_CLK_CONFIG 0x00010239 + #define AFE_PARAM_ID_SLIMBUS_CONFIG 0x00010212 +#define AFE_PARAM_ID_I2S_CONFIG 0x0001020D + +/* I2S config specific */ +#define AFE_API_VERSION_I2S_CONFIG 0x1 +#define AFE_PORT_I2S_SD0 0x1 +#define AFE_PORT_I2S_SD1 0x2 +#define AFE_PORT_I2S_SD2 0x3 +#define AFE_PORT_I2S_SD3 0x4 +#define AFE_PORT_I2S_SD0_MASK BIT(0x1) +#define AFE_PORT_I2S_SD1_MASK BIT(0x2) +#define AFE_PORT_I2S_SD2_MASK BIT(0x3) +#define AFE_PORT_I2S_SD3_MASK BIT(0x4) +#define AFE_PORT_I2S_SD0_1_MASK GENMASK(2, 1) +#define AFE_PORT_I2S_SD2_3_MASK GENMASK(4, 3) +#define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(3, 1) +#define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(4, 1) +#define AFE_PORT_I2S_QUAD01 0x5 +#define AFE_PORT_I2S_QUAD23 0x6 +#define AFE_PORT_I2S_6CHS 0x7 +#define AFE_PORT_I2S_8CHS 0x8 +#define AFE_PORT_I2S_MONO 0x0 +#define AFE_PORT_I2S_STEREO 0x1 +#define AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL 0x0 +#define AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL 0x1 +#define AFE_LINEAR_PCM_DATA 0x0 + /* Port IDs */ #define AFE_API_VERSION_HDMI_CONFIG 0x1 @@ -64,6 +97,19 @@ #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX 0x400c /* SLIMbus Tx port on channel 6. */ #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX 0x400d +#define AFE_PORT_ID_PRIMARY_MI2S_RX 0x1000 +#define AFE_PORT_ID_PRIMARY_MI2S_TX 0x1001 +#define AFE_PORT_ID_SECONDARY_MI2S_RX 0x1002 +#define AFE_PORT_ID_SECONDARY_MI2S_TX 0x1003 +#define AFE_PORT_ID_TERTIARY_MI2S_RX 0x1004 +#define AFE_PORT_ID_TERTIARY_MI2S_TX 0x1005 +#define AFE_PORT_ID_QUATERNARY_MI2S_RX 0x1006 +#define AFE_PORT_ID_QUATERNARY_MI2S_TX 0x1007 + +#define Q6AFE_LPASS_MODE_CLK1_VALID 1 +#define Q6AFE_LPASS_MODE_CLK2_VALID 2 +#define Q6AFE_LPASS_CLK_SRC_INTERNAL 1 +#define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0 #define TIMEOUT_MS 1000 #define AFE_CMD_RESP_AVAIL 0 @@ -160,10 +206,21 @@ struct afe_param_id_slimbus_cfg { */ } __packed; +struct afe_param_id_i2s_cfg { + u32 i2s_cfg_minor_version; + u16 bit_width; + u16 channel_mode; + u16 mono_stereo; + u16 ws_src; + u32 sample_rate; + u16 data_format; + u16 reserved; +} __packed; union afe_port_config { struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch; struct afe_param_id_slimbus_cfg slim_cfg; + struct afe_param_id_i2s_cfg i2s_cfg; } __packed; struct q6afe_port { @@ -210,6 +267,22 @@ static struct afe_port_map port_maps[AFE_PORT_MAX] = { SLIMBUS_4_RX, 1, 1}, [SLIMBUS_5_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX, SLIMBUS_5_RX, 1, 1}, + [QUATERNARY_MI2S_RX] = { AFE_PORT_ID_QUATERNARY_MI2S_RX, + QUATERNARY_MI2S_RX, 1, 1}, + [QUATERNARY_MI2S_TX] = { AFE_PORT_ID_QUATERNARY_MI2S_TX, + QUATERNARY_MI2S_TX, 0, 1}, + [SECONDARY_MI2S_RX] = { AFE_PORT_ID_SECONDARY_MI2S_RX, + SECONDARY_MI2S_RX, 1, 1}, + [SECONDARY_MI2S_TX] = { AFE_PORT_ID_SECONDARY_MI2S_TX, + SECONDARY_MI2S_TX, 0, 1}, + [TERTIARY_MI2S_RX] = { AFE_PORT_ID_TERTIARY_MI2S_RX, + TERTIARY_MI2S_RX, 1, 1}, + [TERTIARY_MI2S_TX] = { AFE_PORT_ID_TERTIARY_MI2S_TX, + TERTIARY_MI2S_TX, 0, 1}, + [PRIMARY_MI2S_RX] = { AFE_PORT_ID_PRIMARY_MI2S_RX, + PRIMARY_MI2S_RX, 1, 1}, + [PRIMARY_MI2S_TX] = { AFE_PORT_ID_PRIMARY_MI2S_TX, + PRIMARY_MI2S_RX, 0, 1}, [SLIMBUS_6_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX, SLIMBUS_6_RX, 1, 1}, }; @@ -448,6 +521,150 @@ void q6afe_hdmi_port_prepare(struct q6afe_port *port, } EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare); +/** + * q6afe_i2s_port_prepare() - Prepare i2s afe port. + * + * @port: Instance of afe port + * @cfg: I2S configuration for the afe port + * + Return: Will be an negative on error and zero on success. + */ +int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg) +{ + union afe_port_config *pcfg = &port->port_cfg; + struct device *dev = port->afe->dev; + int num_sd_lines; + + pcfg->i2s_cfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; + pcfg->i2s_cfg.sample_rate = cfg->sample_rate; + pcfg->i2s_cfg.bit_width = cfg->bit_width; + pcfg->i2s_cfg.data_format = AFE_LINEAR_PCM_DATA; + + switch (cfg->fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL; + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* CPU is slave */ + pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL; + break; + default: + break; + } + + num_sd_lines = hweight_long(cfg->sd_line_mask); + + switch (num_sd_lines) { + case 0: + dev_err(dev, "no line is assigned\n"); + return -EINVAL; + case 1: + switch (cfg->sd_line_mask) { + case AFE_PORT_I2S_SD0_MASK: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0; + break; + case AFE_PORT_I2S_SD1_MASK: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD1; + break; + case AFE_PORT_I2S_SD2_MASK: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2; + break; + case AFE_PORT_I2S_SD3_MASK: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD3; + break; + default: + dev_err(dev, "Invalid SD lines\n"); + return -EINVAL; + } + break; + case 2: + switch (cfg->sd_line_mask) { + case AFE_PORT_I2S_SD0_1_MASK: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD01; + break; + case AFE_PORT_I2S_SD2_3_MASK: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD23; + break; + default: + dev_err(dev, "Invalid SD lines\n"); + return -EINVAL; + } + break; + case 3: + switch (cfg->sd_line_mask) { + case AFE_PORT_I2S_SD0_1_2_MASK: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_6CHS; + break; + default: + dev_err(dev, "Invalid SD lines\n"); + return -EINVAL; + } + break; + case 4: + switch (cfg->sd_line_mask) { + case AFE_PORT_I2S_SD0_1_2_3_MASK: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_8CHS; + + break; + default: + dev_err(dev, "Invalid SD lines\n"); + return -EINVAL; + } + break; + default: + dev_err(dev, "Invalid SD lines\n"); + return -EINVAL; + } + + switch (cfg->num_channels) { + case 1: + case 2: + switch (pcfg->i2s_cfg.channel_mode) { + case AFE_PORT_I2S_QUAD01: + case AFE_PORT_I2S_6CHS: + case AFE_PORT_I2S_8CHS: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0; + break; + case AFE_PORT_I2S_QUAD23: + pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2; + break; + } + + if (cfg->num_channels == 2) + pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_STEREO; + else + pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_MONO; + + break; + case 3: + case 4: + if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_QUAD01) { + dev_err(dev, "Invalid Channel mode\n"); + return -EINVAL; + } + break; + case 5: + case 6: + if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_6CHS) { + dev_err(dev, "Invalid Channel mode\n"); + return -EINVAL; + } + break; + case 7: + case 8: + if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_8CHS) { + dev_err(dev, "Invalid Channel mode\n"); + return -EINVAL; + } + break; + default: + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(q6afe_i2s_port_prepare); + /** * q6afe_port_start() - Start a afe port * @@ -529,6 +746,17 @@ struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id) case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX: cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG; break; + + case AFE_PORT_ID_PRIMARY_MI2S_RX: + case AFE_PORT_ID_PRIMARY_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_TX: + case AFE_PORT_ID_TERTIARY_MI2S_RX: + case AFE_PORT_ID_TERTIARY_MI2S_TX: + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + cfg_type = AFE_PARAM_ID_I2S_CONFIG; + break; default: dev_err(dev, "Invalid port id 0x%x\n", port_id); return ERR_PTR(-EINVAL); diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h index 155d6e47d7ce..05c61014abea 100644 --- a/sound/soc/qcom/qdsp6/q6afe.h +++ b/sound/soc/qcom/qdsp6/q6afe.h @@ -11,6 +11,8 @@ #define MSM_AFE_PORT_TYPE_TX 1 #define AFE_MAX_PORTS AFE_PORT_MAX +#define Q6AFE_MAX_MI2S_LINES 4 + #define AFE_MAX_CHAN_COUNT 8 #define AFE_PORT_MAX_AUDIO_CHAN_CNT 0x8 @@ -29,9 +31,19 @@ struct q6afe_slim_cfg { u8 ch_mapping[AFE_MAX_CHAN_COUNT]; }; +struct q6afe_i2s_cfg { + u32 sample_rate; + u16 bit_width; + u16 data_format; + u16 num_channels; + u32 sd_line_mask; + int fmt; +}; + struct q6afe_port_config { struct q6afe_hdmi_cfg hdmi; struct q6afe_slim_cfg slim; + struct q6afe_i2s_cfg i2s_cfg; }; struct q6afe_port; @@ -45,5 +57,6 @@ void q6afe_hdmi_port_prepare(struct q6afe_port *port, struct q6afe_hdmi_cfg *cfg); void q6afe_slim_port_prepare(struct q6afe_port *port, struct q6afe_slim_cfg *cfg); +int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg); #endif /* __Q6AFE_H__ */ From patchwork Sat Mar 10 02:24:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131273 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1691383lja; Fri, 9 Mar 2018 18:29:32 -0800 (PST) X-Google-Smtp-Source: AG47ELvf/peoNnLan1ncdJiXYnXxzQT9VFIEfT+7Hj3pSdEqr9OQpuhxntRsXj3+YT8dOXjY7gCi X-Received: by 10.223.157.131 with SMTP id p3mr394206wre.278.1520648971976; Fri, 09 Mar 2018 18:29:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648971; cv=none; d=google.com; s=arc-20160816; b=NL4kuUdLexsGtMVF5UUE9X2aX7rSKD9nJVbss+4bnITy5/D/YH+1FRoWleAfqzJxHd qAlX+kP/ChJMe8s/f/EHkuuxU71OvzySZiJ9iZ/NjGio5u8QtpTzOZbtvE41c50v1OEV nu9WO2wKFCueIwo5DSjz4hDtB6ayw5u4DNcHiy+9zLRyYd6J7LJ/tYaKrmlSvrmEf3on mqGO+4MyN6eD1yHmh+dkYi3lBFyf5IPqw3B7jpvCb0RaTAA7c2Wti81Ohwp4UGM9cMcg UT+8EsDnwxYVhH7gdUWBy608rhi/E8FiZs3bf7X/jX0CRsrw3TD1Dike25NcljJFYXVx ZV+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=YMaw58ob3mUoBwknfNehK2xLK+2V48uUYXutoSI4h30=; b=FP4sVHvWxWg116fMN+KcRmmaqijisjm+5J7a5npyCL7vbFRp8f5eSXX8qfyiivhKVe R6PAQhI0ImqPURTUO7CWi9IbVEhkPiR3Bo4f0QPTFIJh1HUKFxv7Et1Gfr70vWXEac15 Mi+wI3NtEGAvC18onLH4MktWuL7uc4snYWLia6swXCGwRwtFomlu5ivVoLsLm8GKOKng MzL03kp/8Q7bMsrMdqbQP8HFsCkN4riqrRwq8x7ADqfqIZHF6mhg0VeBsUZ8Sd+Fgb54 q5kOdu3UZhu+hIVbyhVmHQESSRC8eD7tjaPLu0tD6XoRAP8gtVoH7SoYfJp72n+cyFjj 0MrQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=EcThlLNy; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id 34si1785168wrd.123.2018.03.09.18.29.31; Fri, 09 Mar 2018 18:29:31 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=EcThlLNy; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 784D526766D; Sat, 10 Mar 2018 03:28:31 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 0D09C267672; Sat, 10 Mar 2018 03:28:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f66.google.com (mail-wm0-f66.google.com [74.125.82.66]) by alsa0.perex.cz (Postfix) with ESMTP id 58F2126766E for ; Sat, 10 Mar 2018 03:27:55 +0100 (CET) Received: by mail-wm0-f66.google.com with SMTP id t6so6971618wmt.5 for ; Fri, 09 Mar 2018 18:27:55 -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=fMls88C4Lk9OuBgVBfoRD8vu2ASzjRy+dybaMsLdW+g=; b=EcThlLNya9RQVQHx6p7jlWfDVFNO5tcxaFi8Zj6UBWa9htPv09J+zfgZqqL+E5FCKK CGTdGI57nyiqsuoMIjsUrabeab6nNDP0dqO+p4efBqa+JkAyPmZxZbplew+/4kOJ3vOK cFz9mHKPKX0xAyW5mPubPueIr1CoXRQoYMHNc= 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=fMls88C4Lk9OuBgVBfoRD8vu2ASzjRy+dybaMsLdW+g=; b=Vv8AmiF6+T2e0xiUOBmraLEOmA5wuUh0W2SmqVs3XSO/inVLBc7qWq8DV609b57Pld i+o4LGsBYJZBQk3vFCrHwv2leZcjo1jyCCY0PRXNymBD4kfid856J8c5noTIb9Gh09J7 gN6KXYmr0cxPvj9+lO8/JnAfZslwnw/NDFsbRXwzq1thRcfIgv53IkFfQuPkZyMlryQb EgICuShIFmL0meNBXBQL7kt+yBjVzYlqF1NQsi8TS7UvQGmoyLd+b29A90m5AB7vW5rR MvADdJ8xRDob6cIk3ipU+mYrYZeshIu2mPGEJ2wUlHosslIeX1wa79OCL8J7BYLpJ6jd ImPg== X-Gm-Message-State: AElRT7GDis0A0kefZzCfPd8lWHnDZrCxyym9Eb7fq14K1M6fi7d91DQZ w/3fV83oPCUKsa7CuCEQgnwq7Q== X-Received: by 10.28.191.138 with SMTP id o10mr70135wmi.26.1520648874824; Fri, 09 Mar 2018 18:27:54 -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 g78sm21489wmc.31.2018.03.09.18.27.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:54 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:42 +0000 Message-Id: <20180310022456.26739-11-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 10/24] ASoC: qdsp6: q6afe: Add support to MI2S sysclks X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org From: Srinivas Kandagatla This patch adds support to LPASS Bit clock, LPASS Digital core clock and OSR clock. These clocks are required for both MI2S and PCM setup. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/qdsp6/q6afe.c | 211 ++++++++++++++++++++++++++++++++++++++++++- sound/soc/qcom/qdsp6/q6afe.h | 131 +++++++++++++++++++++++++++ 2 files changed, 340 insertions(+), 2 deletions(-) -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c index 2da5e3b14e38..40ba53d13e98 100644 --- a/sound/soc/qcom/qdsp6/q6afe.c +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -26,6 +26,7 @@ #define AFE_PORT_CMD_DEVICE_START 0x000100E5 #define AFE_PORT_CMD_DEVICE_STOP 0x000100E6 #define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF +#define AFE_SVC_CMD_SET_PARAM 0x000100f3 #define AFE_PORT_CMDRSP_GET_PARAM_V2 0x00010106 #define AFE_PARAM_ID_HDMI_CONFIG 0x00010210 #define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C @@ -68,6 +69,11 @@ #define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E #define AFE_API_VERSION_SLIMBUS_CONFIG 0x1 +/* Clock set API version */ +#define AFE_API_VERSION_CLOCK_SET 1 +#define Q6AFE_LPASS_CLK_CONFIG_API_VERSION 0x1 +#define AFE_MODULE_CLOCK_SET 0x0001028F +#define AFE_PARAM_ID_CLOCK_SET 0x00010290 /* SLIMbus Rx port on channel 0. */ #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX 0x4000 @@ -146,6 +152,13 @@ struct afe_port_param_data_v2 { u16 reserved; } __packed; +struct afe_svc_cmd_set_param { + uint32_t payload_size; + uint32_t payload_address_lsw; + uint32_t payload_address_msw; + uint32_t mem_map_handle; +} __packed; + struct afe_port_cmd_set_param_v2 { u16 port_id; u16 payload_size; @@ -206,6 +219,23 @@ struct afe_param_id_slimbus_cfg { */ } __packed; +struct afe_clk_cfg { + u32 i2s_cfg_minor_version; + u32 clk_val1; + u32 clk_val2; + u16 clk_src; + u16 clk_root; + u16 clk_set_mode; + u16 reserved; +} __packed; + +struct afe_digital_clk_cfg { + u32 i2s_cfg_minor_version; + u32 clk_val; + u16 clk_root; + u16 reserved; +} __packed; + struct afe_param_id_i2s_cfg { u32 i2s_cfg_minor_version; u16 bit_width; @@ -223,9 +253,43 @@ union afe_port_config { struct afe_param_id_i2s_cfg i2s_cfg; } __packed; + +struct afe_clk_set { + uint32_t clk_set_minor_version; + uint32_t clk_id; + uint32_t clk_freq_in_hz; + uint16_t clk_attri; + uint16_t clk_root; + uint32_t enable; +}; + +struct afe_lpass_clk_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_clk_cfg clk_cfg; +} __packed; + +struct afe_lpass_clk_config_command_v2 { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_port_param_data_v2 pdata; + struct afe_clk_set clk_cfg; +} __packed; + + + +struct afe_lpass_digital_clk_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_digital_clk_cfg clk_cfg; +} __packed; + struct q6afe_port { wait_queue_head_t wait; union afe_port_config port_cfg; + struct aprv2_ibasic_rsp_result_t result; int token; int id; int cfg_type; @@ -393,6 +457,46 @@ static int afe_apr_send_pkt(struct q6afe *afe, void *data, return ret; } +static int q6afe_port_set_param(struct q6afe_port *port, void *data, + int param_id, int module_id, int psize) +{ + struct apr_hdr *hdr; + struct afe_svc_cmd_set_param *param; + struct afe_port_param_data_v2 *pdata; + struct q6afe *afe = port->afe; + u16 port_id = port->id; + int ret; + + hdr = data; + param = data + sizeof(*hdr); + pdata = data + sizeof(*hdr) + sizeof(*param); + + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + hdr->pkt_size = sizeof(*hdr) + sizeof(*param) + + sizeof(*pdata) + psize; + hdr->src_port = 0; + hdr->dest_port = 0; + hdr->token = port->token; + hdr->opcode = AFE_SVC_CMD_SET_PARAM; + + param->payload_size = sizeof(*pdata) + psize; + param->payload_address_lsw = 0x00; + param->payload_address_msw = 0x00; + param->mem_map_handle = 0x00; + pdata->module_id = module_id; + pdata->param_id = param_id; + pdata->param_size = psize; + + ret = afe_apr_send_pkt(afe, data, port); + if (ret) + dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n", + port_id, ret); + + return ret; +} + static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data, int param_id, int psize) { @@ -434,6 +538,110 @@ static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data, return ret; } +static int q6afe_set_lpass_clock(struct q6afe_port *port, + struct afe_clk_cfg *cfg) +{ + struct afe_lpass_clk_config_command clk_cfg = {0}; + int param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG; + struct q6afe *afe = port->afe; + + if (!cfg) { + dev_err(afe->dev, "clock cfg is NULL\n"); + return -EINVAL; + } + + clk_cfg.clk_cfg = *cfg; + + return q6afe_port_set_param_v2(port, &clk_cfg, param_id, sizeof(*cfg)); +} + +static int q6afe_set_lpass_clock_v2(struct q6afe_port *port, + struct afe_clk_set *cfg) +{ + struct afe_lpass_clk_config_command_v2 clk_cfg = {0}; + int param_id = AFE_PARAM_ID_CLOCK_SET; + int module_id = AFE_MODULE_CLOCK_SET; + struct q6afe *afe = port->afe; + + if (!cfg) { + dev_err(afe->dev, "clock cfg is NULL\n"); + return -EINVAL; + } + + clk_cfg.clk_cfg = *cfg; + + return q6afe_port_set_param(port, &clk_cfg, param_id, + module_id, sizeof(*cfg)); +} + +static int q6afe_set_digital_codec_core_clock(struct q6afe_port *port, + struct afe_digital_clk_cfg *cfg) +{ + struct afe_lpass_digital_clk_config_command clk_cfg = {0}; + int param_id = AFE_PARAM_ID_INTERNAL_DIGITAL_CDC_CLK_CONFIG; + struct q6afe *afe = port->afe; + + if (!cfg) { + dev_err(afe->dev, "clock cfg is NULL\n"); + return -EINVAL; + } + + clk_cfg.clk_cfg = *cfg; + + return q6afe_port_set_param_v2(port, &clk_cfg, param_id, sizeof(*cfg)); +} + +int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id, + int clk_src, int clk_root, + unsigned int freq, int dir) +{ + struct afe_clk_cfg ccfg = {0,}; + struct afe_clk_set cset = {0,}; + struct afe_digital_clk_cfg dcfg = {0,}; + int ret; + + switch (clk_id) { + case LPAIF_DIG_CLK: + dcfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; + dcfg.clk_val = freq; + dcfg.clk_root = clk_root; + ret = q6afe_set_digital_codec_core_clock(port, &dcfg); + break; + case LPAIF_BIT_CLK: + ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; + ccfg.clk_val1 = freq; + ccfg.clk_src = clk_src; + ccfg.clk_root = clk_root; + ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; + ret = q6afe_set_lpass_clock(port, &ccfg); + break; + + case LPAIF_OSR_CLK: + ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG; + ccfg.clk_val2 = freq; + ccfg.clk_src = clk_src; + ccfg.clk_root = clk_root; + ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID; + ret = q6afe_set_lpass_clock(port, &ccfg); + break; + case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1: + cset.clk_set_minor_version = AFE_API_VERSION_CLOCK_SET; + cset.clk_id = clk_id; + cset.clk_freq_in_hz = freq; + cset.clk_attri = clk_src; + cset.clk_root = clk_root; + cset.enable = !!freq; + ret = q6afe_set_lpass_clock_v2(port, &cset); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} +EXPORT_SYMBOL_GPL(q6afe_port_set_sysclk); + /** * q6afe_port_stop() - Stop a afe port * @@ -526,8 +734,7 @@ EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare); * * @port: Instance of afe port * @cfg: I2S configuration for the afe port - * - Return: Will be an negative on error and zero on success. + * Return: Will be an negative on error and zero on success. */ int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg) { diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h index 05c61014abea..f21c89a25c29 100644 --- a/sound/soc/qcom/qdsp6/q6afe.h +++ b/sound/soc/qcom/qdsp6/q6afe.h @@ -16,6 +16,134 @@ #define AFE_MAX_CHAN_COUNT 8 #define AFE_PORT_MAX_AUDIO_CHAN_CNT 0x8 +#define Q6AFE_LPASS_CLK_SRC_INTERNAL 1 +#define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0 + +#define LPAIF_DIG_CLK 1 +#define LPAIF_BIT_CLK 2 +#define LPAIF_OSR_CLK 3 + +/* Clock ID for Primary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT 0x100 +/* Clock ID for Primary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT 0x101 +/* Clock ID for Secondary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT 0x102 +/* Clock ID for Secondary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT 0x103 +/* Clock ID for Tertiary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT 0x104 +/* Clock ID for Tertiary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT 0x105 +/* Clock ID for Quartnery I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT 0x106 +/* Clock ID for Quartnery I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT 0x107 +/* Clock ID for Speaker I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_IBIT 0x108 +/* Clock ID for Speaker I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_EBIT 0x109 +/* Clock ID for Speaker I2S OSR */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR 0x10A + +/* Clock ID for QUINARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT 0x10B +/* Clock ID for QUINARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT 0x10C +/* Clock ID for SENARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT 0x10D +/* Clock ID for SENARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT 0x10E +/* Clock ID for INT0 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT 0x10F +/* Clock ID for INT1 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT 0x110 +/* Clock ID for INT2 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT 0x111 +/* Clock ID for INT3 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT 0x112 +/* Clock ID for INT4 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT 0x113 +/* Clock ID for INT5 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT 0x114 +/* Clock ID for INT6 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT 0x115 + +/* Clock ID for QUINARY MI2S OSR CLK */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR 0x116 + +/* Clock ID for Primary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT 0x200 +/* Clock ID for Primary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_EBIT 0x201 +/* Clock ID for Secondary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT 0x202 +/* Clock ID for Secondary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_EBIT 0x203 +/* Clock ID for Tertiary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT 0x204 +/* Clock ID for Tertiary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_EBIT 0x205 +/* Clock ID for Quartery PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT 0x206 +/* Clock ID for Quartery PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT 0x207 +/* Clock ID for Quinary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT 0x208 +/* Clock ID for Quinary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_PCM_EBIT 0x209 +/* Clock ID for QUINARY PCM OSR */ +#define Q6AFE_LPASS_CLK_ID_QUI_PCM_OSR 0x20A + +/** Clock ID for Primary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT 0x200 +/** Clock ID for Primary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT 0x201 +/** Clock ID for Secondary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT 0x202 +/** Clock ID for Secondary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT 0x203 +/** Clock ID for Tertiary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT 0x204 +/** Clock ID for Tertiary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT 0x205 +/** Clock ID for Quartery TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT 0x206 +/** Clock ID for Quartery TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT 0x207 +/** Clock ID for Quinary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT 0x208 +/** Clock ID for Quinary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT 0x209 +/** Clock ID for Quinary TDM OSR */ +#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_OSR 0x20A + +/* Clock ID for MCLK1 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_1 0x300 +/* Clock ID for MCLK2 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_2 0x301 +/* Clock ID for MCLK3 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_3 0x302 +/* Clock ID for MCLK4 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_4 0x304 +/* Clock ID for Internal Digital Codec Core */ +#define Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 0x303 +/* Clock ID for INT MCLK0 */ +#define Q6AFE_LPASS_CLK_ID_INT_MCLK_0 0x305 +/* Clock ID for INT MCLK1 */ +#define Q6AFE_LPASS_CLK_ID_INT_MCLK_1 0x306 + +/* Clock attribute for invalid use (reserved for internal usage) */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVALID 0x0 +/* Clock attribute for no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1 +/* Clock attribute for dividend couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND 0x2 +/* Clock attribute for divisor couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR 0x3 +/* Clock attribute for invert and no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO 0x4 + struct q6afe_hdmi_cfg { u16 datatype; u16 channel_allocation; @@ -59,4 +187,7 @@ void q6afe_slim_port_prepare(struct q6afe_port *port, struct q6afe_slim_cfg *cfg); int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg); +int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id, + int clk_src, int clk_root, + unsigned int freq, int dir); #endif /* __Q6AFE_H__ */ From patchwork Sat Mar 10 02:24:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131276 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1691556lja; Fri, 9 Mar 2018 18:29:48 -0800 (PST) X-Google-Smtp-Source: AG47ELuCLwm7Y16q5vCJLMCKXqvMgYwaAEiZrVfmMNnb0L0QK7AZPzR1ZAZwK88CA2HQcpDN1E4H X-Received: by 10.223.135.178 with SMTP id b47mr415263wrb.108.1520648988467; Fri, 09 Mar 2018 18:29:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648988; cv=none; d=google.com; s=arc-20160816; b=l6bc6xLbCkmb0OSN1X131qUxJv6HoJPmpqnPphCNLxGk6tl+NahpwQq+N8y1k/gwub bUhhGAiFutRcgzCh/dUBmpvIcJXwubVLoqQ1EOqQieMV0DFyPiUEIvkL3EinhdUV/3QZ 7OSjFL4cCW11QLjU0g+xsim695kXzQH3Drq7XiDFXVz9rAeqmpcc0sEpizJYK9d/illC GR7xROCKWoEAH7B6UII/xRfUpSGTMl2DjFE7qXrHvAa5SbCoKoZH5t0bcQVfPbxhc1zm x8OW5B6hH0PFQFdTtPDrVqEbtbrLjqVF+XZjOreVLIYF6f3h9v8p377Wz/HKjEu7mYkG CZgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=FnOsH8w58dY+5v/cU8x4SbcPa+/Tw4XHpTRnVPFOoHs=; b=o8uAOWsz2zJ30LQswThlreGxG/a8Sld+0lHMMkgHRkerynsh+4SC+4TJID74jULSAf F5FBNf2Drnrv/N84AUvp+jPRr1kK+xZPkGvaJPR9JecK/R8ChTgyr6Hs3p2vD3Ncw6Hc ogMbiBJSL+5XFZ1jHInMxzdCC9hFcfqTkusLsYfzXuZHMGDpXJ87jggT0NsFYxcs39+p AJH5fOtkM75RBFAyTssVq+cVYDRruG94g2y9+AHH3o6hAIK7TUqmT04+xcxlSGi8ZdWP N7wrSxFMUqXP1YSrN15tyAarT5DyZVF4ASAAurUmgn8MW7z85lU0VqTe7K43idWuRUE2 i5iA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=OK30JF2r; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id h30si1834552wrh.247.2018.03.09.18.29.48; Fri, 09 Mar 2018 18:29:48 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=OK30JF2r; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id F205D2676BD; Sat, 10 Mar 2018 03:28:38 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 0979B26768B; Sat, 10 Mar 2018 03:28:06 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by alsa0.perex.cz (Postfix) with ESMTP id CE0CD267677 for ; Sat, 10 Mar 2018 03:27:56 +0100 (CET) Received: by mail-wm0-f67.google.com with SMTP id 139so7008788wmn.2 for ; Fri, 09 Mar 2018 18:27:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ha4hyPmNTGXa3//PTkRj9mn5wIid/UCbQMRONnkdGbU=; b=OK30JF2rhN5k87NDh0RCgxyewfRRa4clmlNn+gaXcIBbVDfM4Jn1rfQzecLPq4bS77 UmjnqAGBYOjM8FzJ6AFInKCCoaUPWnVlZg2eTjaGW6l2/HGAQTkGi8vIu8qEOziDVA4Z H7jny8gx/GSrf7GMvhDgJc0YUbB69/AsHn2Z0= 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=Ha4hyPmNTGXa3//PTkRj9mn5wIid/UCbQMRONnkdGbU=; b=f2zADBNMjVaXigHnrU+zm1v96yC7vkrBCb8Zwk26f4CTGas0FGhjdPCoCriv1WvJZp JC4H1QeBExp+PqJHIEHg72ETrekR2TzDY7vlPVf6WvHVZhLZ6HRrpAXSGOhF6bj9Oq+h uWVYJiys1PDrAykTka0WC7WXw10WzCqYdEZBfGmuTLtuLyBLTcQBW9ZRg8xji6mkTg6M qkP7MUE4cWdrekK7fzvfpzW5FAjeaXi3e5++P2FWxSa9I8f4btMWum8mjwyPCuHu0fsN vkC5SE4FPJFp9k9xrttpHDYm7QZt0EMkL9bWrg74B9kdajLCaqZoVlWlf1Pt6k4e8LhO 4dkA== X-Gm-Message-State: AElRT7HBGE/ImwdhhvhaNGEqOlfVJ+KLw9rjURsKqP0sfSvLRnR5z2Up Dr0TF4sz4D2+LG7U3Q/A407H8g== X-Received: by 10.28.113.79 with SMTP id m76mr69137wmc.27.1520648876120; Fri, 09 Mar 2018 18:27:56 -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 g78sm21489wmc.31.2018.03.09.18.27.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:55 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:43 +0000 Message-Id: <20180310022456.26739-12-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 11/24] ASoC: qdsp6: q6adm: Add q6adm driver X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org From: Srinivas Kandagatla This patch adds support to Q6ADM (Audio Device Manager) module in q6dsp. ADM performs routing between audio streams and AFE ports. It does Rate matching for streams going to devices driven by different clocks, it handles volume ramping, Mixing with channel and bit-width. ADM creates and destroys dynamic COPP services for device-related audio processing as needed. This patch adds basic support to ADM. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/Kconfig | 4 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6adm.c | 664 ++++++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6adm.h | 25 ++ 4 files changed, 694 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6adm.c create mode 100644 sound/soc/qcom/qdsp6/q6adm.h -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index f50c76d712c0..5090ffa75648 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -50,11 +50,15 @@ config SND_SOC_QDSP6_COMMON config SND_SOC_QDSP6_AFE tristate +config SND_SOC_QDSP6_ADM + tristate + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" depends on QCOM_APR && HAS_DMA select SND_SOC_QDSP6_COMMON select SND_SOC_QDSP6_AFE + select SND_SOC_QDSP6_ADM 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 9ec951e0833b..930944425051 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o +obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c new file mode 100644 index 000000000000..4b4c604cb998 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6adm.c @@ -0,0 +1,664 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2011-2017, The Linux Foundation +// Copyright (c) 2018, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6adm.h" +#include "q6afe.h" +#include "q6core.h" +#include "q6dsp-errno.h" +#include "q6dsp-common.h" + +#define ADM_CMD_DEVICE_OPEN_V5 0x00010326 +#define ADM_CMDRSP_DEVICE_OPEN_V5 0x00010329 +#define ADM_CMD_DEVICE_CLOSE_V5 0x00010327 +#define ADM_CMD_MATRIX_MAP_ROUTINGS_V5 0x00010325 + +#define TIMEOUT_MS 1000 +#define RESET_COPP_ID 99 +#define INVALID_COPP_ID 0xFF +/* Definition for a legacy device session. */ +#define ADM_LEGACY_DEVICE_SESSION 0 +#define ADM_MATRIX_ID_AUDIO_RX 0 +#define ADM_MATRIX_ID_AUDIO_TX 1 + +struct copp { + int afe_port; + int copp_idx; + int id; + int topology; + int mode; + int rate; + int bit_width; + int channels; + int app_type; + int acdb_id; + + struct aprv2_ibasic_rsp_result_t result; + struct kref refcount; + wait_queue_head_t wait; + struct list_head node; + struct q6adm *adm; +}; + +struct q6adm { + struct apr_device *apr; + struct device *dev; + struct q6core_svc_api_info ainfo; + unsigned long copp_bitmap[AFE_MAX_PORTS]; + struct list_head copps_list; + spinlock_t copps_list_lock; + struct aprv2_ibasic_rsp_result_t result; + struct mutex lock; + wait_queue_head_t matrix_map_wait; + void *routing_data; + struct platform_device *pdev_routing; +}; + +struct adm_cmd_device_open_v5 { + struct apr_hdr hdr; + u16 flags; + u16 mode_of_operation; + u16 endpoint_id_1; + u16 endpoint_id_2; + u32 topology_id; + u16 dev_num_channel; + u16 bit_width; + u32 sample_rate; + u8 dev_channel_mapping[8]; +} __packed; + +struct adm_cmd_matrix_map_routings_v5 { + struct apr_hdr hdr; + u32 matrix_id; + u32 num_sessions; +} __packed; + +struct adm_session_map_node_v5 { + u16 session_id; + u16 num_copps; +} __packed; + +static struct copp *adm_find_copp(struct q6adm *adm, int port_idx, + int copp_idx) +{ + struct copp *c = NULL; + unsigned long flags; + + spin_lock_irqsave(&adm->copps_list_lock, flags); + list_for_each_entry(c, &adm->copps_list, node) { + if ((port_idx == c->afe_port) && (copp_idx == c->copp_idx)) + break; + } + + spin_unlock_irqrestore(&adm->copps_list_lock, flags); + + return c; + +} + +static int q6adm_callback(struct apr_device *adev, + struct apr_client_message *data) +{ + struct aprv2_ibasic_rsp_result_t *result = data->payload; + int port_idx, copp_idx; + struct copp *copp; + struct q6adm *adm = dev_get_drvdata(&adev->dev); + + if (!data->payload_size) + return 0; + + copp_idx = (data->token) & 0XFF; + port_idx = ((data->token) >> 16) & 0xFF; + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + dev_err(&adev->dev, "Invalid port idx %d token %d\n", + port_idx, data->token); + return 0; + } + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + dev_err(&adev->dev, "Invalid copp idx %d token %d\n", + copp_idx, data->token); + return 0; + } + + switch (data->opcode) { + case APR_BASIC_RSP_RESULT: { + if (result->status != 0) { + dev_err(&adev->dev, "cmd = 0x%x return error = 0x%x\n", + result->opcode, result->status); + } + switch (result->opcode) { + case ADM_CMD_DEVICE_OPEN_V5: + case ADM_CMD_DEVICE_CLOSE_V5: + copp = adm_find_copp(adm, port_idx, copp_idx); + if (!copp) + return 0; + + copp->result = *result; + wake_up(&copp->wait); + break; + case ADM_CMD_MATRIX_MAP_ROUTINGS_V5: + adm->result = *result; + wake_up(&adm->matrix_map_wait); + break; + + default: + dev_err(&adev->dev, "Unknown Cmd: 0x%x\n", + result->opcode); + break; + } + return 0; + } + case ADM_CMDRSP_DEVICE_OPEN_V5: { + struct adm_cmd_rsp_device_open_v5 { + u32 status; + u16 copp_id; + u16 reserved; + } __packed * open = data->payload; + + open = data->payload; + copp = adm_find_copp(adm, port_idx, copp_idx); + if (!copp) + return 0; + + if (open->copp_id == INVALID_COPP_ID) { + dev_err(&adev->dev, "Invalid coppid rxed %d\n", + open->copp_id); + copp->result.status = ADSP_EBADPARAM; + wake_up(&copp->wait); + break; + } + copp->result.opcode = data->opcode; + copp->id = open->copp_id; + wake_up(&copp->wait); + } + break; + default: + dev_err(&adev->dev, "Unknown cmd:0x%x\n", + data->opcode); + break; + } + + return 0; +} + +static struct copp *adm_alloc_copp(struct q6adm *adm, int port_idx) +{ + struct copp *c; + int idx; + + idx = find_first_zero_bit(&adm->copp_bitmap[port_idx], + MAX_COPPS_PER_PORT); + + if (idx > MAX_COPPS_PER_PORT) + return ERR_PTR(-EBUSY); + + c = kzalloc(sizeof(*c), GFP_KERNEL); + if (!c) + return ERR_PTR(-ENOMEM); + + set_bit(idx, &adm->copp_bitmap[port_idx]); + c->copp_idx = idx; + c->afe_port = port_idx; + c->adm = adm; + + init_waitqueue_head(&c->wait); + + return c; +} + +static int q6adm_apr_send_copp_pkt(struct q6adm *adm, struct copp *copp, + void *data, uint32_t rsp_opcode) +{ + struct device *dev = adm->dev; + struct apr_hdr *hdr = data; + uint32_t opcode = hdr->opcode; + int ret; + + mutex_lock(&adm->lock); + copp->result.opcode = 0; + copp->result.status = 0; + ret = apr_send_pkt(adm->apr, data); + if (ret < 0) { + dev_err(dev, "Failed to send APR packet\n"); + ret = -EINVAL; + goto err; + } + + /* Wait for the callback with copp id */ + if (rsp_opcode) + ret = wait_event_timeout(copp->wait, + (copp->result.opcode == opcode) || + (copp->result.opcode == rsp_opcode), + msecs_to_jiffies(TIMEOUT_MS)); + else + ret = wait_event_timeout(copp->wait, + (copp->result.opcode == opcode), + msecs_to_jiffies(TIMEOUT_MS)); + + if (!ret) { + dev_err(dev, "ADM copp cmd timedout\n"); + ret = -EINVAL; + } else if (copp->result.status > 0) { + dev_err(dev, "DSP returned error[%d]\n", + copp->result.status); + ret = -EINVAL; + } + +err: + mutex_unlock(&adm->lock); + return ret; +} + +static int q6adm_device_close(struct q6adm *adm, struct copp *copp, + int port_id, int copp_idx) +{ + struct apr_hdr close = {0}; + + close.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + close.pkt_size = sizeof(close); + close.src_svc = APR_SVC_ADM; + close.src_domain = APR_DOMAIN_APPS; + close.src_port = port_id; + close.dest_svc = APR_SVC_ADM; + close.dest_domain = APR_DOMAIN_ADSP; + close.dest_port = copp->id; + close.token = port_id << 16 | copp_idx; + close.opcode = ADM_CMD_DEVICE_CLOSE_V5; + + return q6adm_apr_send_copp_pkt(adm, copp, &close, 0); +} + +static void adm_free_copp(struct kref *ref) +{ + struct copp *c = container_of(ref, struct copp, refcount); + struct q6adm *adm = c->adm; + int port_idx = c->afe_port; + int copp_idx = c->copp_idx; + unsigned long flags; + int ret; + + ret = q6adm_device_close(adm, c, port_idx, copp_idx); + if (ret < 0) + dev_err(adm->dev, "Failed to close copp %d\n", ret); + + clear_bit(c->copp_idx, &adm->copp_bitmap[port_idx]); + spin_lock_irqsave(&adm->copps_list_lock, flags); + list_del(&c->node); + spin_unlock_irqrestore(&adm->copps_list_lock, flags); + kfree(c); +} + +static struct copp *adm_find_matching_copp(struct q6adm *adm, + int port_id, int topology, + int mode, int rate, int channel_mode, + int bit_width, int app_type) +{ + unsigned long flags; + struct copp *c; + + spin_lock_irqsave(&adm->copps_list_lock, flags); + + list_for_each_entry(c, &adm->copps_list, node) { + if ((port_id == c->afe_port) && (topology == c->topology) && + (mode == c->mode) && (rate == c->rate) && + (bit_width == c->bit_width) && (app_type == c->app_type)) { + spin_unlock_irqrestore(&adm->copps_list_lock, flags); + return c; + } + } + spin_unlock_irqrestore(&adm->copps_list_lock, flags); + + c = adm_alloc_copp(adm, port_id); + if (IS_ERR_OR_NULL(c)) + return ERR_CAST(c); + + kref_init(&c->refcount); + c->topology = topology; + c->mode = mode; + c->rate = rate; + c->channels = channel_mode; + c->bit_width = bit_width; + c->app_type = app_type; + + spin_lock_irqsave(&adm->copps_list_lock, flags); + list_add_tail(&c->node, &adm->copps_list); + spin_unlock_irqrestore(&adm->copps_list_lock, flags); + + return c; + +} + +static int q6adm_device_open(struct q6adm *adm, struct copp *copp, int port_id, + int path, int topology, int channel_mode, + int bit_width, int rate) +{ + struct adm_cmd_device_open_v5 open = {0,}; + int afe_port = q6afe_get_port_id(port_id); + int ret; + + open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + open.hdr.pkt_size = sizeof(open); + open.hdr.src_svc = APR_SVC_ADM; + open.hdr.src_domain = APR_DOMAIN_APPS; + open.hdr.src_port = afe_port; + open.hdr.dest_svc = APR_SVC_ADM; + open.hdr.dest_domain = APR_DOMAIN_ADSP; + open.hdr.dest_port = afe_port; + open.hdr.token = port_id << 16 | copp->copp_idx; + open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5; + open.flags = ADM_LEGACY_DEVICE_SESSION; + open.mode_of_operation = path; + open.endpoint_id_1 = afe_port; + open.topology_id = topology; + open.dev_num_channel = channel_mode & 0x00FF; + open.bit_width = bit_width; + open.sample_rate = rate; + + ret = q6dsp_map_channels(&open.dev_channel_mapping[0], + channel_mode); + if (ret) + return ret; + + return q6adm_apr_send_copp_pkt(adm, copp, &open, + ADM_CMDRSP_DEVICE_OPEN_V5); +} + +/** + * q6adm_open() - open adm and grab a free copp + * + * @dev: Pointer to adm child device. + * @port_id: port id + * @path: playback or capture path. + * @rate: rate at which copp is required. + * @channel_mode: channel mode + * @topology: adm topology id + * @perf_mode: performace mode. + * @bit_width: audio sample bit width + * @app_type: Application type. + * @acdb_id: ACDB id + * + * Return: Will be an negative on error or a valid copp index on success. + */ +int q6adm_open(struct device *dev, int port_id, int path, int rate, + int channel_mode, int topology, int perf_mode, + uint16_t bit_width, int app_type, int acdb_id) +{ + struct q6adm *adm = dev_get_drvdata(dev->parent); + struct copp *copp; + int ret = 0; + + if (port_id < 0) { + dev_err(dev, "Invalid port_id 0x%x\n", port_id); + return -EINVAL; + } + + copp = adm_find_matching_copp(adm, port_id, topology, perf_mode, + rate, channel_mode, bit_width, app_type); + if (kref_read(&copp->refcount) == 1) { + /* not initialized yet */ + ret = q6adm_device_open(adm, copp, port_id, path, topology, + channel_mode, bit_width, rate); + if (ret < 0) + return ret; + } + + kref_get(&copp->refcount); + + return copp->copp_idx; +} +EXPORT_SYMBOL_GPL(q6adm_open); + +/** + * q6adm_set_routing_data() - set routing private data + * + * @dev: Pointer to adm device. + * @data: routing private data + * + */ +void q6adm_set_routing_data(struct device *dev, void *data) +{ + struct q6adm *adm = dev_get_drvdata(dev->parent); + + adm->routing_data = data; +} +EXPORT_SYMBOL_GPL(q6adm_set_routing_data); + +/** + * q6adm_get_routing_data() - get routing private data + * + * @dev: Pointer to adm device. + * + * Return: pointer to routing private data + */ +void *q6adm_get_routing_data(struct device *dev) +{ + struct q6adm *adm = dev_get_drvdata(dev->parent); + + return adm->routing_data; +} +EXPORT_SYMBOL_GPL(q6adm_get_routing_data); + +/** + * q6adm_matrix_map() - Map asm streams and afe ports using payload + * + * @dev: Pointer to adm child device. + * @path: playback or capture path. + * @payload_map: map between session id and afe ports. + * @perf_mode: Performace mode. + * + * Return: Will be an negative on error or a zero on success. + */ +int q6adm_matrix_map(struct device *dev, int path, + struct route_payload payload_map, int perf_mode) +{ + struct q6adm *adm = dev_get_drvdata(dev->parent); + struct adm_cmd_matrix_map_routings_v5 *route; + struct adm_session_map_node_v5 *node; + uint16_t *copps_list; + int cmd_size, ret, i, copp_idx; + void *matrix_map = NULL; + struct copp *copp; + + /* Assumes port_ids have already been validated during adm_open */ + cmd_size = (sizeof(*route) + + sizeof(*node) + + (sizeof(uint32_t) * payload_map.num_copps)); + matrix_map = kzalloc(cmd_size, GFP_KERNEL); + if (!matrix_map) + return -ENOMEM; + + route = matrix_map; + route->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + route->hdr.pkt_size = cmd_size; + route->hdr.src_svc = 0; + route->hdr.src_domain = APR_DOMAIN_APPS; + route->hdr.dest_svc = APR_SVC_ADM; + route->hdr.dest_domain = APR_DOMAIN_ADSP; + route->hdr.token = 0; + route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; + route->num_sessions = 1; + + switch (path) { + case ADM_PATH_PLAYBACK: + route->matrix_id = ADM_MATRIX_ID_AUDIO_RX; + break; + case ADM_PATH_LIVE_REC: + route->matrix_id = ADM_MATRIX_ID_AUDIO_TX; + break; + default: + dev_err(dev, "Wrong path set[%d]\n", path); + + break; + } + + node = matrix_map + sizeof(*route); + node->session_id = payload_map.session_id; + node->num_copps = payload_map.num_copps; + copps_list = matrix_map + sizeof(*route) + sizeof(*node); + + for (i = 0; i < payload_map.num_copps; i++) { + int port_idx = payload_map.port_id[i]; + + if (port_idx < 0) { + dev_err(dev, "Invalid port_id 0x%x\n", + payload_map.port_id[i]); + ret = -EINVAL; + goto fail_cmd; + } + copp_idx = payload_map.copp_idx[i]; + + copp = adm_find_copp(adm, port_idx, copp_idx); + if (!copp) { + ret = -EINVAL; + goto fail_cmd; + } + + copps_list[i] = copp->id; + } + + mutex_lock(&adm->lock); + adm->result.status = 0; + adm->result.opcode = 0; + + ret = apr_send_pkt(adm->apr, matrix_map); + if (ret < 0) { + dev_err(dev, "routing for syream %d failed ret %d\n", + payload_map.session_id, ret); + goto fail_cmd; + } + ret = wait_event_timeout(adm->matrix_map_wait, + adm->result.opcode == route->hdr.opcode, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + dev_err(dev, "routing for syream %d failed\n", + payload_map.session_id); + ret = -ETIMEDOUT; + goto fail_cmd; + } else if (adm->result.status > 0) { + dev_err(dev, "DSP returned error[%d]\n", + adm->result.status); + ret = -EINVAL; + goto fail_cmd; + } + +fail_cmd: + mutex_unlock(&adm->lock); + kfree(matrix_map); + return ret; +} +EXPORT_SYMBOL_GPL(q6adm_matrix_map); + +/** + * q6adm_close() - Close adm copp + * + * @dev: Pointer to adm child device. + * @port_id: afe port id. + * @perf_mode: perf_mode mode + * @copp_idx: copp index to close + * + * Return: Will be an negative on error or a zero on success. + */ +int q6adm_close(struct device *dev, int port_id, int perf_mode, int copp_idx) +{ + struct q6adm *adm = dev_get_drvdata(dev->parent); + struct copp *copp; + + if (port_id < 0) { + dev_err(dev, "Invalid port_id 0x%x\n", port_id); + return -EINVAL; + } + + if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { + dev_err(dev, "Invalid copp idx: %d\n", copp_idx); + return -EINVAL; + } + + copp = adm_find_copp(adm, port_id, copp_idx); + if (!copp) + return -EINVAL; + + kref_put(&copp->refcount, adm_free_copp); + + return 0; +} +EXPORT_SYMBOL_GPL(q6adm_close); + +static int q6adm_probe(struct apr_device *adev) +{ + struct device *dev = &adev->dev; + struct device_node *dais_np; + struct q6adm *adm; + + adm = devm_kzalloc(&adev->dev, sizeof(*adm), GFP_KERNEL); + if (!adm) + return -ENOMEM; + + adm->apr = adev; + dev_set_drvdata(&adev->dev, adm); + adm->dev = dev; + q6core_get_svc_api_info(adev->svc_id, &adm->ainfo); + mutex_init(&adm->lock); + init_waitqueue_head(&adm->matrix_map_wait); + + INIT_LIST_HEAD(&adm->copps_list); + spin_lock_init(&adm->copps_list_lock); + + dais_np = of_get_child_by_name(dev->of_node, "routing"); + if (dais_np) { + adm->pdev_routing = of_platform_device_create(dais_np, + "q6routing", dev); + of_node_put(dais_np); + } + + return 0; +} + +static int q6adm_remove(struct apr_device *adev) +{ + struct q6adm *adm = dev_get_drvdata(&adev->dev); + + if (adm->pdev_routing) + of_platform_device_destroy(&adm->pdev_routing->dev, NULL); + + return 0; +} + +static const struct of_device_id q6adm_device_id[] = { + { .compatible = "qcom,q6adm" }, + {}, +}; +MODULE_DEVICE_TABLE(of, q6adm_device_id); + +static struct apr_driver qcom_q6adm_driver = { + .probe = q6adm_probe, + .remove = q6adm_remove, + .callback = q6adm_callback, + .driver = { + .name = "qcom-q6adm", + .of_match_table = of_match_ptr(q6adm_device_id), + }, +}; + +module_apr_driver(qcom_q6adm_driver); +MODULE_DESCRIPTION("Q6 Audio Device Manager"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/qcom/qdsp6/q6adm.h b/sound/soc/qcom/qdsp6/q6adm.h new file mode 100644 index 000000000000..7ad278399ec0 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6adm.h @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __Q6_ADM_V2_H__ +#define __Q6_ADM_V2_H__ + +#define ADM_PATH_PLAYBACK 0x1 +#define ADM_PATH_LIVE_REC 0x2 +#define MAX_COPPS_PER_PORT 8 +#define NULL_COPP_TOPOLOGY 0x00010312 + +/* multiple copp per stream. */ +struct route_payload { + int num_copps; + int session_id; + int copp_idx[MAX_COPPS_PER_PORT]; + int port_id[MAX_COPPS_PER_PORT]; +}; + +int q6adm_open(struct device *dev, int port_id, int path, int rate, + int channel_mode, int topology, int perf_mode, + uint16_t bit_width, int app_type, int acdb_id); +int q6adm_close(struct device *dev, int port, int topology, int perf_mode); +int q6adm_matrix_map(struct device *dev, int path, + struct route_payload payload_map, int perf_mode); + +#endif /* __Q6_ADM_V2_H__ */ From patchwork Sat Mar 10 02:24:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131274 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1691479lja; Fri, 9 Mar 2018 18:29:40 -0800 (PST) X-Google-Smtp-Source: AG47ELsCCOiFA2KEdvsEveADPN87BSsIZQBTaZB1cQbdlIUprMBmcrvFz00BKrYMIIcFN1GckQft X-Received: by 10.28.227.66 with SMTP id a63mr63667wmh.128.1520648980482; Fri, 09 Mar 2018 18:29:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520648980; cv=none; d=google.com; s=arc-20160816; b=bM60rXHD6O+W4PSF/eVE6KDYOMvOyKPkXUpWuNCeaznipWsKdIji66UYz97PM/NmGe Xyq9whL5f7xngHfpZz0HEPiXJP9WhlDRupm3ZJHrlzAkLAIczVDzi+rmXSuo8X8lqIYi WiNXiDRfQl1DIThIBhKSv2QYFT5R1XRB/6BFC+GzmJMcwJjNZh2yFIqgZowmiuwg1ahC emutoDWpfbHuYajRJ58YTM3O1kWbvs55YfAY9pMQPRgfAGc9XaxFxuEEmL1mGNzU+59t 3tAOHsvo8p+NuRgOL0p2tfNQWH054crawmCpA7XGwLCc08IZ4brK9BmP25dhhwRes/II sUsA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=/zvftrhA7+2CWuQeCLI3S0xgRtGHKSnUh1OyysgTaLg=; b=zu5Mp3CngDhXcCwqgdLtR+hltdVGm4D0vQvPBGJHrnNpRttwZb4CyAWMf7hwt0f70G laxJOqWN/1i8g0C5Zl5eJaCeeiPiljyc5nuJmOjSUa1h6GC4yjc0QKs9RXVvH+d/hO1e PXDkIWOx+kowBLnCjQVwDmQUZqB0Y/cNw5i5R7T04SfGEUBumiWPIzfnJxvc7FnzKxeu ZobMJHAkPXguqTzUdT+I/KmcM/GGGNiqN0lwjCwjj/U7qdEbvkzIQVQhPDC+dAlil2t5 usGAHQE5J8cV0bg+PmzJG+8w3HBS8AnrDoApLLzRCMoxYRSN7GUwkSZecGiyqsnBHiqn 8rng== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=kN7zMql1; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id w189si36492wma.171.2018.03.09.18.29.40; Fri, 09 Mar 2018 18:29:40 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=kN7zMql1; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 1CBE92676AB; Sat, 10 Mar 2018 03:28:35 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 72E30267684; Sat, 10 Mar 2018 03:28:04 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by alsa0.perex.cz (Postfix) with ESMTP id C3EA326766D for ; Sat, 10 Mar 2018 03:27:57 +0100 (CET) Received: by mail-wm0-f68.google.com with SMTP id h21so7055159wmd.1 for ; Fri, 09 Mar 2018 18:27:57 -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=sElVrxwi06OIeVBR2HNuZ9qSgfebl4ocPBi3Kxry3MY=; b=kN7zMql1hr9jfUsp+l0VOVDy72gGNZ9Pbryts6rV06qqhYsOUIrgPyedLv0dymhOev XwLjIIZryfEJu/zreIKhK9Hke7XRaF16THHekIiNARLPlaZZfBiu5+MIsnwUH5OSYr0V kB/7w3cwApouAv1F6Uc2zl6GYFkkp/RFLIvF4= 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=sElVrxwi06OIeVBR2HNuZ9qSgfebl4ocPBi3Kxry3MY=; b=pUVJXNppLpvec0hUz7hXF9N2qEjH6mRmBYmLyzQRM9kmd8sJLyrzqasQSFId32IxyO 9lhVAWFr125str7de2f5HIKAeMjR6Hhy+N5erxQMZCRJ8eq8EmwZrftltD30AwCqxsVO PEXzBrNSgZOWhDGJCsdPzrdAhUTKeY9MByB4z9IhBHVCcFtLuZpVcI6/UBCw9bYEBK0S cWduzsVRe5Ljh865bYZd/4vpBGCTuZAoDbu1Q9wR7c0a3Rn0GUQqDTXK9V1hI/Gpekcr H0OdGOzePBArG+PtvQgWP1ufDCjiy0bgFJb1Sdy1aJjJV/GGey7nImny7Qp/XRfHyf0e fMIQ== X-Gm-Message-State: AElRT7EIHFsqOcPCfLMBZJGGWFvG/leKKqbClmKHJ2+23Ok6BGelbdhS bUxiiOr8jnz9PC26VxOveBt0og== X-Received: by 10.28.211.132 with SMTP id k126mr59308wmg.142.1520648877371; Fri, 09 Mar 2018 18:27:57 -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 g78sm21489wmc.31.2018.03.09.18.27.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:27:56 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:44 +0000 Message-Id: <20180310022456.26739-13-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 12/24] ASoC: qdsp6: q6asm: Add q6asm driver X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org From: Srinivas Kandagatla This patch adds basic support to Q6 ASM (Audio Stream Manager) module on Q6DSP. ASM supports up to 8 concurrent streams. each stream can be setup as playback/capture. ASM provides top control functions like Pause/flush/resume for playback and record. ASM can Create/destroy encoder, decoder and also provides POPP dynamic services. This patch adds support to basic features to allow hdmi playback. Signed-off-by: Srinivas Kandagatla --- sound/soc/qcom/Kconfig | 4 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6asm.c | 230 ++++++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6asm.h | 15 +++ 4 files changed, 250 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6asm.c create mode 100644 sound/soc/qcom/qdsp6/q6asm.h -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 5090ffa75648..a07181290624 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -53,12 +53,16 @@ config SND_SOC_QDSP6_AFE config SND_SOC_QDSP6_ADM tristate +config SND_SOC_QDSP6_ASM + tristate + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" depends on QCOM_APR && HAS_DMA select SND_SOC_QDSP6_COMMON select SND_SOC_QDSP6_AFE select SND_SOC_QDSP6_ADM + select SND_SOC_QDSP6_ASM 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 930944425051..eea962315ab3 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o +obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c new file mode 100644 index 000000000000..4ed64d32c6b0 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6asm.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2011-2017, The Linux Foundation +// Copyright (c) 2018, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6asm.h" +#include "q6core.h" +#include "q6dsp-errno.h" +#include "q6dsp-common.h" + +#define ASM_SYNC_IO_MODE 0x0001 +#define ASM_ASYNC_IO_MODE 0x0002 +#define ASM_TUN_READ_IO_MODE 0x0004 /* tunnel read write mode */ +#define ASM_TUN_WRITE_IO_MODE 0x0008 /* tunnel read write mode */ + +struct audio_client { + int session; + q6asm_cb cb; + void *priv; + uint32_t io_mode; + struct apr_device *adev; + struct mutex lock; + wait_queue_head_t cmd_wait; + struct aprv2_ibasic_rsp_result_t result; + int perf_mode; + int stream_id; + struct device *dev; +}; + +struct q6asm { + struct apr_device *adev; + struct device *dev; + struct q6core_svc_api_info ainfo; + wait_queue_head_t mem_wait; + struct platform_device *pcmdev; + struct audio_client *session[MAX_SESSIONS + 1]; + struct platform_device *pdev_dais; +}; + +static bool q6asm_is_valid_audio_client(struct audio_client *ac) +{ + struct q6asm *a = dev_get_drvdata(ac->dev->parent); + int n; + + if (!ac) + return false; + + for (n = 1; n <= MAX_SESSIONS; n++) { + if (a->session[n] == ac) + return true; + } + + return false; +} + +/** + * q6asm_audio_client_free() - Freee allocated audio client + * + * @ac: audio client to free + */ +void q6asm_audio_client_free(struct audio_client *ac) +{ + struct q6asm *a = dev_get_drvdata(ac->dev->parent); + + a->session[ac->session] = NULL; + kfree(ac); +} +EXPORT_SYMBOL_GPL(q6asm_audio_client_free); + +static struct audio_client *q6asm_get_audio_client(struct q6asm *a, + int session_id) +{ + if ((session_id <= 0) || (session_id > MAX_SESSIONS)) { + dev_err(a->dev, "invalid session: %d\n", session_id); + return NULL; + } + + if (!a->session[session_id]) { + dev_err(a->dev, "session not active: %d\n", session_id); + return NULL; + } + + return a->session[session_id]; +} + +static int q6asm_srvc_callback(struct apr_device *adev, + struct apr_client_message *data) +{ + struct aprv2_ibasic_rsp_result_t *result; + 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; + + result = data->payload; + sid = (data->token >> 8) & 0x0F; + ac = q6asm_get_audio_client(q6asm, sid); + if (!ac) { + dev_err(&adev->dev, "Audio Client not active\n"); + return 0; + } + + if (ac->cb) + ac->cb(data->opcode, data->token, data->payload, ac->priv); + + return 0; +} + +/** + * q6asm_get_session_id() - get session id for audio client + * + * @ac: audio client pointer + * + * Return: Will be an session id of the audio client. + */ +int q6asm_get_session_id(struct audio_client *c) +{ + return c->session; +} +EXPORT_SYMBOL_GPL(q6asm_get_session_id); + +/** + * q6asm_audio_client_alloc() - Allocate a new audio client + * + * @dev: Pointer to asm child device. + * @cb: event callback. + * @priv: private data associated with this client. + * + * Return: Will be an error pointer on error or a valid audio client + * on success. + */ +struct audio_client *q6asm_audio_client_alloc(struct device *dev, q6asm_cb cb, + void *priv, int stream_id, + int perf_mode) +{ + struct q6asm *a = dev_get_drvdata(dev->parent); + struct audio_client *ac; + + if (stream_id + 1 > MAX_SESSIONS) + return ERR_PTR(-EINVAL); + + ac = kzalloc(sizeof(*ac), GFP_KERNEL); + if (!ac) + return ERR_PTR(-ENOMEM); + + a->session[stream_id + 1] = ac; + ac->session = stream_id + 1; + ac->cb = cb; + ac->dev = dev; + ac->priv = priv; + ac->io_mode = ASM_SYNC_IO_MODE; + ac->perf_mode = perf_mode; + /* DSP expects stream id from 1 */ + ac->stream_id = 1; + ac->adev = a->adev; + + init_waitqueue_head(&ac->cmd_wait); + mutex_init(&ac->lock); + spin_lock_init(&ac->buf_lock); + + return ac; +} +EXPORT_SYMBOL_GPL(q6asm_audio_client_alloc); + + +static int q6asm_probe(struct apr_device *adev) +{ + struct device *dev = &adev->dev; + struct device_node *dais_np; + struct q6asm *q6asm; + + q6asm = devm_kzalloc(dev, sizeof(*q6asm), GFP_KERNEL); + if (!q6asm) + return -ENOMEM; + + q6core_get_svc_api_info(adev->svc_id, &q6asm->ainfo); + + q6asm->dev = dev; + q6asm->adev = adev; + init_waitqueue_head(&q6asm->mem_wait); + dev_set_drvdata(dev, q6asm); + + dais_np = of_get_child_by_name(dev->of_node, "dais"); + if (dais_np) { + q6asm->pdev_dais = of_platform_device_create(dais_np, + "q6asm-dai", dev); + of_node_put(dais_np); + } + + return 0; +} + +static int q6asm_remove(struct apr_device *adev) +{ + struct q6asm *q6asm = dev_get_drvdata(&adev->dev); + + if (q6asm->pdev_dais) + of_platform_device_destroy(&q6asm->pdev_dais->dev, NULL); + + return 0; +} +static const struct of_device_id q6asm_device_id[] = { + { .compatible = "qcom,q6asm" }, + {}, +}; +MODULE_DEVICE_TABLE(of, q6asm_device_id); + +static struct apr_driver qcom_q6asm_driver = { + .probe = q6asm_probe, + .remove = q6asm_remove, + .callback = q6asm_srvc_callback, + .driver = { + .name = "qcom-q6asm", + .of_match_table = of_match_ptr(q6asm_device_id), + }, +}; + +module_apr_driver(qcom_q6asm_driver); +MODULE_DESCRIPTION("Q6 Audio Stream Manager driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h new file mode 100644 index 000000000000..6a68afc5d8b6 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6asm.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __Q6_ASM_H__ +#define __Q6_ASM_H__ + +#define MAX_SESSIONS 16 + +typedef void (*q6asm_cb) (uint32_t opcode, uint32_t token, + void *payload, void *priv); +struct audio_client; +struct audio_client *q6asm_audio_client_alloc(struct device *dev, + q6asm_cb cb, void *priv, + int session_id, int perf_mode); +void q6asm_audio_client_free(struct audio_client *ac); +int q6asm_get_session_id(struct audio_client *ac); +#endif /* __Q6_ASM_H__ */ From patchwork Sat Mar 10 02:24:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 131279 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp1691950lja; Fri, 9 Mar 2018 18:30:18 -0800 (PST) X-Google-Smtp-Source: AG47ELvV1Zt4xWHzeHDZ/5JQ8Yjll7I6lX6zPv2XFo4XqkJHFDwJVw5UBlh87wuSyV5wtAqY+PAE X-Received: by 10.223.162.152 with SMTP id s24mr413027wra.148.1520649018323; Fri, 09 Mar 2018 18:30:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520649018; cv=none; d=google.com; s=arc-20160816; b=cKUB5LV5XF4Qwys/yvDF3UfMawu+IH9DRQSo2SnyAFPcegkpvD1PMIrlAkIM815jPH 9F2EaIGYKbL3VQWoXW56ixErPDkzsqqUL/gNVl5PoI+PlPr6rTk//jhyvQyHsc4eptod sPoOzujtNPI2goq8H3j0WybKF/HHLAoD3q1fYxlNpgAGH7F2zQhU/83gZa3I3hJZA2k3 41QRyCXR1vEp2lYvSH5o1trzMRHqn0C+lEwx8PYzFPVvi6rq+t/SaokX7qMGEj2HCoEw EAVLLz2mJPLOgSgPXnkPCRNj6uZTftqTyhGQ8chkk8NfUtypHQzn1K1zZEfa2s45XRZX R2jQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=idSt8MWj1F+xUfXx+v4llPTBmNBjDQ3NrgwQURHnVZ0=; b=T7vKoH44VBjiJPTf/Mweuzrv/tq2afK/unilkpne46DSfy7a7juSs7gq9/qNIHzRNj Pd2QIiwQi5KP7G3MJWrNfJSDAti/+VOgoFlIvryUNFO9rhWo/+hAQMYzGQ5uTWqIiWc6 oBxZlA62PNpYEklGCrxKnmVxa6rme1IZcWs72iYQDOKRQN1dy00C7+gPLApIpHfUvUpA BKO+Zr5ou/HaY/vZSLT3h85mrNJMjgiao3wfRTL5zXZGhMG4tAsdCj67NuStUFmp733o 8nAzeZydwJRsWexI+CPrGkO+Q6JSSE/EOVRN0HcCOsd9gTAd35d6esxWLS2LbRaEDwrb JtUg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Jt1hLxx/; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id a13si45894wmg.110.2018.03.09.18.30.18; Fri, 09 Mar 2018 18:30:18 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Jt1hLxx/; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 709F62676D4; Sat, 10 Mar 2018 03:28:55 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 44F4126769E; Sat, 10 Mar 2018 03:28:10 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by alsa0.perex.cz (Postfix) with ESMTP id 952DE26767D for ; Sat, 10 Mar 2018 03:28:01 +0100 (CET) Received: by mail-wm0-f68.google.com with SMTP id w128so7119588wmw.0 for ; Fri, 09 Mar 2018 18:28:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=bigQdqHfoPHrVv/kqUx6ZhNE2NzbZ/jpFVebqhWQSCs=; b=Jt1hLxx/tqvg3HoZPwOY9t3iRGznzYoU40C8q6fEBZmYWCHTwzcEBNK2HbH540xZ9V GllHYmGPVrkKVK8rFOjYTqfCuMiDKh1Cm+2iaFr40oFgRT/vLioBtW2D8A9psQpb7ilW SCFXyAdtQFwR/4WEsvRVgYf1eLj8YNobq+0ws= 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=bigQdqHfoPHrVv/kqUx6ZhNE2NzbZ/jpFVebqhWQSCs=; b=uQAoP73NQz0QFK4/DSP8n6bdvRvd5HHlKStf7ZYFhqTfTmTN9O+ILk7wRkJiXIVtkf S2RnghTQDrGd4CnqK6QOZGQWKlTfoMZ7F7YMbgRzhPYOh/0Us5YefYrz0TLShD4/38dv e1/Y8E/Icml2T5p5uJCjMXjP3DxunkTONrcScRbrbHJ3jA8UUZGphpXNpINChiNRJ+0C g95QWnHWEMdHSlc9rcJKqWqyAbcyYTlYfvbKL3i1EkV9vwVeOWkHaYSLU0Lvs6/m/rUi maMEC3GV1BtLIGHH9pOCyZzXTE2ORwVHn95/KVnT88E6zNiy28JmNal1IeSXwBEdej6Y KQOQ== X-Gm-Message-State: AElRT7GM/qrxCencPsDg8omb9AN3tof75GOKgV87fmsWk+0DrTDKhWc8 fq/SNp6S04/w707thNYmtpjEEw== X-Received: by 10.28.118.20 with SMTP id r20mr53535wmc.145.1520648881172; Fri, 09 Mar 2018 18:28:01 -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 g78sm21489wmc.31.2018.03.09.18.27.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 09 Mar 2018 18:28:00 -0800 (PST) From: srinivas.kandagatla@linaro.org To: andy.gross@linaro.org, broonie@kernel.org, linux-arm-msm@vger.kernel.org, alsa-devel@alsa-project.org, robh+dt@kernel.org Date: Sat, 10 Mar 2018 02:24:47 +0000 Message-Id: <20180310022456.26739-16-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> References: <20180310022456.26739-1-srinivas.kandagatla@linaro.org> Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, bgoswami@codeaurora.org, rohkumar@qti.qualcomm.com, gregkh@linuxfoundation.org, plai@codeaurora.org, lgirdwood@gmail.com, tiwai@suse.com, david.brown@linaro.org, srinivas.kandagatla@linaro.org, linux-arm-kernel@lists.infradead.org, spatakok@qti.qualcomm.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH v4 15/24] ASoC: qdsp6: q6core: Add q6core driver X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.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 | 4 + sound/soc/qcom/qdsp6/Makefile | 1 + sound/soc/qcom/qdsp6/q6core.c | 381 ++++++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/qdsp6/q6core.h | 15 ++ 4 files changed, 401 insertions(+) create mode 100644 sound/soc/qcom/qdsp6/q6core.c create mode 100644 sound/soc/qcom/qdsp6/q6core.h -- 2.15.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index a07181290624..488ee93ee084 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -56,6 +56,9 @@ config SND_SOC_QDSP6_ADM config SND_SOC_QDSP6_ASM tristate +config SND_SOC_QDSP6_CORE + tristate + config SND_SOC_QDSP6 tristate "SoC ALSA audio driver for QDSP6" depends on QCOM_APR && HAS_DMA @@ -63,6 +66,7 @@ config SND_SOC_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 eea962315ab3..61f089bc0d25 100644 --- a/sound/soc/qcom/qdsp6/Makefile +++ b/sound/soc/qcom/qdsp6/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o 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..0d9cef4b7544 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6core.c @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2011-2017, The Linux Foundation +// Copyright (c) 2018, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6core.h" +#include "q6dsp-errno.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 +#define AVCS_CMD_GET_FWK_VERSION 0x001292c +#define AVCS_CMDRSP_GET_FWK_VERSION 0x001292d + +struct avcs_svc_info { + uint32_t service_id; + uint32_t version; +} __packed; + +struct avcs_cmdrsp_get_version { + uint32_t build_id; + uint32_t num_services; + struct avcs_svc_info svc_api_info[]; +} __packed; + +/* for ADSP2.8 and above */ +struct avcs_svc_api_info { + uint32_t service_id; + uint32_t api_version; + uint32_t api_branch_version; +} __packed; + +struct avcs_cmdrsp_get_fwk_version { + uint32_t build_major_version; + uint32_t build_minor_version; + uint32_t build_branch_version; + uint32_t build_subbranch_version; + uint32_t num_services; + struct avcs_svc_api_info svc_api_info[]; +} __packed; + +struct q6core { + struct apr_device *adev; + wait_queue_head_t wait; + uint32_t avcs_state; + struct mutex lock; + bool resp_received; + uint32_t num_services; + struct avcs_cmdrsp_get_fwk_version *fwk_version; + struct avcs_cmdrsp_get_version *svc_version; + bool fwk_version_supported; + bool get_state_supported; + bool get_version_supported; + bool is_version_requested; +}; + +struct q6core *g_core; + +static int q6core_callback(struct apr_device *adev, + struct apr_client_message *data) +{ + struct q6core *core = dev_get_drvdata(&adev->dev); + struct aprv2_ibasic_rsp_result_t *result; + + result = data->payload; + switch (data->opcode) { + case APR_BASIC_RSP_RESULT:{ + result = data->payload; + switch (result->opcode) { + case AVCS_GET_VERSIONS: + if (result->status == ADSP_EUNSUPPORTED) + core->get_version_supported = false; + core->resp_received = true; + break; + case AVCS_CMD_GET_FWK_VERSION: + if (result->status == ADSP_EUNSUPPORTED) + core->fwk_version_supported = false; + core->resp_received = true; + break; + case AVCS_CMD_ADSP_EVENT_GET_STATE: + if (result->status == ADSP_EUNSUPPORTED) + core->get_state_supported = false; + core->resp_received = true; + break; + } + break; + } + case AVCS_CMDRSP_GET_FWK_VERSION: { + struct avcs_cmdrsp_get_fwk_version *fwk; + int bytes; + + fwk = data->payload; + core->fwk_version_supported = true; + bytes = sizeof(*fwk) + fwk->num_services * + sizeof(fwk->svc_api_info[0]); + + core->fwk_version = kzalloc(bytes, GFP_ATOMIC); + if (!core->fwk_version) + return -ENOMEM; + + memcpy(core->fwk_version, data->payload, bytes); + + core->resp_received = true; + + break; + } + case AVCS_GET_VERSIONS_RSP: { + struct avcs_cmdrsp_get_version *v; + int len; + + v = data->payload; + core->get_version_supported = true; + + len = sizeof(*v) + v->num_services * sizeof(v->svc_api_info[0]); + + core->svc_version = kzalloc(len, GFP_ATOMIC); + if (!core->svc_version) + return -ENOMEM; + + memcpy(core->svc_version, data->payload, len); + + core->resp_received = true; + + break; + } + case AVCS_CMDRSP_ADSP_EVENT_GET_STATE: + core->get_state_supported = true; + core->avcs_state = result->opcode; + + core->resp_received = true; + break; + default: + dev_err(&adev->dev, "Message id from adsp core svc: 0x%x\n", + data->opcode); + break; + } + + if (core->resp_received) + wake_up(&core->wait); + + return 0; +} + +static int q6core_get_fwk_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_HDR_SIZE; + hdr.opcode = AVCS_CMD_GET_FWK_VERSION; + + rc = apr_send_pkt(adev, &hdr); + if (rc < 0) + return rc; + + rc = wait_event_timeout(core->wait, (core->resp_received), + msecs_to_jiffies(Q6_READY_TIMEOUT_MS)); + if (rc > 0 && core->resp_received) { + core->resp_received = false; + + if (!core->fwk_version_supported) + return -ENOTSUPP; + else + return 0; + } + + + return rc; +} + +static int q6core_get_svc_versions(struct q6core *core) +{ + struct apr_device *adev = core->adev; + struct apr_hdr hdr = {0}; + int rc; + + core->get_version_supported = true; + hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + hdr.pkt_size = APR_HDR_SIZE; + hdr.opcode = AVCS_GET_VERSIONS; + + rc = apr_send_pkt(adev, &hdr); + if (rc < 0) + return rc; + + rc = wait_event_timeout(core->wait, (core->resp_received), + msecs_to_jiffies(Q6_READY_TIMEOUT_MS)); + if (rc > 0 && core->resp_received) { + core->resp_received = false; + 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; + + core->get_state_supported = false; + + hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + hdr.pkt_size = APR_HDR_SIZE; + hdr.opcode = AVCS_CMD_ADSP_EVENT_GET_STATE; + + rc = apr_send_pkt(adev, &hdr); + if (rc < 0) + return false; + + rc = wait_event_timeout(core->wait, (core->resp_received), + msecs_to_jiffies(Q6_READY_TIMEOUT_MS)); + if (rc > 0 && core->resp_received) { + core->resp_received = false; + + if (core->avcs_state == 0x1) + return true; + } + + /* assume that the adsp is up if we not support this command */ + if (!core->get_state_supported) + return true; + + return false; +} + +/** + * q6core_get_svc_api_info() - Get version number of a service. + * + * @svc_id: service id of the service. + * @info: Valid struct pointer to fill svc api information. + * + * Return: zero on success and error code on failure or unsupported + */ +int q6core_get_svc_api_info(int svc_id, struct q6core_svc_api_info *ainfo) +{ + int i; + int ret = -ENOTSUPP; + + if (!g_core || !ainfo) + return 0; + + mutex_lock(&g_core->lock); + if (!g_core->is_version_requested) { + if (q6core_get_fwk_versions(g_core) == -ENOTSUPP) + q6core_get_svc_versions(g_core); + g_core->is_version_requested = true; + } + + if (g_core->fwk_version_supported) { + for (i = 0; i < g_core->fwk_version->num_services; i++) { + struct avcs_svc_api_info *info; + + info = &g_core->fwk_version->svc_api_info[i]; + if (svc_id != info->service_id) + continue; + + ainfo->api_version = info->api_version; + ainfo->api_branch_version = info->api_branch_version; + ret = 0; + break; + } + } else if (g_core->get_version_supported) { + for (i = 0; i < g_core->svc_version->num_services; i++) { + struct avcs_svc_info *info; + + info = &g_core->svc_version->svc_api_info[i]; + if (svc_id != info->service_id) + continue; + + ainfo->api_version = info->version; + ainfo->api_branch_version = 0; + ret = 0; + break; + } + } + + mutex_unlock(&g_core->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(q6core_get_svc_api_info); + +/** + * q6core_is_adsp_ready() - Get status of adsp + * + * Return: Will be an true if adsp is ready and false if not. + */ +bool q6core_is_adsp_ready(void) +{ + unsigned long timeout; + bool ret = false; + + if (!g_core) + return false; + + mutex_lock(&g_core->lock); + timeout = jiffies + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + for (;;) { + if (__q6core_is_adsp_ready(g_core)) { + ret = true; + break; + } + + if (!time_after(timeout, jiffies)) { + ret = false; + break; + } + } + + mutex_unlock(&g_core->lock); + return ret; +} +EXPORT_SYMBOL_GPL(q6core_is_adsp_ready); + +static int q6core_probe(struct apr_device *adev) +{ + g_core = kzalloc(sizeof(*g_core), GFP_KERNEL); + if (!g_core) + return -ENOMEM; + + dev_set_drvdata(&adev->dev, g_core); + + mutex_init(&g_core->lock); + g_core->adev = adev; + init_waitqueue_head(&g_core->wait); + return 0; +} + +static int q6core_exit(struct apr_device *adev) +{ + struct q6core *core = dev_get_drvdata(&adev->dev); + + if (core->fwk_version_supported) + kfree(core->fwk_version); + if (core->get_version_supported) + kfree(core->svc_version); + + kfree(core); + g_core = NULL; + + return 0; +} + +static const struct of_device_id q6core_device_id[] = { + { .compatible = "qcom,q6core" }, + {}, +}; +MODULE_DEVICE_TABLE(of, q6core_device_id); + +static struct apr_driver qcom_q6core_driver = { + .probe = q6core_probe, + .remove = q6core_exit, + .callback = q6core_callback, + .driver = { + .name = "qcom-q6core", + .of_match_table = of_match_ptr(q6core_device_id), + }, +}; + +module_apr_driver(qcom_q6core_driver); +MODULE_DESCRIPTION("q6 core"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/qcom/qdsp6/q6core.h b/sound/soc/qcom/qdsp6/q6core.h new file mode 100644 index 000000000000..7678abd8fd46 --- /dev/null +++ b/sound/soc/qcom/qdsp6/q6core.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef __Q6CORE_H__ +#define __Q6CORE_H__ + +struct q6core_svc_api_info { + uint32_t service_id; + uint32_t api_version; + uint32_t api_branch_version; +}; + +bool q6core_is_adsp_ready(void); +int q6core_get_svc_api_info(int svc_id, struct q6core_svc_api_info *ainfo); + +#endif /* __Q6CORE_H__ */