diff options
Diffstat (limited to 'linux-2.6-v4l-dvb-uvcvideo-update.patch')
-rw-r--r-- | linux-2.6-v4l-dvb-uvcvideo-update.patch | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/linux-2.6-v4l-dvb-uvcvideo-update.patch b/linux-2.6-v4l-dvb-uvcvideo-update.patch new file mode 100644 index 000000000..3251c7fa3 --- /dev/null +++ b/linux-2.6-v4l-dvb-uvcvideo-update.patch @@ -0,0 +1,362 @@ +From: Martin Rubli <martin_rubli@logitech.com> +Date: Wed, 19 May 2010 22:51:56 +0000 (+0200) +Subject: uvcvideo: Add support for absolute pan/tilt controls +X-Git-Url: http://git.linuxtv.org/pinchartl/uvcvideo.git?a=commitdiff_plain;h=d3c2f664ec76aff14c3841c99e84cd78d7227f79 + +uvcvideo: Add support for absolute pan/tilt controls + +Signed-off-by: Martin Rubli <martin_rubli@logitech.com> +--- + +diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c +index aa0720a..5ec2f4a 100644 +--- a/drivers/media/video/uvc/uvc_ctrl.c ++++ b/drivers/media/video/uvc/uvc_ctrl.c +@@ -606,6 +606,26 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { + .set = uvc_ctrl_set_zoom, + }, + { ++ .id = V4L2_CID_PAN_ABSOLUTE, ++ .name = "Pan (Absolute)", ++ .entity = UVC_GUID_UVC_CAMERA, ++ .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL, ++ .size = 32, ++ .offset = 0, ++ .v4l2_type = V4L2_CTRL_TYPE_INTEGER, ++ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, ++ }, ++ { ++ .id = V4L2_CID_TILT_ABSOLUTE, ++ .name = "Tilt (Absolute)", ++ .entity = UVC_GUID_UVC_CAMERA, ++ .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL, ++ .size = 32, ++ .offset = 32, ++ .v4l2_type = V4L2_CTRL_TYPE_INTEGER, ++ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, ++ }, ++ { + .id = V4L2_CID_PRIVACY, + .name = "Privacy", + .entity = UVC_GUID_UVC_CAMERA, +From: Hans de Goede <hdegoede@redhat.com> +Date: Wed, 19 May 2010 23:15:00 +0000 (+0200) +Subject: uvcvideo: Make button controls work properly +X-Git-Url: http://git.linuxtv.org/pinchartl/uvcvideo.git?a=commitdiff_plain;h=2bd47ad4894bfaf1a97660b821cbc46439a614d6 + +uvcvideo: Make button controls work properly + +According to the v4l2 spec, writing any value to a button control should +result in the action belonging to the button control being triggered. +UVC cams however want to see a 1 written, this patch fixes this by +overriding whatever value user space passed in with -1 (0xffffffff) when +the control is a button control. + +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +--- + +diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c +index 5ec2f4a..8bb825d 100644 +--- a/drivers/media/video/uvc/uvc_ctrl.c ++++ b/drivers/media/video/uvc/uvc_ctrl.c +@@ -698,6 +698,14 @@ static void uvc_set_le_value(struct uvc_control_mapping *mapping, + int offset = mapping->offset; + __u8 mask; + ++ /* According to the v4l2 spec, writing any value to a button control ++ * should result in the action belonging to the button control being ++ * triggered. UVC devices however want to see a 1 written -> override ++ * value. ++ */ ++ if (mapping->v4l2_type == V4L2_CTRL_TYPE_BUTTON) ++ value = -1; ++ + data += offset / 8; + offset &= 7; + +From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Date: Thu, 18 Feb 2010 19:38:52 +0000 (+0100) +Subject: uvcvideo: Support menu controls in the control mapping API +X-Git-Url: http://git.linuxtv.org/pinchartl/uvcvideo.git?a=commitdiff_plain;h=4930f2662e47d33e5baedac620da401a225bc3a8 + +uvcvideo: Support menu controls in the control mapping API + +The UVCIOC_CTRL_MAP ioctl doesn't support menu entries for menu +controls. As the uvc_xu_control_mapping structure has no reserved +fields, this can't be fixed while keeping ABI compatibility. + +Modify the UVCIOC_CTRL_MAP ioctl to add menu entries support, and define +UVCIOC_CTRL_MAP_OLD that supports the old ABI without any ability to add +menu controls. + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + +diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c +index 8bb825d..c88d72e 100644 +--- a/drivers/media/video/uvc/uvc_ctrl.c ++++ b/drivers/media/video/uvc/uvc_ctrl.c +@@ -1606,6 +1606,28 @@ void uvc_ctrl_cleanup_device(struct uvc_device *dev) + } + } + ++void uvc_ctrl_cleanup(void) ++{ ++ struct uvc_control_info *info; ++ struct uvc_control_info *ni; ++ struct uvc_control_mapping *mapping; ++ struct uvc_control_mapping *nm; ++ ++ list_for_each_entry_safe(info, ni, &uvc_driver.controls, list) { ++ if (!(info->flags & UVC_CONTROL_EXTENSION)) ++ continue; ++ ++ list_for_each_entry_safe(mapping, nm, &info->mappings, list) { ++ list_del(&mapping->list); ++ kfree(mapping->menu_info); ++ kfree(mapping); ++ } ++ ++ list_del(&info->list); ++ kfree(info); ++ } ++} ++ + void uvc_ctrl_init(void) + { + struct uvc_control_info *ctrl = uvc_ctrls; +diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c +index 838b56f..34818c1 100644 +--- a/drivers/media/video/uvc/uvc_driver.c ++++ b/drivers/media/video/uvc/uvc_driver.c +@@ -2261,6 +2261,7 @@ static int __init uvc_init(void) + static void __exit uvc_cleanup(void) + { + usb_deregister(&uvc_driver.driver); ++ uvc_ctrl_cleanup(); + } + + module_init(uvc_init); +diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c +index 7c9ab29..485a899 100644 +--- a/drivers/media/video/uvc/uvc_v4l2.c ++++ b/drivers/media/video/uvc/uvc_v4l2.c +@@ -29,6 +29,71 @@ + #include "uvcvideo.h" + + /* ------------------------------------------------------------------------ ++ * UVC ioctls ++ */ ++static int uvc_ioctl_ctrl_map(struct uvc_xu_control_mapping *xmap, int old) ++{ ++ struct uvc_control_mapping *map; ++ unsigned int size; ++ int ret; ++ ++ map = kzalloc(sizeof *map, GFP_KERNEL); ++ if (map == NULL) ++ return -ENOMEM; ++ ++ map->id = xmap->id; ++ memcpy(map->name, xmap->name, sizeof map->name); ++ memcpy(map->entity, xmap->entity, sizeof map->entity); ++ map->selector = xmap->selector; ++ map->size = xmap->size; ++ map->offset = xmap->offset; ++ map->v4l2_type = xmap->v4l2_type; ++ map->data_type = xmap->data_type; ++ ++ switch (xmap->v4l2_type) { ++ case V4L2_CTRL_TYPE_INTEGER: ++ case V4L2_CTRL_TYPE_BOOLEAN: ++ case V4L2_CTRL_TYPE_BUTTON: ++ break; ++ ++ case V4L2_CTRL_TYPE_MENU: ++ if (old) { ++ ret = -EINVAL; ++ goto done; ++ } ++ ++ size = xmap->menu_count * sizeof(*map->menu_info); ++ map->menu_info = kmalloc(size, GFP_KERNEL); ++ if (map->menu_info == NULL) { ++ ret = -ENOMEM; ++ goto done; ++ } ++ ++ if (copy_from_user(map->menu_info, xmap->menu_info, size)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ++ map->menu_count = xmap->menu_count; ++ break; ++ ++ default: ++ ret = -EINVAL; ++ goto done; ++ } ++ ++ ret = uvc_ctrl_add_mapping(map); ++ ++done: ++ if (ret < 0) { ++ kfree(map->menu_info); ++ kfree(map); ++ } ++ ++ return ret; ++} ++ ++/* ------------------------------------------------------------------------ + * V4L2 interface + */ + +@@ -974,7 +1039,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) + info->flags = xinfo->flags; + + info->flags |= UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | +- UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF; ++ UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF | ++ UVC_CONTROL_EXTENSION; + + ret = uvc_ctrl_add_info(info); + if (ret < 0) +@@ -982,32 +1048,12 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) + break; + } + ++ case UVCIOC_CTRL_MAP_OLD: + case UVCIOC_CTRL_MAP: +- { +- struct uvc_xu_control_mapping *xmap = arg; +- struct uvc_control_mapping *map; +- + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- map = kzalloc(sizeof *map, GFP_KERNEL); +- if (map == NULL) +- return -ENOMEM; +- +- map->id = xmap->id; +- memcpy(map->name, xmap->name, sizeof map->name); +- memcpy(map->entity, xmap->entity, sizeof map->entity); +- map->selector = xmap->selector; +- map->size = xmap->size; +- map->offset = xmap->offset; +- map->v4l2_type = xmap->v4l2_type; +- map->data_type = xmap->data_type; +- +- ret = uvc_ctrl_add_mapping(map); +- if (ret < 0) +- kfree(map); +- break; +- } ++ return uvc_ioctl_ctrl_map(arg, cmd == UVCIOC_CTRL_MAP_OLD); + + case UVCIOC_CTRL_GET: + return uvc_xu_ctrl_query(chain, arg, 0); +diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h +index d1f8840..14f77e4 100644 +--- a/drivers/media/video/uvc/uvcvideo.h ++++ b/drivers/media/video/uvc/uvcvideo.h +@@ -27,6 +27,8 @@ + #define UVC_CONTROL_RESTORE (1 << 6) + /* Control can be updated by the camera. */ + #define UVC_CONTROL_AUTO_UPDATE (1 << 7) ++/* Control is an extension unit control. */ ++#define UVC_CONTROL_EXTENSION (1 << 8) + + #define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \ + UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \ +@@ -40,6 +42,15 @@ struct uvc_xu_control_info { + __u32 flags; + }; + ++struct uvc_menu_info { ++ __u32 value; ++ __u8 name[32]; ++}; ++ ++struct uvc_xu_control_mapping_old { ++ __u8 reserved[64]; ++}; ++ + struct uvc_xu_control_mapping { + __u32 id; + __u8 name[32]; +@@ -50,6 +61,11 @@ struct uvc_xu_control_mapping { + __u8 offset; + enum v4l2_ctrl_type v4l2_type; + __u32 data_type; ++ ++ struct uvc_menu_info __user *menu_info; ++ __u32 menu_count; ++ ++ __u32 reserved[4]; + }; + + struct uvc_xu_control { +@@ -60,6 +76,7 @@ struct uvc_xu_control { + }; + + #define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info) ++#define UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old) + #define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping) + #define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control) + #define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control) +@@ -198,11 +215,6 @@ struct uvc_streaming_control { + __u8 bMaxVersion; + }; + +-struct uvc_menu_info { +- __u32 value; +- __u8 name[32]; +-}; +- + struct uvc_control_info { + struct list_head list; + struct list_head mappings; +@@ -625,6 +637,7 @@ extern int uvc_ctrl_init_device(struct uvc_device *dev); + extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); + extern int uvc_ctrl_resume_device(struct uvc_device *dev); + extern void uvc_ctrl_init(void); ++extern void uvc_ctrl_cleanup(void); + + extern int uvc_ctrl_begin(struct uvc_video_chain *chain); + extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback); +From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Date: Fri, 25 Jun 2010 07:58:43 +0000 (+0200) +Subject: uvcvideo: Add support for Manta MM-353 Plako +X-Git-Url: http://git.linuxtv.org/pinchartl/uvcvideo.git?a=commitdiff_plain;h=352e661e1f347390a86cf34bc5e41adbdd1caa41 + +uvcvideo: Add support for Manta MM-353 Plako + +The camera requires the PROBE_MINMAX quirk. Add a corresponding entry +in the device IDs list + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + +diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c +index 34818c1..1a89384 100644 +--- a/drivers/media/video/uvc/uvc_driver.c ++++ b/drivers/media/video/uvc/uvc_driver.c +@@ -2174,6 +2174,15 @@ static struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, ++ /* Manta MM-353 Plako */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x18ec, ++ .idProduct = 0x3188, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* FSC WebCam V30S */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, |