From patchwork Fri Jul 21 09:47:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 704997 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 50459C0015E for ; Fri, 21 Jul 2023 09:48:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231825AbjGUJsv (ORCPT ); Fri, 21 Jul 2023 05:48:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59840 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231857AbjGUJsY (ORCPT ); Fri, 21 Jul 2023 05:48:24 -0400 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E2A730E4 for ; Fri, 21 Jul 2023 02:47: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=1689932869; x=1721468869; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qtiLhsf1muF68bUesmkIPwplSyQK7i0TnEuGTR4VegA=; b=Omn+01MrV9rnRUzPNWxtNo8BzAhHTKV8+E7ZKIb9Z9ER3xoW4UQMMDpG IRofGlrHgGaQmr+OrNrBVTouElUHLk0BxyvACczRl9PBtwLUd/83NtIAP zU9fsn7SdRqEAgMpL7zbPVH1SgURCN+mQImMes5hv28dH01wJO+1WUZ9w LhiYxBCYURw/iAuD1kZo9FV5elPicrLYMQ9/elIkMW0CrUTXHEHVofaE6 SphCRlEE5z+VE1gRk5zWI+qYjWZ+F9mBb3kgfIrdKXxBh39M/tDnV1MU7 bksCPZw4OKfIrevtBgRlUfV2mW3+PCelhuRyVl2+909uEgNieNUFyErwP g==; X-IronPort-AV: E=McAfee;i="6600,9927,10777"; a="367022168" X-IronPort-AV: E=Sophos;i="6.01,220,1684825200"; d="scan'208";a="367022168" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jul 2023 02:47:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10777"; a="1055508027" X-IronPort-AV: E=Sophos;i="6.01,220,1684825200"; d="scan'208";a="1055508027" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga005.fm.intel.com with ESMTP; 21 Jul 2023 02:47:31 -0700 From: Cezary Rojewski To: rafael@kernel.org, robert.moore@intel.com Cc: linux-acpi@vger.kernel.org, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, pierre-louis.bossart@linux.intel.com, Cezary Rojewski Subject: [PATCH v3 1/4] ACPI: NHLT: Device configuration access interface Date: Fri, 21 Jul 2023 11:47:19 +0200 Message-Id: <20230721094722.300586-2-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230721094722.300586-1-cezary.rojewski@intel.com> References: <20230721094722.300586-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 Fri Jul 21 09:47:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 705336 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 F0ADEEB64DC for ; Fri, 21 Jul 2023 09:48:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231839AbjGUJsy (ORCPT ); Fri, 21 Jul 2023 05:48:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231880AbjGUJs2 (ORCPT ); Fri, 21 Jul 2023 05:48:28 -0400 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 96D3F3C2F for ; Fri, 21 Jul 2023 02:47:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689932872; x=1721468872; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ntc2AuuLCbxpFb9xi09ep5DSt/dQDflFNekY48H8YSo=; b=ImPtud/jl6RMeq/b65Dy+lc/Pe2gYk6P2qK3BjPlw0+OI3q7x6+f/P0p w0L447LavsmXQRZOcgMmB7Kh9kaZQZkA7H2evQYvqHRIyEeC1QoCkTo27 PT1f1zO4l5DQ1AiYWAc0dq0cAT0bCfHA0f9M6Aot0eednRM1Pg9FbW5jO 12wFUU1L+3FbbRyIsgn7M1Qm962i24/TuVNYL+hCaMSodwC0mo+HyC9wr AYANZBe7WCLo5w2a7BaChuMb2ucJRkd1/t2gdA+4X6rYxgcJgfb6CcYLD +LxoN3PsiRgId3dXxg/GNn5ClmVN6fYxyldmhZpcmZFmVVZ4wf1+vGkjQ A==; X-IronPort-AV: E=McAfee;i="6600,9927,10777"; a="367022174" X-IronPort-AV: E=Sophos;i="6.01,220,1684825200"; d="scan'208";a="367022174" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jul 2023 02:47:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10777"; a="1055508033" X-IronPort-AV: E=Sophos;i="6.01,220,1684825200"; d="scan'208";a="1055508033" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga005.fm.intel.com with ESMTP; 21 Jul 2023 02:47:33 -0700 From: Cezary Rojewski To: rafael@kernel.org, robert.moore@intel.com Cc: linux-acpi@vger.kernel.org, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, pierre-louis.bossart@linux.intel.com, Cezary Rojewski Subject: [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt Date: Fri, 21 Jul 2023 11:47:20 +0200 Message-Id: <20230721094722.300586-3-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230721094722.300586-1-cezary.rojewski@intel.com> References: <20230721094722.300586-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. Signed-off-by: Cezary Rojewski --- drivers/acpi/Kconfig | 3 +++ drivers/acpi/Makefile | 1 + drivers/acpi/nhlt.c | 47 +++++++++++++++++++++++++++++++++++++++++++ include/acpi/nhlt.h | 30 +++++++++++++++++++++++++++ 4 files changed, 81 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..18b2f3752840 --- /dev/null +++ b/drivers/acpi/nhlt.c @@ -0,0 +1,47 @@ +// 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); + +static struct acpi_table_nhlt empty_nhlt = { + .header = { + .signature = ACPI_SIG_NHLT, + }, +}; + +/** + * acpi_nhlt_get_gbl_table - Retrieve a pointer to the first NHLT table. + * + * If there is no NHLT in the system, acpi_gbl_nhlt will instead point to an + * empty table. + * + * Return: ACPI status code of the operation. + */ +acpi_status acpi_nhlt_get_gbl_table(void) +{ + acpi_status status; + + status = acpi_get_table(ACPI_SIG_NHLT, 0, (struct acpi_table_header **)(&acpi_gbl_nhlt)); + if (!acpi_gbl_nhlt) + acpi_gbl_nhlt = &empty_nhlt; + return status; +} +EXPORT_SYMBOL_GPL(acpi_nhlt_get_gbl_table); + +/** + * acpi_nhlt_put_gbl_table - Release the global NHLT table. + */ +void acpi_nhlt_put_gbl_table(void) +{ + acpi_put_table((struct acpi_table_header *)acpi_gbl_nhlt); +} +EXPORT_SYMBOL_GPL(acpi_nhlt_put_gbl_table); diff --git a/include/acpi/nhlt.h b/include/acpi/nhlt.h index af3ec45ba4f9..e68e0534412d 100644 --- a/include/acpi/nhlt.h +++ b/include/acpi/nhlt.h @@ -63,4 +63,34 @@ __cfg->capabilities_size == struct_size(__cfg, mics, __cfg->num_mics) ? \ __cfg : NULL; }) +#if IS_ENABLED(CONFIG_ACPI_NHLT) + +/* + * System-wide pointer to the first NHLT table. + * + * A sound driver may utilize acpi_nhlt_get/put_gbl_table() on its + * initialization and removal respectively to avoid excessive mapping + * and unmapping of the memory occupied by the table between streaming + * operations. + */ +extern struct acpi_table_nhlt *acpi_gbl_nhlt; + +acpi_status acpi_nhlt_get_gbl_table(void); +void acpi_nhlt_put_gbl_table(void); + +#else /* !CONFIG_ACPI_NHLT */ + +#define acpi_gbl_nhlt NULL + +static inline acpi_status acpi_nhlt_get_gbl_table(void) +{ + return AE_NOT_FOUND; +} + +static inline void acpi_nhlt_put_gbl_table(void) +{ +} + +#endif /* CONFIG_ACPI_NHLT */ + #endif /* __ACPI_NHLT_H__ */ From patchwork Fri Jul 21 09:47:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 704996 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 B9CACEB64DC for ; Fri, 21 Jul 2023 09:49:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231845AbjGUJtl (ORCPT ); Fri, 21 Jul 2023 05:49:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59888 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231846AbjGUJsy (ORCPT ); Fri, 21 Jul 2023 05:48:54 -0400 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 600273AAA for ; Fri, 21 Jul 2023 02:48:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689932902; x=1721468902; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PlqKy6hW9kRFjbpiqtqOjs5qDex2xducMY9u7GQQluk=; b=XgncFPzWa24rBzeaxWpNzTqAsrWlyfLSHzBSOjSM60ZcjVy4O8yahsDi KJ1kMxZSASo4SbK9mTnsOzeRAPvDg82eQVZi5rB9cjloUFGzqBR1dOWt9 1fYoUJ7uqmyXL/7EqiJGTnVeoT7I6rAh9l7itgH2xUtMuXvzKN9YfGe6O EwuGsA+HeDkRpco8GaycLfxPLuzj5BIpbUUMIt71V7n01F8n1xcURV8JP LY5IP05o0JTxrGxNgWUUlI+bcpmNiPAG2QnWDij/0EOIH526qXmrw9ZN5 CUdsZbqtIFs9rBP0yBgQ9ZcXjmg1gv53uMUsAYSPCanpLp2KHpqvGpWme Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10777"; a="367022178" X-IronPort-AV: E=Sophos;i="6.01,220,1684825200"; d="scan'208";a="367022178" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jul 2023 02:47:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10777"; a="1055508037" X-IronPort-AV: E=Sophos;i="6.01,220,1684825200"; d="scan'208";a="1055508037" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga005.fm.intel.com with ESMTP; 21 Jul 2023 02:47:35 -0700 From: Cezary Rojewski To: rafael@kernel.org, robert.moore@intel.com Cc: linux-acpi@vger.kernel.org, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, pierre-louis.bossart@linux.intel.com, Cezary Rojewski Subject: [PATCH v3 3/4] ACPI: NHLT: Table manipulation helpers Date: Fri, 21 Jul 2023 11:47:21 +0200 Message-Id: <20230721094722.300586-4-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230721094722.300586-1-cezary.rojewski@intel.com> References: <20230721094722.300586-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 e68e0534412d..9a2e47e49de7 100644 --- a/include/acpi/nhlt.h +++ b/include/acpi/nhlt.h @@ -63,6 +63,74 @@ __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) + #if IS_ENABLED(CONFIG_ACPI_NHLT) /* From patchwork Fri Jul 21 09:47:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 705335 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 45526EB64DC for ; Fri, 21 Jul 2023 09:49:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231975AbjGUJtt (ORCPT ); Fri, 21 Jul 2023 05:49:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231872AbjGUJtQ (ORCPT ); Fri, 21 Jul 2023 05:49:16 -0400 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BC1793AB5 for ; Fri, 21 Jul 2023 02:48:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689932904; x=1721468904; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cySBGfBYVJQ6BEtfhOj4KYgmkkdob9E12qsjuLIfraE=; b=byl075Olg+u9a/3KXdWX9vvR4HmCGNzxc+L2xjBcbD8JIPXNaSbLRxph ea4U3tNcoMI7KAyRlU+ZZwQKM4AMeG2fyDI7gLWs+aRQkMzvhy0xlQyvO PlbeUqEmGYLUknEurfn3LHVsfRzAzqxyTRaXE0ALOdttcqYSwO4QxOwCD CNJhcQFoTzHOjwVc9QuELYwCuwEpHU3wz0nnyJDvwGS8wLFC+xPz543W8 sOTIojKL5kxoHlheg0FAgbq6kHJOgO82QD/+A+wedkX/Lajz6d3u8utAw ld4IzFkU0puuqMAU8mW278D5HKTGdX49JkbbKwVnnE9yC7XJzdTdP+maI A==; X-IronPort-AV: E=McAfee;i="6600,9927,10777"; a="367022180" X-IronPort-AV: E=Sophos;i="6.01,220,1684825200"; d="scan'208";a="367022180" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jul 2023 02:47:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10777"; a="1055508044" X-IronPort-AV: E=Sophos;i="6.01,220,1684825200"; d="scan'208";a="1055508044" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga005.fm.intel.com with ESMTP; 21 Jul 2023 02:47:37 -0700 From: Cezary Rojewski To: rafael@kernel.org, robert.moore@intel.com Cc: linux-acpi@vger.kernel.org, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, pierre-louis.bossart@linux.intel.com, Cezary Rojewski Subject: [PATCH v3 4/4] ACPI: NHLT: Add query functions Date: Fri, 21 Jul 2023 11:47:22 +0200 Message-Id: <20230721094722.300586-5-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230721094722.300586-1-cezary.rojewski@intel.com> References: <20230721094722.300586-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 Reviewed-by: Andy Shevchenko Signed-off-by: Cezary Rojewski --- drivers/acpi/nhlt.c | 174 ++++++++++++++++++++++++++++++++++++++++++++ include/acpi/nhlt.h | 48 ++++++++++++ 2 files changed, 222 insertions(+) diff --git a/drivers/acpi/nhlt.c b/drivers/acpi/nhlt.c index 18b2f3752840..c93ac6fccaea 100644 --- a/drivers/acpi/nhlt.c +++ b/drivers/acpi/nhlt.c @@ -6,6 +6,8 @@ // Amadeusz Slawinski // +#define pr_fmt(fmt) "ACPI: NHLT: " fmt + #include #include @@ -45,3 +47,175 @@ void acpi_nhlt_put_gbl_table(void) acpi_put_table((struct acpi_table_header *)acpi_gbl_nhlt); } EXPORT_SYMBOL_GPL(acpi_nhlt_put_gbl_table); + +/** + * 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 9a2e47e49de7..e537af1cc690 100644 --- a/include/acpi/nhlt.h +++ b/include/acpi/nhlt.h @@ -146,6 +146,20 @@ extern struct acpi_table_nhlt *acpi_gbl_nhlt; acpi_status acpi_nhlt_get_gbl_table(void); void acpi_nhlt_put_gbl_table(void); +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 */ #define acpi_gbl_nhlt NULL @@ -159,6 +173,40 @@ static inline void acpi_nhlt_put_gbl_table(void) { } +static inline 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__ */