Commit 324e4f85 authored by Dan Vacura's avatar Dan Vacura Committed by Greg Kroah-Hartman

usb: gadget: uvc: allow changing interface name via configfs

Add a configfs entry, "function_name", to change the iInterface field
for VideoControl. This name is used on host devices for user selection,
useful when multiple cameras are present. The default will remain "UVC
Camera".
Signed-off-by: default avatarDan Vacura <w36195@motorola.com>
Link: https://lore.kernel.org/r/20220401160447.5919-1-w36195@motorola.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 31231092
...@@ -7,6 +7,7 @@ Description: UVC function directory ...@@ -7,6 +7,7 @@ Description: UVC function directory
streaming_maxburst 0..15 (ss only) streaming_maxburst 0..15 (ss only)
streaming_maxpacket 1..1023 (fs), 1..3072 (hs/ss) streaming_maxpacket 1..1023 (fs), 1..3072 (hs/ss)
streaming_interval 1..16 streaming_interval 1..16
function_name string [32]
=================== ============================= =================== =============================
What: /config/usb-gadget/gadget/functions/uvc.name/control What: /config/usb-gadget/gadget/functions/uvc.name/control
......
...@@ -787,6 +787,7 @@ The uvc function provides these attributes in its function directory: ...@@ -787,6 +787,7 @@ The uvc function provides these attributes in its function directory:
streaming_maxpacket maximum packet size this endpoint is capable of streaming_maxpacket maximum packet size this endpoint is capable of
sending or receiving when this configuration is sending or receiving when this configuration is
selected selected
function_name name of the interface
=================== ================================================ =================== ================================================
There are also "control" and "streaming" subdirectories, each of which contain There are also "control" and "streaming" subdirectories, each of which contain
......
...@@ -44,7 +44,7 @@ MODULE_PARM_DESC(trace, "Trace level bitmask"); ...@@ -44,7 +44,7 @@ MODULE_PARM_DESC(trace, "Trace level bitmask");
#define UVC_STRING_STREAMING_IDX 1 #define UVC_STRING_STREAMING_IDX 1
static struct usb_string uvc_en_us_strings[] = { static struct usb_string uvc_en_us_strings[] = {
[UVC_STRING_CONTROL_IDX].s = "UVC Camera", /* [UVC_STRING_CONTROL_IDX].s = DYNAMIC, */
[UVC_STRING_STREAMING_IDX].s = "Video Streaming", [UVC_STRING_STREAMING_IDX].s = "Video Streaming",
{ } { }
}; };
...@@ -676,6 +676,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) ...@@ -676,6 +676,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address; uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address; uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address;
uvc_en_us_strings[UVC_STRING_CONTROL_IDX].s = opts->function_name;
us = usb_gstrings_attach(cdev, uvc_function_strings, us = usb_gstrings_attach(cdev, uvc_function_strings,
ARRAY_SIZE(uvc_en_us_strings)); ARRAY_SIZE(uvc_en_us_strings));
if (IS_ERR(us)) { if (IS_ERR(us)) {
...@@ -866,6 +867,7 @@ static struct usb_function_instance *uvc_alloc_inst(void) ...@@ -866,6 +867,7 @@ static struct usb_function_instance *uvc_alloc_inst(void)
opts->streaming_interval = 1; opts->streaming_interval = 1;
opts->streaming_maxpacket = 1024; opts->streaming_maxpacket = 1024;
snprintf(opts->function_name, sizeof(opts->function_name), "UVC Camera");
ret = uvcg_attach_configfs(opts); ret = uvcg_attach_configfs(opts);
if (ret < 0) { if (ret < 0) {
......
...@@ -27,6 +27,7 @@ struct f_uvc_opts { ...@@ -27,6 +27,7 @@ struct f_uvc_opts {
unsigned int control_interface; unsigned int control_interface;
unsigned int streaming_interface; unsigned int streaming_interface;
char function_name[32];
/* /*
* Control descriptors array pointers for full-/high-speed and * Control descriptors array pointers for full-/high-speed and
......
...@@ -2425,10 +2425,51 @@ UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15); ...@@ -2425,10 +2425,51 @@ UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15);
#undef UVCG_OPTS_ATTR #undef UVCG_OPTS_ATTR
#define UVCG_OPTS_STRING_ATTR(cname, aname) \
static ssize_t f_uvc_opts_string_##cname##_show(struct config_item *item,\
char *page) \
{ \
struct f_uvc_opts *opts = to_f_uvc_opts(item); \
int result; \
\
mutex_lock(&opts->lock); \
result = snprintf(page, sizeof(opts->aname), "%s", opts->aname);\
mutex_unlock(&opts->lock); \
\
return result; \
} \
\
static ssize_t f_uvc_opts_string_##cname##_store(struct config_item *item,\
const char *page, size_t len) \
{ \
struct f_uvc_opts *opts = to_f_uvc_opts(item); \
int ret = 0; \
\
mutex_lock(&opts->lock); \
if (opts->refcnt) { \
ret = -EBUSY; \
goto end; \
} \
\
ret = snprintf(opts->aname, min(sizeof(opts->aname), len), \
"%s", page); \
\
end: \
mutex_unlock(&opts->lock); \
return ret; \
} \
\
UVC_ATTR(f_uvc_opts_string_, cname, aname)
UVCG_OPTS_STRING_ATTR(function_name, function_name);
#undef UVCG_OPTS_STRING_ATTR
static struct configfs_attribute *uvc_attrs[] = { static struct configfs_attribute *uvc_attrs[] = {
&f_uvc_opts_attr_streaming_interval, &f_uvc_opts_attr_streaming_interval,
&f_uvc_opts_attr_streaming_maxpacket, &f_uvc_opts_attr_streaming_maxpacket,
&f_uvc_opts_attr_streaming_maxburst, &f_uvc_opts_attr_streaming_maxburst,
&f_uvc_opts_string_attr_function_name,
NULL, NULL,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment