From: Joel Pepper <joel.pepper@rwth-aachen.de>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Felipe Balbi <balbi@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Paul Elder <paul.elder@pitt.edu>,
linux-usb@vger.kernel.org,
Joel Pepper <joel.pepper@rwth-aachen.de>
Subject: [v4] usb/gadget/uvc-configs Fix host unable to negotiate framesizes other than first
Date: Wed, 21 Mar 2018 11:20:18 +0100 [thread overview]
Message-ID: <31bf1ba2-9f9c-4d4d-af63-f610147fc14e@rwthex-s3-b.rwth-ad.de> (raw)
- Add bFrameIndex as a UVCG_FRAME_ATTR_RO for each frame size.
- Automatically assign ascending bFrameIndex to each frame in a format.
Before all "bFrameindex" attributes were set to "1" with no way to
configure the gadget otherwise. This resulted in the host always
negotiating for bFrameIndex 1 (i.e. the first framesize of the gadget).
After the negotiation the host driver will set the user or application
selected framesize, while the gadget is actually set to the first
framesize.
Now, when the containing format is linked into the streaming header,
iterate over all child frame descriptors and assign ascending indices.
The automatically assigned indices can be read from the new read only
bFrameIndex configsfs attribute in each frame descriptor item.
v2: Add the new attribute to both MJPEG and uncompressed frame descriptors
in Documentation/ABI, with note that it was added only in a later
kernel version
v3: Changed from simply allowing user to set the value for bFrameIndex to
automatically assigning correct distinct frame indexes. Changed
bFrameIndex from RW to RO
v4: Actually include updated patch
Signed-off-by: Joel Pepper <joel.pepper@rwth-aachen.de>
---
Documentation/ABI/testing/configfs-usb-gadget-uvc | 18 ++++++++
drivers/usb/gadget/function/uvc_configfs.c | 53 +++++++++++++++++++++++
2 files changed, 71 insertions(+)
diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uvc b/Documentation/ABI/testing/configfs-usb-gadget-uvc
index 1ba0d0f..872ed8a 100644
--- a/Documentation/ABI/testing/configfs-usb-gadget-uvc
+++ b/Documentation/ABI/testing/configfs-usb-gadget-uvc
@@ -194,6 +194,14 @@ Description: Specific MJPEG frame descriptors
bmCapabilities - still image support, fixed frame-rate
support
+Date: Mar 2018
+KernelVersion: 4.16
+
+ bFrameIndex - unique id for this framedescriptor;
+ only defined after parent format is
+ linked into the streaming header;
+ read-only
+
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/uncompressed
Date: Dec 2014
KernelVersion: 4.0
@@ -241,6 +249,16 @@ Description: Specific uncompressed frame descriptors
bmCapabilities - still image support, fixed frame-rate
support
+Date: Mar 2018
+KernelVersion: 4.16
+
+ bFrameIndex - unique id for this framedescriptor;
+ only defined after parent format is
+ linked into the streaming header;
+ read-only
+
+
+
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header
Date: Dec 2014
KernelVersion: 4.0
diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
index c9b8cc4a..a73dbc5 100644
--- a/drivers/usb/gadget/function/uvc_configfs.c
+++ b/drivers/usb/gadget/function/uvc_configfs.c
@@ -32,6 +32,7 @@ static struct configfs_attribute prefix##attr_##cname = { \
}
static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item);
+static void __uvcg_fmt_set_indices(struct config_group* fmt);
/* control/header/<NAME> */
DECLARE_UVC_HEADER_DESCRIPTOR(1);
@@ -751,6 +752,8 @@ static int uvcg_streaming_header_allow_link(struct config_item *src,
if (!target_fmt)
goto out;
+ __uvcg_fmt_set_indices(to_config_group(target));
+
format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL);
if (!format_ptr) {
ret = -ENOMEM;
@@ -929,6 +932,30 @@ static struct uvcg_frame *to_uvcg_frame(struct config_item *item)
return container_of(item, struct uvcg_frame, item);
}
+#define UVCG_FRAME_ATTR_RO(cname, aname, to_cpu_endian, to_little_endian, bits) \
+static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\
+{ \
+ struct uvcg_frame *f = to_uvcg_frame(item); \
+ struct f_uvc_opts *opts; \
+ struct config_item *opts_item; \
+ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
+ int result; \
+ \
+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
+ \
+ opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \
+ opts = to_f_uvc_opts(opts_item); \
+ \
+ mutex_lock(&opts->lock); \
+ result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname)); \
+ mutex_unlock(&opts->lock); \
+ \
+ mutex_unlock(su_mutex); \
+ return result; \
+} \
+ \
+UVC_ATTR_RO(uvcg_frame_, cname, aname);
+
#define UVCG_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \
static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\
{ \
@@ -990,6 +1017,9 @@ UVC_ATTR(uvcg_frame_, cname, aname);
#define noop_conversion(x) (x)
+UVCG_FRAME_ATTR_RO(b_frame_index, bFrameIndex, noop_conversion,
+ noop_conversion, 8);
+
UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion,
noop_conversion, 8);
UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16);
@@ -1137,6 +1167,7 @@ UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
static struct configfs_attribute *uvcg_frame_attrs[] = {
&uvcg_frame_attr_bm_capabilities,
+ &uvcg_frame_attr_b_frame_index,
&uvcg_frame_attr_w_width,
&uvcg_frame_attr_w_height,
&uvcg_frame_attr_dw_min_bit_rate,
@@ -1214,6 +1245,28 @@ static void uvcg_frame_drop(struct config_group *group, struct config_item *item
mutex_unlock(&opts->lock);
}
+static void __uvcg_fmt_set_indices(struct config_group* fmt)
+{
+ u8 i = 1;
+ struct list_head *entry;
+ struct config_item *ci;
+ struct uvcg_frame *frm;
+
+ list_for_each(entry,&(fmt->cg_children)){
+ ci = container_of(entry,struct config_item,ci_entry);
+
+ if(ci->ci_type != &uvcg_frame_type){
+ continue;
+ }
+
+ frm = to_uvcg_frame(ci);
+ frm->frame.b_frame_index = i;
+ i++;
+
+ }
+
+}
+
/* streaming/uncompressed/<NAME> */
struct uvcg_uncompressed {
struct uvcg_format fmt;
next reply other threads:[~2018-03-21 10:20 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-21 10:20 Joel Pepper [this message]
2018-03-21 13:53 [v4] usb/gadget/uvc-configs Fix host unable to negotiate framesizes other than first Joel Pepper
2018-03-21 14:25 Joel Pepper
2018-04-26 10:17 Joel Pepper
2018-05-29 19:02 Joel Pepper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=31bf1ba2-9f9c-4d4d-af63-f610147fc14e@rwthex-s3-b.rwth-ad.de \
--to=joel.pepper@rwth-aachen.de \
--cc=balbi@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-usb@vger.kernel.org \
--cc=paul.elder@pitt.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.