mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
usb: gadget: uvc: Allow creating new color matching descriptors
Allow users to create new color matching descriptors in addition to the default one. These must be associated with a UVC format in order to be transmitted to the host, which is achieved by symlinking from the format to the newly created color matching descriptor - extend the uncompressed and mjpeg formats to support that linking operation. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> Link: https://lore.kernel.org/r/20230202114142.300858-7-dan.scally@ideasonboard.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
58f227871f
commit
f5e7bdd34a
2 changed files with 114 additions and 2 deletions
|
@ -179,6 +179,23 @@ Description: Default color matching descriptors
|
||||||
white
|
white
|
||||||
======================== ======================================
|
======================== ======================================
|
||||||
|
|
||||||
|
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/color_matching/name
|
||||||
|
Date: Dec 2022
|
||||||
|
KernelVersion: 6.3
|
||||||
|
Description: Additional color matching descriptors
|
||||||
|
|
||||||
|
All attributes read/write:
|
||||||
|
|
||||||
|
======================== ======================================
|
||||||
|
bMatrixCoefficients matrix used to compute luma and
|
||||||
|
chroma values from the color primaries
|
||||||
|
bTransferCharacteristics optoelectronic transfer
|
||||||
|
characteristic of the source picture,
|
||||||
|
also called the gamma function
|
||||||
|
bColorPrimaries color primaries and the reference
|
||||||
|
white
|
||||||
|
======================== ======================================
|
||||||
|
|
||||||
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/mjpeg
|
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/mjpeg
|
||||||
Date: Dec 2014
|
Date: Dec 2014
|
||||||
KernelVersion: 4.0
|
KernelVersion: 4.0
|
||||||
|
|
|
@ -824,6 +824,77 @@ uvcg_format_get_default_color_match(struct config_item *streaming)
|
||||||
return color_match;
|
return color_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int uvcg_format_allow_link(struct config_item *src, struct config_item *tgt)
|
||||||
|
{
|
||||||
|
struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
|
||||||
|
struct uvcg_color_matching *color_matching_desc;
|
||||||
|
struct config_item *streaming, *color_matching;
|
||||||
|
struct uvcg_format *fmt;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
mutex_lock(su_mutex);
|
||||||
|
|
||||||
|
streaming = src->ci_parent->ci_parent;
|
||||||
|
color_matching = config_group_find_item(to_config_group(streaming), "color_matching");
|
||||||
|
if (!color_matching || color_matching != tgt->ci_parent) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out_put_cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt = to_uvcg_format(src);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There's always a color matching descriptor associated with the format
|
||||||
|
* but without a symlink it should only ever be the default one. If it's
|
||||||
|
* not the default, there's already a symlink and we should bail out.
|
||||||
|
*/
|
||||||
|
color_matching_desc = uvcg_format_get_default_color_match(streaming);
|
||||||
|
if (fmt->color_matching != color_matching_desc) {
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto out_put_cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
color_matching_desc->refcnt--;
|
||||||
|
|
||||||
|
color_matching_desc = to_uvcg_color_matching(to_config_group(tgt));
|
||||||
|
fmt->color_matching = color_matching_desc;
|
||||||
|
color_matching_desc->refcnt++;
|
||||||
|
|
||||||
|
out_put_cm:
|
||||||
|
config_item_put(color_matching);
|
||||||
|
mutex_unlock(su_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uvcg_format_drop_link(struct config_item *src, struct config_item *tgt)
|
||||||
|
{
|
||||||
|
struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
|
||||||
|
struct uvcg_color_matching *color_matching_desc;
|
||||||
|
struct config_item *streaming;
|
||||||
|
struct uvcg_format *fmt;
|
||||||
|
|
||||||
|
mutex_lock(su_mutex);
|
||||||
|
|
||||||
|
color_matching_desc = to_uvcg_color_matching(to_config_group(tgt));
|
||||||
|
color_matching_desc->refcnt--;
|
||||||
|
|
||||||
|
streaming = src->ci_parent->ci_parent;
|
||||||
|
color_matching_desc = uvcg_format_get_default_color_match(streaming);
|
||||||
|
|
||||||
|
fmt = to_uvcg_format(src);
|
||||||
|
fmt->color_matching = color_matching_desc;
|
||||||
|
color_matching_desc->refcnt++;
|
||||||
|
|
||||||
|
mutex_unlock(su_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_item_operations uvcg_format_item_operations = {
|
||||||
|
.release = uvcg_config_item_release,
|
||||||
|
.allow_link = uvcg_format_allow_link,
|
||||||
|
.drop_link = uvcg_format_drop_link,
|
||||||
|
};
|
||||||
|
|
||||||
static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page)
|
static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page)
|
||||||
{
|
{
|
||||||
struct f_uvc_opts *opts;
|
struct f_uvc_opts *opts;
|
||||||
|
@ -1624,7 +1695,7 @@ static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct config_item_type uvcg_uncompressed_type = {
|
static const struct config_item_type uvcg_uncompressed_type = {
|
||||||
.ct_item_ops = &uvcg_config_item_ops,
|
.ct_item_ops = &uvcg_format_item_operations,
|
||||||
.ct_group_ops = &uvcg_uncompressed_group_ops,
|
.ct_group_ops = &uvcg_uncompressed_group_ops,
|
||||||
.ct_attrs = uvcg_uncompressed_attrs,
|
.ct_attrs = uvcg_uncompressed_attrs,
|
||||||
.ct_owner = THIS_MODULE,
|
.ct_owner = THIS_MODULE,
|
||||||
|
@ -1820,7 +1891,7 @@ static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct config_item_type uvcg_mjpeg_type = {
|
static const struct config_item_type uvcg_mjpeg_type = {
|
||||||
.ct_item_ops = &uvcg_config_item_ops,
|
.ct_item_ops = &uvcg_format_item_operations,
|
||||||
.ct_group_ops = &uvcg_mjpeg_group_ops,
|
.ct_group_ops = &uvcg_mjpeg_group_ops,
|
||||||
.ct_attrs = uvcg_mjpeg_attrs,
|
.ct_attrs = uvcg_mjpeg_attrs,
|
||||||
.ct_owner = THIS_MODULE,
|
.ct_owner = THIS_MODULE,
|
||||||
|
@ -1978,6 +2049,29 @@ static const struct config_item_type uvcg_color_matching_type = {
|
||||||
* streaming/color_matching
|
* streaming/color_matching
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static struct config_group *uvcg_color_matching_make(struct config_group *group,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
struct uvcg_color_matching *color_match;
|
||||||
|
|
||||||
|
color_match = kzalloc(sizeof(*color_match), GFP_KERNEL);
|
||||||
|
if (!color_match)
|
||||||
|
return ERR_PTR(-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;
|
||||||
|
|
||||||
|
config_group_init_type_name(&color_match->group, name,
|
||||||
|
&uvcg_color_matching_type);
|
||||||
|
|
||||||
|
return &color_match->group;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct configfs_group_operations uvcg_color_matching_grp_group_ops = {
|
||||||
|
.make_group = uvcg_color_matching_make,
|
||||||
|
};
|
||||||
|
|
||||||
static int uvcg_color_matching_create_children(struct config_group *parent)
|
static int uvcg_color_matching_create_children(struct config_group *parent)
|
||||||
{
|
{
|
||||||
struct uvcg_color_matching *color_match;
|
struct uvcg_color_matching *color_match;
|
||||||
|
@ -2003,6 +2097,7 @@ static int uvcg_color_matching_create_children(struct config_group *parent)
|
||||||
static const struct uvcg_config_group_type uvcg_color_matching_grp_type = {
|
static const struct uvcg_config_group_type uvcg_color_matching_grp_type = {
|
||||||
.type = {
|
.type = {
|
||||||
.ct_item_ops = &uvcg_config_item_ops,
|
.ct_item_ops = &uvcg_config_item_ops,
|
||||||
|
.ct_group_ops = &uvcg_color_matching_grp_group_ops,
|
||||||
.ct_owner = THIS_MODULE,
|
.ct_owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.name = "color_matching",
|
.name = "color_matching",
|
||||||
|
|
Loading…
Add table
Reference in a new issue