0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/list.h>
0011 #include <linux/module.h>
0012 #include <linux/slab.h>
0013 #include <linux/uaccess.h>
0014 #include <linux/usb.h>
0015 #include <linux/videodev2.h>
0016 #include <linux/vmalloc.h>
0017 #include <linux/wait.h>
0018 #include <linux/workqueue.h>
0019 #include <linux/atomic.h>
0020 #include <media/v4l2-ctrls.h>
0021
0022 #include "uvcvideo.h"
0023
0024 #define UVC_CTRL_DATA_CURRENT 0
0025 #define UVC_CTRL_DATA_BACKUP 1
0026 #define UVC_CTRL_DATA_MIN 2
0027 #define UVC_CTRL_DATA_MAX 3
0028 #define UVC_CTRL_DATA_RES 4
0029 #define UVC_CTRL_DATA_DEF 5
0030 #define UVC_CTRL_DATA_LAST 6
0031
0032
0033
0034
0035
0036 static const struct uvc_control_info uvc_ctrls[] = {
0037 {
0038 .entity = UVC_GUID_UVC_PROCESSING,
0039 .selector = UVC_PU_BRIGHTNESS_CONTROL,
0040 .index = 0,
0041 .size = 2,
0042 .flags = UVC_CTRL_FLAG_SET_CUR
0043 | UVC_CTRL_FLAG_GET_RANGE
0044 | UVC_CTRL_FLAG_RESTORE,
0045 },
0046 {
0047 .entity = UVC_GUID_UVC_PROCESSING,
0048 .selector = UVC_PU_CONTRAST_CONTROL,
0049 .index = 1,
0050 .size = 2,
0051 .flags = UVC_CTRL_FLAG_SET_CUR
0052 | UVC_CTRL_FLAG_GET_RANGE
0053 | UVC_CTRL_FLAG_RESTORE,
0054 },
0055 {
0056 .entity = UVC_GUID_UVC_PROCESSING,
0057 .selector = UVC_PU_HUE_CONTROL,
0058 .index = 2,
0059 .size = 2,
0060 .flags = UVC_CTRL_FLAG_SET_CUR
0061 | UVC_CTRL_FLAG_GET_RANGE
0062 | UVC_CTRL_FLAG_RESTORE
0063 | UVC_CTRL_FLAG_AUTO_UPDATE,
0064 },
0065 {
0066 .entity = UVC_GUID_UVC_PROCESSING,
0067 .selector = UVC_PU_SATURATION_CONTROL,
0068 .index = 3,
0069 .size = 2,
0070 .flags = UVC_CTRL_FLAG_SET_CUR
0071 | UVC_CTRL_FLAG_GET_RANGE
0072 | UVC_CTRL_FLAG_RESTORE,
0073 },
0074 {
0075 .entity = UVC_GUID_UVC_PROCESSING,
0076 .selector = UVC_PU_SHARPNESS_CONTROL,
0077 .index = 4,
0078 .size = 2,
0079 .flags = UVC_CTRL_FLAG_SET_CUR
0080 | UVC_CTRL_FLAG_GET_RANGE
0081 | UVC_CTRL_FLAG_RESTORE,
0082 },
0083 {
0084 .entity = UVC_GUID_UVC_PROCESSING,
0085 .selector = UVC_PU_GAMMA_CONTROL,
0086 .index = 5,
0087 .size = 2,
0088 .flags = UVC_CTRL_FLAG_SET_CUR
0089 | UVC_CTRL_FLAG_GET_RANGE
0090 | UVC_CTRL_FLAG_RESTORE,
0091 },
0092 {
0093 .entity = UVC_GUID_UVC_PROCESSING,
0094 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
0095 .index = 6,
0096 .size = 2,
0097 .flags = UVC_CTRL_FLAG_SET_CUR
0098 | UVC_CTRL_FLAG_GET_RANGE
0099 | UVC_CTRL_FLAG_RESTORE
0100 | UVC_CTRL_FLAG_AUTO_UPDATE,
0101 },
0102 {
0103 .entity = UVC_GUID_UVC_PROCESSING,
0104 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
0105 .index = 7,
0106 .size = 4,
0107 .flags = UVC_CTRL_FLAG_SET_CUR
0108 | UVC_CTRL_FLAG_GET_RANGE
0109 | UVC_CTRL_FLAG_RESTORE
0110 | UVC_CTRL_FLAG_AUTO_UPDATE,
0111 },
0112 {
0113 .entity = UVC_GUID_UVC_PROCESSING,
0114 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
0115 .index = 8,
0116 .size = 2,
0117 .flags = UVC_CTRL_FLAG_SET_CUR
0118 | UVC_CTRL_FLAG_GET_RANGE
0119 | UVC_CTRL_FLAG_RESTORE,
0120 },
0121 {
0122 .entity = UVC_GUID_UVC_PROCESSING,
0123 .selector = UVC_PU_GAIN_CONTROL,
0124 .index = 9,
0125 .size = 2,
0126 .flags = UVC_CTRL_FLAG_SET_CUR
0127 | UVC_CTRL_FLAG_GET_RANGE
0128 | UVC_CTRL_FLAG_RESTORE,
0129 },
0130 {
0131 .entity = UVC_GUID_UVC_PROCESSING,
0132 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
0133 .index = 10,
0134 .size = 1,
0135 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
0136 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
0137 },
0138 {
0139 .entity = UVC_GUID_UVC_PROCESSING,
0140 .selector = UVC_PU_HUE_AUTO_CONTROL,
0141 .index = 11,
0142 .size = 1,
0143 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
0144 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
0145 },
0146 {
0147 .entity = UVC_GUID_UVC_PROCESSING,
0148 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
0149 .index = 12,
0150 .size = 1,
0151 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
0152 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
0153 },
0154 {
0155 .entity = UVC_GUID_UVC_PROCESSING,
0156 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
0157 .index = 13,
0158 .size = 1,
0159 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
0160 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
0161 },
0162 {
0163 .entity = UVC_GUID_UVC_PROCESSING,
0164 .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL,
0165 .index = 14,
0166 .size = 2,
0167 .flags = UVC_CTRL_FLAG_SET_CUR
0168 | UVC_CTRL_FLAG_GET_RANGE
0169 | UVC_CTRL_FLAG_RESTORE,
0170 },
0171 {
0172 .entity = UVC_GUID_UVC_PROCESSING,
0173 .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
0174 .index = 15,
0175 .size = 2,
0176 .flags = UVC_CTRL_FLAG_SET_CUR
0177 | UVC_CTRL_FLAG_GET_RANGE
0178 | UVC_CTRL_FLAG_RESTORE,
0179 },
0180 {
0181 .entity = UVC_GUID_UVC_PROCESSING,
0182 .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,
0183 .index = 16,
0184 .size = 1,
0185 .flags = UVC_CTRL_FLAG_GET_CUR,
0186 },
0187 {
0188 .entity = UVC_GUID_UVC_PROCESSING,
0189 .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL,
0190 .index = 17,
0191 .size = 1,
0192 .flags = UVC_CTRL_FLAG_GET_CUR,
0193 },
0194 {
0195 .entity = UVC_GUID_UVC_CAMERA,
0196 .selector = UVC_CT_SCANNING_MODE_CONTROL,
0197 .index = 0,
0198 .size = 1,
0199 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
0200 | UVC_CTRL_FLAG_RESTORE,
0201 },
0202 {
0203 .entity = UVC_GUID_UVC_CAMERA,
0204 .selector = UVC_CT_AE_MODE_CONTROL,
0205 .index = 1,
0206 .size = 1,
0207 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
0208 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_GET_RES
0209 | UVC_CTRL_FLAG_RESTORE,
0210 },
0211 {
0212 .entity = UVC_GUID_UVC_CAMERA,
0213 .selector = UVC_CT_AE_PRIORITY_CONTROL,
0214 .index = 2,
0215 .size = 1,
0216 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
0217 | UVC_CTRL_FLAG_RESTORE,
0218 },
0219 {
0220 .entity = UVC_GUID_UVC_CAMERA,
0221 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
0222 .index = 3,
0223 .size = 4,
0224 .flags = UVC_CTRL_FLAG_SET_CUR
0225 | UVC_CTRL_FLAG_GET_RANGE
0226 | UVC_CTRL_FLAG_RESTORE
0227 | UVC_CTRL_FLAG_AUTO_UPDATE,
0228 },
0229 {
0230 .entity = UVC_GUID_UVC_CAMERA,
0231 .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
0232 .index = 4,
0233 .size = 1,
0234 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_RESTORE,
0235 },
0236 {
0237 .entity = UVC_GUID_UVC_CAMERA,
0238 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
0239 .index = 5,
0240 .size = 2,
0241 .flags = UVC_CTRL_FLAG_SET_CUR
0242 | UVC_CTRL_FLAG_GET_RANGE
0243 | UVC_CTRL_FLAG_RESTORE
0244 | UVC_CTRL_FLAG_AUTO_UPDATE,
0245 },
0246 {
0247 .entity = UVC_GUID_UVC_CAMERA,
0248 .selector = UVC_CT_FOCUS_RELATIVE_CONTROL,
0249 .index = 6,
0250 .size = 2,
0251 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
0252 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
0253 | UVC_CTRL_FLAG_GET_DEF
0254 | UVC_CTRL_FLAG_AUTO_UPDATE,
0255 },
0256 {
0257 .entity = UVC_GUID_UVC_CAMERA,
0258 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
0259 .index = 7,
0260 .size = 2,
0261 .flags = UVC_CTRL_FLAG_SET_CUR
0262 | UVC_CTRL_FLAG_GET_RANGE
0263 | UVC_CTRL_FLAG_RESTORE
0264 | UVC_CTRL_FLAG_AUTO_UPDATE,
0265 },
0266 {
0267 .entity = UVC_GUID_UVC_CAMERA,
0268 .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
0269 .index = 8,
0270 .size = 1,
0271 .flags = UVC_CTRL_FLAG_SET_CUR
0272 | UVC_CTRL_FLAG_AUTO_UPDATE,
0273 },
0274 {
0275 .entity = UVC_GUID_UVC_CAMERA,
0276 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
0277 .index = 9,
0278 .size = 2,
0279 .flags = UVC_CTRL_FLAG_SET_CUR
0280 | UVC_CTRL_FLAG_GET_RANGE
0281 | UVC_CTRL_FLAG_RESTORE
0282 | UVC_CTRL_FLAG_AUTO_UPDATE,
0283 },
0284 {
0285 .entity = UVC_GUID_UVC_CAMERA,
0286 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
0287 .index = 10,
0288 .size = 3,
0289 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
0290 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
0291 | UVC_CTRL_FLAG_GET_DEF
0292 | UVC_CTRL_FLAG_AUTO_UPDATE,
0293 },
0294 {
0295 .entity = UVC_GUID_UVC_CAMERA,
0296 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
0297 .index = 11,
0298 .size = 8,
0299 .flags = UVC_CTRL_FLAG_SET_CUR
0300 | UVC_CTRL_FLAG_GET_RANGE
0301 | UVC_CTRL_FLAG_RESTORE
0302 | UVC_CTRL_FLAG_AUTO_UPDATE,
0303 },
0304 {
0305 .entity = UVC_GUID_UVC_CAMERA,
0306 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,
0307 .index = 12,
0308 .size = 4,
0309 .flags = UVC_CTRL_FLAG_SET_CUR
0310 | UVC_CTRL_FLAG_GET_RANGE
0311 | UVC_CTRL_FLAG_AUTO_UPDATE,
0312 },
0313 {
0314 .entity = UVC_GUID_UVC_CAMERA,
0315 .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL,
0316 .index = 13,
0317 .size = 2,
0318 .flags = UVC_CTRL_FLAG_SET_CUR
0319 | UVC_CTRL_FLAG_GET_RANGE
0320 | UVC_CTRL_FLAG_RESTORE
0321 | UVC_CTRL_FLAG_AUTO_UPDATE,
0322 },
0323 {
0324 .entity = UVC_GUID_UVC_CAMERA,
0325 .selector = UVC_CT_ROLL_RELATIVE_CONTROL,
0326 .index = 14,
0327 .size = 2,
0328 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
0329 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
0330 | UVC_CTRL_FLAG_GET_DEF
0331 | UVC_CTRL_FLAG_AUTO_UPDATE,
0332 },
0333 {
0334 .entity = UVC_GUID_UVC_CAMERA,
0335 .selector = UVC_CT_FOCUS_AUTO_CONTROL,
0336 .index = 17,
0337 .size = 1,
0338 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
0339 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
0340 },
0341 {
0342 .entity = UVC_GUID_UVC_CAMERA,
0343 .selector = UVC_CT_PRIVACY_CONTROL,
0344 .index = 18,
0345 .size = 1,
0346 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
0347 | UVC_CTRL_FLAG_RESTORE
0348 | UVC_CTRL_FLAG_AUTO_UPDATE,
0349 },
0350 {
0351 .entity = UVC_GUID_EXT_GPIO_CONTROLLER,
0352 .selector = UVC_CT_PRIVACY_CONTROL,
0353 .index = 0,
0354 .size = 1,
0355 .flags = UVC_CTRL_FLAG_GET_CUR
0356 | UVC_CTRL_FLAG_AUTO_UPDATE,
0357 },
0358 };
0359
0360 static const u32 uvc_control_classes[] = {
0361 V4L2_CID_CAMERA_CLASS,
0362 V4L2_CID_USER_CLASS,
0363 };
0364
0365 static const struct uvc_menu_info power_line_frequency_controls[] = {
0366 { 0, "Disabled" },
0367 { 1, "50 Hz" },
0368 { 2, "60 Hz" },
0369 { 3, "Auto" },
0370 };
0371
0372 static const struct uvc_menu_info exposure_auto_controls[] = {
0373 { 2, "Auto Mode" },
0374 { 1, "Manual Mode" },
0375 { 4, "Shutter Priority Mode" },
0376 { 8, "Aperture Priority Mode" },
0377 };
0378
0379 static s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping,
0380 u8 query, const u8 *data)
0381 {
0382 s8 zoom = (s8)data[0];
0383
0384 switch (query) {
0385 case UVC_GET_CUR:
0386 return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);
0387
0388 case UVC_GET_MIN:
0389 case UVC_GET_MAX:
0390 case UVC_GET_RES:
0391 case UVC_GET_DEF:
0392 default:
0393 return data[2];
0394 }
0395 }
0396
0397 static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,
0398 s32 value, u8 *data)
0399 {
0400 data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
0401 data[2] = min((int)abs(value), 0xff);
0402 }
0403
0404 static s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping,
0405 u8 query, const u8 *data)
0406 {
0407 unsigned int first = mapping->offset / 8;
0408 s8 rel = (s8)data[first];
0409
0410 switch (query) {
0411 case UVC_GET_CUR:
0412 return (rel == 0) ? 0 : (rel > 0 ? data[first+1]
0413 : -data[first+1]);
0414 case UVC_GET_MIN:
0415 return -data[first+1];
0416 case UVC_GET_MAX:
0417 case UVC_GET_RES:
0418 case UVC_GET_DEF:
0419 default:
0420 return data[first+1];
0421 }
0422 }
0423
0424 static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping,
0425 s32 value, u8 *data)
0426 {
0427 unsigned int first = mapping->offset / 8;
0428
0429 data[first] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
0430 data[first+1] = min_t(int, abs(value), 0xff);
0431 }
0432
0433 static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
0434 {
0435 .id = V4L2_CID_BRIGHTNESS,
0436 .entity = UVC_GUID_UVC_PROCESSING,
0437 .selector = UVC_PU_BRIGHTNESS_CONTROL,
0438 .size = 16,
0439 .offset = 0,
0440 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0441 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0442 },
0443 {
0444 .id = V4L2_CID_CONTRAST,
0445 .entity = UVC_GUID_UVC_PROCESSING,
0446 .selector = UVC_PU_CONTRAST_CONTROL,
0447 .size = 16,
0448 .offset = 0,
0449 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0450 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0451 },
0452 {
0453 .id = V4L2_CID_HUE,
0454 .entity = UVC_GUID_UVC_PROCESSING,
0455 .selector = UVC_PU_HUE_CONTROL,
0456 .size = 16,
0457 .offset = 0,
0458 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0459 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0460 .master_id = V4L2_CID_HUE_AUTO,
0461 .master_manual = 0,
0462 },
0463 {
0464 .id = V4L2_CID_SATURATION,
0465 .entity = UVC_GUID_UVC_PROCESSING,
0466 .selector = UVC_PU_SATURATION_CONTROL,
0467 .size = 16,
0468 .offset = 0,
0469 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0470 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0471 },
0472 {
0473 .id = V4L2_CID_SHARPNESS,
0474 .entity = UVC_GUID_UVC_PROCESSING,
0475 .selector = UVC_PU_SHARPNESS_CONTROL,
0476 .size = 16,
0477 .offset = 0,
0478 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0479 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0480 },
0481 {
0482 .id = V4L2_CID_GAMMA,
0483 .entity = UVC_GUID_UVC_PROCESSING,
0484 .selector = UVC_PU_GAMMA_CONTROL,
0485 .size = 16,
0486 .offset = 0,
0487 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0488 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0489 },
0490 {
0491 .id = V4L2_CID_BACKLIGHT_COMPENSATION,
0492 .entity = UVC_GUID_UVC_PROCESSING,
0493 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
0494 .size = 16,
0495 .offset = 0,
0496 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0497 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0498 },
0499 {
0500 .id = V4L2_CID_GAIN,
0501 .entity = UVC_GUID_UVC_PROCESSING,
0502 .selector = UVC_PU_GAIN_CONTROL,
0503 .size = 16,
0504 .offset = 0,
0505 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0506 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0507 },
0508 {
0509 .id = V4L2_CID_HUE_AUTO,
0510 .entity = UVC_GUID_UVC_PROCESSING,
0511 .selector = UVC_PU_HUE_AUTO_CONTROL,
0512 .size = 1,
0513 .offset = 0,
0514 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
0515 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
0516 .slave_ids = { V4L2_CID_HUE, },
0517 },
0518 {
0519 .id = V4L2_CID_EXPOSURE_AUTO,
0520 .entity = UVC_GUID_UVC_CAMERA,
0521 .selector = UVC_CT_AE_MODE_CONTROL,
0522 .size = 4,
0523 .offset = 0,
0524 .v4l2_type = V4L2_CTRL_TYPE_MENU,
0525 .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
0526 .menu_info = exposure_auto_controls,
0527 .menu_count = ARRAY_SIZE(exposure_auto_controls),
0528 .slave_ids = { V4L2_CID_EXPOSURE_ABSOLUTE, },
0529 },
0530 {
0531 .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
0532 .entity = UVC_GUID_UVC_CAMERA,
0533 .selector = UVC_CT_AE_PRIORITY_CONTROL,
0534 .size = 1,
0535 .offset = 0,
0536 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
0537 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
0538 },
0539 {
0540 .id = V4L2_CID_EXPOSURE_ABSOLUTE,
0541 .entity = UVC_GUID_UVC_CAMERA,
0542 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
0543 .size = 32,
0544 .offset = 0,
0545 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0546 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0547 .master_id = V4L2_CID_EXPOSURE_AUTO,
0548 .master_manual = V4L2_EXPOSURE_MANUAL,
0549 },
0550 {
0551 .id = V4L2_CID_AUTO_WHITE_BALANCE,
0552 .entity = UVC_GUID_UVC_PROCESSING,
0553 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
0554 .size = 1,
0555 .offset = 0,
0556 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
0557 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
0558 .slave_ids = { V4L2_CID_WHITE_BALANCE_TEMPERATURE, },
0559 },
0560 {
0561 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
0562 .entity = UVC_GUID_UVC_PROCESSING,
0563 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
0564 .size = 16,
0565 .offset = 0,
0566 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0567 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0568 .master_id = V4L2_CID_AUTO_WHITE_BALANCE,
0569 .master_manual = 0,
0570 },
0571 {
0572 .id = V4L2_CID_AUTO_WHITE_BALANCE,
0573 .entity = UVC_GUID_UVC_PROCESSING,
0574 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
0575 .size = 1,
0576 .offset = 0,
0577 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
0578 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
0579 .slave_ids = { V4L2_CID_BLUE_BALANCE,
0580 V4L2_CID_RED_BALANCE },
0581 },
0582 {
0583 .id = V4L2_CID_BLUE_BALANCE,
0584 .entity = UVC_GUID_UVC_PROCESSING,
0585 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
0586 .size = 16,
0587 .offset = 0,
0588 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0589 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0590 .master_id = V4L2_CID_AUTO_WHITE_BALANCE,
0591 .master_manual = 0,
0592 },
0593 {
0594 .id = V4L2_CID_RED_BALANCE,
0595 .entity = UVC_GUID_UVC_PROCESSING,
0596 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
0597 .size = 16,
0598 .offset = 16,
0599 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0600 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0601 .master_id = V4L2_CID_AUTO_WHITE_BALANCE,
0602 .master_manual = 0,
0603 },
0604 {
0605 .id = V4L2_CID_FOCUS_ABSOLUTE,
0606 .entity = UVC_GUID_UVC_CAMERA,
0607 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
0608 .size = 16,
0609 .offset = 0,
0610 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0611 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0612 .master_id = V4L2_CID_FOCUS_AUTO,
0613 .master_manual = 0,
0614 },
0615 {
0616 .id = V4L2_CID_FOCUS_AUTO,
0617 .entity = UVC_GUID_UVC_CAMERA,
0618 .selector = UVC_CT_FOCUS_AUTO_CONTROL,
0619 .size = 1,
0620 .offset = 0,
0621 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
0622 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
0623 .slave_ids = { V4L2_CID_FOCUS_ABSOLUTE, },
0624 },
0625 {
0626 .id = V4L2_CID_IRIS_ABSOLUTE,
0627 .entity = UVC_GUID_UVC_CAMERA,
0628 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
0629 .size = 16,
0630 .offset = 0,
0631 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0632 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0633 },
0634 {
0635 .id = V4L2_CID_IRIS_RELATIVE,
0636 .entity = UVC_GUID_UVC_CAMERA,
0637 .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
0638 .size = 8,
0639 .offset = 0,
0640 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0641 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0642 },
0643 {
0644 .id = V4L2_CID_ZOOM_ABSOLUTE,
0645 .entity = UVC_GUID_UVC_CAMERA,
0646 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
0647 .size = 16,
0648 .offset = 0,
0649 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0650 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
0651 },
0652 {
0653 .id = V4L2_CID_ZOOM_CONTINUOUS,
0654 .entity = UVC_GUID_UVC_CAMERA,
0655 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
0656 .size = 0,
0657 .offset = 0,
0658 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0659 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0660 .get = uvc_ctrl_get_zoom,
0661 .set = uvc_ctrl_set_zoom,
0662 },
0663 {
0664 .id = V4L2_CID_PAN_ABSOLUTE,
0665 .entity = UVC_GUID_UVC_CAMERA,
0666 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
0667 .size = 32,
0668 .offset = 0,
0669 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0670 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0671 },
0672 {
0673 .id = V4L2_CID_TILT_ABSOLUTE,
0674 .entity = UVC_GUID_UVC_CAMERA,
0675 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
0676 .size = 32,
0677 .offset = 32,
0678 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0679 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0680 },
0681 {
0682 .id = V4L2_CID_PAN_SPEED,
0683 .entity = UVC_GUID_UVC_CAMERA,
0684 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,
0685 .size = 16,
0686 .offset = 0,
0687 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0688 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0689 .get = uvc_ctrl_get_rel_speed,
0690 .set = uvc_ctrl_set_rel_speed,
0691 },
0692 {
0693 .id = V4L2_CID_TILT_SPEED,
0694 .entity = UVC_GUID_UVC_CAMERA,
0695 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,
0696 .size = 16,
0697 .offset = 16,
0698 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
0699 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
0700 .get = uvc_ctrl_get_rel_speed,
0701 .set = uvc_ctrl_set_rel_speed,
0702 },
0703 {
0704 .id = V4L2_CID_PRIVACY,
0705 .entity = UVC_GUID_UVC_CAMERA,
0706 .selector = UVC_CT_PRIVACY_CONTROL,
0707 .size = 1,
0708 .offset = 0,
0709 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
0710 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
0711 },
0712 {
0713 .id = V4L2_CID_PRIVACY,
0714 .entity = UVC_GUID_EXT_GPIO_CONTROLLER,
0715 .selector = UVC_CT_PRIVACY_CONTROL,
0716 .size = 1,
0717 .offset = 0,
0718 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
0719 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
0720 },
0721 };
0722
0723 static const struct uvc_control_mapping uvc_ctrl_mappings_uvc11[] = {
0724 {
0725 .id = V4L2_CID_POWER_LINE_FREQUENCY,
0726 .entity = UVC_GUID_UVC_PROCESSING,
0727 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
0728 .size = 2,
0729 .offset = 0,
0730 .v4l2_type = V4L2_CTRL_TYPE_MENU,
0731 .data_type = UVC_CTRL_DATA_TYPE_ENUM,
0732 .menu_info = power_line_frequency_controls,
0733 .menu_count = ARRAY_SIZE(power_line_frequency_controls) - 1,
0734 },
0735 };
0736
0737 static const struct uvc_control_mapping uvc_ctrl_mappings_uvc15[] = {
0738 {
0739 .id = V4L2_CID_POWER_LINE_FREQUENCY,
0740 .entity = UVC_GUID_UVC_PROCESSING,
0741 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
0742 .size = 2,
0743 .offset = 0,
0744 .v4l2_type = V4L2_CTRL_TYPE_MENU,
0745 .data_type = UVC_CTRL_DATA_TYPE_ENUM,
0746 .menu_info = power_line_frequency_controls,
0747 .menu_count = ARRAY_SIZE(power_line_frequency_controls),
0748 },
0749 };
0750
0751
0752
0753
0754
0755 static inline u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)
0756 {
0757 return ctrl->uvc_data + id * ctrl->info.size;
0758 }
0759
0760 static inline int uvc_test_bit(const u8 *data, int bit)
0761 {
0762 return (data[bit >> 3] >> (bit & 7)) & 1;
0763 }
0764
0765 static inline void uvc_clear_bit(u8 *data, int bit)
0766 {
0767 data[bit >> 3] &= ~(1 << (bit & 7));
0768 }
0769
0770
0771
0772
0773
0774
0775
0776 static s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
0777 u8 query, const u8 *data)
0778 {
0779 int bits = mapping->size;
0780 int offset = mapping->offset;
0781 s32 value = 0;
0782 u8 mask;
0783
0784 data += offset / 8;
0785 offset &= 7;
0786 mask = ((1LL << bits) - 1) << offset;
0787
0788 while (1) {
0789 u8 byte = *data & mask;
0790 value |= offset > 0 ? (byte >> offset) : (byte << (-offset));
0791 bits -= 8 - (offset > 0 ? offset : 0);
0792 if (bits <= 0)
0793 break;
0794
0795 offset -= 8;
0796 mask = (1 << bits) - 1;
0797 data++;
0798 }
0799
0800
0801 if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
0802 value |= -(value & (1 << (mapping->size - 1)));
0803
0804 return value;
0805 }
0806
0807
0808
0809
0810
0811 static void uvc_set_le_value(struct uvc_control_mapping *mapping,
0812 s32 value, u8 *data)
0813 {
0814 int bits = mapping->size;
0815 int offset = mapping->offset;
0816 u8 mask;
0817
0818
0819
0820
0821
0822
0823
0824 if (mapping->v4l2_type == V4L2_CTRL_TYPE_BUTTON)
0825 value = -1;
0826
0827 data += offset / 8;
0828 offset &= 7;
0829
0830 for (; bits > 0; data++) {
0831 mask = ((1LL << bits) - 1) << offset;
0832 *data = (*data & ~mask) | ((value << offset) & mask);
0833 value >>= offset ? offset : 8;
0834 bits -= 8 - offset;
0835 offset = 0;
0836 }
0837 }
0838
0839
0840
0841
0842
0843 static int uvc_entity_match_guid(const struct uvc_entity *entity,
0844 const u8 guid[16])
0845 {
0846 return memcmp(entity->guid, guid, sizeof(entity->guid)) == 0;
0847 }
0848
0849
0850
0851
0852
0853 static void __uvc_find_control(struct uvc_entity *entity, u32 v4l2_id,
0854 struct uvc_control_mapping **mapping, struct uvc_control **control,
0855 int next)
0856 {
0857 struct uvc_control *ctrl;
0858 struct uvc_control_mapping *map;
0859 unsigned int i;
0860
0861 if (entity == NULL)
0862 return;
0863
0864 for (i = 0; i < entity->ncontrols; ++i) {
0865 ctrl = &entity->controls[i];
0866 if (!ctrl->initialized)
0867 continue;
0868
0869 list_for_each_entry(map, &ctrl->info.mappings, list) {
0870 if ((map->id == v4l2_id) && !next) {
0871 *control = ctrl;
0872 *mapping = map;
0873 return;
0874 }
0875
0876 if ((*mapping == NULL || (*mapping)->id > map->id) &&
0877 (map->id > v4l2_id) && next) {
0878 *control = ctrl;
0879 *mapping = map;
0880 }
0881 }
0882 }
0883 }
0884
0885 static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
0886 u32 v4l2_id, struct uvc_control_mapping **mapping)
0887 {
0888 struct uvc_control *ctrl = NULL;
0889 struct uvc_entity *entity;
0890 int next = v4l2_id & V4L2_CTRL_FLAG_NEXT_CTRL;
0891
0892 *mapping = NULL;
0893
0894
0895 v4l2_id &= V4L2_CTRL_ID_MASK;
0896
0897
0898 list_for_each_entry(entity, &chain->entities, chain) {
0899 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
0900 if (ctrl && !next)
0901 return ctrl;
0902 }
0903
0904 if (ctrl == NULL && !next)
0905 uvc_dbg(chain->dev, CONTROL, "Control 0x%08x not found\n",
0906 v4l2_id);
0907
0908 return ctrl;
0909 }
0910
0911 static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
0912 struct uvc_control *ctrl)
0913 {
0914 int ret;
0915
0916 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
0917 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
0918 chain->dev->intfnum, ctrl->info.selector,
0919 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),
0920 ctrl->info.size);
0921 if (ret < 0)
0922 return ret;
0923 }
0924
0925 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) {
0926 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
0927 chain->dev->intfnum, ctrl->info.selector,
0928 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),
0929 ctrl->info.size);
0930 if (ret < 0)
0931 return ret;
0932 }
0933 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) {
0934 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
0935 chain->dev->intfnum, ctrl->info.selector,
0936 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),
0937 ctrl->info.size);
0938 if (ret < 0)
0939 return ret;
0940 }
0941 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
0942 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
0943 chain->dev->intfnum, ctrl->info.selector,
0944 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),
0945 ctrl->info.size);
0946 if (ret < 0) {
0947 if (UVC_ENTITY_TYPE(ctrl->entity) !=
0948 UVC_VC_EXTENSION_UNIT)
0949 return ret;
0950
0951
0952
0953
0954
0955
0956 uvc_warn_once(chain->dev, UVC_WARN_XU_GET_RES,
0957 "UVC non compliance - GET_RES failed on "
0958 "an XU control. Enabling workaround.\n");
0959 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), 0,
0960 ctrl->info.size);
0961 }
0962 }
0963
0964 ctrl->cached = 1;
0965 return 0;
0966 }
0967
0968 static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
0969 const u8 *data)
0970 {
0971 s32 value = mapping->get(mapping, UVC_GET_CUR, data);
0972
0973 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
0974 const struct uvc_menu_info *menu = mapping->menu_info;
0975 unsigned int i;
0976
0977 for (i = 0; i < mapping->menu_count; ++i, ++menu) {
0978 if (menu->value == value) {
0979 value = i;
0980 break;
0981 }
0982 }
0983 }
0984
0985 return value;
0986 }
0987
0988 static int __uvc_ctrl_get(struct uvc_video_chain *chain,
0989 struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
0990 s32 *value)
0991 {
0992 int ret;
0993
0994 if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
0995 return -EACCES;
0996
0997 if (!ctrl->loaded) {
0998 if (ctrl->entity->get_cur) {
0999 ret = ctrl->entity->get_cur(chain->dev,
1000 ctrl->entity,
1001 ctrl->info.selector,
1002 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1003 ctrl->info.size);
1004 } else {
1005 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
1006 ctrl->entity->id,
1007 chain->dev->intfnum,
1008 ctrl->info.selector,
1009 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1010 ctrl->info.size);
1011 }
1012 if (ret < 0)
1013 return ret;
1014
1015 ctrl->loaded = 1;
1016 }
1017
1018 *value = __uvc_ctrl_get_value(mapping,
1019 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
1020
1021 return 0;
1022 }
1023
1024 static int __uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,
1025 u32 found_id)
1026 {
1027 bool find_next = req_id & V4L2_CTRL_FLAG_NEXT_CTRL;
1028 unsigned int i;
1029
1030 req_id &= V4L2_CTRL_ID_MASK;
1031
1032 for (i = 0; i < ARRAY_SIZE(uvc_control_classes); i++) {
1033 if (!(chain->ctrl_class_bitmap & BIT(i)))
1034 continue;
1035 if (!find_next) {
1036 if (uvc_control_classes[i] == req_id)
1037 return i;
1038 continue;
1039 }
1040 if (uvc_control_classes[i] > req_id &&
1041 uvc_control_classes[i] < found_id)
1042 return i;
1043 }
1044
1045 return -ENODEV;
1046 }
1047
1048 static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,
1049 u32 found_id, struct v4l2_queryctrl *v4l2_ctrl)
1050 {
1051 int idx;
1052
1053 idx = __uvc_query_v4l2_class(chain, req_id, found_id);
1054 if (idx < 0)
1055 return -ENODEV;
1056
1057 memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));
1058 v4l2_ctrl->id = uvc_control_classes[idx];
1059 strscpy(v4l2_ctrl->name, v4l2_ctrl_get_name(v4l2_ctrl->id),
1060 sizeof(v4l2_ctrl->name));
1061 v4l2_ctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;
1062 v4l2_ctrl->flags = V4L2_CTRL_FLAG_WRITE_ONLY
1063 | V4L2_CTRL_FLAG_READ_ONLY;
1064 return 0;
1065 }
1066
1067 int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
1068 bool read)
1069 {
1070 struct uvc_control_mapping *mapping;
1071 struct uvc_control *ctrl;
1072
1073 if (__uvc_query_v4l2_class(chain, v4l2_id, 0) >= 0)
1074 return -EACCES;
1075
1076 ctrl = uvc_find_control(chain, v4l2_id, &mapping);
1077 if (!ctrl)
1078 return -EINVAL;
1079
1080 if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) && read)
1081 return -EACCES;
1082
1083 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) && !read)
1084 return -EACCES;
1085
1086 return 0;
1087 }
1088
1089 static const char *uvc_map_get_name(const struct uvc_control_mapping *map)
1090 {
1091 const char *name;
1092
1093 if (map->name)
1094 return map->name;
1095
1096 name = v4l2_ctrl_get_name(map->id);
1097 if (name)
1098 return name;
1099
1100 return "Unknown Control";
1101 }
1102
1103 static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
1104 struct uvc_control *ctrl,
1105 struct uvc_control_mapping *mapping,
1106 struct v4l2_queryctrl *v4l2_ctrl)
1107 {
1108 struct uvc_control_mapping *master_map = NULL;
1109 struct uvc_control *master_ctrl = NULL;
1110 const struct uvc_menu_info *menu;
1111 unsigned int i;
1112
1113 memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));
1114 v4l2_ctrl->id = mapping->id;
1115 v4l2_ctrl->type = mapping->v4l2_type;
1116 strscpy(v4l2_ctrl->name, uvc_map_get_name(mapping),
1117 sizeof(v4l2_ctrl->name));
1118 v4l2_ctrl->flags = 0;
1119
1120 if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
1121 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
1122 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
1123 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1124
1125 if (mapping->master_id)
1126 __uvc_find_control(ctrl->entity, mapping->master_id,
1127 &master_map, &master_ctrl, 0);
1128 if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {
1129 s32 val;
1130 int ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);
1131 if (ret < 0)
1132 return ret;
1133
1134 if (val != mapping->master_manual)
1135 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
1136 }
1137
1138 if (!ctrl->cached) {
1139 int ret = uvc_ctrl_populate_cache(chain, ctrl);
1140 if (ret < 0)
1141 return ret;
1142 }
1143
1144 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
1145 v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
1146 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
1147 }
1148
1149 switch (mapping->v4l2_type) {
1150 case V4L2_CTRL_TYPE_MENU:
1151 v4l2_ctrl->minimum = 0;
1152 v4l2_ctrl->maximum = mapping->menu_count - 1;
1153 v4l2_ctrl->step = 1;
1154
1155 menu = mapping->menu_info;
1156 for (i = 0; i < mapping->menu_count; ++i, ++menu) {
1157 if (menu->value == v4l2_ctrl->default_value) {
1158 v4l2_ctrl->default_value = i;
1159 break;
1160 }
1161 }
1162
1163 return 0;
1164
1165 case V4L2_CTRL_TYPE_BOOLEAN:
1166 v4l2_ctrl->minimum = 0;
1167 v4l2_ctrl->maximum = 1;
1168 v4l2_ctrl->step = 1;
1169 return 0;
1170
1171 case V4L2_CTRL_TYPE_BUTTON:
1172 v4l2_ctrl->minimum = 0;
1173 v4l2_ctrl->maximum = 0;
1174 v4l2_ctrl->step = 0;
1175 return 0;
1176
1177 default:
1178 break;
1179 }
1180
1181 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)
1182 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
1183 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
1184
1185 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)
1186 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
1187 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
1188
1189 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)
1190 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
1191 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1192
1193 return 0;
1194 }
1195
1196 int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
1197 struct v4l2_queryctrl *v4l2_ctrl)
1198 {
1199 struct uvc_control *ctrl;
1200 struct uvc_control_mapping *mapping;
1201 int ret;
1202
1203 ret = mutex_lock_interruptible(&chain->ctrl_mutex);
1204 if (ret < 0)
1205 return -ERESTARTSYS;
1206
1207
1208 if (!(v4l2_ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL)) {
1209 ret = uvc_query_v4l2_class(chain, v4l2_ctrl->id, 0, v4l2_ctrl);
1210 if (!ret)
1211 goto done;
1212 }
1213
1214 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
1215 if (ctrl == NULL) {
1216 ret = -EINVAL;
1217 goto done;
1218 }
1219
1220
1221
1222
1223
1224
1225 if (v4l2_ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
1226 ret = uvc_query_v4l2_class(chain, v4l2_ctrl->id, mapping->id,
1227 v4l2_ctrl);
1228 if (!ret)
1229 goto done;
1230 }
1231
1232 ret = __uvc_query_v4l2_ctrl(chain, ctrl, mapping, v4l2_ctrl);
1233 done:
1234 mutex_unlock(&chain->ctrl_mutex);
1235 return ret;
1236 }
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247 int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
1248 struct v4l2_querymenu *query_menu)
1249 {
1250 const struct uvc_menu_info *menu_info;
1251 struct uvc_control_mapping *mapping;
1252 struct uvc_control *ctrl;
1253 u32 index = query_menu->index;
1254 u32 id = query_menu->id;
1255 int ret;
1256
1257 memset(query_menu, 0, sizeof(*query_menu));
1258 query_menu->id = id;
1259 query_menu->index = index;
1260
1261 ret = mutex_lock_interruptible(&chain->ctrl_mutex);
1262 if (ret < 0)
1263 return -ERESTARTSYS;
1264
1265 ctrl = uvc_find_control(chain, query_menu->id, &mapping);
1266 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
1267 ret = -EINVAL;
1268 goto done;
1269 }
1270
1271 if (query_menu->index >= mapping->menu_count) {
1272 ret = -EINVAL;
1273 goto done;
1274 }
1275
1276 menu_info = &mapping->menu_info[query_menu->index];
1277
1278 if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
1279 (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
1280 s32 bitmap;
1281
1282 if (!ctrl->cached) {
1283 ret = uvc_ctrl_populate_cache(chain, ctrl);
1284 if (ret < 0)
1285 goto done;
1286 }
1287
1288 bitmap = mapping->get(mapping, UVC_GET_RES,
1289 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1290 if (!(bitmap & menu_info->value)) {
1291 ret = -EINVAL;
1292 goto done;
1293 }
1294 }
1295
1296 strscpy(query_menu->name, menu_info->name, sizeof(query_menu->name));
1297
1298 done:
1299 mutex_unlock(&chain->ctrl_mutex);
1300 return ret;
1301 }
1302
1303
1304
1305
1306
1307 static void uvc_ctrl_fill_event(struct uvc_video_chain *chain,
1308 struct v4l2_event *ev,
1309 struct uvc_control *ctrl,
1310 struct uvc_control_mapping *mapping,
1311 s32 value, u32 changes)
1312 {
1313 struct v4l2_queryctrl v4l2_ctrl;
1314
1315 __uvc_query_v4l2_ctrl(chain, ctrl, mapping, &v4l2_ctrl);
1316
1317 memset(ev, 0, sizeof(*ev));
1318 ev->type = V4L2_EVENT_CTRL;
1319 ev->id = v4l2_ctrl.id;
1320 ev->u.ctrl.value = value;
1321 ev->u.ctrl.changes = changes;
1322 ev->u.ctrl.type = v4l2_ctrl.type;
1323 ev->u.ctrl.flags = v4l2_ctrl.flags;
1324 ev->u.ctrl.minimum = v4l2_ctrl.minimum;
1325 ev->u.ctrl.maximum = v4l2_ctrl.maximum;
1326 ev->u.ctrl.step = v4l2_ctrl.step;
1327 ev->u.ctrl.default_value = v4l2_ctrl.default_value;
1328 }
1329
1330
1331
1332
1333
1334
1335
1336
1337 static void uvc_ctrl_send_event(struct uvc_video_chain *chain,
1338 struct uvc_fh *handle, struct uvc_control *ctrl,
1339 struct uvc_control_mapping *mapping, s32 value, u32 changes)
1340 {
1341 struct v4l2_fh *originator = handle ? &handle->vfh : NULL;
1342 struct v4l2_subscribed_event *sev;
1343 struct v4l2_event ev;
1344
1345 if (list_empty(&mapping->ev_subs))
1346 return;
1347
1348 uvc_ctrl_fill_event(chain, &ev, ctrl, mapping, value, changes);
1349
1350 list_for_each_entry(sev, &mapping->ev_subs, node) {
1351 if (sev->fh != originator ||
1352 (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK) ||
1353 (changes & V4L2_EVENT_CTRL_CH_FLAGS))
1354 v4l2_event_queue_fh(sev->fh, &ev);
1355 }
1356 }
1357
1358
1359
1360
1361
1362
1363 static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain,
1364 struct uvc_fh *handle, struct uvc_control *master, u32 slave_id)
1365 {
1366 struct uvc_control_mapping *mapping = NULL;
1367 struct uvc_control *ctrl = NULL;
1368 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
1369 s32 val = 0;
1370
1371 __uvc_find_control(master->entity, slave_id, &mapping, &ctrl, 0);
1372 if (ctrl == NULL)
1373 return;
1374
1375 if (__uvc_ctrl_get(chain, ctrl, mapping, &val) == 0)
1376 changes |= V4L2_EVENT_CTRL_CH_VALUE;
1377
1378 uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
1379 }
1380
1381 void uvc_ctrl_status_event(struct uvc_video_chain *chain,
1382 struct uvc_control *ctrl, const u8 *data)
1383 {
1384 struct uvc_control_mapping *mapping;
1385 struct uvc_fh *handle;
1386 unsigned int i;
1387
1388 mutex_lock(&chain->ctrl_mutex);
1389
1390 handle = ctrl->handle;
1391 ctrl->handle = NULL;
1392
1393 list_for_each_entry(mapping, &ctrl->info.mappings, list) {
1394 s32 value = __uvc_ctrl_get_value(mapping, data);
1395
1396
1397
1398
1399
1400 for (i = 0; i < ARRAY_SIZE(mapping->slave_ids); ++i) {
1401 if (!mapping->slave_ids[i])
1402 break;
1403
1404 uvc_ctrl_send_slave_event(chain, handle, ctrl,
1405 mapping->slave_ids[i]);
1406 }
1407
1408 uvc_ctrl_send_event(chain, handle, ctrl, mapping, value,
1409 V4L2_EVENT_CTRL_CH_VALUE);
1410 }
1411
1412 mutex_unlock(&chain->ctrl_mutex);
1413 }
1414
1415 static void uvc_ctrl_status_event_work(struct work_struct *work)
1416 {
1417 struct uvc_device *dev = container_of(work, struct uvc_device,
1418 async_ctrl.work);
1419 struct uvc_ctrl_work *w = &dev->async_ctrl;
1420 int ret;
1421
1422 uvc_ctrl_status_event(w->chain, w->ctrl, w->data);
1423
1424
1425 w->urb->interval = dev->int_ep->desc.bInterval;
1426 ret = usb_submit_urb(w->urb, GFP_KERNEL);
1427 if (ret < 0)
1428 dev_err(&dev->udev->dev,
1429 "Failed to resubmit status URB (%d).\n", ret);
1430 }
1431
1432 bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain,
1433 struct uvc_control *ctrl, const u8 *data)
1434 {
1435 struct uvc_device *dev = chain->dev;
1436 struct uvc_ctrl_work *w = &dev->async_ctrl;
1437
1438 if (list_empty(&ctrl->info.mappings)) {
1439 ctrl->handle = NULL;
1440 return false;
1441 }
1442
1443 w->data = data;
1444 w->urb = urb;
1445 w->chain = chain;
1446 w->ctrl = ctrl;
1447
1448 schedule_work(&w->work);
1449
1450 return true;
1451 }
1452
1453 static bool uvc_ctrl_xctrls_has_control(const struct v4l2_ext_control *xctrls,
1454 unsigned int xctrls_count, u32 id)
1455 {
1456 unsigned int i;
1457
1458 for (i = 0; i < xctrls_count; ++i) {
1459 if (xctrls[i].id == id)
1460 return true;
1461 }
1462
1463 return false;
1464 }
1465
1466 static void uvc_ctrl_send_events(struct uvc_fh *handle,
1467 const struct v4l2_ext_control *xctrls, unsigned int xctrls_count)
1468 {
1469 struct uvc_control_mapping *mapping;
1470 struct uvc_control *ctrl;
1471 u32 changes = V4L2_EVENT_CTRL_CH_VALUE;
1472 unsigned int i;
1473 unsigned int j;
1474
1475 for (i = 0; i < xctrls_count; ++i) {
1476 ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping);
1477
1478 if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
1479
1480 continue;
1481
1482 for (j = 0; j < ARRAY_SIZE(mapping->slave_ids); ++j) {
1483 u32 slave_id = mapping->slave_ids[j];
1484
1485 if (!slave_id)
1486 break;
1487
1488
1489
1490
1491
1492 if (uvc_ctrl_xctrls_has_control(xctrls, xctrls_count,
1493 slave_id))
1494 continue;
1495
1496 uvc_ctrl_send_slave_event(handle->chain, handle, ctrl,
1497 slave_id);
1498 }
1499
1500
1501
1502
1503
1504 if (mapping->master_id &&
1505 uvc_ctrl_xctrls_has_control(xctrls, xctrls_count,
1506 mapping->master_id))
1507 changes |= V4L2_EVENT_CTRL_CH_FLAGS;
1508
1509 uvc_ctrl_send_event(handle->chain, handle, ctrl, mapping,
1510 xctrls[i].value, changes);
1511 }
1512 }
1513
1514 static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
1515 {
1516 struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh);
1517 struct uvc_control_mapping *mapping;
1518 struct uvc_control *ctrl;
1519 int ret;
1520
1521 ret = mutex_lock_interruptible(&handle->chain->ctrl_mutex);
1522 if (ret < 0)
1523 return -ERESTARTSYS;
1524
1525 if (__uvc_query_v4l2_class(handle->chain, sev->id, 0) >= 0) {
1526 ret = 0;
1527 goto done;
1528 }
1529
1530 ctrl = uvc_find_control(handle->chain, sev->id, &mapping);
1531 if (ctrl == NULL) {
1532 ret = -EINVAL;
1533 goto done;
1534 }
1535
1536 list_add_tail(&sev->node, &mapping->ev_subs);
1537 if (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) {
1538 struct v4l2_event ev;
1539 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
1540 s32 val = 0;
1541
1542 if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
1543 changes |= V4L2_EVENT_CTRL_CH_VALUE;
1544
1545 uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val,
1546 changes);
1547
1548
1549
1550
1551 sev->elems = elems;
1552 v4l2_event_queue_fh(sev->fh, &ev);
1553 }
1554
1555 done:
1556 mutex_unlock(&handle->chain->ctrl_mutex);
1557 return ret;
1558 }
1559
1560 static void uvc_ctrl_del_event(struct v4l2_subscribed_event *sev)
1561 {
1562 struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh);
1563
1564 mutex_lock(&handle->chain->ctrl_mutex);
1565 if (__uvc_query_v4l2_class(handle->chain, sev->id, 0) >= 0)
1566 goto done;
1567 list_del(&sev->node);
1568 done:
1569 mutex_unlock(&handle->chain->ctrl_mutex);
1570 }
1571
1572 const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops = {
1573 .add = uvc_ctrl_add_event,
1574 .del = uvc_ctrl_del_event,
1575 .replace = v4l2_ctrl_replace,
1576 .merge = v4l2_ctrl_merge,
1577 };
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603 int uvc_ctrl_begin(struct uvc_video_chain *chain)
1604 {
1605 return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0;
1606 }
1607
1608 static int uvc_ctrl_commit_entity(struct uvc_device *dev,
1609 struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)
1610 {
1611 struct uvc_control *ctrl;
1612 unsigned int i;
1613 int ret;
1614
1615 if (entity == NULL)
1616 return 0;
1617
1618 for (i = 0; i < entity->ncontrols; ++i) {
1619 ctrl = &entity->controls[i];
1620 if (!ctrl->initialized)
1621 continue;
1622
1623
1624
1625
1626
1627
1628
1629
1630 if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE ||
1631 !(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
1632 ctrl->loaded = 0;
1633
1634 if (!ctrl->dirty)
1635 continue;
1636
1637 if (!rollback)
1638 ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id,
1639 dev->intfnum, ctrl->info.selector,
1640 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1641 ctrl->info.size);
1642 else
1643 ret = 0;
1644
1645 if (rollback || ret < 0)
1646 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1647 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1648 ctrl->info.size);
1649
1650 ctrl->dirty = 0;
1651
1652 if (ret < 0) {
1653 if (err_ctrl)
1654 *err_ctrl = ctrl;
1655 return ret;
1656 }
1657 }
1658
1659 return 0;
1660 }
1661
1662 static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity,
1663 struct v4l2_ext_controls *ctrls,
1664 struct uvc_control *uvc_control)
1665 {
1666 struct uvc_control_mapping *mapping = NULL;
1667 struct uvc_control *ctrl_found = NULL;
1668 unsigned int i;
1669
1670 if (!entity)
1671 return ctrls->count;
1672
1673 for (i = 0; i < ctrls->count; i++) {
1674 __uvc_find_control(entity, ctrls->controls[i].id, &mapping,
1675 &ctrl_found, 0);
1676 if (uvc_control == ctrl_found)
1677 return i;
1678 }
1679
1680 return ctrls->count;
1681 }
1682
1683 int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
1684 struct v4l2_ext_controls *ctrls)
1685 {
1686 struct uvc_video_chain *chain = handle->chain;
1687 struct uvc_control *err_ctrl;
1688 struct uvc_entity *entity;
1689 int ret = 0;
1690
1691
1692 list_for_each_entry(entity, &chain->entities, chain) {
1693 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
1694 &err_ctrl);
1695 if (ret < 0)
1696 goto done;
1697 }
1698
1699 if (!rollback)
1700 uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
1701 done:
1702 if (ret < 0 && ctrls)
1703 ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls,
1704 err_ctrl);
1705 mutex_unlock(&chain->ctrl_mutex);
1706 return ret;
1707 }
1708
1709 int uvc_ctrl_get(struct uvc_video_chain *chain,
1710 struct v4l2_ext_control *xctrl)
1711 {
1712 struct uvc_control *ctrl;
1713 struct uvc_control_mapping *mapping;
1714
1715 if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0)
1716 return -EACCES;
1717
1718 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1719 if (ctrl == NULL)
1720 return -EINVAL;
1721
1722 return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
1723 }
1724
1725 int uvc_ctrl_set(struct uvc_fh *handle,
1726 struct v4l2_ext_control *xctrl)
1727 {
1728 struct uvc_video_chain *chain = handle->chain;
1729 struct uvc_control *ctrl;
1730 struct uvc_control_mapping *mapping;
1731 s32 value;
1732 u32 step;
1733 s32 min;
1734 s32 max;
1735 int ret;
1736
1737 if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0)
1738 return -EACCES;
1739
1740 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1741 if (ctrl == NULL)
1742 return -EINVAL;
1743 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
1744 return -EACCES;
1745
1746
1747 switch (mapping->v4l2_type) {
1748 case V4L2_CTRL_TYPE_INTEGER:
1749 if (!ctrl->cached) {
1750 ret = uvc_ctrl_populate_cache(chain, ctrl);
1751 if (ret < 0)
1752 return ret;
1753 }
1754
1755 min = mapping->get(mapping, UVC_GET_MIN,
1756 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
1757 max = mapping->get(mapping, UVC_GET_MAX,
1758 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
1759 step = mapping->get(mapping, UVC_GET_RES,
1760 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1761 if (step == 0)
1762 step = 1;
1763
1764 xctrl->value = min + DIV_ROUND_CLOSEST((u32)(xctrl->value - min),
1765 step) * step;
1766 if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
1767 xctrl->value = clamp(xctrl->value, min, max);
1768 else
1769 xctrl->value = clamp_t(u32, xctrl->value, min, max);
1770 value = xctrl->value;
1771 break;
1772
1773 case V4L2_CTRL_TYPE_BOOLEAN:
1774 xctrl->value = clamp(xctrl->value, 0, 1);
1775 value = xctrl->value;
1776 break;
1777
1778 case V4L2_CTRL_TYPE_MENU:
1779 if (xctrl->value < 0 || xctrl->value >= mapping->menu_count)
1780 return -ERANGE;
1781 value = mapping->menu_info[xctrl->value].value;
1782
1783
1784
1785
1786
1787 if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
1788 (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
1789 if (!ctrl->cached) {
1790 ret = uvc_ctrl_populate_cache(chain, ctrl);
1791 if (ret < 0)
1792 return ret;
1793 }
1794
1795 step = mapping->get(mapping, UVC_GET_RES,
1796 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1797 if (!(step & value))
1798 return -EINVAL;
1799 }
1800
1801 break;
1802
1803 default:
1804 value = xctrl->value;
1805 break;
1806 }
1807
1808
1809
1810
1811
1812
1813 if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
1814 if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
1815 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1816 0, ctrl->info.size);
1817 } else {
1818 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
1819 ctrl->entity->id, chain->dev->intfnum,
1820 ctrl->info.selector,
1821 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1822 ctrl->info.size);
1823 if (ret < 0)
1824 return ret;
1825 }
1826
1827 ctrl->loaded = 1;
1828 }
1829
1830
1831 if (!ctrl->dirty) {
1832 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1833 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1834 ctrl->info.size);
1835 }
1836
1837 mapping->set(mapping, value,
1838 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
1839
1840 if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
1841 ctrl->handle = handle;
1842
1843 ctrl->dirty = 1;
1844 ctrl->modified = 1;
1845 return 0;
1846 }
1847
1848
1849
1850
1851
1852
1853
1854
1855 static int uvc_ctrl_get_flags(struct uvc_device *dev,
1856 const struct uvc_control *ctrl,
1857 struct uvc_control_info *info)
1858 {
1859 u8 *data;
1860 int ret;
1861
1862 data = kmalloc(1, GFP_KERNEL);
1863 if (data == NULL)
1864 return -ENOMEM;
1865
1866 if (ctrl->entity->get_info)
1867 ret = ctrl->entity->get_info(dev, ctrl->entity,
1868 ctrl->info.selector, data);
1869 else
1870 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
1871 dev->intfnum, info->selector, data, 1);
1872 if (!ret)
1873 info->flags |= (data[0] & UVC_CONTROL_CAP_GET ?
1874 UVC_CTRL_FLAG_GET_CUR : 0)
1875 | (data[0] & UVC_CONTROL_CAP_SET ?
1876 UVC_CTRL_FLAG_SET_CUR : 0)
1877 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
1878 UVC_CTRL_FLAG_AUTO_UPDATE : 0)
1879 | (data[0] & UVC_CONTROL_CAP_ASYNCHRONOUS ?
1880 UVC_CTRL_FLAG_ASYNCHRONOUS : 0);
1881
1882 kfree(data);
1883 return ret;
1884 }
1885
1886 static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev,
1887 const struct uvc_control *ctrl, struct uvc_control_info *info)
1888 {
1889 struct uvc_ctrl_fixup {
1890 struct usb_device_id id;
1891 u8 entity;
1892 u8 selector;
1893 u8 flags;
1894 };
1895
1896 static const struct uvc_ctrl_fixup fixups[] = {
1897 { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
1898 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
1899 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
1900 UVC_CTRL_FLAG_AUTO_UPDATE },
1901 { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
1902 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
1903 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
1904 UVC_CTRL_FLAG_AUTO_UPDATE },
1905 { { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
1906 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
1907 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
1908 UVC_CTRL_FLAG_AUTO_UPDATE },
1909 };
1910
1911 unsigned int i;
1912
1913 for (i = 0; i < ARRAY_SIZE(fixups); ++i) {
1914 if (!usb_match_one_id(dev->intf, &fixups[i].id))
1915 continue;
1916
1917 if (fixups[i].entity == ctrl->entity->id &&
1918 fixups[i].selector == info->selector) {
1919 info->flags = fixups[i].flags;
1920 return;
1921 }
1922 }
1923 }
1924
1925
1926
1927
1928 static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
1929 const struct uvc_control *ctrl, struct uvc_control_info *info)
1930 {
1931 u8 *data;
1932 int ret;
1933
1934 data = kmalloc(2, GFP_KERNEL);
1935 if (data == NULL)
1936 return -ENOMEM;
1937
1938 memcpy(info->entity, ctrl->entity->guid, sizeof(info->entity));
1939 info->index = ctrl->index;
1940 info->selector = ctrl->index + 1;
1941
1942
1943 ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, dev->intfnum,
1944 info->selector, data, 2);
1945 if (ret < 0) {
1946 uvc_dbg(dev, CONTROL,
1947 "GET_LEN failed on control %pUl/%u (%d)\n",
1948 info->entity, info->selector, ret);
1949 goto done;
1950 }
1951
1952 info->size = le16_to_cpup((__le16 *)data);
1953
1954 info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
1955 | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF;
1956
1957 ret = uvc_ctrl_get_flags(dev, ctrl, info);
1958 if (ret < 0) {
1959 uvc_dbg(dev, CONTROL,
1960 "Failed to get flags for control %pUl/%u (%d)\n",
1961 info->entity, info->selector, ret);
1962 goto done;
1963 }
1964
1965 uvc_ctrl_fixup_xu_info(dev, ctrl, info);
1966
1967 uvc_dbg(dev, CONTROL,
1968 "XU control %pUl/%u queried: len %u, flags { get %u set %u auto %u }\n",
1969 info->entity, info->selector, info->size,
1970 (info->flags & UVC_CTRL_FLAG_GET_CUR) ? 1 : 0,
1971 (info->flags & UVC_CTRL_FLAG_SET_CUR) ? 1 : 0,
1972 (info->flags & UVC_CTRL_FLAG_AUTO_UPDATE) ? 1 : 0);
1973
1974 done:
1975 kfree(data);
1976 return ret;
1977 }
1978
1979 static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl,
1980 const struct uvc_control_info *info);
1981
1982 static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev,
1983 struct uvc_control *ctrl)
1984 {
1985 struct uvc_control_info info;
1986 int ret;
1987
1988 if (ctrl->initialized)
1989 return 0;
1990
1991 ret = uvc_ctrl_fill_xu_info(dev, ctrl, &info);
1992 if (ret < 0)
1993 return ret;
1994
1995 ret = uvc_ctrl_add_info(dev, ctrl, &info);
1996 if (ret < 0)
1997 uvc_dbg(dev, CONTROL,
1998 "Failed to initialize control %pUl/%u on device %s entity %u\n",
1999 info.entity, info.selector, dev->udev->devpath,
2000 ctrl->entity->id);
2001
2002 return ret;
2003 }
2004
2005 int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
2006 struct uvc_xu_control_query *xqry)
2007 {
2008 struct uvc_entity *entity;
2009 struct uvc_control *ctrl;
2010 unsigned int i;
2011 bool found;
2012 u32 reqflags;
2013 u16 size;
2014 u8 *data = NULL;
2015 int ret;
2016
2017
2018 found = false;
2019 list_for_each_entry(entity, &chain->entities, chain) {
2020 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
2021 entity->id == xqry->unit) {
2022 found = true;
2023 break;
2024 }
2025 }
2026
2027 if (!found) {
2028 uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n",
2029 xqry->unit);
2030 return -ENOENT;
2031 }
2032
2033
2034 found = false;
2035 for (i = 0; i < entity->ncontrols; ++i) {
2036 ctrl = &entity->controls[i];
2037 if (ctrl->index == xqry->selector - 1) {
2038 found = true;
2039 break;
2040 }
2041 }
2042
2043 if (!found) {
2044 uvc_dbg(chain->dev, CONTROL, "Control %pUl/%u not found\n",
2045 entity->guid, xqry->selector);
2046 return -ENOENT;
2047 }
2048
2049 if (mutex_lock_interruptible(&chain->ctrl_mutex))
2050 return -ERESTARTSYS;
2051
2052 ret = uvc_ctrl_init_xu_ctrl(chain->dev, ctrl);
2053 if (ret < 0) {
2054 ret = -ENOENT;
2055 goto done;
2056 }
2057
2058
2059 reqflags = 0;
2060 size = ctrl->info.size;
2061
2062 switch (xqry->query) {
2063 case UVC_GET_CUR:
2064 reqflags = UVC_CTRL_FLAG_GET_CUR;
2065 break;
2066 case UVC_GET_MIN:
2067 reqflags = UVC_CTRL_FLAG_GET_MIN;
2068 break;
2069 case UVC_GET_MAX:
2070 reqflags = UVC_CTRL_FLAG_GET_MAX;
2071 break;
2072 case UVC_GET_DEF:
2073 reqflags = UVC_CTRL_FLAG_GET_DEF;
2074 break;
2075 case UVC_GET_RES:
2076 reqflags = UVC_CTRL_FLAG_GET_RES;
2077 break;
2078 case UVC_SET_CUR:
2079 reqflags = UVC_CTRL_FLAG_SET_CUR;
2080 break;
2081 case UVC_GET_LEN:
2082 size = 2;
2083 break;
2084 case UVC_GET_INFO:
2085 size = 1;
2086 break;
2087 default:
2088 ret = -EINVAL;
2089 goto done;
2090 }
2091
2092 if (size != xqry->size) {
2093 ret = -ENOBUFS;
2094 goto done;
2095 }
2096
2097 if (reqflags && !(ctrl->info.flags & reqflags)) {
2098 ret = -EBADRQC;
2099 goto done;
2100 }
2101
2102 data = kmalloc(size, GFP_KERNEL);
2103 if (data == NULL) {
2104 ret = -ENOMEM;
2105 goto done;
2106 }
2107
2108 if (xqry->query == UVC_SET_CUR &&
2109 copy_from_user(data, xqry->data, size)) {
2110 ret = -EFAULT;
2111 goto done;
2112 }
2113
2114 ret = uvc_query_ctrl(chain->dev, xqry->query, xqry->unit,
2115 chain->dev->intfnum, xqry->selector, data, size);
2116 if (ret < 0)
2117 goto done;
2118
2119 if (xqry->query != UVC_SET_CUR &&
2120 copy_to_user(xqry->data, data, size))
2121 ret = -EFAULT;
2122 done:
2123 kfree(data);
2124 mutex_unlock(&chain->ctrl_mutex);
2125 return ret;
2126 }
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141 int uvc_ctrl_restore_values(struct uvc_device *dev)
2142 {
2143 struct uvc_control *ctrl;
2144 struct uvc_entity *entity;
2145 unsigned int i;
2146 int ret;
2147
2148
2149 list_for_each_entry(entity, &dev->entities, list) {
2150
2151 for (i = 0; i < entity->ncontrols; ++i) {
2152 ctrl = &entity->controls[i];
2153
2154 if (!ctrl->initialized || !ctrl->modified ||
2155 (ctrl->info.flags & UVC_CTRL_FLAG_RESTORE) == 0)
2156 continue;
2157 dev_dbg(&dev->udev->dev,
2158 "restoring control %pUl/%u/%u\n",
2159 ctrl->info.entity, ctrl->info.index,
2160 ctrl->info.selector);
2161 ctrl->dirty = 1;
2162 }
2163
2164 ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);
2165 if (ret < 0)
2166 return ret;
2167 }
2168
2169 return 0;
2170 }
2171
2172
2173
2174
2175
2176
2177
2178
2179 static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl,
2180 const struct uvc_control_info *info)
2181 {
2182 ctrl->info = *info;
2183 INIT_LIST_HEAD(&ctrl->info.mappings);
2184
2185
2186 ctrl->uvc_data = kzalloc(ctrl->info.size * UVC_CTRL_DATA_LAST + 1,
2187 GFP_KERNEL);
2188 if (!ctrl->uvc_data)
2189 return -ENOMEM;
2190
2191 ctrl->initialized = 1;
2192
2193 uvc_dbg(dev, CONTROL, "Added control %pUl/%u to device %s entity %u\n",
2194 ctrl->info.entity, ctrl->info.selector, dev->udev->devpath,
2195 ctrl->entity->id);
2196
2197 return 0;
2198 }
2199
2200
2201
2202
2203 static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
2204 struct uvc_control *ctrl, const struct uvc_control_mapping *mapping)
2205 {
2206 struct uvc_control_mapping *map;
2207 unsigned int size;
2208 unsigned int i;
2209
2210
2211
2212
2213
2214
2215 map = kmemdup(mapping, sizeof(*mapping), GFP_KERNEL);
2216 if (map == NULL)
2217 return -ENOMEM;
2218
2219
2220 if (mapping->name) {
2221 map->name = kstrdup(mapping->name, GFP_KERNEL);
2222 if (!map->name) {
2223 kfree(map);
2224 return -ENOMEM;
2225 }
2226 }
2227
2228 INIT_LIST_HEAD(&map->ev_subs);
2229
2230 size = sizeof(*mapping->menu_info) * mapping->menu_count;
2231 map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL);
2232 if (map->menu_info == NULL) {
2233 kfree(map->name);
2234 kfree(map);
2235 return -ENOMEM;
2236 }
2237
2238 if (map->get == NULL)
2239 map->get = uvc_get_le_value;
2240 if (map->set == NULL)
2241 map->set = uvc_set_le_value;
2242
2243 for (i = 0; i < ARRAY_SIZE(uvc_control_classes); i++) {
2244 if (V4L2_CTRL_ID2WHICH(uvc_control_classes[i]) ==
2245 V4L2_CTRL_ID2WHICH(map->id)) {
2246 chain->ctrl_class_bitmap |= BIT(i);
2247 break;
2248 }
2249 }
2250
2251 list_add_tail(&map->list, &ctrl->info.mappings);
2252 uvc_dbg(chain->dev, CONTROL, "Adding mapping '%s' to control %pUl/%u\n",
2253 uvc_map_get_name(map), ctrl->info.entity,
2254 ctrl->info.selector);
2255
2256 return 0;
2257 }
2258
2259 int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
2260 const struct uvc_control_mapping *mapping)
2261 {
2262 struct uvc_device *dev = chain->dev;
2263 struct uvc_control_mapping *map;
2264 struct uvc_entity *entity;
2265 struct uvc_control *ctrl;
2266 int found = 0;
2267 int ret;
2268
2269 if (mapping->id & ~V4L2_CTRL_ID_MASK) {
2270 uvc_dbg(dev, CONTROL,
2271 "Can't add mapping '%s', control id 0x%08x is invalid\n",
2272 uvc_map_get_name(mapping), mapping->id);
2273 return -EINVAL;
2274 }
2275
2276
2277 list_for_each_entry(entity, &chain->entities, chain) {
2278 unsigned int i;
2279
2280 if (UVC_ENTITY_TYPE(entity) != UVC_VC_EXTENSION_UNIT ||
2281 !uvc_entity_match_guid(entity, mapping->entity))
2282 continue;
2283
2284 for (i = 0; i < entity->ncontrols; ++i) {
2285 ctrl = &entity->controls[i];
2286 if (ctrl->index == mapping->selector - 1) {
2287 found = 1;
2288 break;
2289 }
2290 }
2291
2292 if (found)
2293 break;
2294 }
2295 if (!found)
2296 return -ENOENT;
2297
2298 if (mutex_lock_interruptible(&chain->ctrl_mutex))
2299 return -ERESTARTSYS;
2300
2301
2302 ret = uvc_ctrl_init_xu_ctrl(dev, ctrl);
2303 if (ret < 0) {
2304 ret = -ENOENT;
2305 goto done;
2306 }
2307
2308
2309 if (mapping->size > 32 ||
2310 mapping->offset + mapping->size > ctrl->info.size * 8) {
2311 ret = -EINVAL;
2312 goto done;
2313 }
2314
2315 list_for_each_entry(map, &ctrl->info.mappings, list) {
2316 if (mapping->id == map->id) {
2317 uvc_dbg(dev, CONTROL,
2318 "Can't add mapping '%s', control id 0x%08x already exists\n",
2319 uvc_map_get_name(mapping), mapping->id);
2320 ret = -EEXIST;
2321 goto done;
2322 }
2323 }
2324
2325
2326 if (atomic_inc_return(&dev->nmappings) > UVC_MAX_CONTROL_MAPPINGS) {
2327 atomic_dec(&dev->nmappings);
2328 uvc_dbg(dev, CONTROL,
2329 "Can't add mapping '%s', maximum mappings count (%u) exceeded\n",
2330 uvc_map_get_name(mapping), UVC_MAX_CONTROL_MAPPINGS);
2331 ret = -ENOMEM;
2332 goto done;
2333 }
2334
2335 ret = __uvc_ctrl_add_mapping(chain, ctrl, mapping);
2336 if (ret < 0)
2337 atomic_dec(&dev->nmappings);
2338
2339 done:
2340 mutex_unlock(&chain->ctrl_mutex);
2341 return ret;
2342 }
2343
2344
2345
2346
2347
2348
2349 static void uvc_ctrl_prune_entity(struct uvc_device *dev,
2350 struct uvc_entity *entity)
2351 {
2352 struct uvc_ctrl_blacklist {
2353 struct usb_device_id id;
2354 u8 index;
2355 };
2356
2357 static const struct uvc_ctrl_blacklist processing_blacklist[] = {
2358 { { USB_DEVICE(0x13d3, 0x509b) }, 9 },
2359 { { USB_DEVICE(0x1c4f, 0x3000) }, 6 },
2360 { { USB_DEVICE(0x5986, 0x0241) }, 2 },
2361 };
2362 static const struct uvc_ctrl_blacklist camera_blacklist[] = {
2363 { { USB_DEVICE(0x06f8, 0x3005) }, 9 },
2364 };
2365
2366 const struct uvc_ctrl_blacklist *blacklist;
2367 unsigned int size;
2368 unsigned int count;
2369 unsigned int i;
2370 u8 *controls;
2371
2372 switch (UVC_ENTITY_TYPE(entity)) {
2373 case UVC_VC_PROCESSING_UNIT:
2374 blacklist = processing_blacklist;
2375 count = ARRAY_SIZE(processing_blacklist);
2376 controls = entity->processing.bmControls;
2377 size = entity->processing.bControlSize;
2378 break;
2379
2380 case UVC_ITT_CAMERA:
2381 blacklist = camera_blacklist;
2382 count = ARRAY_SIZE(camera_blacklist);
2383 controls = entity->camera.bmControls;
2384 size = entity->camera.bControlSize;
2385 break;
2386
2387 default:
2388 return;
2389 }
2390
2391 for (i = 0; i < count; ++i) {
2392 if (!usb_match_one_id(dev->intf, &blacklist[i].id))
2393 continue;
2394
2395 if (blacklist[i].index >= 8 * size ||
2396 !uvc_test_bit(controls, blacklist[i].index))
2397 continue;
2398
2399 uvc_dbg(dev, CONTROL,
2400 "%u/%u control is black listed, removing it\n",
2401 entity->id, blacklist[i].index);
2402
2403 uvc_clear_bit(controls, blacklist[i].index);
2404 }
2405 }
2406
2407
2408
2409
2410
2411 static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
2412 struct uvc_control *ctrl)
2413 {
2414 const struct uvc_control_info *info = uvc_ctrls;
2415 const struct uvc_control_info *iend = info + ARRAY_SIZE(uvc_ctrls);
2416 const struct uvc_control_mapping *mapping;
2417 const struct uvc_control_mapping *mend;
2418
2419
2420
2421
2422
2423
2424
2425 if (UVC_ENTITY_TYPE(ctrl->entity) == UVC_VC_EXTENSION_UNIT)
2426 return;
2427
2428 for (; info < iend; ++info) {
2429 if (uvc_entity_match_guid(ctrl->entity, info->entity) &&
2430 ctrl->index == info->index) {
2431 uvc_ctrl_add_info(chain->dev, ctrl, info);
2432
2433
2434
2435
2436
2437
2438 uvc_ctrl_get_flags(chain->dev, ctrl, &ctrl->info);
2439 break;
2440 }
2441 }
2442
2443 if (!ctrl->initialized)
2444 return;
2445
2446
2447
2448
2449
2450
2451
2452
2453 if (chain->dev->info->mappings) {
2454 bool custom = false;
2455 unsigned int i;
2456
2457 for (i = 0; (mapping = chain->dev->info->mappings[i]); ++i) {
2458 if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
2459 ctrl->info.selector == mapping->selector) {
2460 __uvc_ctrl_add_mapping(chain, ctrl, mapping);
2461 custom = true;
2462 }
2463 }
2464
2465 if (custom)
2466 return;
2467 }
2468
2469
2470 mapping = uvc_ctrl_mappings;
2471 mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings);
2472
2473 for (; mapping < mend; ++mapping) {
2474 if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
2475 ctrl->info.selector == mapping->selector)
2476 __uvc_ctrl_add_mapping(chain, ctrl, mapping);
2477 }
2478
2479
2480 if (chain->dev->uvc_version < 0x0150) {
2481 mapping = uvc_ctrl_mappings_uvc11;
2482 mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings_uvc11);
2483 } else {
2484 mapping = uvc_ctrl_mappings_uvc15;
2485 mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings_uvc15);
2486 }
2487
2488 for (; mapping < mend; ++mapping) {
2489 if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
2490 ctrl->info.selector == mapping->selector)
2491 __uvc_ctrl_add_mapping(chain, ctrl, mapping);
2492 }
2493 }
2494
2495
2496
2497
2498 static int uvc_ctrl_init_chain(struct uvc_video_chain *chain)
2499 {
2500 struct uvc_entity *entity;
2501 unsigned int i;
2502
2503
2504 list_for_each_entry(entity, &chain->entities, chain) {
2505 struct uvc_control *ctrl;
2506 unsigned int bControlSize = 0, ncontrols;
2507 u8 *bmControls = NULL;
2508
2509 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
2510 bmControls = entity->extension.bmControls;
2511 bControlSize = entity->extension.bControlSize;
2512 } else if (UVC_ENTITY_TYPE(entity) == UVC_VC_PROCESSING_UNIT) {
2513 bmControls = entity->processing.bmControls;
2514 bControlSize = entity->processing.bControlSize;
2515 } else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) {
2516 bmControls = entity->camera.bmControls;
2517 bControlSize = entity->camera.bControlSize;
2518 } else if (UVC_ENTITY_TYPE(entity) == UVC_EXT_GPIO_UNIT) {
2519 bmControls = entity->gpio.bmControls;
2520 bControlSize = entity->gpio.bControlSize;
2521 }
2522
2523
2524 uvc_ctrl_prune_entity(chain->dev, entity);
2525
2526
2527 ncontrols = memweight(bmControls, bControlSize);
2528 if (ncontrols == 0)
2529 continue;
2530
2531 entity->controls = kcalloc(ncontrols, sizeof(*ctrl),
2532 GFP_KERNEL);
2533 if (entity->controls == NULL)
2534 return -ENOMEM;
2535 entity->ncontrols = ncontrols;
2536
2537
2538 ctrl = entity->controls;
2539 for (i = 0; i < bControlSize * 8; ++i) {
2540 if (uvc_test_bit(bmControls, i) == 0)
2541 continue;
2542
2543 ctrl->entity = entity;
2544 ctrl->index = i;
2545
2546 uvc_ctrl_init_ctrl(chain, ctrl);
2547 ctrl++;
2548 }
2549 }
2550
2551 return 0;
2552 }
2553
2554 int uvc_ctrl_init_device(struct uvc_device *dev)
2555 {
2556 struct uvc_video_chain *chain;
2557 int ret;
2558
2559 INIT_WORK(&dev->async_ctrl.work, uvc_ctrl_status_event_work);
2560
2561 list_for_each_entry(chain, &dev->chains, list) {
2562 ret = uvc_ctrl_init_chain(chain);
2563 if (ret)
2564 return ret;
2565 }
2566
2567 return 0;
2568 }
2569
2570
2571
2572
2573 static void uvc_ctrl_cleanup_mappings(struct uvc_device *dev,
2574 struct uvc_control *ctrl)
2575 {
2576 struct uvc_control_mapping *mapping, *nm;
2577
2578 list_for_each_entry_safe(mapping, nm, &ctrl->info.mappings, list) {
2579 list_del(&mapping->list);
2580 kfree(mapping->menu_info);
2581 kfree(mapping->name);
2582 kfree(mapping);
2583 }
2584 }
2585
2586 void uvc_ctrl_cleanup_device(struct uvc_device *dev)
2587 {
2588 struct uvc_entity *entity;
2589 unsigned int i;
2590
2591
2592 if (dev->async_ctrl.work.func)
2593 cancel_work_sync(&dev->async_ctrl.work);
2594
2595
2596 list_for_each_entry(entity, &dev->entities, list) {
2597 for (i = 0; i < entity->ncontrols; ++i) {
2598 struct uvc_control *ctrl = &entity->controls[i];
2599
2600 if (!ctrl->initialized)
2601 continue;
2602
2603 uvc_ctrl_cleanup_mappings(dev, ctrl);
2604 kfree(ctrl->uvc_data);
2605 }
2606
2607 kfree(entity->controls);
2608 }
2609 }