From patchwork Fri Jul 21 15:48:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 705329 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 7BF51C0015E for ; Fri, 21 Jul 2023 15:48:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232240AbjGUPsy (ORCPT ); Fri, 21 Jul 2023 11:48:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49054 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232252AbjGUPsw (ORCPT ); Fri, 21 Jul 2023 11:48:52 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 291E81710 for ; Fri, 21 Jul 2023 08:48:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689954531; x=1721490531; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qtiLhsf1muF68bUesmkIPwplSyQK7i0TnEuGTR4VegA=; b=AMXo+xbHXfPEnyZZWMNRanjtp1ZjlxAKI6WE11a7Vc64HO+nZREUF2vG zcUhWr+77N4rux2xA+kjKD8frK2lLNQ2lOa7qTVt8IKsh6icSCicZO0Cs /ekFnbik82Fdob3em8X8ROaAhGMnjf+twvNY3nhq5tUXmNzb/WqIBh8vJ rhI9lqMESTSCfKUax13NR3jZoLxes2SwO6Emt3G8c0b6sNSVUhDhaUKDe /Re3YlYjhq4eWfUbWYjP6ery84JVoco7fHR0TC2ysc8+k0A5u6kQs+x5N Xxkb6jf/PeRthyda9y5U/CfINF0wOKK9ZVXVqC3O302eqJ0ALPsx9o0wd w==; X-IronPort-AV: E=McAfee;i="6600,9927,10778"; a="357043525" X-IronPort-AV: E=Sophos;i="6.01,222,1684825200"; d="scan'208";a="357043525" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jul 2023 08:48:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.01,202,1684825200"; d="scan'208";a="868275326" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga001.fm.intel.com with ESMTP; 21 Jul 2023 08:48:50 -0700 From: Cezary Rojewski To: rafael@kernel.org Cc: linux-acpi@vger.kernel.org, robert.moore@intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, pierre-louis.bossart@linux.intel.com, Cezary Rojewski Subject: [PATCH v4 1/4] ACPI: NHLT: Device configuration access interface Date: Fri, 21 Jul 2023 17:48:10 +0200 Message-Id: <20230721154813.310996-2-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230721154813.310996-1-cezary.rojewski@intel.com> References: <20230721154813.310996-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 15:48:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 704989 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 17E49EB64DD for ; Fri, 21 Jul 2023 15:48:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229836AbjGUPsz (ORCPT ); Fri, 21 Jul 2023 11:48:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49084 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231481AbjGUPsy (ORCPT ); Fri, 21 Jul 2023 11:48:54 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 33AA31BD for ; Fri, 21 Jul 2023 08:48:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689954533; x=1721490533; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LZJu3jvoTsXJwtvaVYECY5sp0CgYqMoY47klmAFc7Q0=; b=htZqf5TvgGSNwMHt0cv3EoRIWWhEb0a1ZXML34p/x3/enBLOgNED3FZM OJsSmx4TW1UGwPF3X996iUUgOdy4jK8sKKsAMNFIHghF4ITUnV9GCURcu mQaN35CJnn0azVZD8FcNCR/kM37tWuUeutAc8noNnvv/wEa1fSukeNOIq PLFMavwBTrOgdAsxCBF9mem1ZZg0n0Ka3HZ2ZEUtULycucs0o4h/dExJ9 ubZCbvhp0yYohSsyoNb7X/EgjboPDjQBQZC8TjF8eZIU5bPBC2o2GQrzV X7rKt/E40YoVpxq36N5wlhwho2CD4si7mlyAH2m8SmlnAVIGGrq558AtN g==; X-IronPort-AV: E=McAfee;i="6600,9927,10778"; a="357043528" X-IronPort-AV: E=Sophos;i="6.01,222,1684825200"; d="scan'208";a="357043528" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jul 2023 08:48:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.01,202,1684825200"; d="scan'208";a="868275331" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga001.fm.intel.com with ESMTP; 21 Jul 2023 08:48:52 -0700 From: Cezary Rojewski To: rafael@kernel.org Cc: linux-acpi@vger.kernel.org, robert.moore@intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, pierre-louis.bossart@linux.intel.com, Cezary Rojewski Subject: [PATCH v4 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt Date: Fri, 21 Jul 2023 17:48:11 +0200 Message-Id: <20230721154813.310996-3-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230721154813.310996-1-cezary.rojewski@intel.com> References: <20230721154813.310996-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 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..10c16b82a391 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -101,6 +101,9 @@ config ACPI_LPIT depends on X86_64 default y +config ACPI_NHLT + bool + config ACPI_SLEEP bool depends on SUSPEND || HIBERNATION 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 15:48:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 705328 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 006AFEB64DC for ; Fri, 21 Jul 2023 15:49:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231481AbjGUPtE (ORCPT ); Fri, 21 Jul 2023 11:49:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49106 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232252AbjGUPs4 (ORCPT ); Fri, 21 Jul 2023 11:48:56 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E3EE1BD for ; Fri, 21 Jul 2023 08:48:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689954535; x=1721490535; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PlqKy6hW9kRFjbpiqtqOjs5qDex2xducMY9u7GQQluk=; b=N3MV09eFDOcSSbhe/r0XUWI+2+/n3S7DSxXJEn1uGskuE+V/jC+N5L+0 tKHEJ09Gpa19dHuNhOcbcre4os7borc0knKEM0ogv5YBPmWIA9K/1UA0u tscy4PEO31qcoNeFh3JdB1WmNoesxG2pSk5R9F0bs7gTOto8rJ29ChisC ldu/1QZNa7elkZI1ZZnPyHWOK+LqyqY1nA6i5TmFbkQugipvTMAdxizZP Tapr15/4tps1yen5Hc1I8i43RcX5mYMKOqWnRY7A6mYazkGEstvESvljk 4f851cIYiROnjkeemyV1If+W3dAoZliWQEbaKDs4/udregx4b51eVHqwQ A==; X-IronPort-AV: E=McAfee;i="6600,9927,10778"; a="357043532" X-IronPort-AV: E=Sophos;i="6.01,222,1684825200"; d="scan'208";a="357043532" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jul 2023 08:48:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.01,202,1684825200"; d="scan'208";a="868275338" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga001.fm.intel.com with ESMTP; 21 Jul 2023 08:48:54 -0700 From: Cezary Rojewski To: rafael@kernel.org Cc: linux-acpi@vger.kernel.org, robert.moore@intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, pierre-louis.bossart@linux.intel.com, Cezary Rojewski Subject: [PATCH v4 3/4] ACPI: NHLT: Table manipulation helpers Date: Fri, 21 Jul 2023 17:48:12 +0200 Message-Id: <20230721154813.310996-4-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230721154813.310996-1-cezary.rojewski@intel.com> References: <20230721154813.310996-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 15:48:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cezary Rojewski X-Patchwork-Id: 704988 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 CE135EB64DD for ; Fri, 21 Jul 2023 15:49:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232255AbjGUPtF (ORCPT ); Fri, 21 Jul 2023 11:49:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49136 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229689AbjGUPs6 (ORCPT ); Fri, 21 Jul 2023 11:48:58 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4D9919A1 for ; Fri, 21 Jul 2023 08:48:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689954536; x=1721490536; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cySBGfBYVJQ6BEtfhOj4KYgmkkdob9E12qsjuLIfraE=; b=CaHyPucXa/fepdZ+Owbw5kzxOWlbeeEDhlSSlEyp8L1ndVa0H18U76L+ Q9krc04XOytzpks4zmprNNKO0Ydv8DXr6EoUEqRlMRWbLQIencEXMJQud 9s4B7gjWISE3Nyoxpjd3pc9OmqIX20A7lmlpE/qePjPHXf3B9QXL/6lBP sdF4rzd8Pg06mwqVFzfgsAMiW4VqkMJyklzLvfsqubWMPVFr0mLgH8dwE 0UEfsPeNa0I8hCdtgujxbcVj0WDzLRmvxuUqMr9IRFU5HSGCb8Pose/3E S9vsdo4ZImaTe13RRLoUh1+O14JA/oG0rFoMUroNx/KKTzN27zKmGXGkk g==; X-IronPort-AV: E=McAfee;i="6600,9927,10778"; a="357043541" X-IronPort-AV: E=Sophos;i="6.01,222,1684825200"; d="scan'208";a="357043541" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jul 2023 08:48:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.01,202,1684825200"; d="scan'208";a="868275342" Received: from crojewsk-ctrl.igk.intel.com ([10.102.9.28]) by fmsmga001.fm.intel.com with ESMTP; 21 Jul 2023 08:48:55 -0700 From: Cezary Rojewski To: rafael@kernel.org Cc: linux-acpi@vger.kernel.org, robert.moore@intel.com, amadeuszx.slawinski@linux.intel.com, andriy.shevchenko@linux.intel.com, pierre-louis.bossart@linux.intel.com, Cezary Rojewski Subject: [PATCH v4 4/4] ACPI: NHLT: Add query functions Date: Fri, 21 Jul 2023 17:48:13 +0200 Message-Id: <20230721154813.310996-5-cezary.rojewski@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230721154813.310996-1-cezary.rojewski@intel.com> References: <20230721154813.310996-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__ */