2814 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * uvc_ctrl.c -- USB Video Class driver - Controls4 *5 * Copyright (C) 2005-20106 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)7 */8 9#include <asm/barrier.h>10#include <linux/bitops.h>11#include <linux/kernel.h>12#include <linux/list.h>13#include <linux/module.h>14#include <linux/slab.h>15#include <linux/uaccess.h>16#include <linux/usb.h>17#include <linux/usb/uvc.h>18#include <linux/videodev2.h>19#include <linux/vmalloc.h>20#include <linux/wait.h>21#include <linux/workqueue.h>22#include <linux/atomic.h>23#include <media/v4l2-ctrls.h>24 25#include "uvcvideo.h"26 27#define UVC_CTRL_DATA_CURRENT 028#define UVC_CTRL_DATA_BACKUP 129#define UVC_CTRL_DATA_MIN 230#define UVC_CTRL_DATA_MAX 331#define UVC_CTRL_DATA_RES 432#define UVC_CTRL_DATA_DEF 533#define UVC_CTRL_DATA_LAST 634 35/* ------------------------------------------------------------------------36 * Controls37 */38 39static const struct uvc_control_info uvc_ctrls[] = {40 {41 .entity = UVC_GUID_UVC_PROCESSING,42 .selector = UVC_PU_BRIGHTNESS_CONTROL,43 .index = 0,44 .size = 2,45 .flags = UVC_CTRL_FLAG_SET_CUR46 | UVC_CTRL_FLAG_GET_RANGE47 | UVC_CTRL_FLAG_RESTORE,48 },49 {50 .entity = UVC_GUID_UVC_PROCESSING,51 .selector = UVC_PU_CONTRAST_CONTROL,52 .index = 1,53 .size = 2,54 .flags = UVC_CTRL_FLAG_SET_CUR55 | UVC_CTRL_FLAG_GET_RANGE56 | UVC_CTRL_FLAG_RESTORE,57 },58 {59 .entity = UVC_GUID_UVC_PROCESSING,60 .selector = UVC_PU_HUE_CONTROL,61 .index = 2,62 .size = 2,63 .flags = UVC_CTRL_FLAG_SET_CUR64 | UVC_CTRL_FLAG_GET_RANGE65 | UVC_CTRL_FLAG_RESTORE66 | UVC_CTRL_FLAG_AUTO_UPDATE,67 },68 {69 .entity = UVC_GUID_UVC_PROCESSING,70 .selector = UVC_PU_SATURATION_CONTROL,71 .index = 3,72 .size = 2,73 .flags = UVC_CTRL_FLAG_SET_CUR74 | UVC_CTRL_FLAG_GET_RANGE75 | UVC_CTRL_FLAG_RESTORE,76 },77 {78 .entity = UVC_GUID_UVC_PROCESSING,79 .selector = UVC_PU_SHARPNESS_CONTROL,80 .index = 4,81 .size = 2,82 .flags = UVC_CTRL_FLAG_SET_CUR83 | UVC_CTRL_FLAG_GET_RANGE84 | UVC_CTRL_FLAG_RESTORE,85 },86 {87 .entity = UVC_GUID_UVC_PROCESSING,88 .selector = UVC_PU_GAMMA_CONTROL,89 .index = 5,90 .size = 2,91 .flags = UVC_CTRL_FLAG_SET_CUR92 | UVC_CTRL_FLAG_GET_RANGE93 | UVC_CTRL_FLAG_RESTORE,94 },95 {96 .entity = UVC_GUID_UVC_PROCESSING,97 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,98 .index = 6,99 .size = 2,100 .flags = UVC_CTRL_FLAG_SET_CUR101 | UVC_CTRL_FLAG_GET_RANGE102 | UVC_CTRL_FLAG_RESTORE103 | UVC_CTRL_FLAG_AUTO_UPDATE,104 },105 {106 .entity = UVC_GUID_UVC_PROCESSING,107 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,108 .index = 7,109 .size = 4,110 .flags = UVC_CTRL_FLAG_SET_CUR111 | UVC_CTRL_FLAG_GET_RANGE112 | UVC_CTRL_FLAG_RESTORE113 | UVC_CTRL_FLAG_AUTO_UPDATE,114 },115 {116 .entity = UVC_GUID_UVC_PROCESSING,117 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,118 .index = 8,119 .size = 2,120 .flags = UVC_CTRL_FLAG_SET_CUR121 | UVC_CTRL_FLAG_GET_RANGE122 | UVC_CTRL_FLAG_RESTORE,123 },124 {125 .entity = UVC_GUID_UVC_PROCESSING,126 .selector = UVC_PU_GAIN_CONTROL,127 .index = 9,128 .size = 2,129 .flags = UVC_CTRL_FLAG_SET_CUR130 | UVC_CTRL_FLAG_GET_RANGE131 | UVC_CTRL_FLAG_RESTORE,132 },133 {134 .entity = UVC_GUID_UVC_PROCESSING,135 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,136 .index = 10,137 .size = 1,138 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR139 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,140 },141 {142 .entity = UVC_GUID_UVC_PROCESSING,143 .selector = UVC_PU_HUE_AUTO_CONTROL,144 .index = 11,145 .size = 1,146 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR147 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,148 },149 {150 .entity = UVC_GUID_UVC_PROCESSING,151 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,152 .index = 12,153 .size = 1,154 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR155 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,156 },157 {158 .entity = UVC_GUID_UVC_PROCESSING,159 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,160 .index = 13,161 .size = 1,162 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR163 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,164 },165 {166 .entity = UVC_GUID_UVC_PROCESSING,167 .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL,168 .index = 14,169 .size = 2,170 .flags = UVC_CTRL_FLAG_SET_CUR171 | UVC_CTRL_FLAG_GET_RANGE172 | UVC_CTRL_FLAG_RESTORE,173 },174 {175 .entity = UVC_GUID_UVC_PROCESSING,176 .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,177 .index = 15,178 .size = 2,179 .flags = UVC_CTRL_FLAG_SET_CUR180 | UVC_CTRL_FLAG_GET_RANGE181 | UVC_CTRL_FLAG_RESTORE,182 },183 {184 .entity = UVC_GUID_UVC_PROCESSING,185 .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,186 .index = 16,187 .size = 1,188 .flags = UVC_CTRL_FLAG_GET_CUR,189 },190 {191 .entity = UVC_GUID_UVC_PROCESSING,192 .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL,193 .index = 17,194 .size = 1,195 .flags = UVC_CTRL_FLAG_GET_CUR,196 },197 {198 .entity = UVC_GUID_UVC_CAMERA,199 .selector = UVC_CT_SCANNING_MODE_CONTROL,200 .index = 0,201 .size = 1,202 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR203 | UVC_CTRL_FLAG_RESTORE,204 },205 {206 .entity = UVC_GUID_UVC_CAMERA,207 .selector = UVC_CT_AE_MODE_CONTROL,208 .index = 1,209 .size = 1,210 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR211 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_GET_RES212 | UVC_CTRL_FLAG_RESTORE,213 },214 {215 .entity = UVC_GUID_UVC_CAMERA,216 .selector = UVC_CT_AE_PRIORITY_CONTROL,217 .index = 2,218 .size = 1,219 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR220 | UVC_CTRL_FLAG_RESTORE,221 },222 {223 .entity = UVC_GUID_UVC_CAMERA,224 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,225 .index = 3,226 .size = 4,227 .flags = UVC_CTRL_FLAG_SET_CUR228 | UVC_CTRL_FLAG_GET_RANGE229 | UVC_CTRL_FLAG_RESTORE230 | UVC_CTRL_FLAG_AUTO_UPDATE,231 },232 {233 .entity = UVC_GUID_UVC_CAMERA,234 .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,235 .index = 4,236 .size = 1,237 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_RESTORE,238 },239 {240 .entity = UVC_GUID_UVC_CAMERA,241 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,242 .index = 5,243 .size = 2,244 .flags = UVC_CTRL_FLAG_SET_CUR245 | UVC_CTRL_FLAG_GET_RANGE246 | UVC_CTRL_FLAG_RESTORE247 | UVC_CTRL_FLAG_AUTO_UPDATE,248 },249 {250 .entity = UVC_GUID_UVC_CAMERA,251 .selector = UVC_CT_FOCUS_RELATIVE_CONTROL,252 .index = 6,253 .size = 2,254 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN255 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES256 | UVC_CTRL_FLAG_GET_DEF257 | UVC_CTRL_FLAG_AUTO_UPDATE,258 },259 {260 .entity = UVC_GUID_UVC_CAMERA,261 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,262 .index = 7,263 .size = 2,264 .flags = UVC_CTRL_FLAG_SET_CUR265 | UVC_CTRL_FLAG_GET_RANGE266 | UVC_CTRL_FLAG_RESTORE267 | UVC_CTRL_FLAG_AUTO_UPDATE,268 },269 {270 .entity = UVC_GUID_UVC_CAMERA,271 .selector = UVC_CT_IRIS_RELATIVE_CONTROL,272 .index = 8,273 .size = 1,274 .flags = UVC_CTRL_FLAG_SET_CUR275 | UVC_CTRL_FLAG_AUTO_UPDATE,276 },277 {278 .entity = UVC_GUID_UVC_CAMERA,279 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,280 .index = 9,281 .size = 2,282 .flags = UVC_CTRL_FLAG_SET_CUR283 | UVC_CTRL_FLAG_GET_RANGE284 | UVC_CTRL_FLAG_RESTORE285 | UVC_CTRL_FLAG_AUTO_UPDATE,286 },287 {288 .entity = UVC_GUID_UVC_CAMERA,289 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,290 .index = 10,291 .size = 3,292 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN293 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES294 | UVC_CTRL_FLAG_GET_DEF295 | UVC_CTRL_FLAG_AUTO_UPDATE,296 },297 {298 .entity = UVC_GUID_UVC_CAMERA,299 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,300 .index = 11,301 .size = 8,302 .flags = UVC_CTRL_FLAG_SET_CUR303 | UVC_CTRL_FLAG_GET_RANGE304 | UVC_CTRL_FLAG_RESTORE305 | UVC_CTRL_FLAG_AUTO_UPDATE,306 },307 {308 .entity = UVC_GUID_UVC_CAMERA,309 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,310 .index = 12,311 .size = 4,312 .flags = UVC_CTRL_FLAG_SET_CUR313 | UVC_CTRL_FLAG_GET_RANGE314 | UVC_CTRL_FLAG_AUTO_UPDATE,315 },316 {317 .entity = UVC_GUID_UVC_CAMERA,318 .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL,319 .index = 13,320 .size = 2,321 .flags = UVC_CTRL_FLAG_SET_CUR322 | UVC_CTRL_FLAG_GET_RANGE323 | UVC_CTRL_FLAG_RESTORE324 | UVC_CTRL_FLAG_AUTO_UPDATE,325 },326 {327 .entity = UVC_GUID_UVC_CAMERA,328 .selector = UVC_CT_ROLL_RELATIVE_CONTROL,329 .index = 14,330 .size = 2,331 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN332 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES333 | UVC_CTRL_FLAG_GET_DEF334 | UVC_CTRL_FLAG_AUTO_UPDATE,335 },336 {337 .entity = UVC_GUID_UVC_CAMERA,338 .selector = UVC_CT_FOCUS_AUTO_CONTROL,339 .index = 17,340 .size = 1,341 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR342 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,343 },344 {345 .entity = UVC_GUID_UVC_CAMERA,346 .selector = UVC_CT_PRIVACY_CONTROL,347 .index = 18,348 .size = 1,349 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR350 | UVC_CTRL_FLAG_RESTORE351 | UVC_CTRL_FLAG_AUTO_UPDATE,352 },353 {354 .entity = UVC_GUID_EXT_GPIO_CONTROLLER,355 .selector = UVC_CT_PRIVACY_CONTROL,356 .index = 0,357 .size = 1,358 .flags = UVC_CTRL_FLAG_GET_CUR359 | UVC_CTRL_FLAG_AUTO_UPDATE,360 },361};362 363static const u32 uvc_control_classes[] = {364 V4L2_CID_CAMERA_CLASS,365 V4L2_CID_USER_CLASS,366};367 368static const int exposure_auto_mapping[] = { 2, 1, 4, 8 };369 370/*371 * This function translates the V4L2 menu index @idx, as exposed to userspace as372 * the V4L2 control value, to the corresponding UVC control value used by the373 * device. The custom menu_mapping in the control @mapping is used when374 * available, otherwise the function assumes that the V4L2 and UVC values are375 * identical.376 *377 * For controls of type UVC_CTRL_DATA_TYPE_BITMASK, the UVC control value is378 * expressed as a bitmask and is thus guaranteed to have a single bit set.379 *380 * The function returns -EINVAL if the V4L2 menu index @idx isn't valid for the381 * control, which includes all controls whose type isn't UVC_CTRL_DATA_TYPE_ENUM382 * or UVC_CTRL_DATA_TYPE_BITMASK.383 */384static int uvc_mapping_get_menu_value(const struct uvc_control_mapping *mapping,385 u32 idx)386{387 if (!test_bit(idx, &mapping->menu_mask))388 return -EINVAL;389 390 if (mapping->menu_mapping)391 return mapping->menu_mapping[idx];392 393 return idx;394}395 396static const char *397uvc_mapping_get_menu_name(const struct uvc_control_mapping *mapping, u32 idx)398{399 if (!test_bit(idx, &mapping->menu_mask))400 return NULL;401 402 if (mapping->menu_names)403 return mapping->menu_names[idx];404 405 return v4l2_ctrl_get_menu(mapping->id)[idx];406}407 408static s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping,409 u8 query, const u8 *data)410{411 s8 zoom = (s8)data[0];412 413 switch (query) {414 case UVC_GET_CUR:415 return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);416 417 case UVC_GET_MIN:418 case UVC_GET_MAX:419 case UVC_GET_RES:420 case UVC_GET_DEF:421 default:422 return data[2];423 }424}425 426static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,427 s32 value, u8 *data)428{429 data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;430 data[2] = min((int)abs(value), 0xff);431}432 433static s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping,434 u8 query, const u8 *data)435{436 unsigned int first = mapping->offset / 8;437 s8 rel = (s8)data[first];438 439 switch (query) {440 case UVC_GET_CUR:441 return (rel == 0) ? 0 : (rel > 0 ? data[first+1]442 : -data[first+1]);443 case UVC_GET_MIN:444 return -data[first+1];445 case UVC_GET_MAX:446 case UVC_GET_RES:447 case UVC_GET_DEF:448 default:449 return data[first+1];450 }451}452 453static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping,454 s32 value, u8 *data)455{456 unsigned int first = mapping->offset / 8;457 458 data[first] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;459 data[first+1] = min_t(int, abs(value), 0xff);460}461 462static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_limited = {463 .id = V4L2_CID_POWER_LINE_FREQUENCY,464 .entity = UVC_GUID_UVC_PROCESSING,465 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,466 .size = 2,467 .offset = 0,468 .v4l2_type = V4L2_CTRL_TYPE_MENU,469 .data_type = UVC_CTRL_DATA_TYPE_ENUM,470 .menu_mask = GENMASK(V4L2_CID_POWER_LINE_FREQUENCY_60HZ,471 V4L2_CID_POWER_LINE_FREQUENCY_50HZ),472};473 474static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_uvc11 = {475 .id = V4L2_CID_POWER_LINE_FREQUENCY,476 .entity = UVC_GUID_UVC_PROCESSING,477 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,478 .size = 2,479 .offset = 0,480 .v4l2_type = V4L2_CTRL_TYPE_MENU,481 .data_type = UVC_CTRL_DATA_TYPE_ENUM,482 .menu_mask = GENMASK(V4L2_CID_POWER_LINE_FREQUENCY_60HZ,483 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED),484};485 486static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_uvc15 = {487 .id = V4L2_CID_POWER_LINE_FREQUENCY,488 .entity = UVC_GUID_UVC_PROCESSING,489 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,490 .size = 2,491 .offset = 0,492 .v4l2_type = V4L2_CTRL_TYPE_MENU,493 .data_type = UVC_CTRL_DATA_TYPE_ENUM,494 .menu_mask = GENMASK(V4L2_CID_POWER_LINE_FREQUENCY_AUTO,495 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED),496};497 498static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping(499 struct uvc_video_chain *chain, struct uvc_control *ctrl)500{501 const struct uvc_control_mapping *out_mapping =502 &uvc_ctrl_power_line_mapping_uvc11;503 u8 *buf __free(kfree) = NULL;504 u8 init_val;505 int ret;506 507 buf = kmalloc(sizeof(*buf), GFP_KERNEL);508 if (!buf)509 return NULL;510 511 /* Save the current PLF value, so we can restore it. */512 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,513 chain->dev->intfnum, ctrl->info.selector,514 buf, sizeof(*buf));515 /* If we cannot read the control skip it. */516 if (ret)517 return NULL;518 init_val = *buf;519 520 /* If PLF value cannot be set to off, it is limited. */521 *buf = V4L2_CID_POWER_LINE_FREQUENCY_DISABLED;522 ret = uvc_query_ctrl(chain->dev, UVC_SET_CUR, ctrl->entity->id,523 chain->dev->intfnum, ctrl->info.selector,524 buf, sizeof(*buf));525 if (ret)526 return &uvc_ctrl_power_line_mapping_limited;527 528 /* UVC 1.1 does not define auto, we can exit. */529 if (chain->dev->uvc_version < 0x150)530 goto end;531 532 /* Check if the device supports auto. */533 *buf = V4L2_CID_POWER_LINE_FREQUENCY_AUTO;534 ret = uvc_query_ctrl(chain->dev, UVC_SET_CUR, ctrl->entity->id,535 chain->dev->intfnum, ctrl->info.selector,536 buf, sizeof(*buf));537 if (!ret)538 out_mapping = &uvc_ctrl_power_line_mapping_uvc15;539 540end:541 /* Restore initial value and add mapping. */542 *buf = init_val;543 uvc_query_ctrl(chain->dev, UVC_SET_CUR, ctrl->entity->id,544 chain->dev->intfnum, ctrl->info.selector,545 buf, sizeof(*buf));546 547 return out_mapping;548}549 550static const struct uvc_control_mapping uvc_ctrl_mappings[] = {551 {552 .id = V4L2_CID_BRIGHTNESS,553 .entity = UVC_GUID_UVC_PROCESSING,554 .selector = UVC_PU_BRIGHTNESS_CONTROL,555 .size = 16,556 .offset = 0,557 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,558 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,559 },560 {561 .id = V4L2_CID_CONTRAST,562 .entity = UVC_GUID_UVC_PROCESSING,563 .selector = UVC_PU_CONTRAST_CONTROL,564 .size = 16,565 .offset = 0,566 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,567 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,568 },569 {570 .id = V4L2_CID_HUE,571 .entity = UVC_GUID_UVC_PROCESSING,572 .selector = UVC_PU_HUE_CONTROL,573 .size = 16,574 .offset = 0,575 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,576 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,577 .master_id = V4L2_CID_HUE_AUTO,578 .master_manual = 0,579 },580 {581 .id = V4L2_CID_SATURATION,582 .entity = UVC_GUID_UVC_PROCESSING,583 .selector = UVC_PU_SATURATION_CONTROL,584 .size = 16,585 .offset = 0,586 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,587 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,588 },589 {590 .id = V4L2_CID_SHARPNESS,591 .entity = UVC_GUID_UVC_PROCESSING,592 .selector = UVC_PU_SHARPNESS_CONTROL,593 .size = 16,594 .offset = 0,595 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,596 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,597 },598 {599 .id = V4L2_CID_GAMMA,600 .entity = UVC_GUID_UVC_PROCESSING,601 .selector = UVC_PU_GAMMA_CONTROL,602 .size = 16,603 .offset = 0,604 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,605 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,606 },607 {608 .id = V4L2_CID_BACKLIGHT_COMPENSATION,609 .entity = UVC_GUID_UVC_PROCESSING,610 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,611 .size = 16,612 .offset = 0,613 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,614 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,615 },616 {617 .id = V4L2_CID_GAIN,618 .entity = UVC_GUID_UVC_PROCESSING,619 .selector = UVC_PU_GAIN_CONTROL,620 .size = 16,621 .offset = 0,622 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,623 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,624 },625 {626 .id = V4L2_CID_HUE_AUTO,627 .entity = UVC_GUID_UVC_PROCESSING,628 .selector = UVC_PU_HUE_AUTO_CONTROL,629 .size = 1,630 .offset = 0,631 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,632 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,633 .slave_ids = { V4L2_CID_HUE, },634 },635 {636 .id = V4L2_CID_EXPOSURE_AUTO,637 .entity = UVC_GUID_UVC_CAMERA,638 .selector = UVC_CT_AE_MODE_CONTROL,639 .size = 4,640 .offset = 0,641 .v4l2_type = V4L2_CTRL_TYPE_MENU,642 .data_type = UVC_CTRL_DATA_TYPE_BITMASK,643 .menu_mapping = exposure_auto_mapping,644 .menu_mask = GENMASK(V4L2_EXPOSURE_APERTURE_PRIORITY,645 V4L2_EXPOSURE_AUTO),646 .slave_ids = { V4L2_CID_EXPOSURE_ABSOLUTE, },647 },648 {649 .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,650 .entity = UVC_GUID_UVC_CAMERA,651 .selector = UVC_CT_AE_PRIORITY_CONTROL,652 .size = 1,653 .offset = 0,654 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,655 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,656 },657 {658 .id = V4L2_CID_EXPOSURE_ABSOLUTE,659 .entity = UVC_GUID_UVC_CAMERA,660 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,661 .size = 32,662 .offset = 0,663 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,664 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,665 .master_id = V4L2_CID_EXPOSURE_AUTO,666 .master_manual = V4L2_EXPOSURE_MANUAL,667 },668 {669 .id = V4L2_CID_AUTO_WHITE_BALANCE,670 .entity = UVC_GUID_UVC_PROCESSING,671 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,672 .size = 1,673 .offset = 0,674 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,675 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,676 .slave_ids = { V4L2_CID_WHITE_BALANCE_TEMPERATURE, },677 },678 {679 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,680 .entity = UVC_GUID_UVC_PROCESSING,681 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,682 .size = 16,683 .offset = 0,684 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,685 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,686 .master_id = V4L2_CID_AUTO_WHITE_BALANCE,687 .master_manual = 0,688 },689 {690 .id = V4L2_CID_AUTO_WHITE_BALANCE,691 .entity = UVC_GUID_UVC_PROCESSING,692 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,693 .size = 1,694 .offset = 0,695 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,696 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,697 .slave_ids = { V4L2_CID_BLUE_BALANCE,698 V4L2_CID_RED_BALANCE },699 },700 {701 .id = V4L2_CID_BLUE_BALANCE,702 .entity = UVC_GUID_UVC_PROCESSING,703 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,704 .size = 16,705 .offset = 0,706 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,707 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,708 .master_id = V4L2_CID_AUTO_WHITE_BALANCE,709 .master_manual = 0,710 },711 {712 .id = V4L2_CID_RED_BALANCE,713 .entity = UVC_GUID_UVC_PROCESSING,714 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,715 .size = 16,716 .offset = 16,717 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,718 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,719 .master_id = V4L2_CID_AUTO_WHITE_BALANCE,720 .master_manual = 0,721 },722 {723 .id = V4L2_CID_FOCUS_ABSOLUTE,724 .entity = UVC_GUID_UVC_CAMERA,725 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,726 .size = 16,727 .offset = 0,728 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,729 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,730 .master_id = V4L2_CID_FOCUS_AUTO,731 .master_manual = 0,732 },733 {734 .id = V4L2_CID_FOCUS_AUTO,735 .entity = UVC_GUID_UVC_CAMERA,736 .selector = UVC_CT_FOCUS_AUTO_CONTROL,737 .size = 1,738 .offset = 0,739 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,740 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,741 .slave_ids = { V4L2_CID_FOCUS_ABSOLUTE, },742 },743 {744 .id = V4L2_CID_IRIS_ABSOLUTE,745 .entity = UVC_GUID_UVC_CAMERA,746 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,747 .size = 16,748 .offset = 0,749 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,750 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,751 },752 {753 .id = V4L2_CID_IRIS_RELATIVE,754 .entity = UVC_GUID_UVC_CAMERA,755 .selector = UVC_CT_IRIS_RELATIVE_CONTROL,756 .size = 8,757 .offset = 0,758 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,759 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,760 },761 {762 .id = V4L2_CID_ZOOM_ABSOLUTE,763 .entity = UVC_GUID_UVC_CAMERA,764 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,765 .size = 16,766 .offset = 0,767 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,768 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,769 },770 {771 .id = V4L2_CID_ZOOM_CONTINUOUS,772 .entity = UVC_GUID_UVC_CAMERA,773 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,774 .size = 0,775 .offset = 0,776 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,777 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,778 .get = uvc_ctrl_get_zoom,779 .set = uvc_ctrl_set_zoom,780 },781 {782 .id = V4L2_CID_PAN_ABSOLUTE,783 .entity = UVC_GUID_UVC_CAMERA,784 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,785 .size = 32,786 .offset = 0,787 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,788 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,789 },790 {791 .id = V4L2_CID_TILT_ABSOLUTE,792 .entity = UVC_GUID_UVC_CAMERA,793 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,794 .size = 32,795 .offset = 32,796 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,797 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,798 },799 {800 .id = V4L2_CID_PAN_SPEED,801 .entity = UVC_GUID_UVC_CAMERA,802 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,803 .size = 16,804 .offset = 0,805 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,806 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,807 .get = uvc_ctrl_get_rel_speed,808 .set = uvc_ctrl_set_rel_speed,809 },810 {811 .id = V4L2_CID_TILT_SPEED,812 .entity = UVC_GUID_UVC_CAMERA,813 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,814 .size = 16,815 .offset = 16,816 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,817 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,818 .get = uvc_ctrl_get_rel_speed,819 .set = uvc_ctrl_set_rel_speed,820 },821 {822 .id = V4L2_CID_PRIVACY,823 .entity = UVC_GUID_UVC_CAMERA,824 .selector = UVC_CT_PRIVACY_CONTROL,825 .size = 1,826 .offset = 0,827 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,828 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,829 },830 {831 .id = V4L2_CID_PRIVACY,832 .entity = UVC_GUID_EXT_GPIO_CONTROLLER,833 .selector = UVC_CT_PRIVACY_CONTROL,834 .size = 1,835 .offset = 0,836 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,837 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,838 },839 {840 .entity = UVC_GUID_UVC_PROCESSING,841 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,842 .filter_mapping = uvc_ctrl_filter_plf_mapping,843 },844};845 846/* ------------------------------------------------------------------------847 * Utility functions848 */849 850static inline u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)851{852 return ctrl->uvc_data + id * ctrl->info.size;853}854 855static inline int uvc_test_bit(const u8 *data, int bit)856{857 return (data[bit >> 3] >> (bit & 7)) & 1;858}859 860static inline void uvc_clear_bit(u8 *data, int bit)861{862 data[bit >> 3] &= ~(1 << (bit & 7));863}864 865/*866 * Extract the bit string specified by mapping->offset and mapping->size867 * from the little-endian data stored at 'data' and return the result as868 * a signed 32bit integer. Sign extension will be performed if the mapping869 * references a signed data type.870 */871static s32 uvc_get_le_value(struct uvc_control_mapping *mapping,872 u8 query, const u8 *data)873{874 int bits = mapping->size;875 int offset = mapping->offset;876 s32 value = 0;877 u8 mask;878 879 data += offset / 8;880 offset &= 7;881 mask = ((1LL << bits) - 1) << offset;882 883 while (1) {884 u8 byte = *data & mask;885 value |= offset > 0 ? (byte >> offset) : (byte << (-offset));886 bits -= 8 - max(offset, 0);887 if (bits <= 0)888 break;889 890 offset -= 8;891 mask = (1 << bits) - 1;892 data++;893 }894 895 /* Sign-extend the value if needed. */896 if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)897 value |= -(value & (1 << (mapping->size - 1)));898 899 return value;900}901 902/*903 * Set the bit string specified by mapping->offset and mapping->size904 * in the little-endian data stored at 'data' to the value 'value'.905 */906static void uvc_set_le_value(struct uvc_control_mapping *mapping,907 s32 value, u8 *data)908{909 int bits = mapping->size;910 int offset = mapping->offset;911 u8 mask;912 913 /*914 * According to the v4l2 spec, writing any value to a button control915 * should result in the action belonging to the button control being916 * triggered. UVC devices however want to see a 1 written -> override917 * value.918 */919 if (mapping->v4l2_type == V4L2_CTRL_TYPE_BUTTON)920 value = -1;921 922 data += offset / 8;923 offset &= 7;924 925 for (; bits > 0; data++) {926 mask = ((1LL << bits) - 1) << offset;927 *data = (*data & ~mask) | ((value << offset) & mask);928 value >>= offset ? offset : 8;929 bits -= 8 - offset;930 offset = 0;931 }932}933 934/* ------------------------------------------------------------------------935 * Terminal and unit management936 */937 938static int uvc_entity_match_guid(const struct uvc_entity *entity,939 const u8 guid[16])940{941 return memcmp(entity->guid, guid, sizeof(entity->guid)) == 0;942}943 944/* ------------------------------------------------------------------------945 * UVC Controls946 */947 948static void __uvc_find_control(struct uvc_entity *entity, u32 v4l2_id,949 struct uvc_control_mapping **mapping, struct uvc_control **control,950 int next)951{952 struct uvc_control *ctrl;953 struct uvc_control_mapping *map;954 unsigned int i;955 956 if (entity == NULL)957 return;958 959 for (i = 0; i < entity->ncontrols; ++i) {960 ctrl = &entity->controls[i];961 if (!ctrl->initialized)962 continue;963 964 list_for_each_entry(map, &ctrl->info.mappings, list) {965 if ((map->id == v4l2_id) && !next) {966 *control = ctrl;967 *mapping = map;968 return;969 }970 971 if ((*mapping == NULL || (*mapping)->id > map->id) &&972 (map->id > v4l2_id) && next) {973 *control = ctrl;974 *mapping = map;975 }976 }977 }978}979 980static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,981 u32 v4l2_id, struct uvc_control_mapping **mapping)982{983 struct uvc_control *ctrl = NULL;984 struct uvc_entity *entity;985 int next = v4l2_id & V4L2_CTRL_FLAG_NEXT_CTRL;986 987 *mapping = NULL;988 989 /* Mask the query flags. */990 v4l2_id &= V4L2_CTRL_ID_MASK;991 992 /* Find the control. */993 list_for_each_entry(entity, &chain->entities, chain) {994 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);995 if (ctrl && !next)996 return ctrl;997 }998 999 if (ctrl == NULL && !next)1000 uvc_dbg(chain->dev, CONTROL, "Control 0x%08x not found\n",1001 v4l2_id);1002 1003 return ctrl;1004}1005 1006static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,1007 struct uvc_control *ctrl)1008{1009 int ret;1010 1011 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {1012 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,1013 chain->dev->intfnum, ctrl->info.selector,1014 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),1015 ctrl->info.size);1016 if (ret < 0)1017 return ret;1018 }1019 1020 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) {1021 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,1022 chain->dev->intfnum, ctrl->info.selector,1023 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),1024 ctrl->info.size);1025 if (ret < 0)1026 return ret;1027 }1028 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) {1029 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,1030 chain->dev->intfnum, ctrl->info.selector,1031 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),1032 ctrl->info.size);1033 if (ret < 0)1034 return ret;1035 }1036 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {1037 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,1038 chain->dev->intfnum, ctrl->info.selector,1039 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),1040 ctrl->info.size);1041 if (ret < 0) {1042 if (UVC_ENTITY_TYPE(ctrl->entity) !=1043 UVC_VC_EXTENSION_UNIT)1044 return ret;1045 1046 /*1047 * GET_RES is mandatory for XU controls, but some1048 * cameras still choke on it. Ignore errors and set the1049 * resolution value to zero.1050 */1051 uvc_warn_once(chain->dev, UVC_WARN_XU_GET_RES,1052 "UVC non compliance - GET_RES failed on "1053 "an XU control. Enabling workaround.\n");1054 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), 0,1055 ctrl->info.size);1056 }1057 }1058 1059 ctrl->cached = 1;1060 return 0;1061}1062 1063static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,1064 const u8 *data)1065{1066 s32 value = mapping->get(mapping, UVC_GET_CUR, data);1067 1068 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {1069 unsigned int i;1070 1071 for (i = 0; BIT(i) <= mapping->menu_mask; ++i) {1072 u32 menu_value;1073 1074 if (!test_bit(i, &mapping->menu_mask))1075 continue;1076 1077 menu_value = uvc_mapping_get_menu_value(mapping, i);1078 1079 if (menu_value == value) {1080 value = i;1081 break;1082 }1083 }1084 }1085 1086 return value;1087}1088 1089static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,1090 struct uvc_control *ctrl)1091{1092 u8 *data;1093 int ret;1094 1095 if (ctrl->loaded)1096 return 0;1097 1098 data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);1099 1100 if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {1101 memset(data, 0, ctrl->info.size);1102 ctrl->loaded = 1;1103 1104 return 0;1105 }1106 1107 if (ctrl->entity->get_cur)1108 ret = ctrl->entity->get_cur(chain->dev, ctrl->entity,1109 ctrl->info.selector, data,1110 ctrl->info.size);1111 else1112 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,1113 ctrl->entity->id, chain->dev->intfnum,1114 ctrl->info.selector, data,1115 ctrl->info.size);1116 1117 if (ret < 0)1118 return ret;1119 1120 ctrl->loaded = 1;1121 1122 return ret;1123}1124 1125static int __uvc_ctrl_get(struct uvc_video_chain *chain,1126 struct uvc_control *ctrl,1127 struct uvc_control_mapping *mapping,1128 s32 *value)1129{1130 int ret;1131 1132 if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)1133 return -EACCES;1134 1135 ret = __uvc_ctrl_load_cur(chain, ctrl);1136 if (ret < 0)1137 return ret;1138 1139 *value = __uvc_ctrl_get_value(mapping,1140 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));1141 1142 return 0;1143}1144 1145static int __uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,1146 u32 found_id)1147{1148 bool find_next = req_id & V4L2_CTRL_FLAG_NEXT_CTRL;1149 unsigned int i;1150 1151 req_id &= V4L2_CTRL_ID_MASK;1152 1153 for (i = 0; i < ARRAY_SIZE(uvc_control_classes); i++) {1154 if (!(chain->ctrl_class_bitmap & BIT(i)))1155 continue;1156 if (!find_next) {1157 if (uvc_control_classes[i] == req_id)1158 return i;1159 continue;1160 }1161 if (uvc_control_classes[i] > req_id &&1162 uvc_control_classes[i] < found_id)1163 return i;1164 }1165 1166 return -ENODEV;1167}1168 1169static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,1170 u32 found_id, struct v4l2_queryctrl *v4l2_ctrl)1171{1172 int idx;1173 1174 idx = __uvc_query_v4l2_class(chain, req_id, found_id);1175 if (idx < 0)1176 return -ENODEV;1177 1178 memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));1179 v4l2_ctrl->id = uvc_control_classes[idx];1180 strscpy(v4l2_ctrl->name, v4l2_ctrl_get_name(v4l2_ctrl->id),1181 sizeof(v4l2_ctrl->name));1182 v4l2_ctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;1183 v4l2_ctrl->flags = V4L2_CTRL_FLAG_WRITE_ONLY1184 | V4L2_CTRL_FLAG_READ_ONLY;1185 return 0;1186}1187 1188/*1189 * Check if control @v4l2_id can be accessed by the given control @ioctl1190 * (VIDIOC_G_EXT_CTRLS, VIDIOC_TRY_EXT_CTRLS or VIDIOC_S_EXT_CTRLS).1191 *1192 * For set operations on slave controls, check if the master's value is set to1193 * manual, either in the others controls set in the same ioctl call, or from1194 * the master's current value. This catches VIDIOC_S_EXT_CTRLS calls that set1195 * both the master and slave control, such as for instance setting1196 * auto_exposure=1, exposure_time_absolute=251.1197 */1198int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,1199 const struct v4l2_ext_controls *ctrls,1200 unsigned long ioctl)1201{1202 struct uvc_control_mapping *master_map = NULL;1203 struct uvc_control *master_ctrl = NULL;1204 struct uvc_control_mapping *mapping;1205 struct uvc_control *ctrl;1206 bool read = ioctl == VIDIOC_G_EXT_CTRLS;1207 s32 val;1208 int ret;1209 int i;1210 1211 if (__uvc_query_v4l2_class(chain, v4l2_id, 0) >= 0)1212 return -EACCES;1213 1214 ctrl = uvc_find_control(chain, v4l2_id, &mapping);1215 if (!ctrl)1216 return -EINVAL;1217 1218 if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) && read)1219 return -EACCES;1220 1221 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) && !read)1222 return -EACCES;1223 1224 if (ioctl != VIDIOC_S_EXT_CTRLS || !mapping->master_id)1225 return 0;1226 1227 /*1228 * Iterate backwards in cases where the master control is accessed1229 * multiple times in the same ioctl. We want the last value.1230 */1231 for (i = ctrls->count - 1; i >= 0; i--) {1232 if (ctrls->controls[i].id == mapping->master_id)1233 return ctrls->controls[i].value ==1234 mapping->master_manual ? 0 : -EACCES;1235 }1236 1237 __uvc_find_control(ctrl->entity, mapping->master_id, &master_map,1238 &master_ctrl, 0);1239 1240 if (!master_ctrl || !(master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))1241 return 0;1242 1243 ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);1244 if (ret >= 0 && val != mapping->master_manual)1245 return -EACCES;1246 1247 return 0;1248}1249 1250static const char *uvc_map_get_name(const struct uvc_control_mapping *map)1251{1252 const char *name;1253 1254 if (map->name)1255 return map->name;1256 1257 name = v4l2_ctrl_get_name(map->id);1258 if (name)1259 return name;1260 1261 return "Unknown Control";1262}1263 1264static u32 uvc_get_ctrl_bitmap(struct uvc_control *ctrl,1265 struct uvc_control_mapping *mapping)1266{1267 /*1268 * Some controls, like CT_AE_MODE_CONTROL, use GET_RES to represent1269 * the number of bits supported. Those controls do not list GET_MAX1270 * as supported.1271 */1272 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)1273 return mapping->get(mapping, UVC_GET_RES,1274 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));1275 1276 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)1277 return mapping->get(mapping, UVC_GET_MAX,1278 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));1279 1280 return ~0;1281}1282 1283static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,1284 struct uvc_control *ctrl,1285 struct uvc_control_mapping *mapping,1286 struct v4l2_queryctrl *v4l2_ctrl)1287{1288 struct uvc_control_mapping *master_map = NULL;1289 struct uvc_control *master_ctrl = NULL;1290 unsigned int i;1291 1292 memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));1293 v4l2_ctrl->id = mapping->id;1294 v4l2_ctrl->type = mapping->v4l2_type;1295 strscpy(v4l2_ctrl->name, uvc_map_get_name(mapping),1296 sizeof(v4l2_ctrl->name));1297 v4l2_ctrl->flags = 0;1298 1299 if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))1300 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;1301 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))1302 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;1303 1304 if (mapping->master_id)1305 __uvc_find_control(ctrl->entity, mapping->master_id,1306 &master_map, &master_ctrl, 0);1307 if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {1308 s32 val;1309 int ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);1310 if (ret < 0)1311 return ret;1312 1313 if (val != mapping->master_manual)1314 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;1315 }1316 1317 if (!ctrl->cached) {1318 int ret = uvc_ctrl_populate_cache(chain, ctrl);1319 if (ret < 0)1320 return ret;1321 }1322 1323 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {1324 v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,1325 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));1326 }1327 1328 switch (mapping->v4l2_type) {1329 case V4L2_CTRL_TYPE_MENU:1330 v4l2_ctrl->minimum = ffs(mapping->menu_mask) - 1;1331 v4l2_ctrl->maximum = fls(mapping->menu_mask) - 1;1332 v4l2_ctrl->step = 1;1333 1334 for (i = 0; BIT(i) <= mapping->menu_mask; ++i) {1335 u32 menu_value;1336 1337 if (!test_bit(i, &mapping->menu_mask))1338 continue;1339 1340 menu_value = uvc_mapping_get_menu_value(mapping, i);1341 1342 if (menu_value == v4l2_ctrl->default_value) {1343 v4l2_ctrl->default_value = i;1344 break;1345 }1346 }1347 1348 return 0;1349 1350 case V4L2_CTRL_TYPE_BOOLEAN:1351 v4l2_ctrl->minimum = 0;1352 v4l2_ctrl->maximum = 1;1353 v4l2_ctrl->step = 1;1354 return 0;1355 1356 case V4L2_CTRL_TYPE_BUTTON:1357 v4l2_ctrl->minimum = 0;1358 v4l2_ctrl->maximum = 0;1359 v4l2_ctrl->step = 0;1360 return 0;1361 1362 case V4L2_CTRL_TYPE_BITMASK:1363 v4l2_ctrl->minimum = 0;1364 v4l2_ctrl->maximum = uvc_get_ctrl_bitmap(ctrl, mapping);1365 v4l2_ctrl->step = 0;1366 return 0;1367 1368 default:1369 break;1370 }1371 1372 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)1373 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,1374 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));1375 1376 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)1377 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,1378 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));1379 1380 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)1381 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,1382 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));1383 1384 return 0;1385}1386 1387int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,1388 struct v4l2_queryctrl *v4l2_ctrl)1389{1390 struct uvc_control *ctrl;1391 struct uvc_control_mapping *mapping;1392 int ret;1393 1394 ret = mutex_lock_interruptible(&chain->ctrl_mutex);1395 if (ret < 0)1396 return -ERESTARTSYS;1397 1398 /* Check if the ctrl is a know class */1399 if (!(v4l2_ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL)) {1400 ret = uvc_query_v4l2_class(chain, v4l2_ctrl->id, 0, v4l2_ctrl);1401 if (!ret)1402 goto done;1403 }1404 1405 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);1406 if (ctrl == NULL) {1407 ret = -EINVAL;1408 goto done;1409 }1410 1411 /*1412 * If we're enumerating control with V4L2_CTRL_FLAG_NEXT_CTRL, check if1413 * a class should be inserted between the previous control and the one1414 * we have just found.1415 */1416 if (v4l2_ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL) {1417 ret = uvc_query_v4l2_class(chain, v4l2_ctrl->id, mapping->id,1418 v4l2_ctrl);1419 if (!ret)1420 goto done;1421 }1422 1423 ret = __uvc_query_v4l2_ctrl(chain, ctrl, mapping, v4l2_ctrl);1424done:1425 mutex_unlock(&chain->ctrl_mutex);1426 return ret;1427}1428 1429/*1430 * Mapping V4L2 controls to UVC controls can be straightforward if done well.1431 * Most of the UVC controls exist in V4L2, and can be mapped directly. Some1432 * must be grouped (for instance the Red Balance, Blue Balance and Do White1433 * Balance V4L2 controls use the White Balance Component UVC control) or1434 * otherwise translated. The approach we take here is to use a translation1435 * table for the controls that can be mapped directly, and handle the others1436 * manually.1437 */1438int uvc_query_v4l2_menu(struct uvc_video_chain *chain,1439 struct v4l2_querymenu *query_menu)1440{1441 struct uvc_control_mapping *mapping;1442 struct uvc_control *ctrl;1443 u32 index = query_menu->index;1444 u32 id = query_menu->id;1445 const char *name;1446 int ret;1447 1448 memset(query_menu, 0, sizeof(*query_menu));1449 query_menu->id = id;1450 query_menu->index = index;1451 1452 if (index >= BITS_PER_TYPE(mapping->menu_mask))1453 return -EINVAL;1454 1455 ret = mutex_lock_interruptible(&chain->ctrl_mutex);1456 if (ret < 0)1457 return -ERESTARTSYS;1458 1459 ctrl = uvc_find_control(chain, query_menu->id, &mapping);1460 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {1461 ret = -EINVAL;1462 goto done;1463 }1464 1465 if (!test_bit(query_menu->index, &mapping->menu_mask)) {1466 ret = -EINVAL;1467 goto done;1468 }1469 1470 if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) {1471 int mask;1472 1473 if (!ctrl->cached) {1474 ret = uvc_ctrl_populate_cache(chain, ctrl);1475 if (ret < 0)1476 goto done;1477 }1478 1479 mask = uvc_mapping_get_menu_value(mapping, query_menu->index);1480 if (mask < 0) {1481 ret = mask;1482 goto done;1483 }1484 1485 if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & mask)) {1486 ret = -EINVAL;1487 goto done;1488 }1489 }1490 1491 name = uvc_mapping_get_menu_name(mapping, query_menu->index);1492 if (!name) {1493 ret = -EINVAL;1494 goto done;1495 }1496 1497 strscpy(query_menu->name, name, sizeof(query_menu->name));1498 1499done:1500 mutex_unlock(&chain->ctrl_mutex);1501 return ret;1502}1503 1504/* --------------------------------------------------------------------------1505 * Ctrl event handling1506 */1507 1508static void uvc_ctrl_fill_event(struct uvc_video_chain *chain,1509 struct v4l2_event *ev,1510 struct uvc_control *ctrl,1511 struct uvc_control_mapping *mapping,1512 s32 value, u32 changes)1513{1514 struct v4l2_queryctrl v4l2_ctrl;1515 1516 __uvc_query_v4l2_ctrl(chain, ctrl, mapping, &v4l2_ctrl);1517 1518 memset(ev, 0, sizeof(*ev));1519 ev->type = V4L2_EVENT_CTRL;1520 ev->id = v4l2_ctrl.id;1521 ev->u.ctrl.value = value;1522 ev->u.ctrl.changes = changes;1523 ev->u.ctrl.type = v4l2_ctrl.type;1524 ev->u.ctrl.flags = v4l2_ctrl.flags;1525 ev->u.ctrl.minimum = v4l2_ctrl.minimum;1526 ev->u.ctrl.maximum = v4l2_ctrl.maximum;1527 ev->u.ctrl.step = v4l2_ctrl.step;1528 ev->u.ctrl.default_value = v4l2_ctrl.default_value;1529}1530 1531/*1532 * Send control change events to all subscribers for the @ctrl control. By1533 * default the subscriber that generated the event, as identified by @handle,1534 * is not notified unless it has set the V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK flag.1535 * @handle can be NULL for asynchronous events related to auto-update controls,1536 * in which case all subscribers are notified.1537 */1538static void uvc_ctrl_send_event(struct uvc_video_chain *chain,1539 struct uvc_fh *handle, struct uvc_control *ctrl,1540 struct uvc_control_mapping *mapping, s32 value, u32 changes)1541{1542 struct v4l2_fh *originator = handle ? &handle->vfh : NULL;1543 struct v4l2_subscribed_event *sev;1544 struct v4l2_event ev;1545 1546 if (list_empty(&mapping->ev_subs))1547 return;1548 1549 uvc_ctrl_fill_event(chain, &ev, ctrl, mapping, value, changes);1550 1551 list_for_each_entry(sev, &mapping->ev_subs, node) {1552 if (sev->fh != originator ||1553 (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK) ||1554 (changes & V4L2_EVENT_CTRL_CH_FLAGS))1555 v4l2_event_queue_fh(sev->fh, &ev);1556 }1557}1558 1559/*1560 * Send control change events for the slave of the @master control identified1561 * by the V4L2 ID @slave_id. The @handle identifies the event subscriber that1562 * generated the event and may be NULL for auto-update events.1563 */1564static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain,1565 struct uvc_fh *handle, struct uvc_control *master, u32 slave_id)1566{1567 struct uvc_control_mapping *mapping = NULL;1568 struct uvc_control *ctrl = NULL;1569 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;1570 s32 val = 0;1571 1572 __uvc_find_control(master->entity, slave_id, &mapping, &ctrl, 0);1573 if (ctrl == NULL)1574 return;1575 1576 if (__uvc_ctrl_get(chain, ctrl, mapping, &val) == 0)1577 changes |= V4L2_EVENT_CTRL_CH_VALUE;1578 1579 uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);1580}1581 1582void uvc_ctrl_status_event(struct uvc_video_chain *chain,1583 struct uvc_control *ctrl, const u8 *data)1584{1585 struct uvc_control_mapping *mapping;1586 struct uvc_fh *handle;1587 unsigned int i;1588 1589 mutex_lock(&chain->ctrl_mutex);1590 1591 handle = ctrl->handle;1592 ctrl->handle = NULL;1593 1594 list_for_each_entry(mapping, &ctrl->info.mappings, list) {1595 s32 value = __uvc_ctrl_get_value(mapping, data);1596 1597 /*1598 * handle may be NULL here if the device sends auto-update1599 * events without a prior related control set from userspace.1600 */1601 for (i = 0; i < ARRAY_SIZE(mapping->slave_ids); ++i) {1602 if (!mapping->slave_ids[i])1603 break;1604 1605 uvc_ctrl_send_slave_event(chain, handle, ctrl,1606 mapping->slave_ids[i]);1607 }1608 1609 uvc_ctrl_send_event(chain, handle, ctrl, mapping, value,1610 V4L2_EVENT_CTRL_CH_VALUE);1611 }1612 1613 mutex_unlock(&chain->ctrl_mutex);1614}1615 1616static void uvc_ctrl_status_event_work(struct work_struct *work)1617{1618 struct uvc_device *dev = container_of(work, struct uvc_device,1619 async_ctrl.work);1620 struct uvc_ctrl_work *w = &dev->async_ctrl;1621 int ret;1622 1623 uvc_ctrl_status_event(w->chain, w->ctrl, w->data);1624 1625 /* The barrier is needed to synchronize with uvc_status_stop(). */1626 if (smp_load_acquire(&dev->flush_status))1627 return;1628 1629 /* Resubmit the URB. */1630 w->urb->interval = dev->int_ep->desc.bInterval;1631 ret = usb_submit_urb(w->urb, GFP_KERNEL);1632 if (ret < 0)1633 dev_err(&dev->udev->dev,1634 "Failed to resubmit status URB (%d).\n", ret);1635}1636 1637bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain,1638 struct uvc_control *ctrl, const u8 *data)1639{1640 struct uvc_device *dev = chain->dev;1641 struct uvc_ctrl_work *w = &dev->async_ctrl;1642 1643 if (list_empty(&ctrl->info.mappings)) {1644 ctrl->handle = NULL;1645 return false;1646 }1647 1648 w->data = data;1649 w->urb = urb;1650 w->chain = chain;1651 w->ctrl = ctrl;1652 1653 schedule_work(&w->work);1654 1655 return true;1656}1657 1658static bool uvc_ctrl_xctrls_has_control(const struct v4l2_ext_control *xctrls,1659 unsigned int xctrls_count, u32 id)1660{1661 unsigned int i;1662 1663 for (i = 0; i < xctrls_count; ++i) {1664 if (xctrls[i].id == id)1665 return true;1666 }1667 1668 return false;1669}1670 1671static void uvc_ctrl_send_events(struct uvc_fh *handle,1672 const struct v4l2_ext_control *xctrls, unsigned int xctrls_count)1673{1674 struct uvc_control_mapping *mapping;1675 struct uvc_control *ctrl;1676 u32 changes = V4L2_EVENT_CTRL_CH_VALUE;1677 unsigned int i;1678 unsigned int j;1679 1680 for (i = 0; i < xctrls_count; ++i) {1681 ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping);1682 1683 if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)1684 /* Notification will be sent from an Interrupt event. */1685 continue;1686 1687 for (j = 0; j < ARRAY_SIZE(mapping->slave_ids); ++j) {1688 u32 slave_id = mapping->slave_ids[j];1689 1690 if (!slave_id)1691 break;1692 1693 /*1694 * We can skip sending an event for the slave if the1695 * slave is being modified in the same transaction.1696 */1697 if (uvc_ctrl_xctrls_has_control(xctrls, xctrls_count,1698 slave_id))1699 continue;1700 1701 uvc_ctrl_send_slave_event(handle->chain, handle, ctrl,1702 slave_id);1703 }1704 1705 /*1706 * If the master is being modified in the same transaction1707 * flags may change too.1708 */1709 if (mapping->master_id &&1710 uvc_ctrl_xctrls_has_control(xctrls, xctrls_count,1711 mapping->master_id))1712 changes |= V4L2_EVENT_CTRL_CH_FLAGS;1713 1714 uvc_ctrl_send_event(handle->chain, handle, ctrl, mapping,1715 xctrls[i].value, changes);1716 }1717}1718 1719static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)1720{1721 struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh);1722 struct uvc_control_mapping *mapping;1723 struct uvc_control *ctrl;1724 int ret;1725 1726 ret = mutex_lock_interruptible(&handle->chain->ctrl_mutex);1727 if (ret < 0)1728 return -ERESTARTSYS;1729 1730 if (__uvc_query_v4l2_class(handle->chain, sev->id, 0) >= 0) {1731 ret = 0;1732 goto done;1733 }1734 1735 ctrl = uvc_find_control(handle->chain, sev->id, &mapping);1736 if (ctrl == NULL) {1737 ret = -EINVAL;1738 goto done;1739 }1740 1741 list_add_tail(&sev->node, &mapping->ev_subs);1742 if (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) {1743 struct v4l2_event ev;1744 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;1745 s32 val = 0;1746 1747 if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)1748 changes |= V4L2_EVENT_CTRL_CH_VALUE;1749 1750 uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val,1751 changes);1752 /*1753 * Mark the queue as active, allowing this initial event to be1754 * accepted.1755 */1756 sev->elems = elems;1757 v4l2_event_queue_fh(sev->fh, &ev);1758 }1759 1760done:1761 mutex_unlock(&handle->chain->ctrl_mutex);1762 return ret;1763}1764 1765static void uvc_ctrl_del_event(struct v4l2_subscribed_event *sev)1766{1767 struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh);1768 1769 mutex_lock(&handle->chain->ctrl_mutex);1770 if (__uvc_query_v4l2_class(handle->chain, sev->id, 0) >= 0)1771 goto done;1772 list_del(&sev->node);1773done:1774 mutex_unlock(&handle->chain->ctrl_mutex);1775}1776 1777const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops = {1778 .add = uvc_ctrl_add_event,1779 .del = uvc_ctrl_del_event,1780 .replace = v4l2_ctrl_replace,1781 .merge = v4l2_ctrl_merge,1782};1783 1784/* --------------------------------------------------------------------------1785 * Control transactions1786 *1787 * To make extended set operations as atomic as the hardware allows, controls1788 * are handled using begin/commit/rollback operations.1789 *1790 * At the beginning of a set request, uvc_ctrl_begin should be called to1791 * initialize the request. This function acquires the control lock.1792 *1793 * When setting a control, the new value is stored in the control data field1794 * at position UVC_CTRL_DATA_CURRENT. The control is then marked as dirty for1795 * later processing. If the UVC and V4L2 control sizes differ, the current1796 * value is loaded from the hardware before storing the new value in the data1797 * field.1798 *1799 * After processing all controls in the transaction, uvc_ctrl_commit or1800 * uvc_ctrl_rollback must be called to apply the pending changes to the1801 * hardware or revert them. When applying changes, all controls marked as1802 * dirty will be modified in the UVC device, and the dirty flag will be1803 * cleared. When reverting controls, the control data field1804 * UVC_CTRL_DATA_CURRENT is reverted to its previous value1805 * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the1806 * control lock.1807 */1808int uvc_ctrl_begin(struct uvc_video_chain *chain)1809{1810 return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0;1811}1812 1813static int uvc_ctrl_commit_entity(struct uvc_device *dev,1814 struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)1815{1816 struct uvc_control *ctrl;1817 unsigned int i;1818 int ret;1819 1820 if (entity == NULL)1821 return 0;1822 1823 for (i = 0; i < entity->ncontrols; ++i) {1824 ctrl = &entity->controls[i];1825 if (!ctrl->initialized)1826 continue;1827 1828 /*1829 * Reset the loaded flag for auto-update controls that were1830 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent1831 * uvc_ctrl_get from using the cached value, and for write-only1832 * controls to prevent uvc_ctrl_set from setting bits not1833 * explicitly set by the user.1834 */1835 if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE ||1836 !(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))1837 ctrl->loaded = 0;1838 1839 if (!ctrl->dirty)1840 continue;1841 1842 if (!rollback)1843 ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id,1844 dev->intfnum, ctrl->info.selector,1845 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),1846 ctrl->info.size);1847 else1848 ret = 0;1849 1850 if (rollback || ret < 0)1851 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),1852 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),1853 ctrl->info.size);1854 1855 ctrl->dirty = 0;1856 1857 if (ret < 0) {1858 if (err_ctrl)1859 *err_ctrl = ctrl;1860 return ret;1861 }1862 }1863 1864 return 0;1865}1866 1867static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity,1868 struct v4l2_ext_controls *ctrls,1869 struct uvc_control *uvc_control)1870{1871 struct uvc_control_mapping *mapping = NULL;1872 struct uvc_control *ctrl_found = NULL;1873 unsigned int i;1874 1875 if (!entity)1876 return ctrls->count;1877 1878 for (i = 0; i < ctrls->count; i++) {1879 __uvc_find_control(entity, ctrls->controls[i].id, &mapping,1880 &ctrl_found, 0);1881 if (uvc_control == ctrl_found)1882 return i;1883 }1884 1885 return ctrls->count;1886}1887 1888int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,1889 struct v4l2_ext_controls *ctrls)1890{1891 struct uvc_video_chain *chain = handle->chain;1892 struct uvc_control *err_ctrl;1893 struct uvc_entity *entity;1894 int ret = 0;1895 1896 /* Find the control. */1897 list_for_each_entry(entity, &chain->entities, chain) {1898 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,1899 &err_ctrl);1900 if (ret < 0) {1901 if (ctrls)1902 ctrls->error_idx =1903 uvc_ctrl_find_ctrl_idx(entity, ctrls,1904 err_ctrl);1905 goto done;1906 }1907 }1908 1909 if (!rollback)1910 uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);1911done:1912 mutex_unlock(&chain->ctrl_mutex);1913 return ret;1914}1915 1916int uvc_ctrl_get(struct uvc_video_chain *chain,1917 struct v4l2_ext_control *xctrl)1918{1919 struct uvc_control *ctrl;1920 struct uvc_control_mapping *mapping;1921 1922 if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0)1923 return -EACCES;1924 1925 ctrl = uvc_find_control(chain, xctrl->id, &mapping);1926 if (ctrl == NULL)1927 return -EINVAL;1928 1929 return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);1930}1931 1932int uvc_ctrl_set(struct uvc_fh *handle,1933 struct v4l2_ext_control *xctrl)1934{1935 struct uvc_video_chain *chain = handle->chain;1936 struct uvc_control *ctrl;1937 struct uvc_control_mapping *mapping;1938 s32 value;1939 u32 step;1940 s32 min;1941 s32 max;1942 int ret;1943 1944 if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0)1945 return -EACCES;1946 1947 ctrl = uvc_find_control(chain, xctrl->id, &mapping);1948 if (ctrl == NULL)1949 return -EINVAL;1950 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))1951 return -EACCES;1952 1953 /* Clamp out of range values. */1954 switch (mapping->v4l2_type) {1955 case V4L2_CTRL_TYPE_INTEGER:1956 if (!ctrl->cached) {1957 ret = uvc_ctrl_populate_cache(chain, ctrl);1958 if (ret < 0)1959 return ret;1960 }1961 1962 min = mapping->get(mapping, UVC_GET_MIN,1963 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));1964 max = mapping->get(mapping, UVC_GET_MAX,1965 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));1966 step = mapping->get(mapping, UVC_GET_RES,1967 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));1968 if (step == 0)1969 step = 1;1970 1971 xctrl->value = min + DIV_ROUND_CLOSEST((u32)(xctrl->value - min),1972 step) * step;1973 if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)1974 xctrl->value = clamp(xctrl->value, min, max);1975 else1976 xctrl->value = clamp_t(u32, xctrl->value, min, max);1977 value = xctrl->value;1978 break;1979 1980 case V4L2_CTRL_TYPE_BITMASK:1981 if (!ctrl->cached) {1982 ret = uvc_ctrl_populate_cache(chain, ctrl);1983 if (ret < 0)1984 return ret;1985 }1986 1987 xctrl->value &= uvc_get_ctrl_bitmap(ctrl, mapping);1988 value = xctrl->value;1989 break;1990 1991 case V4L2_CTRL_TYPE_BOOLEAN:1992 xctrl->value = clamp(xctrl->value, 0, 1);1993 value = xctrl->value;1994 break;1995 1996 case V4L2_CTRL_TYPE_MENU:1997 if (xctrl->value < (ffs(mapping->menu_mask) - 1) ||1998 xctrl->value > (fls(mapping->menu_mask) - 1))1999 return -ERANGE;2000 2001 if (!test_bit(xctrl->value, &mapping->menu_mask))2002 return -EINVAL;2003 2004 value = uvc_mapping_get_menu_value(mapping, xctrl->value);2005 2006 /*2007 * Valid menu indices are reported by the GET_RES request for2008 * UVC controls that support it.2009 */2010 if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) {2011 if (!ctrl->cached) {2012 ret = uvc_ctrl_populate_cache(chain, ctrl);2013 if (ret < 0)2014 return ret;2015 }2016 2017 if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & value))2018 return -EINVAL;2019 }2020 2021 break;2022 2023 default:2024 value = xctrl->value;2025 break;2026 }2027 2028 /*2029 * If the mapping doesn't span the whole UVC control, the current value2030 * needs to be loaded from the device to perform the read-modify-write2031 * operation.2032 */2033 if ((ctrl->info.size * 8) != mapping->size) {2034 ret = __uvc_ctrl_load_cur(chain, ctrl);2035 if (ret < 0)2036 return ret;2037 }2038 2039 /* Backup the current value in case we need to rollback later. */2040 if (!ctrl->dirty) {2041 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),2042 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),2043 ctrl->info.size);2044 }2045 2046 mapping->set(mapping, value,2047 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));2048 2049 if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)2050 ctrl->handle = handle;2051 2052 ctrl->dirty = 1;2053 ctrl->modified = 1;2054 return 0;2055}2056 2057/* --------------------------------------------------------------------------2058 * Dynamic controls2059 */2060 2061/*2062 * Retrieve flags for a given control2063 */2064static int uvc_ctrl_get_flags(struct uvc_device *dev,2065 const struct uvc_control *ctrl,2066 struct uvc_control_info *info)2067{2068 u8 *data;2069 int ret;2070 2071 data = kmalloc(1, GFP_KERNEL);2072 if (data == NULL)2073 return -ENOMEM;2074 2075 if (ctrl->entity->get_info)2076 ret = ctrl->entity->get_info(dev, ctrl->entity,2077 ctrl->info.selector, data);2078 else2079 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,2080 dev->intfnum, info->selector, data, 1);2081 2082 if (!ret) {2083 info->flags &= ~(UVC_CTRL_FLAG_GET_CUR |2084 UVC_CTRL_FLAG_SET_CUR |2085 UVC_CTRL_FLAG_AUTO_UPDATE |2086 UVC_CTRL_FLAG_ASYNCHRONOUS);2087 2088 info->flags |= (data[0] & UVC_CONTROL_CAP_GET ?2089 UVC_CTRL_FLAG_GET_CUR : 0)2090 | (data[0] & UVC_CONTROL_CAP_SET ?2091 UVC_CTRL_FLAG_SET_CUR : 0)2092 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?2093 UVC_CTRL_FLAG_AUTO_UPDATE : 0)2094 | (data[0] & UVC_CONTROL_CAP_ASYNCHRONOUS ?2095 UVC_CTRL_FLAG_ASYNCHRONOUS : 0);2096 }2097 2098 kfree(data);2099 return ret;2100}2101 2102static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev,2103 const struct uvc_control *ctrl, struct uvc_control_info *info)2104{2105 struct uvc_ctrl_fixup {2106 struct usb_device_id id;2107 u8 entity;2108 u8 selector;2109 u8 flags;2110 };2111 2112 static const struct uvc_ctrl_fixup fixups[] = {2113 { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,2114 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |2115 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |2116 UVC_CTRL_FLAG_AUTO_UPDATE },2117 { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,2118 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |2119 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |2120 UVC_CTRL_FLAG_AUTO_UPDATE },2121 { { USB_DEVICE(0x046d, 0x0994) }, 9, 1,2122 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |2123 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |2124 UVC_CTRL_FLAG_AUTO_UPDATE },2125 };2126 2127 unsigned int i;2128 2129 for (i = 0; i < ARRAY_SIZE(fixups); ++i) {2130 if (!usb_match_one_id(dev->intf, &fixups[i].id))2131 continue;2132 2133 if (fixups[i].entity == ctrl->entity->id &&2134 fixups[i].selector == info->selector) {2135 info->flags = fixups[i].flags;2136 return;2137 }2138 }2139}2140 2141/*2142 * Query control information (size and flags) for XU controls.2143 */2144static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,2145 const struct uvc_control *ctrl, struct uvc_control_info *info)2146{2147 u8 *data;2148 int ret;2149 2150 data = kmalloc(2, GFP_KERNEL);2151 if (data == NULL)2152 return -ENOMEM;2153 2154 memcpy(info->entity, ctrl->entity->guid, sizeof(info->entity));2155 info->index = ctrl->index;2156 info->selector = ctrl->index + 1;2157 2158 /* Query and verify the control length (GET_LEN) */2159 ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, dev->intfnum,2160 info->selector, data, 2);2161 if (ret < 0) {2162 uvc_dbg(dev, CONTROL,2163 "GET_LEN failed on control %pUl/%u (%d)\n",2164 info->entity, info->selector, ret);2165 goto done;2166 }2167 2168 info->size = le16_to_cpup((__le16 *)data);2169 2170 info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX2171 | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF;2172 2173 ret = uvc_ctrl_get_flags(dev, ctrl, info);2174 if (ret < 0) {2175 uvc_dbg(dev, CONTROL,2176 "Failed to get flags for control %pUl/%u (%d)\n",2177 info->entity, info->selector, ret);2178 goto done;2179 }2180 2181 uvc_ctrl_fixup_xu_info(dev, ctrl, info);2182 2183 uvc_dbg(dev, CONTROL,2184 "XU control %pUl/%u queried: len %u, flags { get %u set %u auto %u }\n",2185 info->entity, info->selector, info->size,2186 (info->flags & UVC_CTRL_FLAG_GET_CUR) ? 1 : 0,2187 (info->flags & UVC_CTRL_FLAG_SET_CUR) ? 1 : 0,2188 (info->flags & UVC_CTRL_FLAG_AUTO_UPDATE) ? 1 : 0);2189 2190done:2191 kfree(data);2192 return ret;2193}2194 2195static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl,2196 const struct uvc_control_info *info);2197 2198static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev,2199 struct uvc_control *ctrl)2200{2201 struct uvc_control_info info;2202 int ret;2203 2204 if (ctrl->initialized)2205 return 0;2206 2207 ret = uvc_ctrl_fill_xu_info(dev, ctrl, &info);2208 if (ret < 0)2209 return ret;2210 2211 ret = uvc_ctrl_add_info(dev, ctrl, &info);2212 if (ret < 0)2213 uvc_dbg(dev, CONTROL,2214 "Failed to initialize control %pUl/%u on device %s entity %u\n",2215 info.entity, info.selector, dev->udev->devpath,2216 ctrl->entity->id);2217 2218 return ret;2219}2220 2221int uvc_xu_ctrl_query(struct uvc_video_chain *chain,2222 struct uvc_xu_control_query *xqry)2223{2224 struct uvc_entity *entity, *iter;2225 struct uvc_control *ctrl;2226 unsigned int i;2227 bool found;2228 u32 reqflags;2229 u16 size;2230 u8 *data = NULL;2231 int ret;2232 2233 /* Find the extension unit. */2234 entity = NULL;2235 list_for_each_entry(iter, &chain->entities, chain) {2236 if (UVC_ENTITY_TYPE(iter) == UVC_VC_EXTENSION_UNIT &&2237 iter->id == xqry->unit) {2238 entity = iter;2239 break;2240 }2241 }2242 2243 if (!entity) {2244 uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n",2245 xqry->unit);2246 return -ENOENT;2247 }2248 2249 /* Find the control and perform delayed initialization if needed. */2250 found = false;2251 for (i = 0; i < entity->ncontrols; ++i) {2252 ctrl = &entity->controls[i];2253 if (ctrl->index == xqry->selector - 1) {2254 found = true;2255 break;2256 }2257 }2258 2259 if (!found) {2260 uvc_dbg(chain->dev, CONTROL, "Control %pUl/%u not found\n",2261 entity->guid, xqry->selector);2262 return -ENOENT;2263 }2264 2265 if (mutex_lock_interruptible(&chain->ctrl_mutex))2266 return -ERESTARTSYS;2267 2268 ret = uvc_ctrl_init_xu_ctrl(chain->dev, ctrl);2269 if (ret < 0) {2270 ret = -ENOENT;2271 goto done;2272 }2273 2274 /* Validate the required buffer size and flags for the request */2275 reqflags = 0;2276 size = ctrl->info.size;2277 2278 switch (xqry->query) {2279 case UVC_GET_CUR:2280 reqflags = UVC_CTRL_FLAG_GET_CUR;2281 break;2282 case UVC_GET_MIN:2283 reqflags = UVC_CTRL_FLAG_GET_MIN;2284 break;2285 case UVC_GET_MAX:2286 reqflags = UVC_CTRL_FLAG_GET_MAX;2287 break;2288 case UVC_GET_DEF:2289 reqflags = UVC_CTRL_FLAG_GET_DEF;2290 break;2291 case UVC_GET_RES:2292 reqflags = UVC_CTRL_FLAG_GET_RES;2293 break;2294 case UVC_SET_CUR:2295 reqflags = UVC_CTRL_FLAG_SET_CUR;2296 break;2297 case UVC_GET_LEN:2298 size = 2;2299 break;2300 case UVC_GET_INFO:2301 size = 1;2302 break;2303 default:2304 ret = -EINVAL;2305 goto done;2306 }2307 2308 if (size != xqry->size) {2309 ret = -ENOBUFS;2310 goto done;2311 }2312 2313 if (reqflags && !(ctrl->info.flags & reqflags)) {2314 ret = -EBADRQC;2315 goto done;2316 }2317 2318 data = kmalloc(size, GFP_KERNEL);2319 if (data == NULL) {2320 ret = -ENOMEM;2321 goto done;2322 }2323 2324 if (xqry->query == UVC_SET_CUR &&2325 copy_from_user(data, xqry->data, size)) {2326 ret = -EFAULT;2327 goto done;2328 }2329 2330 ret = uvc_query_ctrl(chain->dev, xqry->query, xqry->unit,2331 chain->dev->intfnum, xqry->selector, data, size);2332 if (ret < 0)2333 goto done;2334 2335 if (xqry->query != UVC_SET_CUR &&2336 copy_to_user(xqry->data, data, size))2337 ret = -EFAULT;2338done:2339 kfree(data);2340 mutex_unlock(&chain->ctrl_mutex);2341 return ret;2342}2343 2344/* --------------------------------------------------------------------------2345 * Suspend/resume2346 */2347 2348/*2349 * Restore control values after resume, skipping controls that haven't been2350 * changed.2351 *2352 * TODO2353 * - Don't restore modified controls that are back to their default value.2354 * - Handle restore order (Auto-Exposure Mode should be restored before2355 * Exposure Time).2356 */2357int uvc_ctrl_restore_values(struct uvc_device *dev)2358{2359 struct uvc_control *ctrl;2360 struct uvc_entity *entity;2361 unsigned int i;2362 int ret;2363 2364 /* Walk the entities list and restore controls when possible. */2365 list_for_each_entry(entity, &dev->entities, list) {2366 2367 for (i = 0; i < entity->ncontrols; ++i) {2368 ctrl = &entity->controls[i];2369 2370 if (!ctrl->initialized || !ctrl->modified ||2371 (ctrl->info.flags & UVC_CTRL_FLAG_RESTORE) == 0)2372 continue;2373 dev_dbg(&dev->udev->dev,2374 "restoring control %pUl/%u/%u\n",2375 ctrl->info.entity, ctrl->info.index,2376 ctrl->info.selector);2377 ctrl->dirty = 1;2378 }2379 2380 ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);2381 if (ret < 0)2382 return ret;2383 }2384 2385 return 0;2386}2387 2388/* --------------------------------------------------------------------------2389 * Control and mapping handling2390 */2391 2392/*2393 * Add control information to a given control.2394 */2395static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl,2396 const struct uvc_control_info *info)2397{2398 ctrl->info = *info;2399 INIT_LIST_HEAD(&ctrl->info.mappings);2400 2401 /* Allocate an array to save control values (cur, def, max, etc.) */2402 ctrl->uvc_data = kzalloc(ctrl->info.size * UVC_CTRL_DATA_LAST + 1,2403 GFP_KERNEL);2404 if (!ctrl->uvc_data)2405 return -ENOMEM;2406 2407 ctrl->initialized = 1;2408 2409 uvc_dbg(dev, CONTROL, "Added control %pUl/%u to device %s entity %u\n",2410 ctrl->info.entity, ctrl->info.selector, dev->udev->devpath,2411 ctrl->entity->id);2412 2413 return 0;2414}2415 2416/*2417 * Add a control mapping to a given control.2418 */2419static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,2420 struct uvc_control *ctrl, const struct uvc_control_mapping *mapping)2421{2422 struct uvc_control_mapping *map;2423 unsigned int size;2424 unsigned int i;2425 2426 /*2427 * Most mappings come from static kernel data, and need to be duplicated.2428 * Mappings that come from userspace will be unnecessarily duplicated,2429 * this could be optimized.2430 */2431 map = kmemdup(mapping, sizeof(*mapping), GFP_KERNEL);2432 if (!map)2433 return -ENOMEM;2434 2435 map->name = NULL;2436 map->menu_names = NULL;2437 map->menu_mapping = NULL;2438 2439 /* For UVCIOC_CTRL_MAP custom control */2440 if (mapping->name) {2441 map->name = kstrdup(mapping->name, GFP_KERNEL);2442 if (!map->name)2443 goto err_nomem;2444 }2445 2446 INIT_LIST_HEAD(&map->ev_subs);2447 2448 if (mapping->menu_mapping && mapping->menu_mask) {2449 size = sizeof(mapping->menu_mapping[0])2450 * fls(mapping->menu_mask);2451 map->menu_mapping = kmemdup(mapping->menu_mapping, size,2452 GFP_KERNEL);2453 if (!map->menu_mapping)2454 goto err_nomem;2455 }2456 if (mapping->menu_names && mapping->menu_mask) {2457 size = sizeof(mapping->menu_names[0])2458 * fls(mapping->menu_mask);2459 map->menu_names = kmemdup(mapping->menu_names, size,2460 GFP_KERNEL);2461 if (!map->menu_names)2462 goto err_nomem;2463 }2464 2465 if (map->get == NULL)2466 map->get = uvc_get_le_value;2467 if (map->set == NULL)2468 map->set = uvc_set_le_value;2469 2470 for (i = 0; i < ARRAY_SIZE(uvc_control_classes); i++) {2471 if (V4L2_CTRL_ID2WHICH(uvc_control_classes[i]) ==2472 V4L2_CTRL_ID2WHICH(map->id)) {2473 chain->ctrl_class_bitmap |= BIT(i);2474 break;2475 }2476 }2477 2478 list_add_tail(&map->list, &ctrl->info.mappings);2479 uvc_dbg(chain->dev, CONTROL, "Adding mapping '%s' to control %pUl/%u\n",2480 uvc_map_get_name(map), ctrl->info.entity,2481 ctrl->info.selector);2482 2483 return 0;2484 2485err_nomem:2486 kfree(map->menu_names);2487 kfree(map->menu_mapping);2488 kfree(map->name);2489 kfree(map);2490 return -ENOMEM;2491}2492 2493int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,2494 const struct uvc_control_mapping *mapping)2495{2496 struct uvc_device *dev = chain->dev;2497 struct uvc_control_mapping *map;2498 struct uvc_entity *entity;2499 struct uvc_control *ctrl;2500 int found = 0;2501 int ret;2502 2503 if (mapping->id & ~V4L2_CTRL_ID_MASK) {2504 uvc_dbg(dev, CONTROL,2505 "Can't add mapping '%s', control id 0x%08x is invalid\n",2506 uvc_map_get_name(mapping), mapping->id);2507 return -EINVAL;2508 }2509 2510 /* Search for the matching (GUID/CS) control on the current chain */2511 list_for_each_entry(entity, &chain->entities, chain) {2512 unsigned int i;2513 2514 if (UVC_ENTITY_TYPE(entity) != UVC_VC_EXTENSION_UNIT ||2515 !uvc_entity_match_guid(entity, mapping->entity))2516 continue;2517 2518 for (i = 0; i < entity->ncontrols; ++i) {2519 ctrl = &entity->controls[i];2520 if (ctrl->index == mapping->selector - 1) {2521 found = 1;2522 break;2523 }2524 }2525 2526 if (found)2527 break;2528 }2529 if (!found)2530 return -ENOENT;2531 2532 if (mutex_lock_interruptible(&chain->ctrl_mutex))2533 return -ERESTARTSYS;2534 2535 /* Perform delayed initialization of XU controls */2536 ret = uvc_ctrl_init_xu_ctrl(dev, ctrl);2537 if (ret < 0) {2538 ret = -ENOENT;2539 goto done;2540 }2541 2542 /* Validate the user-provided bit-size and offset */2543 if (mapping->size > 32 ||2544 mapping->offset + mapping->size > ctrl->info.size * 8) {2545 ret = -EINVAL;2546 goto done;2547 }2548 2549 list_for_each_entry(map, &ctrl->info.mappings, list) {2550 if (mapping->id == map->id) {2551 uvc_dbg(dev, CONTROL,2552 "Can't add mapping '%s', control id 0x%08x already exists\n",2553 uvc_map_get_name(mapping), mapping->id);2554 ret = -EEXIST;2555 goto done;2556 }2557 }2558 2559 /* Prevent excess memory consumption */2560 if (atomic_inc_return(&dev->nmappings) > UVC_MAX_CONTROL_MAPPINGS) {2561 atomic_dec(&dev->nmappings);2562 uvc_dbg(dev, CONTROL,2563 "Can't add mapping '%s', maximum mappings count (%u) exceeded\n",2564 uvc_map_get_name(mapping), UVC_MAX_CONTROL_MAPPINGS);2565 ret = -ENOMEM;2566 goto done;2567 }2568 2569 ret = __uvc_ctrl_add_mapping(chain, ctrl, mapping);2570 if (ret < 0)2571 atomic_dec(&dev->nmappings);2572 2573done:2574 mutex_unlock(&chain->ctrl_mutex);2575 return ret;2576}2577 2578/*2579 * Prune an entity of its bogus controls using a blacklist. Bogus controls2580 * are currently the ones that crash the camera or unconditionally return an2581 * error when queried.2582 */2583static void uvc_ctrl_prune_entity(struct uvc_device *dev,2584 struct uvc_entity *entity)2585{2586 struct uvc_ctrl_blacklist {2587 struct usb_device_id id;2588 u8 index;2589 };2590 2591 static const struct uvc_ctrl_blacklist processing_blacklist[] = {2592 { { USB_DEVICE(0x13d3, 0x509b) }, 9 }, /* Gain */2593 { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */2594 { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */2595 };2596 static const struct uvc_ctrl_blacklist camera_blacklist[] = {2597 { { USB_DEVICE(0x06f8, 0x3005) }, 9 }, /* Zoom, Absolute */2598 };2599 2600 const struct uvc_ctrl_blacklist *blacklist;2601 unsigned int size;2602 unsigned int count;2603 unsigned int i;2604 u8 *controls;2605 2606 switch (UVC_ENTITY_TYPE(entity)) {2607 case UVC_VC_PROCESSING_UNIT:2608 blacklist = processing_blacklist;2609 count = ARRAY_SIZE(processing_blacklist);2610 controls = entity->processing.bmControls;2611 size = entity->processing.bControlSize;2612 break;2613 2614 case UVC_ITT_CAMERA:2615 blacklist = camera_blacklist;2616 count = ARRAY_SIZE(camera_blacklist);2617 controls = entity->camera.bmControls;2618 size = entity->camera.bControlSize;2619 break;2620 2621 default:2622 return;2623 }2624 2625 for (i = 0; i < count; ++i) {2626 if (!usb_match_one_id(dev->intf, &blacklist[i].id))2627 continue;2628 2629 if (blacklist[i].index >= 8 * size ||2630 !uvc_test_bit(controls, blacklist[i].index))2631 continue;2632 2633 uvc_dbg(dev, CONTROL,2634 "%u/%u control is black listed, removing it\n",2635 entity->id, blacklist[i].index);2636 2637 uvc_clear_bit(controls, blacklist[i].index);2638 }2639}2640 2641/*2642 * Add control information and hardcoded stock control mappings to the given2643 * device.2644 */2645static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,2646 struct uvc_control *ctrl)2647{2648 unsigned int i;2649 2650 /*2651 * XU controls initialization requires querying the device for control2652 * information. As some buggy UVC devices will crash when queried2653 * repeatedly in a tight loop, delay XU controls initialization until2654 * first use.2655 */2656 if (UVC_ENTITY_TYPE(ctrl->entity) == UVC_VC_EXTENSION_UNIT)2657 return;2658 2659 for (i = 0; i < ARRAY_SIZE(uvc_ctrls); ++i) {2660 const struct uvc_control_info *info = &uvc_ctrls[i];2661 2662 if (uvc_entity_match_guid(ctrl->entity, info->entity) &&2663 ctrl->index == info->index) {2664 uvc_ctrl_add_info(chain->dev, ctrl, info);2665 /*2666 * Retrieve control flags from the device. Ignore errors2667 * and work with default flag values from the uvc_ctrl2668 * array when the device doesn't properly implement2669 * GET_INFO on standard controls.2670 */2671 uvc_ctrl_get_flags(chain->dev, ctrl, &ctrl->info);2672 break;2673 }2674 }2675 2676 if (!ctrl->initialized)2677 return;2678 2679 /* Process common mappings. */2680 for (i = 0; i < ARRAY_SIZE(uvc_ctrl_mappings); ++i) {2681 const struct uvc_control_mapping *mapping = &uvc_ctrl_mappings[i];2682 2683 if (!uvc_entity_match_guid(ctrl->entity, mapping->entity) ||2684 ctrl->info.selector != mapping->selector)2685 continue;2686 2687 /* Let the device provide a custom mapping. */2688 if (mapping->filter_mapping) {2689 mapping = mapping->filter_mapping(chain, ctrl);2690 if (!mapping)2691 continue;2692 }2693 2694 __uvc_ctrl_add_mapping(chain, ctrl, mapping);2695 }2696}2697 2698/*2699 * Initialize device controls.2700 */2701static int uvc_ctrl_init_chain(struct uvc_video_chain *chain)2702{2703 struct uvc_entity *entity;2704 unsigned int i;2705 2706 /* Walk the entities list and instantiate controls */2707 list_for_each_entry(entity, &chain->entities, chain) {2708 struct uvc_control *ctrl;2709 unsigned int bControlSize = 0, ncontrols;2710 u8 *bmControls = NULL;2711 2712 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {2713 bmControls = entity->extension.bmControls;2714 bControlSize = entity->extension.bControlSize;2715 } else if (UVC_ENTITY_TYPE(entity) == UVC_VC_PROCESSING_UNIT) {2716 bmControls = entity->processing.bmControls;2717 bControlSize = entity->processing.bControlSize;2718 } else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) {2719 bmControls = entity->camera.bmControls;2720 bControlSize = entity->camera.bControlSize;2721 } else if (UVC_ENTITY_TYPE(entity) == UVC_EXT_GPIO_UNIT) {2722 bmControls = entity->gpio.bmControls;2723 bControlSize = entity->gpio.bControlSize;2724 }2725 2726 /* Remove bogus/blacklisted controls */2727 uvc_ctrl_prune_entity(chain->dev, entity);2728 2729 /* Count supported controls and allocate the controls array */2730 ncontrols = memweight(bmControls, bControlSize);2731 if (ncontrols == 0)2732 continue;2733 2734 entity->controls = kcalloc(ncontrols, sizeof(*ctrl),2735 GFP_KERNEL);2736 if (entity->controls == NULL)2737 return -ENOMEM;2738 entity->ncontrols = ncontrols;2739 2740 /* Initialize all supported controls */2741 ctrl = entity->controls;2742 for (i = 0; i < bControlSize * 8; ++i) {2743 if (uvc_test_bit(bmControls, i) == 0)2744 continue;2745 2746 ctrl->entity = entity;2747 ctrl->index = i;2748 2749 uvc_ctrl_init_ctrl(chain, ctrl);2750 ctrl++;2751 }2752 }2753 2754 return 0;2755}2756 2757int uvc_ctrl_init_device(struct uvc_device *dev)2758{2759 struct uvc_video_chain *chain;2760 int ret;2761 2762 INIT_WORK(&dev->async_ctrl.work, uvc_ctrl_status_event_work);2763 2764 list_for_each_entry(chain, &dev->chains, list) {2765 ret = uvc_ctrl_init_chain(chain);2766 if (ret)2767 return ret;2768 }2769 2770 return 0;2771}2772 2773/*2774 * Cleanup device controls.2775 */2776static void uvc_ctrl_cleanup_mappings(struct uvc_device *dev,2777 struct uvc_control *ctrl)2778{2779 struct uvc_control_mapping *mapping, *nm;2780 2781 list_for_each_entry_safe(mapping, nm, &ctrl->info.mappings, list) {2782 list_del(&mapping->list);2783 kfree(mapping->menu_names);2784 kfree(mapping->menu_mapping);2785 kfree(mapping->name);2786 kfree(mapping);2787 }2788}2789 2790void uvc_ctrl_cleanup_device(struct uvc_device *dev)2791{2792 struct uvc_entity *entity;2793 unsigned int i;2794 2795 /* Can be uninitialized if we are aborting on probe error. */2796 if (dev->async_ctrl.work.func)2797 cancel_work_sync(&dev->async_ctrl.work);2798 2799 /* Free controls and control mappings for all entities. */2800 list_for_each_entry(entity, &dev->entities, list) {2801 for (i = 0; i < entity->ncontrols; ++i) {2802 struct uvc_control *ctrl = &entity->controls[i];2803 2804 if (!ctrl->initialized)2805 continue;2806 2807 uvc_ctrl_cleanup_mappings(dev, ctrl);2808 kfree(ctrl->uvc_data);2809 }2810 2811 kfree(entity->controls);2812 }2813}2814