summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
authorKoji KITAYAMA <[email protected]>2024-03-19 22:40:13 +0900
committerGitHub <[email protected]>2024-03-19 22:40:13 +0900
commita4101c41743f22984abf674f405e3015e30e347a (patch)
tree6626b7de7217098a119e7a50db6b73a8819cfe37 /src/class
parent7c66f9b2a4f302268caeab9f8e63fb6ebd8be466 (diff)
parent5d1f6934fbbeee3238267b0444172d47033a2fd9 (diff)
Merge pull request #2520 from lijunru-hub/fix/uvc_support_multiple_interface
fix: uvc multiple interface support
Diffstat (limited to 'src/class')
-rw-r--r--src/class/video/video_device.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c
index c33dfa0b0..249ced83d 100644
--- a/src/class/video/video_device.c
+++ b/src/class/video/video_device.c
@@ -207,6 +207,24 @@ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t des
return cur;
}
+/** Find the first descriptor of two given types
+ *
+ * @param[in] beg The head of descriptor byte array.
+ * @param[in] end The tail of descriptor byte array.
+ * @param[in] desc_type_0 The first target descriptor type.
+ * @param[in] desc_type_1 The second target descriptor type.
+ *
+ * @return The pointer for interface descriptor.
+ * @retval end did not found interface descriptor */
+static void const* _find_desc_2_type(void const *beg, void const *end, uint_fast8_t desc_type_0, uint_fast8_t desc_type_1)
+{
+ void const *cur = beg;
+ while ((cur < end) && (desc_type_0 != tu_desc_type(cur)) && (desc_type_1 != tu_desc_type(cur))) {
+ cur = tu_desc_next(cur);
+ }
+ return cur;
+}
+
/** Find the first descriptor specified by the arguments
*
* @param[in] beg The head of descriptor byte array.
@@ -233,6 +251,10 @@ static void const* _find_desc_3(void const *beg, void const *end,
}
/** Return the next interface descriptor which has another interface number.
+ * If there are multiple VC interfaces, there will be an IAD descriptor before
+ * the next interface descriptor. Check both the IAD descriptor and the interface
+ * descriptor.
+ * 3.1 Descriptor Layout Overview
*
* @param[in] beg The head of descriptor byte array.
* @param[in] end The tail of descriptor byte array.
@@ -245,7 +267,7 @@ static void const* _next_desc_itf(void const *beg, void const *end)
uint_fast8_t itfnum = ((tusb_desc_interface_t const*)cur)->bInterfaceNumber;
while ((cur < end) &&
(itfnum == ((tusb_desc_interface_t const*)cur)->bInterfaceNumber)) {
- cur = _find_desc(tu_desc_next(cur), end, TUSB_DESC_INTERFACE);
+ cur = _find_desc_2_type(tu_desc_next(cur), end, TUSB_DESC_INTERFACE, TUSB_DESC_INTERFACE_ASSOCIATION);
}
return cur;
}
@@ -1216,7 +1238,7 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
* host may not issue set_interface so open the streaming interface here. */
uint8_t const *sbeg = (uint8_t const*)itf_desc + stm->desc.beg;
uint8_t const *send = (uint8_t const*)itf_desc + stm->desc.end;
- if (end == _find_desc_itf(sbeg, send, _desc_itfnum(sbeg), 1)) {
+ if (send == _find_desc_itf(sbeg, send, _desc_itfnum(sbeg), 1)) {
TU_VERIFY(_open_vs_itf(rhport, stm, 0), 0);
}
}