Commit 744eb7b8 authored by Daniel Scally's avatar Daniel Scally Committed by Greg Kroah-Hartman
Browse files

usb: gadget: uvc: Add struct for color matching in configs



Color matching descriptors are meant to be a per-format piece of data
and we need to be able to support different descriptors for different
formats. As a preliminary step towards that goal, switch the default
color matching configfs functionality to point to an instance of a
new struct uvcg_color_matching. Use the same default values for its
attributes as the currently hard-coded ones so that the interface to
userspace is consistent.

Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarDaniel Scally <dan.scally@ideasonboard.com>
Link: https://lore.kernel.org/r/20230202114142.300858-3-dan.scally@ideasonboard.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e16cab9c
Loading
Loading
Loading
Loading
+44 −14
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include "uvc_configfs.h"

#include <linux/sort.h>
#include <linux/usb/video.h>

/* -----------------------------------------------------------------------------
 * Global Utility Structures and Macros
@@ -1841,20 +1842,21 @@ static ssize_t uvcg_color_matching_##cname##_show( \
	struct config_item *item, char *page)				\
{									\
	struct config_group *group = to_config_group(item);		\
	struct uvcg_color_matching *color_match =			\
		to_uvcg_color_matching(group);				\
	struct f_uvc_opts *opts;					\
	struct config_item *opts_item;					\
	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
	struct uvc_color_matching_descriptor *cd;			\
	int result;							\
									\
	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
									\
	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;	\
	opts = to_f_uvc_opts(opts_item);				\
	cd = &opts->uvc_color_matching;					\
									\
	mutex_lock(&opts->lock);					\
	result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname));	\
	result = sprintf(page, "%u\n",					\
			 le##bits##_to_cpu(color_match->desc.aname));	\
	mutex_unlock(&opts->lock);					\
									\
	mutex_unlock(su_mutex);						\
@@ -1876,29 +1878,57 @@ static struct configfs_attribute *uvcg_color_matching_attrs[] = {
	NULL,
};

static const struct uvcg_config_group_type uvcg_color_matching_type = {
	.type = {
		.ct_item_ops	= &uvcg_config_item_ops,
static void uvcg_color_matching_release(struct config_item *item)
{
	struct uvcg_color_matching *color_match =
		to_uvcg_color_matching(to_config_group(item));

	kfree(color_match);
}

static struct configfs_item_operations uvcg_color_matching_item_ops = {
	.release	= uvcg_color_matching_release,
};

static const struct config_item_type uvcg_color_matching_type = {
	.ct_item_ops	= &uvcg_color_matching_item_ops,
	.ct_attrs	= uvcg_color_matching_attrs,
	.ct_owner	= THIS_MODULE,
	},
	.name = "default",
};

/* -----------------------------------------------------------------------------
 * streaming/color_matching
 */

static int uvcg_color_matching_create_children(struct config_group *parent)
{
	struct uvcg_color_matching *color_match;

	color_match = kzalloc(sizeof(*color_match), GFP_KERNEL);
	if (!color_match)
		return -ENOMEM;

	color_match->desc.bLength = UVC_DT_COLOR_MATCHING_SIZE;
	color_match->desc.bDescriptorType = USB_DT_CS_INTERFACE;
	color_match->desc.bDescriptorSubType = UVC_VS_COLORFORMAT;
	color_match->desc.bColorPrimaries = UVC_COLOR_PRIMARIES_BT_709_SRGB;
	color_match->desc.bTransferCharacteristics = UVC_TRANSFER_CHARACTERISTICS_BT_709;
	color_match->desc.bMatrixCoefficients = UVC_MATRIX_COEFFICIENTS_SMPTE_170M;

	config_group_init_type_name(&color_match->group, "default",
				    &uvcg_color_matching_type);
	configfs_add_default_group(&color_match->group, parent);

	return 0;
}

static const struct uvcg_config_group_type uvcg_color_matching_grp_type = {
	.type = {
		.ct_item_ops	= &uvcg_config_item_ops,
		.ct_owner	= THIS_MODULE,
	},
	.name = "color_matching",
	.children = (const struct uvcg_config_group_type*[]) {
		&uvcg_color_matching_type,
		NULL,
	},
	.create_children = uvcg_color_matching_create_children,
};

/* -----------------------------------------------------------------------------
+8 −0
Original line number Diff line number Diff line
@@ -37,6 +37,14 @@ static inline struct uvcg_control_header *to_uvcg_control_header(struct config_i
	return container_of(item, struct uvcg_control_header, item);
}

struct uvcg_color_matching {
	struct config_group group;
	struct uvc_color_matching_descriptor desc;
};

#define to_uvcg_color_matching(group_ptr) \
container_of(group_ptr, struct uvcg_color_matching, group)

enum uvcg_format_type {
	UVCG_UNCOMPRESSED = 0,
	UVCG_MJPEG,