usb: gadget: uvc: Add struct for color matching in configs
authorDaniel Scally <dan.scally@ideasonboard.com>
Thu, 2 Feb 2023 11:41:38 +0000 (11:41 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Feb 2023 12:46:42 +0000 (13:46 +0100)
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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Link: https://lore.kernel.org/r/20230202114142.300858-3-dan.scally@ideasonboard.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/function/uvc_configfs.c
drivers/usb/gadget/function/uvc_configfs.h

index 9ff4b1921ee25b66e0005e0a4f9399556448b6f7..dd14c02dd7ae100cb83b9283557571507cd43f09 100644 (file)
@@ -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,
-               .ct_attrs       = uvcg_color_matching_attrs,
-               .ct_owner       = THIS_MODULE,
-       },
-       .name = "default",
+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,
 };
 
 /* -----------------------------------------------------------------------------
  * 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,
 };
 
 /* -----------------------------------------------------------------------------
index ad2ec8c4c78c35afce3d1c8fd4c305bd10055a21..18b9931c85b10ad7141e6bc2f88edd1033cbf03b 100644 (file)
@@ -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,