aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc/uvc_ctrl.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2010-10-01 14:39:49 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-20 23:18:25 -0400
commitb5977a58c330ac6afdc64bab9b1dd674f11c0635 (patch)
tree3bf9956d28f067aca41cc87e4812abfe53eda7af /drivers/media/video/uvc/uvc_ctrl.c
parent52c58ad6f95ff60343bf0c517182d5f649ca0403 (diff)
[media] uvcvideo: Fix bogus XU controls information
XU control information is supposed to be entirely discoverable using standard UVC queries. As some devices report bogus information (such as reporting a read-only control as being read-write), add a fixup table for XU controls. This table can also be used to selectively disable requests supposed to be supported by all XU controls (GET_MIN, GET_MAX, GET_DEF, GET_RES) but not correctly (or at all) supported by the device. The table currently disables GET_CUR on the Logitech motor control XU pan/tilt controls. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc/uvc_ctrl.c')
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index a0c9d580ca9d..0d310c422412 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1164,6 +1164,45 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1164 * Dynamic controls 1164 * Dynamic controls
1165 */ 1165 */
1166 1166
1167static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev,
1168 const struct uvc_control *ctrl, struct uvc_control_info *info)
1169{
1170 struct uvc_ctrl_fixup {
1171 struct usb_device_id id;
1172 u8 entity;
1173 u8 selector;
1174 u8 flags;
1175 };
1176
1177 static const struct uvc_ctrl_fixup fixups[] = {
1178 { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
1179 UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
1180 UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR |
1181 UVC_CONTROL_AUTO_UPDATE },
1182 { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
1183 UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
1184 UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR |
1185 UVC_CONTROL_AUTO_UPDATE },
1186 { { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
1187 UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
1188 UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR |
1189 UVC_CONTROL_AUTO_UPDATE },
1190 };
1191
1192 unsigned int i;
1193
1194 for (i = 0; i < ARRAY_SIZE(fixups); ++i) {
1195 if (!usb_match_one_id(dev->intf, &fixups[i].id))
1196 continue;
1197
1198 if (fixups[i].entity == ctrl->entity->id &&
1199 fixups[i].selector == info->selector) {
1200 info->flags = fixups[i].flags;
1201 return;
1202 }
1203 }
1204}
1205
1167/* 1206/*
1168 * Query control information (size and flags) for XU controls. 1207 * Query control information (size and flags) for XU controls.
1169 */ 1208 */
@@ -1211,6 +1250,8 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
1211 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? 1250 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
1212 UVC_CONTROL_AUTO_UPDATE : 0); 1251 UVC_CONTROL_AUTO_UPDATE : 0);
1213 1252
1253 uvc_ctrl_fixup_xu_info(dev, ctrl, info);
1254
1214 uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, " 1255 uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, "
1215 "flags { get %u set %u auto %u }.\n", 1256 "flags { get %u set %u auto %u }.\n",
1216 info->entity, info->selector, info->size, 1257 info->entity, info->selector, info->size,