Files
linux/drivers/usb/gadget/function/uvc_configfs.h
Daniel Scally e187408cc1 usb: gadget: uvc: Copy color matching descriptor for each frame
As currently implemented the default color matching descriptor is
appended after _all_ the formats and frames that the gadget is
configured with. According to the UVC specifications however this
is supposed to be on a per-format basis (section 3.9.2.6):

"Only one instance is allowed for a given format and if present,
the Color Matching descriptor shall be placed following the Video
and Still Image Frame descriptors for that format."

Associate the default color matching descriptor with struct
uvcg_format and copy it once-per-format instead of once only.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Link: https://lore.kernel.org/r/20230202114142.300858-4-dan.scally@ideasonboard.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-02-06 13:46:42 +01:00

148 lines
3.4 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* uvc_configfs.h
*
* Configfs support for the uvc function.
*
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
*/
#ifndef UVC_CONFIGFS_H
#define UVC_CONFIGFS_H
#include <linux/configfs.h>
#include "u_uvc.h"
static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item)
{
return container_of(to_config_group(item), struct f_uvc_opts,
func_inst.group);
}
#define UVCG_STREAMING_CONTROL_SIZE 1
DECLARE_UVC_HEADER_DESCRIPTOR(1);
struct uvcg_control_header {
struct config_item item;
struct UVC_HEADER_DESCRIPTOR(1) desc;
unsigned linked;
};
static inline struct uvcg_control_header *to_uvcg_control_header(struct config_item *item)
{
return container_of(item, struct uvcg_control_header, item);
}
struct uvcg_color_matching {
struct config_group group;
struct uvc_color_matching_descriptor desc;
unsigned int refcnt;
};
#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,
};
struct uvcg_format {
struct config_group group;
enum uvcg_format_type type;
unsigned linked;
struct list_head frames;
unsigned num_frames;
__u8 bmaControls[UVCG_STREAMING_CONTROL_SIZE];
struct uvcg_color_matching *color_matching;
};
struct uvcg_format_ptr {
struct uvcg_format *fmt;
struct list_head entry;
};
static inline struct uvcg_format *to_uvcg_format(struct config_item *item)
{
return container_of(to_config_group(item), struct uvcg_format, group);
}
struct uvcg_streaming_header {
struct config_item item;
struct uvc_input_header_descriptor desc;
unsigned linked;
struct list_head formats;
unsigned num_fmt;
};
static inline struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item *item)
{
return container_of(item, struct uvcg_streaming_header, item);
}
struct uvcg_frame_ptr {
struct uvcg_frame *frm;
struct list_head entry;
};
struct uvcg_frame {
struct config_item item;
enum uvcg_format_type fmt_type;
struct {
u8 b_length;
u8 b_descriptor_type;
u8 b_descriptor_subtype;
u8 b_frame_index;
u8 bm_capabilities;
u16 w_width;
u16 w_height;
u32 dw_min_bit_rate;
u32 dw_max_bit_rate;
u32 dw_max_video_frame_buffer_size;
u32 dw_default_frame_interval;
u8 b_frame_interval_type;
} __attribute__((packed)) frame;
u32 *dw_frame_interval;
};
static inline struct uvcg_frame *to_uvcg_frame(struct config_item *item)
{
return container_of(item, struct uvcg_frame, item);
}
/* -----------------------------------------------------------------------------
* streaming/uncompressed/<NAME>
*/
struct uvcg_uncompressed {
struct uvcg_format fmt;
struct uvc_format_uncompressed desc;
};
static inline struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item)
{
return container_of(to_uvcg_format(item), struct uvcg_uncompressed, fmt);
}
/* -----------------------------------------------------------------------------
* streaming/mjpeg/<NAME>
*/
struct uvcg_mjpeg {
struct uvcg_format fmt;
struct uvc_format_mjpeg desc;
};
static inline struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item)
{
return container_of(to_uvcg_format(item), struct uvcg_mjpeg, fmt);
}
int uvcg_attach_configfs(struct f_uvc_opts *opts);
#endif /* UVC_CONFIGFS_H */