Hi Herton,

On Friday 28 December 2007, Herton Ronaldo Krzesinski wrote:
> This patch from Claudio S. Matsuoka adds a new quirk to make the Syntek
> 174f:5212 work.
>
> From 79775881893806a3aab141b278cf4039673121d7 Mon Sep 17 00:00:00 2001
> From: Claudio Matsuoka <[EMAIL PROTECTED]>
> Date: Thu, 27 Dec 2007 13:10:14 -0200
> Subject: [PATCH] Add quirk for Syntek 174f:5212 camera
>
> The Syntek 174f:5212 UVC camera in HP Spartan laptops fail to synchronize
> frames, add quirk to skip synchronization.
>
> Signed-off-by: Claudio Matsuoka <[EMAIL PROTECTED]>
> ---
>  uvc_driver.c |   12 ++++++++++++
>  uvc_video.c  |   12 ++++++++----
>  uvcvideo.h   |    1 +
>  3 files changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/uvc_driver.c b/uvc_driver.c
> index 715b4b1..49fb900 100644
> --- a/uvc_driver.c
> +++ b/uvc_driver.c
> @@ -1530,6 +1530,7 @@ static int uvc_probe(struct usb_interface *intf,
>       dev->intf = usb_get_intf(intf);
>       dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
>       dev->quirks = id->driver_info;
> +     dev->udev->quirks = id->driver_info;

The dev->udev->quirks field is meant to be filed with values found in 
linux/usb/quirks.h.

I have a pending patch that passes the uvc_video_device structure to URB 
completion callbacks instead of the uvc_video_queue structure. This should 
take care of the problem you solved by setting dev->udev->quirks.

>       /* Parse the Video Class control descriptor */
>       if (uvc_parse_control(dev) < 0) {
> @@ -1653,6 +1654,17 @@ static int uvc_resume(struct usb_interface *intf)
>   * though they are compliant.
>   */
>  static struct usb_device_id uvc_ids[] = {
> +     /* Syntek (HP Spartan) */
> +     { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
> +                             | USB_DEVICE_ID_MATCH_INT_INFO,
> +       .idVendor             = 0x174f,
> +       .idProduct            = 0x5212,
> +       .bInterfaceClass      = USB_CLASS_VIDEO,
> +       .bInterfaceSubClass   = 1,
> +       .bInterfaceProtocol   = 0,
> +       .driver_info          = UVC_QUIRK_PROBE_MINMAX
> +                             | UVC_QUIRK_DONT_SYNCHRONIZE
> +     },
>       /* ALi M5606 (Clevo M540SR) */
>       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
>
>                               | USB_DEVICE_ID_MATCH_INT_INFO,
>
> diff --git a/uvc_video.c b/uvc_video.c
> index 60e1507..dde1469 100644
> --- a/uvc_video.c
> +++ b/uvc_video.c
> @@ -266,7 +266,8 @@ done:
>   * uvc_video_decode_end will never be called with a NULL buffer.
>   */
>  static int uvc_video_decode_start(struct uvc_video_queue *queue,
> -             struct uvc_buffer *buf, const __u8 *data, int len)
> +             struct uvc_buffer *buf, const __u8 *data, int len,
> +             const __u32 quirks)
>  {
>       __u8 fid;
>
> @@ -300,7 +301,8 @@ static int uvc_video_decode_start(struct
> uvc_video_queue *queue, * frame will always be in sync.
>        */
>       if (buf->state != UVC_BUF_STATE_ACTIVE) {
> -             if (fid == queue->last_fid) {
> +             if (~quirks & UVC_QUIRK_DONT_SYNCHRONIZE &&
> +                                     fid == queue->last_fid) {

Does the camera really fail to toggle the FID bit, or is there another 
problem ? Could you please send me some debug logs to explain the issue (with 
header bits printed to the kernel log) ?.

>                       uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
>                               "sync).\n");
>                       return -ENODATA;
> @@ -396,7 +398,8 @@ static void uvc_video_decode_isoc(struct urb *urb,
>               mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
>               do {
>                       ret = uvc_video_decode_start(queue, buf, mem,
> -                             urb->iso_frame_desc[i].actual_length);
> +                             urb->iso_frame_desc[i].actual_length,
> +                             urb->dev->quirks);
>                       if (ret == -EAGAIN)
>                               buf = uvc_queue_next_buffer(queue, buf);
>               } while (ret == -EAGAIN);
> @@ -432,7 +435,8 @@ static void uvc_video_decode_bulk(struct urb *urb,
>        */
>       if (queue->bulk.header_size == -1) {
>               do {
> -                     ret = uvc_video_decode_start(queue, buf, mem, len);
> +                     ret = uvc_video_decode_start(queue, buf, mem, len,
> +                                                     urb->dev->quirks);
>                       if (ret == -EAGAIN)
>                               buf = uvc_queue_next_buffer(queue, buf);
>               } while (ret == -EAGAIN);
> diff --git a/uvcvideo.h b/uvcvideo.h
> index 84ef9f4..6545951 100644
> --- a/uvcvideo.h
> +++ b/uvcvideo.h
> @@ -312,6 +312,7 @@ struct uvc_xu_control {
>  #define UVC_QUIRK_PROBE_MINMAX               0x00000002
>  #define UVC_QUIRK_PROBE_EXTRAFIELDS  0x00000004
>  #define UVC_QUIRK_BUILTIN_ISIGHT     0x00000008
> +#define UVC_QUIRK_DONT_SYNCHRONIZE   0x00000010
>
>  /* Format flags */
>  #define UVC_FMT_FLAG_COMPRESSED              0x00000001

Best regards,

Laurent Pinchart
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to