From patchwork Mon Jul 17 15:00:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 13315868 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 93689EB64DC for ; Mon, 17 Jul 2023 15:01:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230359AbjGQPBI (ORCPT ); Mon, 17 Jul 2023 11:01:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230050AbjGQPBB (ORCPT ); Mon, 17 Jul 2023 11:01:01 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E75CBE7F for ; Mon, 17 Jul 2023 08:01:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689606060; x=1721142060; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qtiLhsf1muF68bUesmkIPwplSyQK7i0TnEuGTR4VegA=; b=I1im8oNyFLwMSx5aHGhEzSSYNOkCYBbKU3oCioI/SUqR4a5ZZapIY/4t FYoUgfWt3wRVT48KpmvMT7hw6ASEQxOU0tSd2l5mkAY2xyF9LgipIX7E4 zAFV+k7XrPBAJFEbjLgdcKfiKRP/52hC1p/AMIZfrJYLXvBBujpaGQxJq +4g7vNXuMZl6m8K06KE0RasVmNWlHcdgUYFa5tHDGSHKbR9FsAx03nUGY oNpJW8cw5QKOD2YuhNlZpVXkOsRHImCQ623r+8MJYcSqQMX9OQ0aQp2Av +2YxkzmDeTLBfARnYJ8hlI/5yx7eM5E7pwE47k6i0jBpMZ0nkSL11Yfm2 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="345541886" X-IronPort-AV: E=Sophos;i="6.01,211,1684825200"; d="scan'208";a="345541886" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2023 08:00:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="726567347" X-IronPort-AV: E=Sophos;i="6.01,211,1684825200"; d="scan'208";a="726567347" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga007.fm.intel.com with ESMTP; 17 Jul 2023 08:00:55 -0700 From: Cezary Rojewski To: rafael@kernel.org, linux-acpi@vger.kernel.org Cc: robert.moore@intel.com, pierre-louis.bossart@linux.intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, Cezary Rojewski Subject: [PATCH v2 1/4] ACPI: NHLT: Device configuration access interface Date: Mon, 17 Jul 2023 17:00:44 +0200 Message-Id: <20230717150047.15196-2-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230717150047.15196-1-cezary.rojewski@intel.com> References: <20230717150047.15196-1-cezary.rojewski@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Device configuration structures are plenty so declare a struct for each known variant. As neither of them shall be accessed without verifying the memory block first, introduce macros to make it easy to do so. Link: https://github.com/acpica/acpica/pull/881 Reviewed-by: Andy Shevchenko Reviewed-by: Pierre-Louis Bossart Signed-off-by: Cezary Rojewski --- include/acpi/actbl2.h | 28 ++++++++++++++++++ include/acpi/nhlt.h | 66 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 include/acpi/nhlt.h diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index 0029336775a9..c4c9a3a89ba6 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -2014,6 +2014,25 @@ struct acpi_nhlt_vendor_mic_count { u8 microphone_count; }; +/* The only guaranteed configuration space header. Any other requires validation. */ +struct acpi_nhlt_cfg { + u32 capabilities_size; + u8 capabilities[]; +}; + +struct acpi_nhlt_devcfg { + u32 capabilities_size; + u8 virtual_slot; + u8 config_type; +}; + +struct acpi_nhlt_mic_devcfg { + u32 capabilities_size; + u8 virtual_slot; + u8 config_type; + u8 array_type; +}; + struct acpi_nhlt_vendor_mic_config { u8 type; u8 panel; @@ -2030,6 +2049,15 @@ struct acpi_nhlt_vendor_mic_config { u16 work_horizontal_angle_end; /* -180 - + 180 with 2 deg step */ }; +struct acpi_nhlt_vendor_mic_devcfg { + u32 capabilities_size; + u8 virtual_slot; + u8 config_type; + u8 array_type; + u8 num_mics; + struct acpi_nhlt_vendor_mic_config mics[]; +}; + /* Values for Type field above */ #define ACPI_NHLT_MIC_OMNIDIRECTIONAL 0 diff --git a/include/acpi/nhlt.h b/include/acpi/nhlt.h new file mode 100644 index 000000000000..af3ec45ba4f9 --- /dev/null +++ b/include/acpi/nhlt.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Authors: Cezary Rojewski + * Amadeusz Slawinski + */ + +#ifndef __ACPI_NHLT_H__ +#define __ACPI_NHLT_H__ + +#include +#include +#include + +#define __acpi_nhlt_endpoint_cfg(ep) ((void *)((ep) + 1)) + +/* + * As device configuration spaces present in NHLT tables around the world are + * not following single pattern, first check if 'capabilities_size' is correct + * in respect to size of the specified space type before returning the pointer. + */ +#define __acpi_nhlt_endpoint_devcfg(ep, type) ({ \ + struct acpi_nhlt_cfg *__cfg = __acpi_nhlt_endpoint_cfg(ep); \ + __cfg->capabilities_size >= sizeof(type) ? \ + ((type *)__cfg) : NULL; }) + +/* + * acpi_nhlt_endpoint_devcfg - Test and access device configuration. + * @ep: endpoint for which to retrieve device configuration. + * + * Return: A pointer to device configuration space or NULL if the space's + * 'capabilities_size' is insufficient to cover the nested structure. + */ +#define acpi_nhlt_endpoint_devcfg(ep) \ + __acpi_nhlt_endpoint_devcfg(ep, struct acpi_nhlt_devcfg) + +/* + * acpi_nhlt_endpoint_mic_devcfg - Test and access device configuration. + * @ep: endpoint for which to retrieve device configuration. + * + * Return: A pointer to device configuration space or NULL if the space's + * 'capabilities_size' is insufficient to cover the nested structure. + */ +#define acpi_nhlt_endpoint_mic_devcfg(ep) \ + __acpi_nhlt_endpoint_devcfg(ep, struct acpi_nhlt_mic_devcfg) + +/* + * acpi_nhlt_endpoint_vendor_mic_devcfg - Test and access device configuration. + * @ep: endpoint for which to retrieve device configuration. + * @ptr: pointer to a device configuration structure. + * + * This is the same as acpi_nhlt_endpoint_devcfg(), except that it verifies + * if size of the flexible array following the structure header is also + * reflected in 'capabilities_size'. + * + * Return: A pointer to device configuration space or NULL if the space's + * 'capabilities_size' is insufficient to cover the nested structure. + */ +#define acpi_nhlt_endpoint_vendor_mic_devcfg(ep) ({ \ + struct acpi_nhlt_vendor_mic_devcfg *__cfg = __acpi_nhlt_endpoint_cfg(ep); \ + __cfg->capabilities_size >= sizeof(*__cfg) && \ + __cfg->capabilities_size == struct_size(__cfg, mics, __cfg->num_mics) ? \ + __cfg : NULL; }) + +#endif /* __ACPI_NHLT_H__ */ From patchwork Mon Jul 17 15:00:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 13315869 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A24DC001DC for ; Mon, 17 Jul 2023 15:01:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230340AbjGQPBJ (ORCPT ); Mon, 17 Jul 2023 11:01:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41112 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230338AbjGQPBB (ORCPT ); Mon, 17 Jul 2023 11:01:01 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A74310C0 for ; Mon, 17 Jul 2023 08:01:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689606061; x=1721142061; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=m1PZkm+J+sfu8/dx/yiU3qLbX3DK0bRFHAEtw3Th7Q4=; b=MHRTjyI+0cuJhJgetHTBIjeydz2U8ppyJmlQgIY7I/di9rn8x1lr0vpn PX/nIplYd7rRAvO9V+iRbAqgdF6dWu8tQVBMIuJop25DDJZNozwXD7ZkZ OWPueTGouB7MdcV39fEPZESJcTg6BMA8I+c++6wYc9KmptTOxYZJ6L+a1 5nqjtEQQU+cfYAl6mHIqQUs1Fn7LcS+J8ob4SOGO/gxC86CK59vlJ0420 6l2wgJFGAckfY7Q7hV/Y5MX/xIQ+Kd8Ak4lQnSUM5q1bwMxImKzyYbIFf zw3S84db4JrjbnSM901qaOQcLt/JqXOMmqNXo2yFea89St6d2pjaZcZFS Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="345541894" X-IronPort-AV: E=Sophos;i="6.01,211,1684825200"; d="scan'208";a="345541894" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2023 08:00:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="726567364" X-IronPort-AV: E=Sophos;i="6.01,211,1684825200"; d="scan'208";a="726567364" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga007.fm.intel.com with ESMTP; 17 Jul 2023 08:00:57 -0700 From: Cezary Rojewski To: rafael@kernel.org, linux-acpi@vger.kernel.org Cc: robert.moore@intel.com, pierre-louis.bossart@linux.intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, Cezary Rojewski Subject: [PATCH v2 2/4] ACPI: NHLT: Introduce acpi_gbl_NHLT Date: Mon, 17 Jul 2023 17:00:45 +0200 Message-Id: <20230717150047.15196-3-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230717150047.15196-1-cezary.rojewski@intel.com> References: <20230717150047.15196-1-cezary.rojewski@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org While there is no strict limit to amount of NHLT tables present, usually just the first one is utilized. To simplify implementation of sound drivers, provide publicly accessible pointer. Accessing it after calling acpi_nhlt_get_gbl_table() yields the first NHLT table met during the scan. Reviewed-by: Andy Shevchenko Reviewed-by: Pierre-Louis Bossart Signed-off-by: Cezary Rojewski --- drivers/acpi/Kconfig | 3 +++ drivers/acpi/Makefile | 1 + drivers/acpi/nhlt.c | 13 +++++++++++++ include/acpi/nhlt.h | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 drivers/acpi/nhlt.c diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index ccbeab9500ec..01ce5d3533db 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -594,6 +594,9 @@ config ACPI_PRMT substantially increase computational overhead related to the initialization of some server systems. +config ACPI_NHLT + bool + endif # ACPI config X86_PM_TIMER diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index feb36c0b9446..8de34970e7db 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -93,6 +93,7 @@ obj-$(CONFIG_ACPI) += container.o obj-$(CONFIG_ACPI_THERMAL) += thermal.o obj-$(CONFIG_ACPI_PLATFORM_PROFILE) += platform_profile.o obj-$(CONFIG_ACPI_NFIT) += nfit/ +obj-$(CONFIG_ACPI_NHLT) += nhlt.o obj-$(CONFIG_ACPI_NUMA) += numa/ obj-$(CONFIG_ACPI) += acpi_memhotplug.o obj-$(CONFIG_ACPI_HOTPLUG_IOAPIC) += ioapic.o diff --git a/drivers/acpi/nhlt.c b/drivers/acpi/nhlt.c new file mode 100644 index 000000000000..90d74d0d803e --- /dev/null +++ b/drivers/acpi/nhlt.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include + +struct acpi_table_nhlt *acpi_gbl_NHLT; +EXPORT_SYMBOL_GPL(acpi_gbl_NHLT); diff --git a/include/acpi/nhlt.h b/include/acpi/nhlt.h index af3ec45ba4f9..a2b93b08218f 100644 --- a/include/acpi/nhlt.h +++ b/include/acpi/nhlt.h @@ -13,6 +13,24 @@ #include #include +/* System-wide pointer to the first NHLT table. */ +extern struct acpi_table_nhlt *acpi_gbl_NHLT; + +/* + * A sound driver may utilize the two below on its initialization and removal + * respectively to avoid excessive mapping and unmapping of the memory + * occupied by the table between streaming operations. + */ +static inline acpi_status acpi_nhlt_get_gbl_table(void) +{ + return acpi_get_table(ACPI_SIG_NHLT, 0, (struct acpi_table_header **)(&acpi_gbl_NHLT)); +} + +static inline void acpi_nhlt_put_gbl_table(void) +{ + acpi_put_table((struct acpi_table_header *)acpi_gbl_NHLT); +} + #define __acpi_nhlt_endpoint_cfg(ep) ((void *)((ep) + 1)) /* From patchwork Mon Jul 17 15:00:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 13315870 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C136CEB64DC for ; Mon, 17 Jul 2023 15:01:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230050AbjGQPBO (ORCPT ); Mon, 17 Jul 2023 11:01:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41224 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230357AbjGQPBI (ORCPT ); Mon, 17 Jul 2023 11:01:08 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED94210DF for ; Mon, 17 Jul 2023 08:01:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689606064; x=1721142064; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JcFHFQnXRLMx9P2xVr+Ox8w/iXhzAHMX9YajVnTpC1c=; b=OsN3+2BMpGjXHFhzT6/G9gJ9zWA3oj6SXypNsi6zSjnVmLh33LASYimJ +1kyEl4YoScUK5roS+YvMth+KUro0aQuG1nqcMZ6aOrNzLDA8NFTiped+ oC1fyrDAiDlDG6SmwPQO3uHpAq+2SWNXt5lrOB4urb6S19rY95VnHY4TB A0LWppnXKGH/xPiZ5iRUQq8aqiL5ej2hgZtOTUlkKulXenae3MK26y9Ai cI6n/FE0QYFpf/IjN4XY8IsEA/pRHVj3POqM9YC67qmzL3IZAQkRDuqaU 6yLxI07RsB+286h3nPcr2/hynaZQ+gCb8ig3B0iZt6vj7E++7hnneGdEg Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="345541931" X-IronPort-AV: E=Sophos;i="6.01,211,1684825200"; d="scan'208";a="345541931" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2023 08:01:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="726567386" X-IronPort-AV: E=Sophos;i="6.01,211,1684825200"; d="scan'208";a="726567386" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga007.fm.intel.com with ESMTP; 17 Jul 2023 08:00:59 -0700 From: Cezary Rojewski To: rafael@kernel.org, linux-acpi@vger.kernel.org Cc: robert.moore@intel.com, pierre-louis.bossart@linux.intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, Cezary Rojewski Subject: [PATCH v2 3/4] ACPI: NHLT: Table manipulation helpers Date: Mon, 17 Jul 2023 17:00:46 +0200 Message-Id: <20230717150047.15196-4-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230717150047.15196-1-cezary.rojewski@intel.com> References: <20230717150047.15196-1-cezary.rojewski@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org The table is composed of a range of endpoints with each describing audio formats they support. Thus most of the operations involve iterating over elements of the table. Simplify the process by implementing range of getters. Reviewed-by: Pierre-Louis Bossart Reviewed-by: Andy Shevchenko Signed-off-by: Cezary Rojewski --- include/acpi/nhlt.h | 68 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/include/acpi/nhlt.h b/include/acpi/nhlt.h index a2b93b08218f..90ffa0dc1659 100644 --- a/include/acpi/nhlt.h +++ b/include/acpi/nhlt.h @@ -81,4 +81,72 @@ static inline void acpi_nhlt_put_gbl_table(void) __cfg->capabilities_size == struct_size(__cfg, mics, __cfg->num_mics) ? \ __cfg : NULL; }) +/** + * acpi_nhlt_endpoint_fmtscfg - Get the formats configuration space. + * @ep: the endpoint to retrieve the space for. + * + * Return: A pointer to the formats configuration space. + */ +static inline struct acpi_nhlt_formats_config * +acpi_nhlt_endpoint_fmtscfg(const struct acpi_nhlt_endpoint *ep) +{ + struct acpi_nhlt_cfg *cfg = __acpi_nhlt_endpoint_cfg(ep); + + return (struct acpi_nhlt_formats_config *)((u8 *)(cfg + 1) + cfg->capabilities_size); +} + +#define __acpi_nhlt_first_endpoint(tb) \ + ((void *)(tb + 1)) + +#define __acpi_nhlt_next_endpoint(ep) \ + ((void *)((u8 *)(ep) + (ep)->descriptor_length)) + +#define __acpi_nhlt_get_endpoint(tb, ep, i) \ + ((i) ? __acpi_nhlt_next_endpoint(ep) : __acpi_nhlt_first_endpoint(tb)) + +#define __acpi_nhlt_first_fmtcfg(fmts) \ + ((void *)(fmts + 1)) + +#define __acpi_nhlt_next_fmtcfg(fmt) \ + ((void *)((u8 *)((fmt) + 1) + (fmt)->capability_size)) + +#define __acpi_nhlt_get_fmtcfg(fmts, fmt, i) \ + ((i) ? __acpi_nhlt_next_fmtcfg(fmt) : __acpi_nhlt_first_fmtcfg(fmts)) + +/* + * The for_each_nhlt_*() macros rely on an iterator to deal with the + * variable length of each endpoint structure and the possible presence + * of an OED-Config used by Windows only. + */ + +/** + * for_each_nhlt_endpoint - Iterate over endpoints in a NHLT table. + * @tb: the pointer to a NHLT table. + * @ep: the pointer to endpoint to use as loop cursor. + */ +#define for_each_nhlt_endpoint(tb, ep) \ + for (unsigned int __i = 0; \ + __i < (tb)->endpoint_count && \ + (ep = __acpi_nhlt_get_endpoint(tb, ep, __i)); \ + __i++) + +/** + * for_each_nhlt_fmtcfg - Iterate over format configurations. + * @fmts: the pointer to formats configuration space. + * @fmt: the pointer to format to use as loop cursor. + */ +#define for_each_nhlt_fmtcfg(fmts, fmt) \ + for (unsigned int __i = 0; \ + __i < (fmts)->formats_count && \ + (fmt = __acpi_nhlt_get_fmtcfg(fmts, fmt, __i)); \ + __i++) + +/** + * for_each_nhlt_endpoint_fmtcfg - Iterate over format configurations in an endpoint. + * @ep: the pointer to an endpoint. + * @fmt: the pointer to format to use as loop cursor. + */ +#define for_each_nhlt_endpoint_fmtcfg(ep, fmt) \ + for_each_nhlt_fmtcfg(acpi_nhlt_endpoint_fmtscfg(ep), fmt) + #endif /* __ACPI_NHLT_H__ */ From patchwork Mon Jul 17 15:00:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 13315871 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 136ECEB64DC for ; Mon, 17 Jul 2023 15:01:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229786AbjGQPBX (ORCPT ); Mon, 17 Jul 2023 11:01:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230227AbjGQPBM (ORCPT ); Mon, 17 Jul 2023 11:01:12 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16C8510F8 for ; Mon, 17 Jul 2023 08:01:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689606066; x=1721142066; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fgSVnz+4SoC7+xCUYeWfLAzf4lPNcPBkExpp0MX3h8A=; b=DK04Mtp3foKoC/XsyyOdzHyx1HDNm6WmecLli8c8fJ6YlQ/xjuz/rih6 nZITcu3z3yooj/oDIjOuXElxUCpZ+90WW/VDcH/EM/ORaneZStnGjHYxr 4yG5IYv/h/VIkZRNa5alRinhiEA6xlFHrfB8u/l9AMWaTIoq0Z/44WcZP uHeCM+UPFdL8/OjcKiK8GRQkpUoiAd6flgz/9DuMcI3lGvIVGGYT+2904 XgyzihzN5y5reiN1oO89JaEcLyUETczp3SVqygGzgI1dNRxhbRhc753TA Or4md44ghdiz7V7FIGhD+EH8/hmGv42d1r/Qj2qYvINHR8tAiXeQNsyi/ A==; X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="345541948" X-IronPort-AV: E=Sophos;i="6.01,211,1684825200"; d="scan'208";a="345541948" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2023 08:01:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="726567416" X-IronPort-AV: E=Sophos;i="6.01,211,1684825200"; d="scan'208";a="726567416" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga007.fm.intel.com with ESMTP; 17 Jul 2023 08:01:01 -0700 From: Cezary Rojewski To: rafael@kernel.org, linux-acpi@vger.kernel.org Cc: robert.moore@intel.com, pierre-louis.bossart@linux.intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, Cezary Rojewski Subject: [PATCH v2 4/4] ACPI: NHLT: Add query functions Date: Mon, 17 Jul 2023 17:00:47 +0200 Message-Id: <20230717150047.15196-5-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230717150047.15196-1-cezary.rojewski@intel.com> References: <20230717150047.15196-1-cezary.rojewski@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org With iteration helpers added there is a room for more complex query tasks which are commonly performed by sound drivers. Implement them in common API so that a unified mechanism is available for all of them. While the acpi_nhlt_endpoint_dmic_count() stands out a bit, it is a critical component for any AudioDSP driver to know how many digital microphones it is dealing with. There is no one perfect method, but the best one available is provided. Reviewed-by: Pierre-Louis Bossart Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko --- drivers/acpi/nhlt.c | 174 ++++++++++++++++++++++++++++++++++++++++++++ include/acpi/nhlt.h | 54 ++++++++++++++ 2 files changed, 228 insertions(+) diff --git a/drivers/acpi/nhlt.c b/drivers/acpi/nhlt.c index 90d74d0d803e..9d33266f4663 100644 --- a/drivers/acpi/nhlt.c +++ b/drivers/acpi/nhlt.c @@ -6,8 +6,182 @@ // Amadeusz Slawinski // +#define pr_fmt(fmt) "ACPI: NHLT: " fmt + #include #include struct acpi_table_nhlt *acpi_gbl_NHLT; EXPORT_SYMBOL_GPL(acpi_gbl_NHLT); + +/** + * acpi_nhlt_endpoint_match - Verify if an endpoint matches criteria. + * @ep: the endpoint to check. + * @link_type: the hardware link type, e.g.: PDM or SSP. + * @dev_type: the device type. + * @dir: stream direction. + * @bus_id: the ID of virtual bus hosting the endpoint. + * + * Either of @link_type, @dev_type, @dir or @bus_id may be set to a negative + * value to ignore the parameter when matching. + * + * Return: %true if endpoint matches specified criteria or %false otherwise. + */ +bool acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep, + int link_type, int dev_type, int dir, int bus_id) +{ + return ep && + (link_type < 0 || ep->link_type == link_type) && + (dev_type < 0 || ep->device_type == dev_type) && + (bus_id < 0 || ep->virtual_bus_id == bus_id) && + (dir < 0 || ep->direction == dir); +} +EXPORT_SYMBOL_GPL(acpi_nhlt_endpoint_match); + +/** + * acpi_nhlt_find_endpoint - Search a NHLT table for an endpoint. + * @tb: the table to search. + * @link_type: the hardware link type, e.g.: PDM or SSP. + * @dev_type: the device type. + * @dir: stream direction. + * @bus_id: the ID of virtual bus hosting the endpoint. + * + * Either of @link_type, @dev_type, @dir or @bus_id may be set to a negative + * value to ignore the parameter during the search. + * + * Return: A pointer to endpoint matching the criteria, %NULL if not found or + * an ERR_PTR() otherwise. + */ +struct acpi_nhlt_endpoint * +acpi_nhlt_find_endpoint(const struct acpi_table_nhlt *tb, + int link_type, int dev_type, int dir, int bus_id) +{ + struct acpi_nhlt_endpoint *ep; + + for_each_nhlt_endpoint(tb, ep) + if (acpi_nhlt_endpoint_match(ep, link_type, dev_type, dir, bus_id)) + return ep; + return NULL; +} +EXPORT_SYMBOL_GPL(acpi_nhlt_find_endpoint); + +/** + * acpi_nhlt_endpoint_find_fmtcfg - Search endpoint's formats configuration space + * for a specific format. + * @ep: the endpoint to search. + * @ch: number of channels. + * @rate: samples per second. + * @vbps: valid bits per sample. + * @bps: bits per sample. + * + * Return: A pointer to format matching the criteria, %NULL if not found or + * an ERR_PTR() otherwise. + */ +struct acpi_nhlt_format_config * +acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep, + u16 ch, u32 rate, u16 vbps, u16 bps) +{ + struct acpi_nhlt_wave_extensible *wav; + struct acpi_nhlt_format_config *fmt; + + for_each_nhlt_endpoint_fmtcfg(ep, fmt) { + wav = &fmt->format; + + if (wav->valid_bits_per_sample == vbps && + wav->samples_per_sec == rate && + wav->bits_per_sample == bps && + wav->channel_count == ch) + return fmt; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(acpi_nhlt_endpoint_find_fmtcfg); + +/** + * acpi_nhlt_find_fmtcfg - Search a NHLT table for a specific format. + * @tb: the table to search. + * @link_type: the hardware link type, e.g.: PDM or SSP. + * @dev_type: the device type. + * @dir: stream direction. + * @bus_id: the ID of virtual bus hosting the endpoint. + * + * @ch: number of channels. + * @rate: samples per second. + * @vbps: valid bits per sample. + * @bps: bits per sample. + * + * Either of @link_type, @dev_type, @dir or @bus_id may be set to a negative + * value to ignore the parameter during the search. + * + * Return: A pointer to format matching the criteria, %NULL if not found or + * an ERR_PTR() otherwise. + */ +struct acpi_nhlt_format_config * +acpi_nhlt_find_fmtcfg(const struct acpi_table_nhlt *tb, + int link_type, int dev_type, int dir, int bus_id, + u16 ch, u32 rate, u16 vbps, u16 bps) +{ + struct acpi_nhlt_format_config *fmt; + struct acpi_nhlt_endpoint *ep; + + for_each_nhlt_endpoint(tb, ep) { + if (!acpi_nhlt_endpoint_match(ep, link_type, dev_type, dir, bus_id)) + continue; + + fmt = acpi_nhlt_endpoint_find_fmtcfg(ep, ch, rate, vbps, bps); + if (fmt) + return fmt; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(acpi_nhlt_find_fmtcfg); + +/** + * acpi_nhlt_endpoint_dmic_count - Retrieve number of digital microphones for a PDM endpoint. + * @ep: the endpoint to return microphones count for. + * + * Return: A number of microphones or an error code if an invalid endpoint is provided. + */ +int acpi_nhlt_endpoint_dmic_count(const struct acpi_nhlt_endpoint *ep) +{ + struct acpi_nhlt_vendor_mic_devcfg *vendor_cfg; + struct acpi_nhlt_format_config *fmt; + struct acpi_nhlt_mic_devcfg *devcfg; + u16 max_ch = 0; + + if (!ep || ep->link_type != ACPI_NHLT_PDM) + return -EINVAL; + + /* Find max number of channels based on formats configuration. */ + for_each_nhlt_endpoint_fmtcfg(ep, fmt) + max_ch = max(fmt->format.channel_count, max_ch); + + /* If @ep not a mic array, fallback to channels count. */ + devcfg = acpi_nhlt_endpoint_mic_devcfg(ep); + if (!devcfg || devcfg->config_type != ACPI_NHLT_CONFIG_TYPE_MIC_ARRAY) + return max_ch; + + switch (devcfg->array_type) { + case ACPI_NHLT_SMALL_LINEAR_2ELEMENT: + case ACPI_NHLT_BIG_LINEAR_2ELEMENT: + return 2; + + case ACPI_NHLT_FIRST_GEOMETRY_LINEAR_4ELEMENT: + case ACPI_NHLT_PLANAR_LSHAPED_4ELEMENT: + case ACPI_NHLT_SECOND_GEOMETRY_LINEAR_4ELEMENT: + return 4; + + case ACPI_NHLT_VENDOR_DEFINED: + vendor_cfg = acpi_nhlt_endpoint_vendor_mic_devcfg(ep); + if (!vendor_cfg) + return -EINVAL; + return vendor_cfg->num_mics; + + default: + pr_warn("undefined mic array type: %#x\n", devcfg->array_type); + return max_ch; + } +} +EXPORT_SYMBOL_GPL(acpi_nhlt_endpoint_dmic_count); diff --git a/include/acpi/nhlt.h b/include/acpi/nhlt.h index 90ffa0dc1659..4caada011267 100644 --- a/include/acpi/nhlt.h +++ b/include/acpi/nhlt.h @@ -149,4 +149,58 @@ acpi_nhlt_endpoint_fmtscfg(const struct acpi_nhlt_endpoint *ep) #define for_each_nhlt_endpoint_fmtcfg(ep, fmt) \ for_each_nhlt_fmtcfg(acpi_nhlt_endpoint_fmtscfg(ep), fmt) +#if IS_ENABLED(CONFIG_ACPI_NHLT) + +bool acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep, + int link_type, int dev_type, int dir, int bus_id); +struct acpi_nhlt_endpoint * +acpi_nhlt_find_endpoint(const struct acpi_table_nhlt *tb, + int link_type, int dev_type, int dir, int bus_id); +struct acpi_nhlt_format_config * +acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep, + u16 ch, u32 rate, u16 vbps, u16 bps); +struct acpi_nhlt_format_config * +acpi_nhlt_find_fmtcfg(const struct acpi_table_nhlt *tb, + int link_type, int dev_type, int dir, int bus_id, + u16 ch, u32 rate, u16 vpbs, u16 bps); +int acpi_nhlt_endpoint_dmic_count(const struct acpi_nhlt_endpoint *ep); + +#else /* !CONFIG_ACPI_NHLT */ + +static bool +acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep, + int link_type, int dev_type, int dir, int bus_id) +{ + return false; +} + +static inline struct acpi_nhlt_endpoint * +acpi_nhlt_find_endpoint(const struct acpi_table_nhlt *tb, + int link_type, int dev_type, int dir, int bus_id) +{ + return NULL; +} + +static inline struct acpi_nhlt_format_config * +acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep, + u16 ch, u32 rate, u16 vbps, u16 bps) +{ + return NULL; +} + +static inline struct acpi_nhlt_format_config * +acpi_nhlt_find_fmtcfg(const struct acpi_table_nhlt *tb, + int link_type, int dev_type, int dir, int bus_id, + u16 ch, u32 rate, u16 vpbs, u16 bps); +{ + return NULL; +} + +static inline int acpi_nhlt_endpoint_dmic_count(const struct acpi_nhlt_endpoint *ep) +{ + return 0; +} + +#endif /* !CONFIG_ACPI_NHLT */ + #endif /* __ACPI_NHLT_H__ */