public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: crwulff@gmail.com
To: linux-usb@vger.kernel.org
Cc: Pavel Hofman <pavel.hofman@ivitera.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	James Gruber <jimmyjgruber@gmail.com>,
	Jeff Johnson <quic_jjohnson@quicinc.com>,
	John Keeping <jkeeping@inmusicbrands.com>,
	Jonathan Corbet <corbet@lwn.net>, Lee Jones <lee@kernel.org>,
	Perr Zhang <perr@usb7.net>,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Chris Wulff <crwulff@gmail.com>
Subject: [PATCH RFC 01/14] usb: gadget: f_uac: Refactor common configfs attribute defines used in UAC1/2.
Date: Sat, 28 Sep 2024 11:08:52 -0400	[thread overview]
Message-ID: <20240928150905.2616313-2-crwulff@gmail.com> (raw)
In-Reply-To: <20240928150905.2616313-1-crwulff@gmail.com>

From: Chris Wulff <crwulff@gmail.com>

Consolidate a bunch of common #defines used by both f_uac1 and f_uac2
to make it easier to maintain. Only the #defines moved and the same static
functions get created in each module as before. Formatters are also #define
which makes slightly smaller code.

Signed-off-by: Chris Wulff <crwulff@gmail.com>
---
 drivers/usb/gadget/function/f_uac1.c      | 148 +--------------
 drivers/usb/gadget/function/f_uac2.c      | 207 +--------------------
 drivers/usb/gadget/function/u_uac_utils.h | 217 ++++++++++++++++++++++
 3 files changed, 235 insertions(+), 337 deletions(-)
 create mode 100644 drivers/usb/gadget/function/u_uac_utils.h

diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c
index c87e74afc881..eeedcfa61fa1 100644
--- a/drivers/usb/gadget/function/f_uac1.c
+++ b/drivers/usb/gadget/function/f_uac1.c
@@ -19,6 +19,7 @@
 
 #include "u_audio.h"
 #include "u_uac1.h"
+#include "u_uac_utils.h"
 
 /* UAC1 spec: 3.7.2.3 Audio Channel Cluster Format */
 #define UAC1_CHANNEL_MASK 0x0FFF
@@ -1516,151 +1517,18 @@ static struct configfs_item_operations f_uac1_item_ops = {
 	.release	= f_uac1_attr_release,
 };
 
-#define uac1_kstrtou32			kstrtou32
-#define uac1_kstrtos16			kstrtos16
-#define uac1_kstrtobool(s, base, res)	kstrtobool((s), (res))
-
-static const char *u32_fmt = "%u\n";
-static const char *s16_fmt = "%hd\n";
-static const char *bool_fmt = "%u\n";
-
+#define UAC1_ATTR_TO_OPTS struct f_uac1_opts *opts = to_f_uac1_opts(item)
 #define UAC1_ATTRIBUTE(type, name)					\
-static ssize_t f_uac1_opts_##name##_show(				\
-					  struct config_item *item,	\
-					  char *page)			\
-{									\
-	struct f_uac1_opts *opts = to_f_uac1_opts(item);		\
-	int result;							\
-									\
-	mutex_lock(&opts->lock);					\
-	result = sprintf(page, type##_fmt, opts->name);			\
-	mutex_unlock(&opts->lock);					\
-									\
-	return result;							\
-}									\
-									\
-static ssize_t f_uac1_opts_##name##_store(				\
-					  struct config_item *item,	\
-					  const char *page, size_t len)	\
-{									\
-	struct f_uac1_opts *opts = to_f_uac1_opts(item);		\
-	int ret;							\
-	type num;							\
-									\
-	mutex_lock(&opts->lock);					\
-	if (opts->refcnt) {						\
-		ret = -EBUSY;						\
-		goto end;						\
-	}								\
-									\
-	ret = uac1_kstrto##type(page, 0, &num);				\
-	if (ret)							\
-		goto end;						\
-									\
-	opts->name = num;						\
-	ret = len;							\
-									\
-end:									\
-	mutex_unlock(&opts->lock);					\
-	return ret;							\
-}									\
-									\
-CONFIGFS_ATTR(f_uac1_opts_, name)
+	UAC_ATTRIBUTE(f_uac1_opts, UAC1_ATTR_TO_OPTS, opts,		\
+		      opts->lock, opts->refcnt, type, name)
 
 #define UAC1_RATE_ATTRIBUTE(name)					\
-static ssize_t f_uac1_opts_##name##_show(struct config_item *item,	\
-					 char *page)			\
-{									\
-	struct f_uac1_opts *opts = to_f_uac1_opts(item);		\
-	int result = 0;							\
-	int i;								\
-									\
-	mutex_lock(&opts->lock);					\
-	page[0] = '\0';							\
-	for (i = 0; i < UAC_MAX_RATES; i++) {				\
-		if (opts->name##s[i] == 0)				\
-			break;						\
-		result += sprintf(page + strlen(page), "%u,",		\
-				opts->name##s[i]);			\
-	}								\
-	if (strlen(page) > 0)						\
-		page[strlen(page) - 1] = '\n';				\
-	mutex_unlock(&opts->lock);					\
-									\
-	return result;							\
-}									\
-									\
-static ssize_t f_uac1_opts_##name##_store(struct config_item *item,	\
-					  const char *page, size_t len)	\
-{									\
-	struct f_uac1_opts *opts = to_f_uac1_opts(item);		\
-	char *split_page = NULL;					\
-	int ret = -EINVAL;						\
-	char *token;							\
-	u32 num;							\
-	int i;								\
-									\
-	mutex_lock(&opts->lock);					\
-	if (opts->refcnt) {						\
-		ret = -EBUSY;						\
-		goto end;						\
-	}								\
-									\
-	i = 0;								\
-	memset(opts->name##s, 0x00, sizeof(opts->name##s));		\
-	split_page = kstrdup(page, GFP_KERNEL);				\
-	while ((token = strsep(&split_page, ",")) != NULL) {		\
-		ret = kstrtou32(token, 0, &num);			\
-		if (ret)						\
-			goto end;					\
-									\
-		opts->name##s[i++] = num;				\
-		ret = len;						\
-	};								\
-									\
-end:									\
-	kfree(split_page);						\
-	mutex_unlock(&opts->lock);					\
-	return ret;							\
-}									\
-									\
-CONFIGFS_ATTR(f_uac1_opts_, name)
+	UAC_RATE_ATTRIBUTE(f_uac1_opts, UAC1_ATTR_TO_OPTS, opts,	\
+			   opts->lock, opts->refcnt, name)
 
 #define UAC1_ATTRIBUTE_STRING(name)					\
-static ssize_t f_uac1_opts_##name##_show(struct config_item *item,	\
-					 char *page)			\
-{									\
-	struct f_uac1_opts *opts = to_f_uac1_opts(item);		\
-	int result;							\
-									\
-	mutex_lock(&opts->lock);					\
-	result = scnprintf(page, sizeof(opts->name), "%s", opts->name);	\
-	mutex_unlock(&opts->lock);					\
-									\
-	return result;							\
-}									\
-									\
-static ssize_t f_uac1_opts_##name##_store(struct config_item *item,	\
-					  const char *page, size_t len)	\
-{									\
-	struct f_uac1_opts *opts = to_f_uac1_opts(item);		\
-	int ret = 0;							\
-									\
-	mutex_lock(&opts->lock);					\
-	if (opts->refcnt) {						\
-		ret = -EBUSY;						\
-		goto end;						\
-	}								\
-									\
-	ret = scnprintf(opts->name, min(sizeof(opts->name), len),	\
-			"%s", page);					\
-									\
-end:									\
-	mutex_unlock(&opts->lock);					\
-	return ret;							\
-}									\
-									\
-CONFIGFS_ATTR(f_uac1_opts_, name)
+	UAC_ATTRIBUTE_STRING(f_uac1_opts, UAC1_ATTR_TO_OPTS, opts,	\
+			     opts->lock, opts->refcnt, name)
 
 UAC1_ATTRIBUTE(u32, c_chmask);
 UAC1_RATE_ATTRIBUTE(c_srate);
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
index 1cdda44455b3..2142a0951f71 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -17,6 +17,7 @@
 #include "u_audio.h"
 
 #include "u_uac2.h"
+#include "u_uac_utils.h"
 
 /* UAC2 spec: 4.1 Audio Channel Cluster Descriptor */
 #define UAC2_CHANNEL_MASK 0x07FFFFFF
@@ -1877,210 +1878,22 @@ static struct configfs_item_operations f_uac2_item_ops = {
 	.release	= f_uac2_attr_release,
 };
 
-#define uac2_kstrtou8 kstrtou8
-#define uac2_kstrtou32 kstrtou32
-#define uac2_kstrtos16 kstrtos16
-#define uac2_kstrtobool(s, base, res) kstrtobool((s), (res))
-
-static const char *u8_fmt = "%u\n";
-static const char *u32_fmt = "%u\n";
-static const char *s16_fmt = "%hd\n";
-static const char *bool_fmt = "%u\n";
-
+#define UAC2_ATTR_TO_OPTS struct f_uac2_opts *opts = to_f_uac2_opts(item)
 #define UAC2_ATTRIBUTE(type, name)					\
-static ssize_t f_uac2_opts_##name##_show(struct config_item *item,	\
-					 char *page)			\
-{									\
-	struct f_uac2_opts *opts = to_f_uac2_opts(item);		\
-	int result;							\
-									\
-	mutex_lock(&opts->lock);					\
-	result = sprintf(page, type##_fmt, opts->name);			\
-	mutex_unlock(&opts->lock);					\
-									\
-	return result;							\
-}									\
-									\
-static ssize_t f_uac2_opts_##name##_store(struct config_item *item,	\
-					  const char *page, size_t len)	\
-{									\
-	struct f_uac2_opts *opts = to_f_uac2_opts(item);		\
-	int ret;							\
-	type num;							\
-									\
-	mutex_lock(&opts->lock);					\
-	if (opts->refcnt) {						\
-		ret = -EBUSY;						\
-		goto end;						\
-	}								\
-									\
-	ret = uac2_kstrto##type(page, 0, &num);				\
-	if (ret)							\
-		goto end;						\
-									\
-	opts->name = num;						\
-	ret = len;							\
-									\
-end:									\
-	mutex_unlock(&opts->lock);					\
-	return ret;							\
-}									\
-									\
-CONFIGFS_ATTR(f_uac2_opts_, name)
+	UAC_ATTRIBUTE(f_uac2_opts, UAC2_ATTR_TO_OPTS, opts,		\
+		      opts->lock, opts->refcnt, type, name)
 
 #define UAC2_ATTRIBUTE_SYNC(name)					\
-static ssize_t f_uac2_opts_##name##_show(struct config_item *item,	\
-					 char *page)			\
-{									\
-	struct f_uac2_opts *opts = to_f_uac2_opts(item);		\
-	int result;							\
-	char *str;							\
-									\
-	mutex_lock(&opts->lock);					\
-	switch (opts->name) {						\
-	case USB_ENDPOINT_SYNC_ASYNC:					\
-		str = "async";						\
-		break;							\
-	case USB_ENDPOINT_SYNC_ADAPTIVE:				\
-		str = "adaptive";					\
-		break;							\
-	default:							\
-		str = "unknown";					\
-		break;							\
-	}								\
-	result = sprintf(page, "%s\n", str);				\
-	mutex_unlock(&opts->lock);					\
-									\
-	return result;							\
-}									\
-									\
-static ssize_t f_uac2_opts_##name##_store(struct config_item *item,	\
-					  const char *page, size_t len)	\
-{									\
-	struct f_uac2_opts *opts = to_f_uac2_opts(item);		\
-	int ret = 0;							\
-									\
-	mutex_lock(&opts->lock);					\
-	if (opts->refcnt) {						\
-		ret = -EBUSY;						\
-		goto end;						\
-	}								\
-									\
-	if (!strncmp(page, "async", 5))					\
-		opts->name = USB_ENDPOINT_SYNC_ASYNC;			\
-	else if (!strncmp(page, "adaptive", 8))				\
-		opts->name = USB_ENDPOINT_SYNC_ADAPTIVE;		\
-	else {								\
-		ret = -EINVAL;						\
-		goto end;						\
-	}								\
-									\
-	ret = len;							\
-									\
-end:									\
-	mutex_unlock(&opts->lock);					\
-	return ret;							\
-}									\
-									\
-CONFIGFS_ATTR(f_uac2_opts_, name)
+	UAC_ATTRIBUTE_SYNC(f_uac2_opts, UAC2_ATTR_TO_OPTS, opts,	\
+			   opts->lock, opts->refcnt, name)
 
 #define UAC2_RATE_ATTRIBUTE(name)					\
-static ssize_t f_uac2_opts_##name##_show(struct config_item *item,	\
-					 char *page)			\
-{									\
-	struct f_uac2_opts *opts = to_f_uac2_opts(item);		\
-	int result = 0;							\
-	int i;								\
-									\
-	mutex_lock(&opts->lock);					\
-	page[0] = '\0';							\
-	for (i = 0; i < UAC_MAX_RATES; i++) {				\
-		if (opts->name##s[i] == 0)				\
-			break;						\
-		result += sprintf(page + strlen(page), "%u,",		\
-				opts->name##s[i]);			\
-	}								\
-	if (strlen(page) > 0)						\
-		page[strlen(page) - 1] = '\n';				\
-	mutex_unlock(&opts->lock);					\
-									\
-	return result;							\
-}									\
-									\
-static ssize_t f_uac2_opts_##name##_store(struct config_item *item,	\
-					  const char *page, size_t len)	\
-{									\
-	struct f_uac2_opts *opts = to_f_uac2_opts(item);		\
-	char *split_page = NULL;					\
-	int ret = -EINVAL;						\
-	char *token;							\
-	u32 num;							\
-	int i;								\
-									\
-	mutex_lock(&opts->lock);					\
-	if (opts->refcnt) {						\
-		ret = -EBUSY;						\
-		goto end;						\
-	}								\
-									\
-	i = 0;								\
-	memset(opts->name##s, 0x00, sizeof(opts->name##s));		\
-	split_page = kstrdup(page, GFP_KERNEL);				\
-	while ((token = strsep(&split_page, ",")) != NULL) {		\
-		ret = kstrtou32(token, 0, &num);			\
-		if (ret)						\
-			goto end;					\
-									\
-		opts->name##s[i++] = num;				\
-		ret = len;						\
-	};								\
-									\
-end:									\
-	kfree(split_page);						\
-	mutex_unlock(&opts->lock);					\
-	return ret;							\
-}									\
-									\
-CONFIGFS_ATTR(f_uac2_opts_, name)
+	UAC_RATE_ATTRIBUTE(f_uac2_opts, UAC2_ATTR_TO_OPTS, opts,	\
+			   opts->lock, opts->refcnt, name)
 
 #define UAC2_ATTRIBUTE_STRING(name)					\
-static ssize_t f_uac2_opts_##name##_show(struct config_item *item,	\
-					 char *page)			\
-{									\
-	struct f_uac2_opts *opts = to_f_uac2_opts(item);		\
-	int result;							\
-									\
-	mutex_lock(&opts->lock);					\
-	result = scnprintf(page, sizeof(opts->name), "%s", opts->name);	\
-	mutex_unlock(&opts->lock);					\
-									\
-	return result;							\
-}									\
-									\
-static ssize_t f_uac2_opts_##name##_store(struct config_item *item,	\
-					  const char *page, size_t len)	\
-{									\
-	struct f_uac2_opts *opts = to_f_uac2_opts(item);		\
-	int ret = 0;							\
-									\
-	mutex_lock(&opts->lock);					\
-	if (opts->refcnt) {						\
-		ret = -EBUSY;						\
-		goto end;						\
-	}								\
-									\
-	if (len && page[len - 1] == '\n')				\
-		len--;							\
-									\
-	ret = scnprintf(opts->name, min(sizeof(opts->name), len + 1),	\
-			"%s", page);					\
-									\
-end:									\
-	mutex_unlock(&opts->lock);					\
-	return ret;							\
-}									\
-									\
-CONFIGFS_ATTR(f_uac2_opts_, name)
+	UAC_ATTRIBUTE_STRING(f_uac2_opts, UAC2_ATTR_TO_OPTS, opts,	\
+			     opts->lock, opts->refcnt, name)
 
 UAC2_ATTRIBUTE(u32, p_chmask);
 UAC2_RATE_ATTRIBUTE(p_srate);
diff --git a/drivers/usb/gadget/function/u_uac_utils.h b/drivers/usb/gadget/function/u_uac_utils.h
new file mode 100644
index 000000000000..5f88e31103dd
--- /dev/null
+++ b/drivers/usb/gadget/function/u_uac_utils.h
@@ -0,0 +1,217 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * u_uac_utils.h -- Utilities for UAC1/2 function driver
+ *
+ * Copyright (C) 2024
+ * Author: Chris Wulff <crwulff@gmail.com>
+ */
+
+#ifndef __U_UAC_UTILS_H
+#define __U_UAC_UTILS_H
+
+#define uac_kstrtou8			kstrtou8
+#define uac_kstrtos16			kstrtos16
+#define uac_kstrtou32			kstrtou32
+#define uac_kstrtobool(s, base, res)	kstrtobool((s), (res))
+
+#define u8_FMT "%u\n"
+#define u32_FMT "%u\n"
+#define s16_FMT "%hd\n"
+#define bool_FMT "%u\n"
+
+#define UAC_ATTRIBUTE(prefix, to_struct, var, lock, refcnt, type, name) \
+static ssize_t prefix##_##name##_show(struct config_item *item,		\
+				      char *page)			\
+{									\
+	to_struct;							\
+	int result;							\
+									\
+	mutex_lock(&lock);						\
+	result = sprintf(page, type##_FMT, var->name);			\
+	mutex_unlock(&lock);						\
+									\
+	return result;							\
+}									\
+									\
+static ssize_t prefix##_##name##_store(struct config_item *item,	\
+				       const char *page, size_t len)	\
+{									\
+	to_struct;							\
+	int ret;							\
+	type num;							\
+									\
+	mutex_lock(&lock);						\
+	if (refcnt) {							\
+		ret = -EBUSY;						\
+		goto end;						\
+	}								\
+									\
+	ret = uac_kstrto##type(page, 0, &num);				\
+	if (ret)							\
+		goto end;						\
+									\
+	var->name = num;						\
+	ret = len;							\
+									\
+end:									\
+	mutex_unlock(&lock);						\
+	return ret;							\
+}									\
+									\
+CONFIGFS_ATTR(prefix##_, name)
+
+#define UAC_RATE_ATTRIBUTE(prefix, to_struct, var, lock, refcnt, name)	\
+static ssize_t prefix##_##name##_show(struct config_item *item,		\
+				      char *page)			\
+{									\
+	to_struct;							\
+	int result = 0;							\
+	int i;								\
+									\
+	mutex_lock(&lock);						\
+	page[0] = '\0';							\
+	for (i = 0; i < UAC_MAX_RATES; i++) {				\
+		if (var->name##s[i] == 0)				\
+			break;						\
+		result += sprintf(page + strlen(page), "%u,",		\
+				var->name##s[i]);			\
+	}								\
+	if (strlen(page) > 0)						\
+		page[strlen(page) - 1] = '\n';				\
+	mutex_unlock(&lock);						\
+									\
+	return result;							\
+}									\
+									\
+static ssize_t prefix##_##name##_store(struct config_item *item,	\
+				       const char *page, size_t len)	\
+{									\
+	to_struct;							\
+	char *split_page = NULL;					\
+	int ret = -EINVAL;						\
+	char *token;							\
+	u32 num;							\
+	int i;								\
+									\
+	mutex_lock(&lock);						\
+	if (refcnt) {							\
+		ret = -EBUSY;						\
+		goto end;						\
+	}								\
+									\
+	i = 0;								\
+	memset(var->name##s, 0x00, sizeof(var->name##s));		\
+	split_page = kstrdup(page, GFP_KERNEL);				\
+	while ((token = strsep(&split_page, ",")) != NULL) {		\
+		ret = kstrtou32(token, 0, &num);			\
+		if (ret)						\
+			goto end;					\
+									\
+		var->name##s[i++] = num;				\
+		ret = len;						\
+	};								\
+									\
+end:									\
+	kfree(split_page);						\
+	mutex_unlock(&lock);						\
+	return ret;							\
+}									\
+									\
+CONFIGFS_ATTR(prefix##_, name)
+
+#define UAC_ATTRIBUTE_STRING(prefix, to_struct, var, lock, refcnt, name) \
+static ssize_t prefix##_##name##_show(struct config_item *item,		\
+				      char *page)			\
+{									\
+	to_struct;							\
+	int result;							\
+									\
+	mutex_lock(&lock);						\
+	result = scnprintf(page, sizeof(var->name), "%s", var->name);	\
+	mutex_unlock(&lock);						\
+									\
+	return result;							\
+}									\
+									\
+static ssize_t prefix##_##name##_store(struct config_item *item,	\
+				       const char *page, size_t len)	\
+{									\
+	to_struct;							\
+	int ret = 0;							\
+									\
+	mutex_lock(&lock);						\
+	if (refcnt) {							\
+		ret = -EBUSY;						\
+		goto end;						\
+	}								\
+									\
+	if (len && page[len - 1] == '\n')				\
+		len--;							\
+									\
+	ret = scnprintf(var->name, min(sizeof(var->name), len + 1),	\
+			"%s", page);					\
+									\
+end:									\
+	mutex_unlock(&lock);						\
+	return ret;							\
+}									\
+									\
+CONFIGFS_ATTR(prefix##_, name)
+
+#define UAC_ATTRIBUTE_SYNC(prefix, to_struct, var, lock, refcnt, name)	\
+static ssize_t prefix##_##name##_show(struct config_item *item,		\
+				      char *page)			\
+{									\
+	to_struct;							\
+	int result;							\
+	char *str;							\
+									\
+	mutex_lock(&lock);						\
+	switch (var->name) {						\
+	case USB_ENDPOINT_SYNC_ASYNC:					\
+		str = "async";						\
+		break;							\
+	case USB_ENDPOINT_SYNC_ADAPTIVE:				\
+		str = "adaptive";					\
+		break;							\
+	default:							\
+		str = "unknown";					\
+		break;							\
+	}								\
+	result = sprintf(page, "%s\n", str);				\
+	mutex_unlock(&lock);						\
+									\
+	return result;							\
+}									\
+									\
+static ssize_t prefix##_##name##_store(struct config_item *item,	\
+				       const char *page, size_t len)	\
+{									\
+	to_struct;							\
+	int ret = 0;							\
+									\
+	mutex_lock(&lock);						\
+	if (refcnt) {							\
+		ret = -EBUSY;						\
+		goto end;						\
+	}								\
+									\
+	if (!strncmp(page, "async", 5))					\
+		var->name = USB_ENDPOINT_SYNC_ASYNC;			\
+	else if (!strncmp(page, "adaptive", 8))				\
+		var->name = USB_ENDPOINT_SYNC_ADAPTIVE;			\
+	else {								\
+		ret = -EINVAL;						\
+		goto end;						\
+	}								\
+									\
+	ret = len;							\
+									\
+end:									\
+	mutex_unlock(&lock);						\
+	return ret;							\
+}									\
+									\
+CONFIGFS_ATTR(prefix##_, name)
+
+#endif	/* __U_UAC_UTILS_H */
-- 
2.43.0


  reply	other threads:[~2024-09-28 15:09 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-28 15:08 [PATCH RFC 00/14] usb: gadget: f_uac: Add support for alt mode settings crwulff
2024-09-28 15:08 ` crwulff [this message]
2024-09-28 15:08 ` [PATCH RFC 02/14] usb: gadget: f_uac1: Fix fs/hs/ss descriptors to have correct values crwulff
2024-09-28 15:08 ` [PATCH RFC 03/14] usb: gadget: f_uac1: Add adaptive sync support for capture crwulff
2024-09-28 15:08 ` [PATCH RFC 04/14] usb: gadget: f_uac2: Move max packet size code to a common header crwulff
2024-09-28 15:08 ` [PATCH RFC 05/14] usb: gadget: f_uac1: Add hs_bint to configfs crwulff
2024-09-28 15:08 ` [PATCH RFC 06/14] usb: gadget: f_uac1: Add terminal type attributes crwulff
2024-09-28 15:08 ` [PATCH RFC 07/14] usb: gadget: f_uac1: Add alt mode settings interface crwulff
2024-09-28 15:08 ` [PATCH RFC 08/14] usb: gadget: f_uac2: " crwulff
2024-09-28 15:09 ` [PATCH RFC 09/14] usb: gadget: f_uac1: Make string table dynamic with strings from all alt modes crwulff
2024-09-28 15:09 ` [PATCH RFC 10/14] usb: gadget: f_uac2: " crwulff
2024-09-28 15:09 ` [PATCH RFC 11/14] usb: gadget: f_uac1: Generate dynamic descriptors based on alt opts crwulff
2024-09-28 15:09 ` [PATCH RFC 12/14] usb: gadget: f_uac2: " crwulff
2024-09-28 15:09 ` [PATCH RFC 13/14] usb: gadget: f_uac1: support ganged volume/mute controls crwulff
2024-09-28 15:09 ` [PATCH RFC 14/14] usb: gadget: f_uac2: " crwulff

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240928150905.2616313-2-crwulff@gmail.com \
    --to=crwulff@gmail.com \
    --cc=corbet@lwn.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jimmyjgruber@gmail.com \
    --cc=jkeeping@inmusicbrands.com \
    --cc=lee@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=pavel.hofman@ivitera.com \
    --cc=perr@usb7.net \
    --cc=quic_jjohnson@quicinc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox