On Thu, Nov 28, 2013 at 10:53:03PM +0100, Laurent Pinchart wrote: > On Thursday 28 November 2013 08:43:35 Andrzej Pietrasiewicz wrote: > > A bunch of descriptors is defined in webcam.c. They are used only > > by f_uvc. Move them to their only user. > > The reason why descriptors are located in webcam.c and not f_uvc.c is that I > wanted to separate the code in a generic part (f_uvc.c) and an application- > specific part (webcam.c). This allows instantiating a UVC function with > different parameters, depending on the application, with minimum changes to > the code. webcam.c is merely sample code that shows how to instantiate a UVC > function. With this patch the list of formats and controls become hardcoded in > the function driver. > > How could we solve this problem with configfs ? I would suggest that we move away from static descriptor description to dynamic description from the userspace. We need a similar mechanism like in functionfs to describe the supported endpoints and their formats. As this is limited by the application above anyway. Would this also be possible by configfs? > > Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> > > Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> > > --- > > drivers/usb/gadget/f_uvc.c | 271 ++++++++++++++++++++++++++++++++++++---- > > drivers/usb/gadget/f_uvc.h | 7 +- > > drivers/usb/gadget/webcam.c | 243 +-------------------------------------- > > 3 files changed, 252 insertions(+), 269 deletions(-) > > > > diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c > > index e2a1f50..ac0ac82 100644 > > --- a/drivers/usb/gadget/f_uvc.c > > +++ b/drivers/usb/gadget/f_uvc.c > > @@ -29,21 +29,255 @@ > > #include "uvc.h" > > > > unsigned int uvc_gadget_trace_param; > > +DECLARE_UVC_HEADER_DESCRIPTOR(1); > > + > > +static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = { > > + .bLength = UVC_DT_HEADER_SIZE(1), > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VC_HEADER, > > + .bcdUVC = cpu_to_le16(0x0100), > > + .wTotalLength = 0, /* dynamic */ > > + .dwClockFrequency = cpu_to_le32(48000000), > > + .bInCollection = 0, /* dynamic */ > > + .baInterfaceNr[0] = 0, /* dynamic */ > > +}; > > + > > +static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = { > > + .bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3), > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VC_INPUT_TERMINAL, > > + .bTerminalID = 1, > > + .wTerminalType = cpu_to_le16(0x0201), > > + .bAssocTerminal = 0, > > + .iTerminal = 0, > > + .wObjectiveFocalLengthMin = cpu_to_le16(0), > > + .wObjectiveFocalLengthMax = cpu_to_le16(0), > > + .wOcularFocalLength = cpu_to_le16(0), > > + .bControlSize = 3, > > + .bmControls[0] = 2, > > + .bmControls[1] = 0, > > + .bmControls[2] = 0, > > +}; > > + > > +static const struct uvc_processing_unit_descriptor uvc_processing = { > > + .bLength = UVC_DT_PROCESSING_UNIT_SIZE(2), > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VC_PROCESSING_UNIT, > > + .bUnitID = 2, > > + .bSourceID = 1, > > + .wMaxMultiplier = cpu_to_le16(16*1024), > > + .bControlSize = 2, > > + .bmControls[0] = 1, > > + .bmControls[1] = 0, > > + .iProcessing = 0, > > +}; > > + > > +static const struct uvc_output_terminal_descriptor uvc_output_terminal = { > > + .bLength = UVC_DT_OUTPUT_TERMINAL_SIZE, > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL, > > + .bTerminalID = 3, > > + .wTerminalType = cpu_to_le16(0x0101), > > + .bAssocTerminal = 0, > > + .bSourceID = 2, > > + .iTerminal = 0, > > +}; > > + > > +DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2); > > + > > +static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = { > > + .bLength = UVC_DT_INPUT_HEADER_SIZE(1, 2), > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VS_INPUT_HEADER, > > + .bNumFormats = 2, > > + .wTotalLength = 0, /* dynamic */ > > + .bEndpointAddress = 0, /* dynamic */ > > + .bmInfo = 0, > > + .bTerminalLink = 3, > > + .bStillCaptureMethod = 0, > > + .bTriggerSupport = 0, > > + .bTriggerUsage = 0, > > + .bControlSize = 1, > > + .bmaControls[0][0] = 0, > > + .bmaControls[1][0] = 4, > > +}; > > + > > +static const struct uvc_format_uncompressed uvc_format_yuv = { > > + .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE, > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED, > > + .bFormatIndex = 1, > > + .bNumFrameDescriptors = 2, > > + .guidFormat = > > + { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, > > + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}, > > + .bBitsPerPixel = 16, > > + .bDefaultFrameIndex = 1, > > + .bAspectRatioX = 0, > > + .bAspectRatioY = 0, > > + .bmInterfaceFlags = 0, > > + .bCopyProtect = 0, > > +}; > > + > > +DECLARE_UVC_FRAME_UNCOMPRESSED(1); > > +DECLARE_UVC_FRAME_UNCOMPRESSED(3); > > + > > +static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = { > > + .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3), > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, > > + .bFrameIndex = 1, > > + .bmCapabilities = 0, > > + .wWidth = cpu_to_le16(640), > > + .wHeight = cpu_to_le16(360), > > + .dwMinBitRate = cpu_to_le32(18432000), > > + .dwMaxBitRate = cpu_to_le32(55296000), > > + .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), > > + .dwDefaultFrameInterval = cpu_to_le32(666666), > > + .bFrameIntervalType = 3, > > + .dwFrameInterval[0] = cpu_to_le32(666666), > > + .dwFrameInterval[1] = cpu_to_le32(1000000), > > + .dwFrameInterval[2] = cpu_to_le32(5000000), > > +}; > > + > > +static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = { > > + .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, > > + .bFrameIndex = 2, > > + .bmCapabilities = 0, > > + .wWidth = cpu_to_le16(1280), > > + .wHeight = cpu_to_le16(720), > > + .dwMinBitRate = cpu_to_le32(29491200), > > + .dwMaxBitRate = cpu_to_le32(29491200), > > + .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), > > + .dwDefaultFrameInterval = cpu_to_le32(5000000), > > + .bFrameIntervalType = 1, > > + .dwFrameInterval[0] = cpu_to_le32(5000000), > > +}; > > + > > +static const struct uvc_format_mjpeg uvc_format_mjpg = { > > + .bLength = UVC_DT_FORMAT_MJPEG_SIZE, > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VS_FORMAT_MJPEG, > > + .bFormatIndex = 2, > > + .bNumFrameDescriptors = 2, > > + .bmFlags = 0, > > + .bDefaultFrameIndex = 1, > > + .bAspectRatioX = 0, > > + .bAspectRatioY = 0, > > + .bmInterfaceFlags = 0, > > + .bCopyProtect = 0, > > +}; > > > > /*------------------------------------------------------------------------- > > */ +DECLARE_UVC_FRAME_MJPEG(1); > > +DECLARE_UVC_FRAME_MJPEG(3); > > + > > +static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = { > > + .bLength = UVC_DT_FRAME_MJPEG_SIZE(3), > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VS_FRAME_MJPEG, > > + .bFrameIndex = 1, > > + .bmCapabilities = 0, > > + .wWidth = cpu_to_le16(640), > > + .wHeight = cpu_to_le16(360), > > + .dwMinBitRate = cpu_to_le32(18432000), > > + .dwMaxBitRate = cpu_to_le32(55296000), > > + .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), > > + .dwDefaultFrameInterval = cpu_to_le32(666666), > > + .bFrameIntervalType = 3, > > + .dwFrameInterval[0] = cpu_to_le32(666666), > > + .dwFrameInterval[1] = cpu_to_le32(1000000), > > + .dwFrameInterval[2] = cpu_to_le32(5000000), > > +}; > > > > /* module parameters specific to the Video streaming endpoint */ > > static unsigned int streaming_interval = 1; > > module_param(streaming_interval, uint, S_IRUGO|S_IWUSR); > > MODULE_PARM_DESC(streaming_interval, "1 - 16"); > > +static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = { > > + .bLength = UVC_DT_FRAME_MJPEG_SIZE(1), > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VS_FRAME_MJPEG, > > + .bFrameIndex = 2, > > + .bmCapabilities = 0, > > + .wWidth = cpu_to_le16(1280), > > + .wHeight = cpu_to_le16(720), > > + .dwMinBitRate = cpu_to_le32(29491200), > > + .dwMaxBitRate = cpu_to_le32(29491200), > > + .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), > > + .dwDefaultFrameInterval = cpu_to_le32(5000000), > > + .bFrameIntervalType = 1, > > + .dwFrameInterval[0] = cpu_to_le32(5000000), > > +}; > > > > static unsigned int streaming_maxpacket = 1024; > > module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR); > > MODULE_PARM_DESC(streaming_maxpacket, "1 - 1023 (FS), 1 - 3072 (hs/ss)"); > > +static const struct uvc_color_matching_descriptor uvc_color_matching = { > > + .bLength = UVC_DT_COLOR_MATCHING_SIZE, > > + .bDescriptorType = USB_DT_CS_INTERFACE, > > + .bDescriptorSubType = UVC_VS_COLORFORMAT, > > + .bColorPrimaries = 1, > > + .bTransferCharacteristics = 1, > > + .bMatrixCoefficients = 4, > > +}; > > + > > +static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = { > > + (const struct uvc_descriptor_header *) &uvc_control_header, > > + (const struct uvc_descriptor_header *) &uvc_camera_terminal, > > + (const struct uvc_descriptor_header *) &uvc_processing, > > + (const struct uvc_descriptor_header *) &uvc_output_terminal, > > + NULL, > > +}; > > + > > +static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = { > > + (const struct uvc_descriptor_header *) &uvc_control_header, > > + (const struct uvc_descriptor_header *) &uvc_camera_terminal, > > + (const struct uvc_descriptor_header *) &uvc_processing, > > + (const struct uvc_descriptor_header *) &uvc_output_terminal, > > + NULL, > > +}; > > > > static unsigned int streaming_maxburst; > > module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR); > > MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)"); > > +static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = > > { + (const struct uvc_descriptor_header *) &uvc_input_header, > > + (const struct uvc_descriptor_header *) &uvc_format_yuv, > > + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, > > + (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, > > + (const struct uvc_descriptor_header *) &uvc_format_mjpg, > > + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, > > + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, > > + (const struct uvc_descriptor_header *) &uvc_color_matching, > > + NULL, > > +}; > > + > > +static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = > > { + (const struct uvc_descriptor_header *) &uvc_input_header, > > + (const struct uvc_descriptor_header *) &uvc_format_yuv, > > + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, > > + (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, > > + (const struct uvc_descriptor_header *) &uvc_format_mjpg, > > + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, > > + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, > > + (const struct uvc_descriptor_header *) &uvc_color_matching, > > + NULL, > > +}; > > + > > +static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = > > { + (const struct uvc_descriptor_header *) &uvc_input_header, > > + (const struct uvc_descriptor_header *) &uvc_format_yuv, > > + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, > > + (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, > > + (const struct uvc_descriptor_header *) &uvc_format_mjpg, > > + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, > > + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, > > + (const struct uvc_descriptor_header *) &uvc_color_matching, > > + NULL, > > +}; > > > > /* > > -------------------------------------------------------------------------- > > * Function descriptors > > @@ -744,12 +978,7 @@ error: > > * calling @uvc_cleanup() before module unload. > > */ > > int __init > > -uvc_bind_config(struct usb_configuration *c, > > - const struct uvc_descriptor_header * const *fs_control, > > - const struct uvc_descriptor_header * const *ss_control, > > - const struct uvc_descriptor_header * const *fs_streaming, > > - const struct uvc_descriptor_header * const *hs_streaming, > > - const struct uvc_descriptor_header * const *ss_streaming) > > +uvc_bind_config(struct usb_configuration *c) > > { > > struct uvc_device *uvc; > > int ret = 0; > > @@ -767,31 +996,31 @@ uvc_bind_config(struct usb_configuration *c, > > uvc->state = UVC_STATE_DISCONNECTED; > > > > /* Validate the descriptors. */ > > - if (fs_control == NULL || fs_control[0] == NULL || > > - fs_control[0]->bDescriptorSubType != UVC_VC_HEADER) > > + if (uvc_fs_control_cls[0] == NULL || > > + uvc_fs_control_cls[0]->bDescriptorSubType != UVC_VC_HEADER) > > goto error; > > > > - if (ss_control == NULL || ss_control[0] == NULL || > > - ss_control[0]->bDescriptorSubType != UVC_VC_HEADER) > > + if (uvc_ss_control_cls[0] == NULL || > > + uvc_ss_control_cls[0]->bDescriptorSubType != UVC_VC_HEADER) > > goto error; > > > > - if (fs_streaming == NULL || fs_streaming[0] == NULL || > > - fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) > > + if (uvc_fs_streaming_cls[0] == NULL || > > + uvc_fs_streaming_cls[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) > > goto error; > > > > - if (hs_streaming == NULL || hs_streaming[0] == NULL || > > - hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) > > + if (uvc_hs_streaming_cls[0] == NULL || > > + uvc_hs_streaming_cls[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) > > goto error; > > > > - if (ss_streaming == NULL || ss_streaming[0] == NULL || > > - ss_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) > > + if (uvc_ss_streaming_cls[0] == NULL || > > + uvc_ss_streaming_cls[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) > > goto error; > > > > - uvc->desc.fs_control = fs_control; > > - uvc->desc.ss_control = ss_control; > > - uvc->desc.fs_streaming = fs_streaming; > > - uvc->desc.hs_streaming = hs_streaming; > > - uvc->desc.ss_streaming = ss_streaming; > > + uvc->desc.fs_control = uvc_fs_control_cls; > > + uvc->desc.ss_control = uvc_ss_control_cls; > > + uvc->desc.fs_streaming = uvc_fs_streaming_cls; > > + uvc->desc.hs_streaming = uvc_hs_streaming_cls; > > + uvc->desc.ss_streaming = uvc_ss_streaming_cls; > > > > /* String descriptors are global, we only need to allocate string IDs > > * for the first UVC function. UVC functions beyond the first (if any) > > diff --git a/drivers/usb/gadget/f_uvc.h b/drivers/usb/gadget/f_uvc.h > > index ec52752..edfe772 100644 > > --- a/drivers/usb/gadget/f_uvc.h > > +++ b/drivers/usb/gadget/f_uvc.h > > @@ -16,12 +16,7 @@ > > #include <linux/usb/composite.h> > > #include <linux/usb/video.h> > > > > -int uvc_bind_config(struct usb_configuration *c, > > - const struct uvc_descriptor_header * const *fs_control, > > - const struct uvc_descriptor_header * const *hs_control, > > - const struct uvc_descriptor_header * const *fs_streaming, > > - const struct uvc_descriptor_header * const *hs_streaming, > > - const struct uvc_descriptor_header * const *ss_streaming); > > +int uvc_bind_config(struct usb_configuration *c); > > > > #endif /* _F_UVC_H_ */ > > > > diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c > > index 8cef1e6..df809e7 100644 > > --- a/drivers/usb/gadget/webcam.c > > +++ b/drivers/usb/gadget/webcam.c > > @@ -80,245 +80,6 @@ static struct usb_device_descriptor > > webcam_device_descriptor = { .bNumConfigurations = 0, /* dynamic */ > > }; > > > > -DECLARE_UVC_HEADER_DESCRIPTOR(1); > > - > > -static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = { > > - .bLength = UVC_DT_HEADER_SIZE(1), > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VC_HEADER, > > - .bcdUVC = cpu_to_le16(0x0100), > > - .wTotalLength = 0, /* dynamic */ > > - .dwClockFrequency = cpu_to_le32(48000000), > > - .bInCollection = 0, /* dynamic */ > > - .baInterfaceNr[0] = 0, /* dynamic */ > > -}; > > - > > -static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = { > > - .bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3), > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VC_INPUT_TERMINAL, > > - .bTerminalID = 1, > > - .wTerminalType = cpu_to_le16(0x0201), > > - .bAssocTerminal = 0, > > - .iTerminal = 0, > > - .wObjectiveFocalLengthMin = cpu_to_le16(0), > > - .wObjectiveFocalLengthMax = cpu_to_le16(0), > > - .wOcularFocalLength = cpu_to_le16(0), > > - .bControlSize = 3, > > - .bmControls[0] = 2, > > - .bmControls[1] = 0, > > - .bmControls[2] = 0, > > -}; > > - > > -static const struct uvc_processing_unit_descriptor uvc_processing = { > > - .bLength = UVC_DT_PROCESSING_UNIT_SIZE(2), > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VC_PROCESSING_UNIT, > > - .bUnitID = 2, > > - .bSourceID = 1, > > - .wMaxMultiplier = cpu_to_le16(16*1024), > > - .bControlSize = 2, > > - .bmControls[0] = 1, > > - .bmControls[1] = 0, > > - .iProcessing = 0, > > -}; > > - > > -static const struct uvc_output_terminal_descriptor uvc_output_terminal = { > > - .bLength = UVC_DT_OUTPUT_TERMINAL_SIZE, > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL, > > - .bTerminalID = 3, > > - .wTerminalType = cpu_to_le16(0x0101), > > - .bAssocTerminal = 0, > > - .bSourceID = 2, > > - .iTerminal = 0, > > -}; > > - > > -DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2); > > - > > -static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = { > > - .bLength = UVC_DT_INPUT_HEADER_SIZE(1, 2), > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VS_INPUT_HEADER, > > - .bNumFormats = 2, > > - .wTotalLength = 0, /* dynamic */ > > - .bEndpointAddress = 0, /* dynamic */ > > - .bmInfo = 0, > > - .bTerminalLink = 3, > > - .bStillCaptureMethod = 0, > > - .bTriggerSupport = 0, > > - .bTriggerUsage = 0, > > - .bControlSize = 1, > > - .bmaControls[0][0] = 0, > > - .bmaControls[1][0] = 4, > > -}; > > - > > -static const struct uvc_format_uncompressed uvc_format_yuv = { > > - .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE, > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED, > > - .bFormatIndex = 1, > > - .bNumFrameDescriptors = 2, > > - .guidFormat = > > - { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, > > - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}, > > - .bBitsPerPixel = 16, > > - .bDefaultFrameIndex = 1, > > - .bAspectRatioX = 0, > > - .bAspectRatioY = 0, > > - .bmInterfaceFlags = 0, > > - .bCopyProtect = 0, > > -}; > > - > > -DECLARE_UVC_FRAME_UNCOMPRESSED(1); > > -DECLARE_UVC_FRAME_UNCOMPRESSED(3); > > - > > -static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = { > > - .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3), > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, > > - .bFrameIndex = 1, > > - .bmCapabilities = 0, > > - .wWidth = cpu_to_le16(640), > > - .wHeight = cpu_to_le16(360), > > - .dwMinBitRate = cpu_to_le32(18432000), > > - .dwMaxBitRate = cpu_to_le32(55296000), > > - .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), > > - .dwDefaultFrameInterval = cpu_to_le32(666666), > > - .bFrameIntervalType = 3, > > - .dwFrameInterval[0] = cpu_to_le32(666666), > > - .dwFrameInterval[1] = cpu_to_le32(1000000), > > - .dwFrameInterval[2] = cpu_to_le32(5000000), > > -}; > > - > > -static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = { > > - .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, > > - .bFrameIndex = 2, > > - .bmCapabilities = 0, > > - .wWidth = cpu_to_le16(1280), > > - .wHeight = cpu_to_le16(720), > > - .dwMinBitRate = cpu_to_le32(29491200), > > - .dwMaxBitRate = cpu_to_le32(29491200), > > - .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), > > - .dwDefaultFrameInterval = cpu_to_le32(5000000), > > - .bFrameIntervalType = 1, > > - .dwFrameInterval[0] = cpu_to_le32(5000000), > > -}; > > - > > -static const struct uvc_format_mjpeg uvc_format_mjpg = { > > - .bLength = UVC_DT_FORMAT_MJPEG_SIZE, > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VS_FORMAT_MJPEG, > > - .bFormatIndex = 2, > > - .bNumFrameDescriptors = 2, > > - .bmFlags = 0, > > - .bDefaultFrameIndex = 1, > > - .bAspectRatioX = 0, > > - .bAspectRatioY = 0, > > - .bmInterfaceFlags = 0, > > - .bCopyProtect = 0, > > -}; > > - > > -DECLARE_UVC_FRAME_MJPEG(1); > > -DECLARE_UVC_FRAME_MJPEG(3); > > - > > -static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = { > > - .bLength = UVC_DT_FRAME_MJPEG_SIZE(3), > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VS_FRAME_MJPEG, > > - .bFrameIndex = 1, > > - .bmCapabilities = 0, > > - .wWidth = cpu_to_le16(640), > > - .wHeight = cpu_to_le16(360), > > - .dwMinBitRate = cpu_to_le32(18432000), > > - .dwMaxBitRate = cpu_to_le32(55296000), > > - .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), > > - .dwDefaultFrameInterval = cpu_to_le32(666666), > > - .bFrameIntervalType = 3, > > - .dwFrameInterval[0] = cpu_to_le32(666666), > > - .dwFrameInterval[1] = cpu_to_le32(1000000), > > - .dwFrameInterval[2] = cpu_to_le32(5000000), > > -}; > > - > > -static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = { > > - .bLength = UVC_DT_FRAME_MJPEG_SIZE(1), > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VS_FRAME_MJPEG, > > - .bFrameIndex = 2, > > - .bmCapabilities = 0, > > - .wWidth = cpu_to_le16(1280), > > - .wHeight = cpu_to_le16(720), > > - .dwMinBitRate = cpu_to_le32(29491200), > > - .dwMaxBitRate = cpu_to_le32(29491200), > > - .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), > > - .dwDefaultFrameInterval = cpu_to_le32(5000000), > > - .bFrameIntervalType = 1, > > - .dwFrameInterval[0] = cpu_to_le32(5000000), > > -}; > > - > > -static const struct uvc_color_matching_descriptor uvc_color_matching = { > > - .bLength = UVC_DT_COLOR_MATCHING_SIZE, > > - .bDescriptorType = USB_DT_CS_INTERFACE, > > - .bDescriptorSubType = UVC_VS_COLORFORMAT, > > - .bColorPrimaries = 1, > > - .bTransferCharacteristics = 1, > > - .bMatrixCoefficients = 4, > > -}; > > - > > -static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = { > > - (const struct uvc_descriptor_header *) &uvc_control_header, > > - (const struct uvc_descriptor_header *) &uvc_camera_terminal, > > - (const struct uvc_descriptor_header *) &uvc_processing, > > - (const struct uvc_descriptor_header *) &uvc_output_terminal, > > - NULL, > > -}; > > - > > -static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = { > > - (const struct uvc_descriptor_header *) &uvc_control_header, > > - (const struct uvc_descriptor_header *) &uvc_camera_terminal, > > - (const struct uvc_descriptor_header *) &uvc_processing, > > - (const struct uvc_descriptor_header *) &uvc_output_terminal, > > - NULL, > > -}; > > - > > -static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = > > { - (const struct uvc_descriptor_header *) &uvc_input_header, > > - (const struct uvc_descriptor_header *) &uvc_format_yuv, > > - (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, > > - (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, > > - (const struct uvc_descriptor_header *) &uvc_format_mjpg, > > - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, > > - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, > > - (const struct uvc_descriptor_header *) &uvc_color_matching, > > - NULL, > > -}; > > - > > -static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = > > { - (const struct uvc_descriptor_header *) &uvc_input_header, > > - (const struct uvc_descriptor_header *) &uvc_format_yuv, > > - (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, > > - (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, > > - (const struct uvc_descriptor_header *) &uvc_format_mjpg, > > - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, > > - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, > > - (const struct uvc_descriptor_header *) &uvc_color_matching, > > - NULL, > > -}; > > - > > -static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = > > { - (const struct uvc_descriptor_header *) &uvc_input_header, > > - (const struct uvc_descriptor_header *) &uvc_format_yuv, > > - (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, > > - (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, > > - (const struct uvc_descriptor_header *) &uvc_format_mjpg, > > - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, > > - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, > > - (const struct uvc_descriptor_header *) &uvc_color_matching, > > - NULL, > > -}; > > - > > /* > > -------------------------------------------------------------------------- > > * USB configuration > > */ > > @@ -326,9 +87,7 @@ static const struct uvc_descriptor_header * const > > uvc_ss_streaming_cls[] = { static int __init > > webcam_config_bind(struct usb_configuration *c) > > { > > - return uvc_bind_config(c, uvc_fs_control_cls, uvc_ss_control_cls, > > - uvc_fs_streaming_cls, uvc_hs_streaming_cls, > > - uvc_ss_streaming_cls); > > + return uvc_bind_config(c); > > } > > > > static struct usb_configuration webcam_config_driver = { > -- > Regards, > > Laurent Pinchart > > -- > To unsubscribe from this list: send the line "unsubscribe linux-usb" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html