From patchwork Wed Jul 12 09:10: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: 702315 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 266B4EB64DA for ; Wed, 12 Jul 2023 08:53:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231694AbjGLIxv (ORCPT ); Wed, 12 Jul 2023 04:53:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229610AbjGLIxt (ORCPT ); Wed, 12 Jul 2023 04:53:49 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD0A110C4 for ; Wed, 12 Jul 2023 01:53:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689152022; x=1720688022; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qtiLhsf1muF68bUesmkIPwplSyQK7i0TnEuGTR4VegA=; b=YNwnqJVaWf9533jb4tSIH8HsnfEm/qriKJQwk+5RKLpnlUbYMNrmVB+Z cEckaHQrjyn/+dl5OniQx12j0G/7IBJxOl9RlfsRFIL1WUeySq7f58jLX +oQDtDepAXztwTqrqArZ3Z6Mb039oZCb27ZNq4DDRRKbLlFw7rJUNsn9R yYx3K5SIvwZtfmv93/vzBVGZhHxU+uvdJrf4kaimZVcgvqpu9YZg7pBMH A9kNXqXXoFBLZ3DsMViCyuYSFykt+EH52Q6fLyFIE8jVlB6RzVRRZfsDf NjTuDbMJgZgYDq1+dre0I8ef9/XgNHdE/aI33G+JiAvsRLbltF5QWm+n5 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="363704581" X-IronPort-AV: E=Sophos;i="6.01,199,1684825200"; d="scan'208";a="363704581" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jul 2023 01:53:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="724798339" X-IronPort-AV: E=Sophos;i="6.01,199,1684825200"; d="scan'208";a="724798339" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga007.fm.intel.com with ESMTP; 12 Jul 2023 01:53:22 -0700 From: Cezary Rojewski To: rafael@kernel.org, linux-acpi@vger.kernel.org Cc: robert.moore@intel.com, erik.kaneda@intel.com, pierre-louis.bossart@linux.intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@intel.com, lenb@kernel.org, Cezary Rojewski , Andy Shevchenko Subject: [PATCH 1/4] ACPI: NHLT: Device configuration access interface Date: Wed, 12 Jul 2023 11:10:45 +0200 Message-Id: <20230712091048.2545319-2-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230712091048.2545319-1-cezary.rojewski@intel.com> References: <20230712091048.2545319-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 Wed Jul 12 09:10: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: 701907 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 4B4E1EB64D9 for ; Wed, 12 Jul 2023 08:53:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232757AbjGLIxv (ORCPT ); Wed, 12 Jul 2023 04:53:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45756 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231853AbjGLIxs (ORCPT ); Wed, 12 Jul 2023 04:53:48 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F0A1FB for ; Wed, 12 Jul 2023 01:53:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689152022; x=1720688022; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=m1PZkm+J+sfu8/dx/yiU3qLbX3DK0bRFHAEtw3Th7Q4=; b=F+qeRGF9AlBx/fslyJtYQSLQL+yW10oCdaBqOEE0x4xbWXDOWGIuAt2Q 3YvVlvjKXF0VwGLRZcyMUkf5ddU+KrdQcsCaSAl7+UAITBogZCYCXzVBd 3XRVqJwzF6qLte8wgaah4pXJdSLjZF966G9PyqMXJznv1LnxLGER5RkE8 PgFrSoguJsqvwnRLi9TS8/RjNGCE4xk1Z8UBaSmibiFNB0VKBCaFh/kOB yKlhRjN8O4gr7Ovuv/CIP/w3OpMhQmvEm7X6rooFOJECctH/+zKhcMZGD 2j2Y2GeNVc6zk0p4sH9cgI/NQmx1UqQqGh7ombnDsDn4k9tEq+Aa4J/MG A==; X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="363704588" X-IronPort-AV: E=Sophos;i="6.01,199,1684825200"; d="scan'208";a="363704588" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jul 2023 01:53:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="724798344" X-IronPort-AV: E=Sophos;i="6.01,199,1684825200"; d="scan'208";a="724798344" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga007.fm.intel.com with ESMTP; 12 Jul 2023 01:53:25 -0700 From: Cezary Rojewski To: rafael@kernel.org, linux-acpi@vger.kernel.org Cc: robert.moore@intel.com, erik.kaneda@intel.com, pierre-louis.bossart@linux.intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@intel.com, lenb@kernel.org, Cezary Rojewski , Andy Shevchenko Subject: [PATCH 2/4] ACPI: NHLT: Introduce acpi_gbl_NHLT Date: Wed, 12 Jul 2023 11:10:46 +0200 Message-Id: <20230712091048.2545319-3-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230712091048.2545319-1-cezary.rojewski@intel.com> References: <20230712091048.2545319-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 Wed Jul 12 09:10: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: 701906 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 9F4CFEB64D9 for ; Wed, 12 Jul 2023 08:54:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232118AbjGLIyC (ORCPT ); Wed, 12 Jul 2023 04:54:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231791AbjGLIxy (ORCPT ); Wed, 12 Jul 2023 04:53:54 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB844BE for ; Wed, 12 Jul 2023 01:53:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689152028; x=1720688028; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QLJLLarSnNDpw44tioEvbf2Y47RvKBWuaObIn4/hPXU=; b=BVvEbkSMlIju81eH5M9doRaOCLmvS7SNYssEn+bVKTCGnMvEXjJzxfST Hd5SyRCvEK0bhHUN8iI1ZQjxmEDvjKow5JZmcM65i5Sd2/azZcGWZw6uq COQHXtHzMn7M0798Vc6ISMR/FJJMyeYXAJRHMoHzkhb1QG7VbnU6c2VAp rxuPd9tt0Q9MblXLEEqnbIjHnsgcndIJhqN9OyuA451FJ+RIY1NZ4W5gl sRvPjIkgZr9B6LWCnq+rXS3kwEtiBRtfn3rsWi992vMzHtwF/7ZJr2jf8 CSE6p7IYdbCBoE2erI6m0FzVbuLb/8GraU08s47oq9fxgfVBasXeTYS8p w==; X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="363704594" X-IronPort-AV: E=Sophos;i="6.01,199,1684825200"; d="scan'208";a="363704594" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jul 2023 01:53:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="724798350" X-IronPort-AV: E=Sophos;i="6.01,199,1684825200"; d="scan'208";a="724798350" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga007.fm.intel.com with ESMTP; 12 Jul 2023 01:53:27 -0700 From: Cezary Rojewski To: rafael@kernel.org, linux-acpi@vger.kernel.org Cc: robert.moore@intel.com, erik.kaneda@intel.com, pierre-louis.bossart@linux.intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@intel.com, lenb@kernel.org, Cezary Rojewski Subject: [PATCH 3/4] ACPI: NHLT: Table manipulation helpers Date: Wed, 12 Jul 2023 11:10:47 +0200 Message-Id: <20230712091048.2545319-4-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230712091048.2545319-1-cezary.rojewski@intel.com> References: <20230712091048.2545319-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 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..076aac41a74e 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_xxx() 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 Wed Jul 12 09:10:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 702314 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 9E1F0EB64DA for ; Wed, 12 Jul 2023 08:54:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229742AbjGLIyD (ORCPT ); Wed, 12 Jul 2023 04:54:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45866 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232163AbjGLIxz (ORCPT ); Wed, 12 Jul 2023 04:53:55 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1BE33CF for ; Wed, 12 Jul 2023 01:53:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689152029; x=1720688029; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=URqVmWAvvgTCU8Un0/XjKRSF4qY08iOa8PSt1kj4elo=; b=CPjFVKsGjNi8NRjpM9L7LUSQIOW3/M6PCej+7aQCGchjqzPMGXKWl2ip okkBEgg7Xqt++jwqfTeYGU1Q+Pp2VBFb56z8NMhdVeK09DBZd0AQ5MT9v V5HcupjVMxfapcNvq/RQMMdisi7ndpmeU2N7Jdfduv+sfDEraSUYPn/ZO zf8XQ4CoejzSrcny/Jn1fYnAUfA75B+JrJCs9ZRy4kavrcUp9px5+9dJ7 gFb0X/kAUi6epbgP4swY/HgjJ6wBQvR70501BqFi6++Q3dScEoa0lu2A8 nwqa0EWbMB1120MQS5OLOmHQXQxKO3w0AnSh7KuN+i9S7r9UVHq7yBVN/ A==; X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="363704602" X-IronPort-AV: E=Sophos;i="6.01,199,1684825200"; d="scan'208";a="363704602" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jul 2023 01:53:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="724798356" X-IronPort-AV: E=Sophos;i="6.01,199,1684825200"; d="scan'208";a="724798356" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga007.fm.intel.com with ESMTP; 12 Jul 2023 01:53:29 -0700 From: Cezary Rojewski To: rafael@kernel.org, linux-acpi@vger.kernel.org Cc: robert.moore@intel.com, erik.kaneda@intel.com, pierre-louis.bossart@linux.intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@intel.com, lenb@kernel.org, Cezary Rojewski Subject: [PATCH 4/4] ACPI: NHLT: Add query functions Date: Wed, 12 Jul 2023 11:10:48 +0200 Message-Id: <20230712091048.2545319-5-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230712091048.2545319-1-cezary.rojewski@intel.com> References: <20230712091048.2545319-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 --- drivers/acpi/nhlt.c | 183 ++++++++++++++++++++++++++++++++++++++++++++ include/acpi/nhlt.h | 54 +++++++++++++ 2 files changed, 237 insertions(+) diff --git a/drivers/acpi/nhlt.c b/drivers/acpi/nhlt.c index 90d74d0d803e..c61cdfd78b74 100644 --- a/drivers/acpi/nhlt.c +++ b/drivers/acpi/nhlt.c @@ -6,8 +6,191 @@ // 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) && + (dir < 0 || ep->direction == dir) && + (bus_id < 0 || ep->virtual_bus_id == bus_id); +} +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; + + if (!tb) + return ERR_PTR(-EINVAL); + + 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; + + if (!ep) + return ERR_PTR(-EINVAL); + + for_each_nhlt_endpoint_fmtcfg(ep, fmt) { + wav = &fmt->format; + + if (wav->channel_count == ch && + wav->valid_bits_per_sample == vbps && + wav->bits_per_sample == bps && + wav->samples_per_sec == rate) + 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; + + if (!tb) + return ERR_PTR(-EINVAL); + + 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 076aac41a74e..ba093fe871d5 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__ */