All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] ACPI: NHLT: Access and query helpers
@ 2023-07-21  9:47 Cezary Rojewski
  2023-07-21  9:47 ` [PATCH v3 1/4] ACPI: NHLT: Device configuration access interface Cezary Rojewski
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Cezary Rojewski @ 2023-07-21  9:47 UTC (permalink / raw)
  To: rafael, robert.moore
  Cc: linux-acpi, amadeuszx.slawinski, andriy.shevchenko,
	pierre-louis.bossart, Cezary Rojewski

The goal of this patchset is to enhance existing interface of
NonHDAudioLinkTable (NHLT), that is, accessing device and format
configuration spaces as well as adding query functions for finding
specific endpoints and format configurations. Once that is done,
existing sound-drivers can move from utilizing sound/hda/intel-nhlt.c
to this very code and ultimately the former file can be removed.

It's important to highlight that currently presented implementation is
not final and intention is to first transfer sound-driver to new API and
then provide incremental updates to internal code in drivers/acpi/nhlt.c
to improve reliability and safety.

Series starts with addition of devcfg-access helpers. The main reasoning
for adding access function is inability for a user to predict whether
given space (device config) is valid or not. While inheritance in the
specification is allowed, e.g.: mic_devcfg being inherited by
mic_vendor_devcfg, until size is verified, one shall not be accessing
fields which are not guaranteed by the spec. The only field guaranteed
is "capabilities_size".
The xxx_devcfg structs added here kind of duplicate few existing ones
in actbl2.h. This is mainly motivated by usage improvements -
simplicity, shorten wording. Intention is to have them replacing
existing actbl2.h members in the future.

Follow up is the declaration of acpi_gbl_NHLT. Motivation is to make
sound-drivers life easier i.e.: release them from storing pointer to the
first NHLT in the system internally. Such drivers may utilize
acpi_gbl_NHLT when querying endpoints and formats instead.

Table manipulation functions and macros serve as a base for the
follow-up query functions. So called query functions represent standard
operations performed by user (a sound driver) when attempting to open an
audio stream. These more or less mimic what's present in
sound/hda/intel-nhlt.c.

Changes in v3:
- uncapitalized acpi_gbl_NHLT
- fixed compilation problems when CONFIG_ACPI_NHLT is disabled
- dropped Reviewed-by tags in the 2/4 patch due to above, those were not
  one-line changes

Changes in v2:
- minor wording improvements in kernel-doc for patch 3/4
- dropped parentheses around loop cursors in for_each_nhlt_*() macros
- readability improvements in compound if-statements within query
  functions
- dropped NULL-checks in query functions

Cezary Rojewski (4):
  ACPI: NHLT: Device configuration access interface
  ACPI: NHLT: Introduce acpi_gbl_nhlt
  ACPI: NHLT: Table manipulation helpers
  ACPI: NHLT: Add query functions

 drivers/acpi/Kconfig  |   3 +
 drivers/acpi/Makefile |   1 +
 drivers/acpi/nhlt.c   | 221 ++++++++++++++++++++++++++++++++++++++++++
 include/acpi/actbl2.h |  28 ++++++
 include/acpi/nhlt.h   | 212 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 465 insertions(+)
 create mode 100644 drivers/acpi/nhlt.c
 create mode 100644 include/acpi/nhlt.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v3 1/4] ACPI: NHLT: Device configuration access interface
  2023-07-21  9:47 [PATCH v3 0/4] ACPI: NHLT: Access and query helpers Cezary Rojewski
@ 2023-07-21  9:47 ` Cezary Rojewski
  2023-07-21  9:47 ` [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt Cezary Rojewski
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Cezary Rojewski @ 2023-07-21  9:47 UTC (permalink / raw)
  To: rafael, robert.moore
  Cc: linux-acpi, amadeuszx.slawinski, andriy.shevchenko,
	pierre-louis.bossart, Cezary Rojewski

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 <andriy.shevchenko@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 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 <cezary.rojewski@intel.com>
+ *          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ */
+
+#ifndef __ACPI_NHLT_H__
+#define __ACPI_NHLT_H__
+
+#include <linux/acpi.h>
+#include <linux/overflow.h>
+#include <linux/types.h>
+
+#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__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt
  2023-07-21  9:47 [PATCH v3 0/4] ACPI: NHLT: Access and query helpers Cezary Rojewski
  2023-07-21  9:47 ` [PATCH v3 1/4] ACPI: NHLT: Device configuration access interface Cezary Rojewski
@ 2023-07-21  9:47 ` Cezary Rojewski
  2023-07-21 10:48   ` Andy Shevchenko
  2023-07-21  9:47 ` [PATCH v3 3/4] ACPI: NHLT: Table manipulation helpers Cezary Rojewski
  2023-07-21  9:47 ` [PATCH v3 4/4] ACPI: NHLT: Add query functions Cezary Rojewski
  3 siblings, 1 reply; 10+ messages in thread
From: Cezary Rojewski @ 2023-07-21  9:47 UTC (permalink / raw)
  To: rafael, robert.moore
  Cc: linux-acpi, amadeuszx.slawinski, andriy.shevchenko,
	pierre-louis.bossart, Cezary Rojewski

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 <cezary.rojewski@intel.com>
---
 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 <cezary.rojewski@intel.com>
+//          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+//
+
+#include <linux/export.h>
+#include <acpi/nhlt.h>
+
+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__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 3/4] ACPI: NHLT: Table manipulation helpers
  2023-07-21  9:47 [PATCH v3 0/4] ACPI: NHLT: Access and query helpers Cezary Rojewski
  2023-07-21  9:47 ` [PATCH v3 1/4] ACPI: NHLT: Device configuration access interface Cezary Rojewski
  2023-07-21  9:47 ` [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt Cezary Rojewski
@ 2023-07-21  9:47 ` Cezary Rojewski
  2023-07-21  9:47 ` [PATCH v3 4/4] ACPI: NHLT: Add query functions Cezary Rojewski
  3 siblings, 0 replies; 10+ messages in thread
From: Cezary Rojewski @ 2023-07-21  9:47 UTC (permalink / raw)
  To: rafael, robert.moore
  Cc: linux-acpi, amadeuszx.slawinski, andriy.shevchenko,
	pierre-louis.bossart, Cezary Rojewski

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 <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 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)
 
 /*
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 4/4] ACPI: NHLT: Add query functions
  2023-07-21  9:47 [PATCH v3 0/4] ACPI: NHLT: Access and query helpers Cezary Rojewski
                   ` (2 preceding siblings ...)
  2023-07-21  9:47 ` [PATCH v3 3/4] ACPI: NHLT: Table manipulation helpers Cezary Rojewski
@ 2023-07-21  9:47 ` Cezary Rojewski
  3 siblings, 0 replies; 10+ messages in thread
From: Cezary Rojewski @ 2023-07-21  9:47 UTC (permalink / raw)
  To: rafael, robert.moore
  Cc: linux-acpi, amadeuszx.slawinski, andriy.shevchenko,
	pierre-louis.bossart, Cezary Rojewski

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 <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 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 <amadeuszx.slawinski@linux.intel.com>
 //
 
+#define pr_fmt(fmt) "ACPI: NHLT: " fmt
+
 #include <linux/export.h>
 #include <acpi/nhlt.h>
 
@@ -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__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt
  2023-07-21  9:47 ` [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt Cezary Rojewski
@ 2023-07-21 10:48   ` Andy Shevchenko
  2023-07-21 12:44     ` Cezary Rojewski
  0 siblings, 1 reply; 10+ messages in thread
From: Andy Shevchenko @ 2023-07-21 10:48 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: rafael, robert.moore, linux-acpi, amadeuszx.slawinski,
	pierre-louis.bossart

On Fri, Jul 21, 2023 at 11:47:20AM +0200, Cezary Rojewski wrote:
> 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.

...

> @@ -594,6 +594,9 @@ config ACPI_PRMT

> +config ACPI_NHLT

Wouldn't be better to squeeze it to the most ordered piece of the file, so
the list of the table support code files will be kinda ordered?


Otherwise looks good to me, FWIW,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt
  2023-07-21 10:48   ` Andy Shevchenko
@ 2023-07-21 12:44     ` Cezary Rojewski
  2023-07-21 12:55       ` Andy Shevchenko
  0 siblings, 1 reply; 10+ messages in thread
From: Cezary Rojewski @ 2023-07-21 12:44 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: rafael, robert.moore, linux-acpi, amadeuszx.slawinski,
	pierre-louis.bossart

On 2023-07-21 12:48 PM, Andy Shevchenko wrote:
> On Fri, Jul 21, 2023 at 11:47:20AM +0200, Cezary Rojewski wrote:
>> 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.

...

>> @@ -594,6 +594,9 @@ config ACPI_PRMT
> 
>> +config ACPI_NHLT
> 
> Wouldn't be better to squeeze it to the most ordered piece of the file, so
> the list of the table support code files will be kinda ordered?

I may be wrong about this, but it seems that the driver/acpi/Kconfig 
file does not list tables supported in any kind of ordered fashion. I'd 
refrain from reordering the Kconfig in this very patch and rather have 
such job done in a separate series instead.

> Otherwise looks good to me, FWIW,
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt
  2023-07-21 12:44     ` Cezary Rojewski
@ 2023-07-21 12:55       ` Andy Shevchenko
  2023-07-21 13:18         ` Cezary Rojewski
  0 siblings, 1 reply; 10+ messages in thread
From: Andy Shevchenko @ 2023-07-21 12:55 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: rafael, robert.moore, linux-acpi, amadeuszx.slawinski,
	pierre-louis.bossart

On Fri, Jul 21, 2023 at 02:44:42PM +0200, Cezary Rojewski wrote:
> On 2023-07-21 12:48 PM, Andy Shevchenko wrote:
> > On Fri, Jul 21, 2023 at 11:47:20AM +0200, Cezary Rojewski wrote:

...

> > > @@ -594,6 +594,9 @@ config ACPI_PRMT
> > 
> > > +config ACPI_NHLT
> > 
> > Wouldn't be better to squeeze it to the most ordered piece of the file, so
> > the list of the table support code files will be kinda ordered?
> 
> I may be wrong about this, but it seems that the driver/acpi/Kconfig file
> does not list tables supported in any kind of ordered fashion. I'd refrain
> from reordering the Kconfig in this very patch and rather have such job done
> in a separate series instead.

Yes, but my point to make this job easier to whoever will do it.

> > Otherwise looks good to me, FWIW,
> > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt
  2023-07-21 12:55       ` Andy Shevchenko
@ 2023-07-21 13:18         ` Cezary Rojewski
  2023-07-21 13:52           ` Andy Shevchenko
  0 siblings, 1 reply; 10+ messages in thread
From: Cezary Rojewski @ 2023-07-21 13:18 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: rafael, robert.moore, linux-acpi, amadeuszx.slawinski,
	pierre-louis.bossart



On 2023-07-21 2:55 PM, Andy Shevchenko wrote:
> On Fri, Jul 21, 2023 at 02:44:42PM +0200, Cezary Rojewski wrote:
>> On 2023-07-21 12:48 PM, Andy Shevchenko wrote:
>>> On Fri, Jul 21, 2023 at 11:47:20AM +0200, Cezary Rojewski wrote:

...

>>>> @@ -594,6 +594,9 @@ config ACPI_PRMT
>>>
>>>> +config ACPI_NHLT
>>>
>>> Wouldn't be better to squeeze it to the most ordered piece of the file, so
>>> the list of the table support code files will be kinda ordered?
>>
>> I may be wrong about this, but it seems that the driver/acpi/Kconfig file
>> does not list tables supported in any kind of ordered fashion. I'd refrain
>> from reordering the Kconfig in this very patch and rather have such job done
>> in a separate series instead.
> 
> Yes, but my point to make this job easier to whoever will do it.

Hmm.. I see that the most occurrences of word "Table" is around 
ACPI_SPCR_TABLE/_FPDT/LPIT area. Should I put it after ACPI_LPIT perhaps?

>>> Otherwise looks good to me, FWIW,
>>> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt
  2023-07-21 13:18         ` Cezary Rojewski
@ 2023-07-21 13:52           ` Andy Shevchenko
  0 siblings, 0 replies; 10+ messages in thread
From: Andy Shevchenko @ 2023-07-21 13:52 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: rafael, robert.moore, linux-acpi, amadeuszx.slawinski,
	pierre-louis.bossart

On Fri, Jul 21, 2023 at 03:18:11PM +0200, Cezary Rojewski wrote:
> On 2023-07-21 2:55 PM, Andy Shevchenko wrote:
> > On Fri, Jul 21, 2023 at 02:44:42PM +0200, Cezary Rojewski wrote:
> > > On 2023-07-21 12:48 PM, Andy Shevchenko wrote:
> > > > On Fri, Jul 21, 2023 at 11:47:20AM +0200, Cezary Rojewski wrote:

...

> > > > > @@ -594,6 +594,9 @@ config ACPI_PRMT
> > > > 
> > > > > +config ACPI_NHLT
> > > > 
> > > > Wouldn't be better to squeeze it to the most ordered piece of the file, so
> > > > the list of the table support code files will be kinda ordered?
> > > 
> > > I may be wrong about this, but it seems that the driver/acpi/Kconfig file
> > > does not list tables supported in any kind of ordered fashion. I'd refrain
> > > from reordering the Kconfig in this very patch and rather have such job done
> > > in a separate series instead.
> > 
> > Yes, but my point to make this job easier to whoever will do it.
> 
> Hmm.. I see that the most occurrences of word "Table" is around
> ACPI_SPCR_TABLE/_FPDT/LPIT area. Should I put it after ACPI_LPIT perhaps?

Works for me!
As I wrote "most ordered place" and "kinda ordered" above.

> > > > Otherwise looks good to me, FWIW,
> > > > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-07-21 13:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-21  9:47 [PATCH v3 0/4] ACPI: NHLT: Access and query helpers Cezary Rojewski
2023-07-21  9:47 ` [PATCH v3 1/4] ACPI: NHLT: Device configuration access interface Cezary Rojewski
2023-07-21  9:47 ` [PATCH v3 2/4] ACPI: NHLT: Introduce acpi_gbl_nhlt Cezary Rojewski
2023-07-21 10:48   ` Andy Shevchenko
2023-07-21 12:44     ` Cezary Rojewski
2023-07-21 12:55       ` Andy Shevchenko
2023-07-21 13:18         ` Cezary Rojewski
2023-07-21 13:52           ` Andy Shevchenko
2023-07-21  9:47 ` [PATCH v3 3/4] ACPI: NHLT: Table manipulation helpers Cezary Rojewski
2023-07-21  9:47 ` [PATCH v3 4/4] ACPI: NHLT: Add query functions Cezary Rojewski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.