Lines Matching +full:data +full:- +full:mapping
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * uvc_ctrl.c -- USB Video Class driver - Controls
5 * Copyright (C) 2005-2010
20 #include <media/v4l2-ctrls.h>
21 #include <media/v4l2-uvc.h>
33 /* ------------------------------------------------------------------------
380 static s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, in uvc_ctrl_get_zoom() argument
381 u8 query, const u8 *data) in uvc_ctrl_get_zoom() argument
383 s8 zoom = (s8)data[0]; in uvc_ctrl_get_zoom()
387 return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]); in uvc_ctrl_get_zoom()
394 return data[2]; in uvc_ctrl_get_zoom()
398 static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping, in uvc_ctrl_set_zoom() argument
399 s32 value, u8 *data) in uvc_ctrl_set_zoom() argument
401 data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff; in uvc_ctrl_set_zoom()
402 data[2] = min((int)abs(value), 0xff); in uvc_ctrl_set_zoom()
405 static s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, in uvc_ctrl_get_rel_speed() argument
406 u8 query, const u8 *data) in uvc_ctrl_get_rel_speed() argument
408 unsigned int first = mapping->offset / 8; in uvc_ctrl_get_rel_speed()
409 s8 rel = (s8)data[first]; in uvc_ctrl_get_rel_speed()
413 return (rel == 0) ? 0 : (rel > 0 ? data[first+1] in uvc_ctrl_get_rel_speed()
414 : -data[first+1]); in uvc_ctrl_get_rel_speed()
416 return -data[first+1]; in uvc_ctrl_get_rel_speed()
421 return data[first+1]; in uvc_ctrl_get_rel_speed()
425 static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping, in uvc_ctrl_set_rel_speed() argument
426 s32 value, u8 *data) in uvc_ctrl_set_rel_speed() argument
428 unsigned int first = mapping->offset / 8; in uvc_ctrl_set_rel_speed()
430 data[first] = value == 0 ? 0 : (value > 0) ? 1 : 0xff; in uvc_ctrl_set_rel_speed()
431 data[first+1] = min_t(int, abs(value), 0xff); in uvc_ctrl_set_rel_speed()
734 .menu_count = ARRAY_SIZE(power_line_frequency_controls) - 1,
752 /* ------------------------------------------------------------------------
758 return ctrl->uvc_data + id * ctrl->info.size; in uvc_ctrl_data()
761 static inline int uvc_test_bit(const u8 *data, int bit) in uvc_test_bit() argument
763 return (data[bit >> 3] >> (bit & 7)) & 1; in uvc_test_bit()
766 static inline void uvc_clear_bit(u8 *data, int bit) in uvc_clear_bit() argument
768 data[bit >> 3] &= ~(1 << (bit & 7)); in uvc_clear_bit()
772 * Extract the bit string specified by mapping->offset and mapping->size
773 * from the little-endian data stored at 'data' and return the result as
774 * a signed 32bit integer. Sign extension will be performed if the mapping
775 * references a signed data type.
777 static s32 uvc_get_le_value(struct uvc_control_mapping *mapping, in uvc_get_le_value() argument
778 u8 query, const u8 *data) in uvc_get_le_value() argument
780 int bits = mapping->size; in uvc_get_le_value()
781 int offset = mapping->offset; in uvc_get_le_value()
785 data += offset / 8; in uvc_get_le_value()
787 mask = ((1LL << bits) - 1) << offset; in uvc_get_le_value()
790 u8 byte = *data & mask; in uvc_get_le_value()
791 value |= offset > 0 ? (byte >> offset) : (byte << (-offset)); in uvc_get_le_value()
792 bits -= 8 - (offset > 0 ? offset : 0); in uvc_get_le_value()
796 offset -= 8; in uvc_get_le_value()
797 mask = (1 << bits) - 1; in uvc_get_le_value()
798 data++; in uvc_get_le_value()
801 /* Sign-extend the value if needed. */ in uvc_get_le_value()
802 if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) in uvc_get_le_value()
803 value |= -(value & (1 << (mapping->size - 1))); in uvc_get_le_value()
809 * Set the bit string specified by mapping->offset and mapping->size
810 * in the little-endian data stored at 'data' to the value 'value'.
812 static void uvc_set_le_value(struct uvc_control_mapping *mapping, in uvc_set_le_value() argument
813 s32 value, u8 *data) in uvc_set_le_value() argument
815 int bits = mapping->size; in uvc_set_le_value()
816 int offset = mapping->offset; in uvc_set_le_value()
822 * triggered. UVC devices however want to see a 1 written -> override in uvc_set_le_value()
825 if (mapping->v4l2_type == V4L2_CTRL_TYPE_BUTTON) in uvc_set_le_value()
826 value = -1; in uvc_set_le_value()
828 data += offset / 8; in uvc_set_le_value()
831 for (; bits > 0; data++) { in uvc_set_le_value()
832 mask = ((1LL << bits) - 1) << offset; in uvc_set_le_value()
833 *data = (*data & ~mask) | ((value << offset) & mask); in uvc_set_le_value()
835 bits -= 8 - offset; in uvc_set_le_value()
840 /* ------------------------------------------------------------------------
847 return memcmp(entity->guid, guid, sizeof(entity->guid)) == 0; in uvc_entity_match_guid()
850 /* ------------------------------------------------------------------------
855 struct uvc_control_mapping **mapping, struct uvc_control **control, in __uvc_find_control() argument
865 for (i = 0; i < entity->ncontrols; ++i) { in __uvc_find_control()
866 ctrl = &entity->controls[i]; in __uvc_find_control()
867 if (!ctrl->initialized) in __uvc_find_control()
870 list_for_each_entry(map, &ctrl->info.mappings, list) { in __uvc_find_control()
871 if ((map->id == v4l2_id) && !next) { in __uvc_find_control()
873 *mapping = map; in __uvc_find_control()
877 if ((*mapping == NULL || (*mapping)->id > map->id) && in __uvc_find_control()
878 (map->id > v4l2_id) && next) { in __uvc_find_control()
880 *mapping = map; in __uvc_find_control()
887 u32 v4l2_id, struct uvc_control_mapping **mapping) in uvc_find_control() argument
893 *mapping = NULL; in uvc_find_control()
899 list_for_each_entry(entity, &chain->entities, chain) { in uvc_find_control()
900 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); in uvc_find_control()
906 uvc_dbg(chain->dev, CONTROL, "Control 0x%08x not found\n", in uvc_find_control()
917 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) { in uvc_ctrl_populate_cache()
918 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, in uvc_ctrl_populate_cache()
919 chain->dev->intfnum, ctrl->info.selector, in uvc_ctrl_populate_cache()
921 ctrl->info.size); in uvc_ctrl_populate_cache()
926 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) { in uvc_ctrl_populate_cache()
927 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, in uvc_ctrl_populate_cache()
928 chain->dev->intfnum, ctrl->info.selector, in uvc_ctrl_populate_cache()
930 ctrl->info.size); in uvc_ctrl_populate_cache()
934 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) { in uvc_ctrl_populate_cache()
935 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, in uvc_ctrl_populate_cache()
936 chain->dev->intfnum, ctrl->info.selector, in uvc_ctrl_populate_cache()
938 ctrl->info.size); in uvc_ctrl_populate_cache()
942 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) { in uvc_ctrl_populate_cache()
943 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, in uvc_ctrl_populate_cache()
944 chain->dev->intfnum, ctrl->info.selector, in uvc_ctrl_populate_cache()
946 ctrl->info.size); in uvc_ctrl_populate_cache()
948 if (UVC_ENTITY_TYPE(ctrl->entity) != in uvc_ctrl_populate_cache()
957 uvc_warn_once(chain->dev, UVC_WARN_XU_GET_RES, in uvc_ctrl_populate_cache()
958 "UVC non compliance - GET_RES failed on " in uvc_ctrl_populate_cache()
961 ctrl->info.size); in uvc_ctrl_populate_cache()
965 ctrl->cached = 1; in uvc_ctrl_populate_cache()
969 static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping, in __uvc_ctrl_get_value() argument
970 const u8 *data) in __uvc_ctrl_get_value() argument
972 s32 value = mapping->get(mapping, UVC_GET_CUR, data); in __uvc_ctrl_get_value()
974 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { in __uvc_ctrl_get_value()
975 const struct uvc_menu_info *menu = mapping->menu_info; in __uvc_ctrl_get_value()
978 for (i = 0; i < mapping->menu_count; ++i, ++menu) { in __uvc_ctrl_get_value()
979 if (menu->value == value) { in __uvc_ctrl_get_value()
992 u8 *data; in __uvc_ctrl_load_cur() local
995 if (ctrl->loaded) in __uvc_ctrl_load_cur()
998 data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT); in __uvc_ctrl_load_cur()
1000 if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) { in __uvc_ctrl_load_cur()
1001 memset(data, 0, ctrl->info.size); in __uvc_ctrl_load_cur()
1002 ctrl->loaded = 1; in __uvc_ctrl_load_cur()
1007 if (ctrl->entity->get_cur) in __uvc_ctrl_load_cur()
1008 ret = ctrl->entity->get_cur(chain->dev, ctrl->entity, in __uvc_ctrl_load_cur()
1009 ctrl->info.selector, data, in __uvc_ctrl_load_cur()
1010 ctrl->info.size); in __uvc_ctrl_load_cur()
1012 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, in __uvc_ctrl_load_cur()
1013 ctrl->entity->id, chain->dev->intfnum, in __uvc_ctrl_load_cur()
1014 ctrl->info.selector, data, in __uvc_ctrl_load_cur()
1015 ctrl->info.size); in __uvc_ctrl_load_cur()
1020 ctrl->loaded = 1; in __uvc_ctrl_load_cur()
1027 struct uvc_control_mapping *mapping, in __uvc_ctrl_get() argument
1032 if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) in __uvc_ctrl_get()
1033 return -EACCES; in __uvc_ctrl_get()
1039 *value = __uvc_ctrl_get_value(mapping, in __uvc_ctrl_get()
1054 if (!(chain->ctrl_class_bitmap & BIT(i))) in __uvc_query_v4l2_class()
1066 return -ENODEV; in __uvc_query_v4l2_class()
1076 return -ENODEV; in uvc_query_v4l2_class()
1079 v4l2_ctrl->id = uvc_control_classes[idx]; in uvc_query_v4l2_class()
1080 strscpy(v4l2_ctrl->name, v4l2_ctrl_get_name(v4l2_ctrl->id), in uvc_query_v4l2_class()
1081 sizeof(v4l2_ctrl->name)); in uvc_query_v4l2_class()
1082 v4l2_ctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS; in uvc_query_v4l2_class()
1083 v4l2_ctrl->flags = V4L2_CTRL_FLAG_WRITE_ONLY in uvc_query_v4l2_class()
1091 struct uvc_control_mapping *mapping; in uvc_ctrl_is_accessible() local
1095 return -EACCES; in uvc_ctrl_is_accessible()
1097 ctrl = uvc_find_control(chain, v4l2_id, &mapping); in uvc_ctrl_is_accessible()
1099 return -EINVAL; in uvc_ctrl_is_accessible()
1101 if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) && read) in uvc_ctrl_is_accessible()
1102 return -EACCES; in uvc_ctrl_is_accessible()
1104 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) && !read) in uvc_ctrl_is_accessible()
1105 return -EACCES; in uvc_ctrl_is_accessible()
1114 if (map->name) in uvc_map_get_name()
1115 return map->name; in uvc_map_get_name()
1117 name = v4l2_ctrl_get_name(map->id); in uvc_map_get_name()
1126 struct uvc_control_mapping *mapping, in __uvc_query_v4l2_ctrl() argument
1135 v4l2_ctrl->id = mapping->id; in __uvc_query_v4l2_ctrl()
1136 v4l2_ctrl->type = mapping->v4l2_type; in __uvc_query_v4l2_ctrl()
1137 strscpy(v4l2_ctrl->name, uvc_map_get_name(mapping), in __uvc_query_v4l2_ctrl()
1138 sizeof(v4l2_ctrl->name)); in __uvc_query_v4l2_ctrl()
1139 v4l2_ctrl->flags = 0; in __uvc_query_v4l2_ctrl()
1141 if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) in __uvc_query_v4l2_ctrl()
1142 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; in __uvc_query_v4l2_ctrl()
1143 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) in __uvc_query_v4l2_ctrl()
1144 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in __uvc_query_v4l2_ctrl()
1146 if (mapping->master_id) in __uvc_query_v4l2_ctrl()
1147 __uvc_find_control(ctrl->entity, mapping->master_id, in __uvc_query_v4l2_ctrl()
1149 if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) { in __uvc_query_v4l2_ctrl()
1155 if (val != mapping->master_manual) in __uvc_query_v4l2_ctrl()
1156 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; in __uvc_query_v4l2_ctrl()
1159 if (!ctrl->cached) { in __uvc_query_v4l2_ctrl()
1165 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) { in __uvc_query_v4l2_ctrl()
1166 v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF, in __uvc_query_v4l2_ctrl()
1170 switch (mapping->v4l2_type) { in __uvc_query_v4l2_ctrl()
1172 v4l2_ctrl->minimum = 0; in __uvc_query_v4l2_ctrl()
1173 v4l2_ctrl->maximum = mapping->menu_count - 1; in __uvc_query_v4l2_ctrl()
1174 v4l2_ctrl->step = 1; in __uvc_query_v4l2_ctrl()
1176 menu = mapping->menu_info; in __uvc_query_v4l2_ctrl()
1177 for (i = 0; i < mapping->menu_count; ++i, ++menu) { in __uvc_query_v4l2_ctrl()
1178 if (menu->value == v4l2_ctrl->default_value) { in __uvc_query_v4l2_ctrl()
1179 v4l2_ctrl->default_value = i; in __uvc_query_v4l2_ctrl()
1187 v4l2_ctrl->minimum = 0; in __uvc_query_v4l2_ctrl()
1188 v4l2_ctrl->maximum = 1; in __uvc_query_v4l2_ctrl()
1189 v4l2_ctrl->step = 1; in __uvc_query_v4l2_ctrl()
1193 v4l2_ctrl->minimum = 0; in __uvc_query_v4l2_ctrl()
1194 v4l2_ctrl->maximum = 0; in __uvc_query_v4l2_ctrl()
1195 v4l2_ctrl->step = 0; in __uvc_query_v4l2_ctrl()
1202 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) in __uvc_query_v4l2_ctrl()
1203 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, in __uvc_query_v4l2_ctrl()
1206 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) in __uvc_query_v4l2_ctrl()
1207 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, in __uvc_query_v4l2_ctrl()
1210 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) in __uvc_query_v4l2_ctrl()
1211 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, in __uvc_query_v4l2_ctrl()
1221 struct uvc_control_mapping *mapping; in uvc_query_v4l2_ctrl() local
1224 ret = mutex_lock_interruptible(&chain->ctrl_mutex); in uvc_query_v4l2_ctrl()
1226 return -ERESTARTSYS; in uvc_query_v4l2_ctrl()
1229 if (!(v4l2_ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL)) { in uvc_query_v4l2_ctrl()
1230 ret = uvc_query_v4l2_class(chain, v4l2_ctrl->id, 0, v4l2_ctrl); in uvc_query_v4l2_ctrl()
1235 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); in uvc_query_v4l2_ctrl()
1237 ret = -EINVAL; in uvc_query_v4l2_ctrl()
1246 if (v4l2_ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL) { in uvc_query_v4l2_ctrl()
1247 ret = uvc_query_v4l2_class(chain, v4l2_ctrl->id, mapping->id, in uvc_query_v4l2_ctrl()
1253 ret = __uvc_query_v4l2_ctrl(chain, ctrl, mapping, v4l2_ctrl); in uvc_query_v4l2_ctrl()
1255 mutex_unlock(&chain->ctrl_mutex); in uvc_query_v4l2_ctrl()
1260 * Mapping V4L2 controls to UVC controls can be straightforward if done well.
1272 struct uvc_control_mapping *mapping; in uvc_query_v4l2_menu() local
1274 u32 index = query_menu->index; in uvc_query_v4l2_menu()
1275 u32 id = query_menu->id; in uvc_query_v4l2_menu()
1279 query_menu->id = id; in uvc_query_v4l2_menu()
1280 query_menu->index = index; in uvc_query_v4l2_menu()
1282 ret = mutex_lock_interruptible(&chain->ctrl_mutex); in uvc_query_v4l2_menu()
1284 return -ERESTARTSYS; in uvc_query_v4l2_menu()
1286 ctrl = uvc_find_control(chain, query_menu->id, &mapping); in uvc_query_v4l2_menu()
1287 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) { in uvc_query_v4l2_menu()
1288 ret = -EINVAL; in uvc_query_v4l2_menu()
1292 if (query_menu->index >= mapping->menu_count) { in uvc_query_v4l2_menu()
1293 ret = -EINVAL; in uvc_query_v4l2_menu()
1297 menu_info = &mapping->menu_info[query_menu->index]; in uvc_query_v4l2_menu()
1299 if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && in uvc_query_v4l2_menu()
1300 (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) { in uvc_query_v4l2_menu()
1303 if (!ctrl->cached) { in uvc_query_v4l2_menu()
1309 bitmap = mapping->get(mapping, UVC_GET_RES, in uvc_query_v4l2_menu()
1311 if (!(bitmap & menu_info->value)) { in uvc_query_v4l2_menu()
1312 ret = -EINVAL; in uvc_query_v4l2_menu()
1317 strscpy(query_menu->name, menu_info->name, sizeof(query_menu->name)); in uvc_query_v4l2_menu()
1320 mutex_unlock(&chain->ctrl_mutex); in uvc_query_v4l2_menu()
1324 /* --------------------------------------------------------------------------
1331 struct uvc_control_mapping *mapping, in uvc_ctrl_fill_event() argument
1336 __uvc_query_v4l2_ctrl(chain, ctrl, mapping, &v4l2_ctrl); in uvc_ctrl_fill_event()
1339 ev->type = V4L2_EVENT_CTRL; in uvc_ctrl_fill_event()
1340 ev->id = v4l2_ctrl.id; in uvc_ctrl_fill_event()
1341 ev->u.ctrl.value = value; in uvc_ctrl_fill_event()
1342 ev->u.ctrl.changes = changes; in uvc_ctrl_fill_event()
1343 ev->u.ctrl.type = v4l2_ctrl.type; in uvc_ctrl_fill_event()
1344 ev->u.ctrl.flags = v4l2_ctrl.flags; in uvc_ctrl_fill_event()
1345 ev->u.ctrl.minimum = v4l2_ctrl.minimum; in uvc_ctrl_fill_event()
1346 ev->u.ctrl.maximum = v4l2_ctrl.maximum; in uvc_ctrl_fill_event()
1347 ev->u.ctrl.step = v4l2_ctrl.step; in uvc_ctrl_fill_event()
1348 ev->u.ctrl.default_value = v4l2_ctrl.default_value; in uvc_ctrl_fill_event()
1355 * @handle can be NULL for asynchronous events related to auto-update controls,
1360 struct uvc_control_mapping *mapping, s32 value, u32 changes) in uvc_ctrl_send_event() argument
1362 struct v4l2_fh *originator = handle ? &handle->vfh : NULL; in uvc_ctrl_send_event()
1366 if (list_empty(&mapping->ev_subs)) in uvc_ctrl_send_event()
1369 uvc_ctrl_fill_event(chain, &ev, ctrl, mapping, value, changes); in uvc_ctrl_send_event()
1371 list_for_each_entry(sev, &mapping->ev_subs, node) { in uvc_ctrl_send_event()
1372 if (sev->fh != originator || in uvc_ctrl_send_event()
1373 (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK) || in uvc_ctrl_send_event()
1375 v4l2_event_queue_fh(sev->fh, &ev); in uvc_ctrl_send_event()
1382 * generated the event and may be NULL for auto-update events.
1387 struct uvc_control_mapping *mapping = NULL; in uvc_ctrl_send_slave_event() local
1392 __uvc_find_control(master->entity, slave_id, &mapping, &ctrl, 0); in uvc_ctrl_send_slave_event()
1396 if (__uvc_ctrl_get(chain, ctrl, mapping, &val) == 0) in uvc_ctrl_send_slave_event()
1399 uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); in uvc_ctrl_send_slave_event()
1403 struct uvc_control *ctrl, const u8 *data) in uvc_ctrl_status_event() argument
1405 struct uvc_control_mapping *mapping; in uvc_ctrl_status_event() local
1409 mutex_lock(&chain->ctrl_mutex); in uvc_ctrl_status_event()
1411 handle = ctrl->handle; in uvc_ctrl_status_event()
1412 ctrl->handle = NULL; in uvc_ctrl_status_event()
1414 list_for_each_entry(mapping, &ctrl->info.mappings, list) { in uvc_ctrl_status_event()
1415 s32 value = __uvc_ctrl_get_value(mapping, data); in uvc_ctrl_status_event()
1418 * handle may be NULL here if the device sends auto-update in uvc_ctrl_status_event()
1421 for (i = 0; i < ARRAY_SIZE(mapping->slave_ids); ++i) { in uvc_ctrl_status_event()
1422 if (!mapping->slave_ids[i]) in uvc_ctrl_status_event()
1426 mapping->slave_ids[i]); in uvc_ctrl_status_event()
1429 uvc_ctrl_send_event(chain, handle, ctrl, mapping, value, in uvc_ctrl_status_event()
1433 mutex_unlock(&chain->ctrl_mutex); in uvc_ctrl_status_event()
1440 struct uvc_ctrl_work *w = &dev->async_ctrl; in uvc_ctrl_status_event_work()
1443 uvc_ctrl_status_event(w->chain, w->ctrl, w->data); in uvc_ctrl_status_event_work()
1446 w->urb->interval = dev->int_ep->desc.bInterval; in uvc_ctrl_status_event_work()
1447 ret = usb_submit_urb(w->urb, GFP_KERNEL); in uvc_ctrl_status_event_work()
1449 dev_err(&dev->udev->dev, in uvc_ctrl_status_event_work()
1454 struct uvc_control *ctrl, const u8 *data) in uvc_ctrl_status_event_async() argument
1456 struct uvc_device *dev = chain->dev; in uvc_ctrl_status_event_async()
1457 struct uvc_ctrl_work *w = &dev->async_ctrl; in uvc_ctrl_status_event_async()
1459 if (list_empty(&ctrl->info.mappings)) { in uvc_ctrl_status_event_async()
1460 ctrl->handle = NULL; in uvc_ctrl_status_event_async()
1464 w->data = data; in uvc_ctrl_status_event_async()
1465 w->urb = urb; in uvc_ctrl_status_event_async()
1466 w->chain = chain; in uvc_ctrl_status_event_async()
1467 w->ctrl = ctrl; in uvc_ctrl_status_event_async()
1469 schedule_work(&w->work); in uvc_ctrl_status_event_async()
1490 struct uvc_control_mapping *mapping; in uvc_ctrl_send_events() local
1497 ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); in uvc_ctrl_send_events()
1499 if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) in uvc_ctrl_send_events()
1503 for (j = 0; j < ARRAY_SIZE(mapping->slave_ids); ++j) { in uvc_ctrl_send_events()
1504 u32 slave_id = mapping->slave_ids[j]; in uvc_ctrl_send_events()
1517 uvc_ctrl_send_slave_event(handle->chain, handle, ctrl, in uvc_ctrl_send_events()
1525 if (mapping->master_id && in uvc_ctrl_send_events()
1527 mapping->master_id)) in uvc_ctrl_send_events()
1530 uvc_ctrl_send_event(handle->chain, handle, ctrl, mapping, in uvc_ctrl_send_events()
1537 struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh); in uvc_ctrl_add_event()
1538 struct uvc_control_mapping *mapping; in uvc_ctrl_add_event() local
1542 ret = mutex_lock_interruptible(&handle->chain->ctrl_mutex); in uvc_ctrl_add_event()
1544 return -ERESTARTSYS; in uvc_ctrl_add_event()
1546 if (__uvc_query_v4l2_class(handle->chain, sev->id, 0) >= 0) { in uvc_ctrl_add_event()
1551 ctrl = uvc_find_control(handle->chain, sev->id, &mapping); in uvc_ctrl_add_event()
1553 ret = -EINVAL; in uvc_ctrl_add_event()
1557 list_add_tail(&sev->node, &mapping->ev_subs); in uvc_ctrl_add_event()
1558 if (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) { in uvc_ctrl_add_event()
1563 if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0) in uvc_ctrl_add_event()
1566 uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val, in uvc_ctrl_add_event()
1572 sev->elems = elems; in uvc_ctrl_add_event()
1573 v4l2_event_queue_fh(sev->fh, &ev); in uvc_ctrl_add_event()
1577 mutex_unlock(&handle->chain->ctrl_mutex); in uvc_ctrl_add_event()
1583 struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh); in uvc_ctrl_del_event()
1585 mutex_lock(&handle->chain->ctrl_mutex); in uvc_ctrl_del_event()
1586 if (__uvc_query_v4l2_class(handle->chain, sev->id, 0) >= 0) in uvc_ctrl_del_event()
1588 list_del(&sev->node); in uvc_ctrl_del_event()
1590 mutex_unlock(&handle->chain->ctrl_mutex); in uvc_ctrl_del_event()
1600 /* --------------------------------------------------------------------------
1609 * When setting a control, the new value is stored in the control data field
1612 * value is loaded from the hardware before storing the new value in the data
1619 * cleared. When reverting controls, the control data field
1626 return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0; in uvc_ctrl_begin()
1639 for (i = 0; i < entity->ncontrols; ++i) { in uvc_ctrl_commit_entity()
1640 ctrl = &entity->controls[i]; in uvc_ctrl_commit_entity()
1641 if (!ctrl->initialized) in uvc_ctrl_commit_entity()
1645 * Reset the loaded flag for auto-update controls that were in uvc_ctrl_commit_entity()
1647 * uvc_ctrl_get from using the cached value, and for write-only in uvc_ctrl_commit_entity()
1651 if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE || in uvc_ctrl_commit_entity()
1652 !(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) in uvc_ctrl_commit_entity()
1653 ctrl->loaded = 0; in uvc_ctrl_commit_entity()
1655 if (!ctrl->dirty) in uvc_ctrl_commit_entity()
1659 ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id, in uvc_ctrl_commit_entity()
1660 dev->intfnum, ctrl->info.selector, in uvc_ctrl_commit_entity()
1662 ctrl->info.size); in uvc_ctrl_commit_entity()
1669 ctrl->info.size); in uvc_ctrl_commit_entity()
1671 ctrl->dirty = 0; in uvc_ctrl_commit_entity()
1687 struct uvc_control_mapping *mapping = NULL; in uvc_ctrl_find_ctrl_idx() local
1692 return ctrls->count; in uvc_ctrl_find_ctrl_idx()
1694 for (i = 0; i < ctrls->count; i++) { in uvc_ctrl_find_ctrl_idx()
1695 __uvc_find_control(entity, ctrls->controls[i].id, &mapping, in uvc_ctrl_find_ctrl_idx()
1701 return ctrls->count; in uvc_ctrl_find_ctrl_idx()
1707 struct uvc_video_chain *chain = handle->chain; in __uvc_ctrl_commit()
1713 list_for_each_entry(entity, &chain->entities, chain) { in __uvc_ctrl_commit()
1714 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback, in __uvc_ctrl_commit()
1721 uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count); in __uvc_ctrl_commit()
1724 ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls, in __uvc_ctrl_commit()
1726 mutex_unlock(&chain->ctrl_mutex); in __uvc_ctrl_commit()
1734 struct uvc_control_mapping *mapping; in uvc_ctrl_get() local
1736 if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0) in uvc_ctrl_get()
1737 return -EACCES; in uvc_ctrl_get()
1739 ctrl = uvc_find_control(chain, xctrl->id, &mapping); in uvc_ctrl_get()
1741 return -EINVAL; in uvc_ctrl_get()
1743 return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value); in uvc_ctrl_get()
1749 struct uvc_video_chain *chain = handle->chain; in uvc_ctrl_set()
1751 struct uvc_control_mapping *mapping; in uvc_ctrl_set() local
1758 if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0) in uvc_ctrl_set()
1759 return -EACCES; in uvc_ctrl_set()
1761 ctrl = uvc_find_control(chain, xctrl->id, &mapping); in uvc_ctrl_set()
1763 return -EINVAL; in uvc_ctrl_set()
1764 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) in uvc_ctrl_set()
1765 return -EACCES; in uvc_ctrl_set()
1768 switch (mapping->v4l2_type) { in uvc_ctrl_set()
1770 if (!ctrl->cached) { in uvc_ctrl_set()
1776 min = mapping->get(mapping, UVC_GET_MIN, in uvc_ctrl_set()
1778 max = mapping->get(mapping, UVC_GET_MAX, in uvc_ctrl_set()
1780 step = mapping->get(mapping, UVC_GET_RES, in uvc_ctrl_set()
1785 xctrl->value = min + DIV_ROUND_CLOSEST((u32)(xctrl->value - min), in uvc_ctrl_set()
1787 if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) in uvc_ctrl_set()
1788 xctrl->value = clamp(xctrl->value, min, max); in uvc_ctrl_set()
1790 xctrl->value = clamp_t(u32, xctrl->value, min, max); in uvc_ctrl_set()
1791 value = xctrl->value; in uvc_ctrl_set()
1795 xctrl->value = clamp(xctrl->value, 0, 1); in uvc_ctrl_set()
1796 value = xctrl->value; in uvc_ctrl_set()
1800 if (xctrl->value < 0 || xctrl->value >= mapping->menu_count) in uvc_ctrl_set()
1801 return -ERANGE; in uvc_ctrl_set()
1802 value = mapping->menu_info[xctrl->value].value; in uvc_ctrl_set()
1808 if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && in uvc_ctrl_set()
1809 (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) { in uvc_ctrl_set()
1810 if (!ctrl->cached) { in uvc_ctrl_set()
1816 step = mapping->get(mapping, UVC_GET_RES, in uvc_ctrl_set()
1819 return -EINVAL; in uvc_ctrl_set()
1825 value = xctrl->value; in uvc_ctrl_set()
1830 * If the mapping doesn't span the whole UVC control, the current value in uvc_ctrl_set()
1831 * needs to be loaded from the device to perform the read-modify-write in uvc_ctrl_set()
1834 if ((ctrl->info.size * 8) != mapping->size) { in uvc_ctrl_set()
1841 if (!ctrl->dirty) { in uvc_ctrl_set()
1844 ctrl->info.size); in uvc_ctrl_set()
1847 mapping->set(mapping, value, in uvc_ctrl_set()
1850 if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) in uvc_ctrl_set()
1851 ctrl->handle = handle; in uvc_ctrl_set()
1853 ctrl->dirty = 1; in uvc_ctrl_set()
1854 ctrl->modified = 1; in uvc_ctrl_set()
1858 /* --------------------------------------------------------------------------
1869 u8 *data; in uvc_ctrl_get_flags() local
1872 data = kmalloc(1, GFP_KERNEL); in uvc_ctrl_get_flags()
1873 if (data == NULL) in uvc_ctrl_get_flags()
1874 return -ENOMEM; in uvc_ctrl_get_flags()
1876 if (ctrl->entity->get_info) in uvc_ctrl_get_flags()
1877 ret = ctrl->entity->get_info(dev, ctrl->entity, in uvc_ctrl_get_flags()
1878 ctrl->info.selector, data); in uvc_ctrl_get_flags()
1880 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, in uvc_ctrl_get_flags()
1881 dev->intfnum, info->selector, data, 1); in uvc_ctrl_get_flags()
1883 info->flags |= (data[0] & UVC_CONTROL_CAP_GET ? in uvc_ctrl_get_flags()
1885 | (data[0] & UVC_CONTROL_CAP_SET ? in uvc_ctrl_get_flags()
1887 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? in uvc_ctrl_get_flags()
1889 | (data[0] & UVC_CONTROL_CAP_ASYNCHRONOUS ? in uvc_ctrl_get_flags()
1892 kfree(data); in uvc_ctrl_get_flags()
1924 if (!usb_match_one_id(dev->intf, &fixups[i].id)) in uvc_ctrl_fixup_xu_info()
1927 if (fixups[i].entity == ctrl->entity->id && in uvc_ctrl_fixup_xu_info()
1928 fixups[i].selector == info->selector) { in uvc_ctrl_fixup_xu_info()
1929 info->flags = fixups[i].flags; in uvc_ctrl_fixup_xu_info()
1941 u8 *data; in uvc_ctrl_fill_xu_info() local
1944 data = kmalloc(2, GFP_KERNEL); in uvc_ctrl_fill_xu_info()
1945 if (data == NULL) in uvc_ctrl_fill_xu_info()
1946 return -ENOMEM; in uvc_ctrl_fill_xu_info()
1948 memcpy(info->entity, ctrl->entity->guid, sizeof(info->entity)); in uvc_ctrl_fill_xu_info()
1949 info->index = ctrl->index; in uvc_ctrl_fill_xu_info()
1950 info->selector = ctrl->index + 1; in uvc_ctrl_fill_xu_info()
1953 ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, dev->intfnum, in uvc_ctrl_fill_xu_info()
1954 info->selector, data, 2); in uvc_ctrl_fill_xu_info()
1958 info->entity, info->selector, ret); in uvc_ctrl_fill_xu_info()
1962 info->size = le16_to_cpup((__le16 *)data); in uvc_ctrl_fill_xu_info()
1964 info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX in uvc_ctrl_fill_xu_info()
1971 info->entity, info->selector, ret); in uvc_ctrl_fill_xu_info()
1979 info->entity, info->selector, info->size, in uvc_ctrl_fill_xu_info()
1980 (info->flags & UVC_CTRL_FLAG_GET_CUR) ? 1 : 0, in uvc_ctrl_fill_xu_info()
1981 (info->flags & UVC_CTRL_FLAG_SET_CUR) ? 1 : 0, in uvc_ctrl_fill_xu_info()
1982 (info->flags & UVC_CTRL_FLAG_AUTO_UPDATE) ? 1 : 0); in uvc_ctrl_fill_xu_info()
1985 kfree(data); in uvc_ctrl_fill_xu_info()
1998 if (ctrl->initialized) in uvc_ctrl_init_xu_ctrl()
2009 info.entity, info.selector, dev->udev->devpath, in uvc_ctrl_init_xu_ctrl()
2010 ctrl->entity->id); in uvc_ctrl_init_xu_ctrl()
2024 u8 *data = NULL; in uvc_xu_ctrl_query() local
2029 list_for_each_entry(entity, &chain->entities, chain) { in uvc_xu_ctrl_query()
2031 entity->id == xqry->unit) { in uvc_xu_ctrl_query()
2038 uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n", in uvc_xu_ctrl_query()
2039 xqry->unit); in uvc_xu_ctrl_query()
2040 return -ENOENT; in uvc_xu_ctrl_query()
2045 for (i = 0; i < entity->ncontrols; ++i) { in uvc_xu_ctrl_query()
2046 ctrl = &entity->controls[i]; in uvc_xu_ctrl_query()
2047 if (ctrl->index == xqry->selector - 1) { in uvc_xu_ctrl_query()
2054 uvc_dbg(chain->dev, CONTROL, "Control %pUl/%u not found\n", in uvc_xu_ctrl_query()
2055 entity->guid, xqry->selector); in uvc_xu_ctrl_query()
2056 return -ENOENT; in uvc_xu_ctrl_query()
2059 if (mutex_lock_interruptible(&chain->ctrl_mutex)) in uvc_xu_ctrl_query()
2060 return -ERESTARTSYS; in uvc_xu_ctrl_query()
2062 ret = uvc_ctrl_init_xu_ctrl(chain->dev, ctrl); in uvc_xu_ctrl_query()
2064 ret = -ENOENT; in uvc_xu_ctrl_query()
2070 size = ctrl->info.size; in uvc_xu_ctrl_query()
2072 switch (xqry->query) { in uvc_xu_ctrl_query()
2098 ret = -EINVAL; in uvc_xu_ctrl_query()
2102 if (size != xqry->size) { in uvc_xu_ctrl_query()
2103 ret = -ENOBUFS; in uvc_xu_ctrl_query()
2107 if (reqflags && !(ctrl->info.flags & reqflags)) { in uvc_xu_ctrl_query()
2108 ret = -EBADRQC; in uvc_xu_ctrl_query()
2112 data = kmalloc(size, GFP_KERNEL); in uvc_xu_ctrl_query()
2113 if (data == NULL) { in uvc_xu_ctrl_query()
2114 ret = -ENOMEM; in uvc_xu_ctrl_query()
2118 if (xqry->query == UVC_SET_CUR && in uvc_xu_ctrl_query()
2119 copy_from_user(data, xqry->data, size)) { in uvc_xu_ctrl_query()
2120 ret = -EFAULT; in uvc_xu_ctrl_query()
2124 ret = uvc_query_ctrl(chain->dev, xqry->query, xqry->unit, in uvc_xu_ctrl_query()
2125 chain->dev->intfnum, xqry->selector, data, size); in uvc_xu_ctrl_query()
2129 if (xqry->query != UVC_SET_CUR && in uvc_xu_ctrl_query()
2130 copy_to_user(xqry->data, data, size)) in uvc_xu_ctrl_query()
2131 ret = -EFAULT; in uvc_xu_ctrl_query()
2133 kfree(data); in uvc_xu_ctrl_query()
2134 mutex_unlock(&chain->ctrl_mutex); in uvc_xu_ctrl_query()
2138 /* --------------------------------------------------------------------------
2147 * - Don't restore modified controls that are back to their default value.
2148 * - Handle restore order (Auto-Exposure Mode should be restored before
2159 list_for_each_entry(entity, &dev->entities, list) { in uvc_ctrl_restore_values()
2161 for (i = 0; i < entity->ncontrols; ++i) { in uvc_ctrl_restore_values()
2162 ctrl = &entity->controls[i]; in uvc_ctrl_restore_values()
2164 if (!ctrl->initialized || !ctrl->modified || in uvc_ctrl_restore_values()
2165 (ctrl->info.flags & UVC_CTRL_FLAG_RESTORE) == 0) in uvc_ctrl_restore_values()
2167 dev_dbg(&dev->udev->dev, in uvc_ctrl_restore_values()
2169 ctrl->info.entity, ctrl->info.index, in uvc_ctrl_restore_values()
2170 ctrl->info.selector); in uvc_ctrl_restore_values()
2171 ctrl->dirty = 1; in uvc_ctrl_restore_values()
2182 /* --------------------------------------------------------------------------
2183 * Control and mapping handling
2192 ctrl->info = *info; in uvc_ctrl_add_info()
2193 INIT_LIST_HEAD(&ctrl->info.mappings); in uvc_ctrl_add_info()
2196 ctrl->uvc_data = kzalloc(ctrl->info.size * UVC_CTRL_DATA_LAST + 1, in uvc_ctrl_add_info()
2198 if (!ctrl->uvc_data) in uvc_ctrl_add_info()
2199 return -ENOMEM; in uvc_ctrl_add_info()
2201 ctrl->initialized = 1; in uvc_ctrl_add_info()
2204 ctrl->info.entity, ctrl->info.selector, dev->udev->devpath, in uvc_ctrl_add_info()
2205 ctrl->entity->id); in uvc_ctrl_add_info()
2211 * Add a control mapping to a given control.
2214 struct uvc_control *ctrl, const struct uvc_control_mapping *mapping) in __uvc_ctrl_add_mapping() argument
2221 * Most mappings come from static kernel data and need to be duplicated. in __uvc_ctrl_add_mapping()
2225 map = kmemdup(mapping, sizeof(*mapping), GFP_KERNEL); in __uvc_ctrl_add_mapping()
2227 return -ENOMEM; in __uvc_ctrl_add_mapping()
2230 if (mapping->name) { in __uvc_ctrl_add_mapping()
2231 map->name = kstrdup(mapping->name, GFP_KERNEL); in __uvc_ctrl_add_mapping()
2232 if (!map->name) { in __uvc_ctrl_add_mapping()
2234 return -ENOMEM; in __uvc_ctrl_add_mapping()
2238 INIT_LIST_HEAD(&map->ev_subs); in __uvc_ctrl_add_mapping()
2240 size = sizeof(*mapping->menu_info) * mapping->menu_count; in __uvc_ctrl_add_mapping()
2241 map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL); in __uvc_ctrl_add_mapping()
2242 if (map->menu_info == NULL) { in __uvc_ctrl_add_mapping()
2243 kfree(map->name); in __uvc_ctrl_add_mapping()
2245 return -ENOMEM; in __uvc_ctrl_add_mapping()
2248 if (map->get == NULL) in __uvc_ctrl_add_mapping()
2249 map->get = uvc_get_le_value; in __uvc_ctrl_add_mapping()
2250 if (map->set == NULL) in __uvc_ctrl_add_mapping()
2251 map->set = uvc_set_le_value; in __uvc_ctrl_add_mapping()
2255 V4L2_CTRL_ID2WHICH(map->id)) { in __uvc_ctrl_add_mapping()
2256 chain->ctrl_class_bitmap |= BIT(i); in __uvc_ctrl_add_mapping()
2261 list_add_tail(&map->list, &ctrl->info.mappings); in __uvc_ctrl_add_mapping()
2262 uvc_dbg(chain->dev, CONTROL, "Adding mapping '%s' to control %pUl/%u\n", in __uvc_ctrl_add_mapping()
2263 uvc_map_get_name(map), ctrl->info.entity, in __uvc_ctrl_add_mapping()
2264 ctrl->info.selector); in __uvc_ctrl_add_mapping()
2270 const struct uvc_control_mapping *mapping) in uvc_ctrl_add_mapping() argument
2272 struct uvc_device *dev = chain->dev; in uvc_ctrl_add_mapping()
2279 if (mapping->id & ~V4L2_CTRL_ID_MASK) { in uvc_ctrl_add_mapping()
2281 "Can't add mapping '%s', control id 0x%08x is invalid\n", in uvc_ctrl_add_mapping()
2282 uvc_map_get_name(mapping), mapping->id); in uvc_ctrl_add_mapping()
2283 return -EINVAL; in uvc_ctrl_add_mapping()
2287 list_for_each_entry(entity, &chain->entities, chain) { in uvc_ctrl_add_mapping()
2291 !uvc_entity_match_guid(entity, mapping->entity)) in uvc_ctrl_add_mapping()
2294 for (i = 0; i < entity->ncontrols; ++i) { in uvc_ctrl_add_mapping()
2295 ctrl = &entity->controls[i]; in uvc_ctrl_add_mapping()
2296 if (ctrl->index == mapping->selector - 1) { in uvc_ctrl_add_mapping()
2306 return -ENOENT; in uvc_ctrl_add_mapping()
2308 if (mutex_lock_interruptible(&chain->ctrl_mutex)) in uvc_ctrl_add_mapping()
2309 return -ERESTARTSYS; in uvc_ctrl_add_mapping()
2314 ret = -ENOENT; in uvc_ctrl_add_mapping()
2318 /* Validate the user-provided bit-size and offset */ in uvc_ctrl_add_mapping()
2319 if (mapping->size > 32 || in uvc_ctrl_add_mapping()
2320 mapping->offset + mapping->size > ctrl->info.size * 8) { in uvc_ctrl_add_mapping()
2321 ret = -EINVAL; in uvc_ctrl_add_mapping()
2325 list_for_each_entry(map, &ctrl->info.mappings, list) { in uvc_ctrl_add_mapping()
2326 if (mapping->id == map->id) { in uvc_ctrl_add_mapping()
2328 "Can't add mapping '%s', control id 0x%08x already exists\n", in uvc_ctrl_add_mapping()
2329 uvc_map_get_name(mapping), mapping->id); in uvc_ctrl_add_mapping()
2330 ret = -EEXIST; in uvc_ctrl_add_mapping()
2336 if (atomic_inc_return(&dev->nmappings) > UVC_MAX_CONTROL_MAPPINGS) { in uvc_ctrl_add_mapping()
2337 atomic_dec(&dev->nmappings); in uvc_ctrl_add_mapping()
2339 "Can't add mapping '%s', maximum mappings count (%u) exceeded\n", in uvc_ctrl_add_mapping()
2340 uvc_map_get_name(mapping), UVC_MAX_CONTROL_MAPPINGS); in uvc_ctrl_add_mapping()
2341 ret = -ENOMEM; in uvc_ctrl_add_mapping()
2345 ret = __uvc_ctrl_add_mapping(chain, ctrl, mapping); in uvc_ctrl_add_mapping()
2347 atomic_dec(&dev->nmappings); in uvc_ctrl_add_mapping()
2350 mutex_unlock(&chain->ctrl_mutex); in uvc_ctrl_add_mapping()
2386 controls = entity->processing.bmControls; in uvc_ctrl_prune_entity()
2387 size = entity->processing.bControlSize; in uvc_ctrl_prune_entity()
2393 controls = entity->camera.bmControls; in uvc_ctrl_prune_entity()
2394 size = entity->camera.bControlSize; in uvc_ctrl_prune_entity()
2402 if (!usb_match_one_id(dev->intf, &blacklist[i].id)) in uvc_ctrl_prune_entity()
2411 entity->id, blacklist[i].index); in uvc_ctrl_prune_entity()
2434 if (UVC_ENTITY_TYPE(ctrl->entity) == UVC_VC_EXTENSION_UNIT) in uvc_ctrl_init_ctrl()
2440 if (uvc_entity_match_guid(ctrl->entity, info->entity) && in uvc_ctrl_init_ctrl()
2441 ctrl->index == info->index) { in uvc_ctrl_init_ctrl()
2442 uvc_ctrl_add_info(chain->dev, ctrl, info); in uvc_ctrl_init_ctrl()
2449 uvc_ctrl_get_flags(chain->dev, ctrl, &ctrl->info); in uvc_ctrl_init_ctrl()
2454 if (!ctrl->initialized) in uvc_ctrl_init_ctrl()
2458 * First check if the device provides a custom mapping for this control, in uvc_ctrl_init_ctrl()
2459 * used to override standard mappings for non-conformant devices. Don't in uvc_ctrl_init_ctrl()
2460 * process standard mappings if a custom mapping is found. This in uvc_ctrl_init_ctrl()
2464 if (chain->dev->info->mappings) { in uvc_ctrl_init_ctrl()
2467 for (i = 0; chain->dev->info->mappings[i]; ++i) { in uvc_ctrl_init_ctrl()
2468 const struct uvc_control_mapping *mapping = in uvc_ctrl_init_ctrl() local
2469 chain->dev->info->mappings[i]; in uvc_ctrl_init_ctrl()
2471 if (uvc_entity_match_guid(ctrl->entity, mapping->entity) && in uvc_ctrl_init_ctrl()
2472 ctrl->info.selector == mapping->selector) { in uvc_ctrl_init_ctrl()
2473 __uvc_ctrl_add_mapping(chain, ctrl, mapping); in uvc_ctrl_init_ctrl()
2484 const struct uvc_control_mapping *mapping = &uvc_ctrl_mappings[i]; in uvc_ctrl_init_ctrl() local
2486 if (uvc_entity_match_guid(ctrl->entity, mapping->entity) && in uvc_ctrl_init_ctrl()
2487 ctrl->info.selector == mapping->selector) in uvc_ctrl_init_ctrl()
2488 __uvc_ctrl_add_mapping(chain, ctrl, mapping); in uvc_ctrl_init_ctrl()
2491 /* Finally process version-specific mappings. */ in uvc_ctrl_init_ctrl()
2492 if (chain->dev->uvc_version < 0x0150) { in uvc_ctrl_init_ctrl()
2501 const struct uvc_control_mapping *mapping = &mappings[i]; in uvc_ctrl_init_ctrl() local
2503 if (uvc_entity_match_guid(ctrl->entity, mapping->entity) && in uvc_ctrl_init_ctrl()
2504 ctrl->info.selector == mapping->selector) in uvc_ctrl_init_ctrl()
2505 __uvc_ctrl_add_mapping(chain, ctrl, mapping); in uvc_ctrl_init_ctrl()
2518 list_for_each_entry(entity, &chain->entities, chain) { in uvc_ctrl_init_chain()
2524 bmControls = entity->extension.bmControls; in uvc_ctrl_init_chain()
2525 bControlSize = entity->extension.bControlSize; in uvc_ctrl_init_chain()
2527 bmControls = entity->processing.bmControls; in uvc_ctrl_init_chain()
2528 bControlSize = entity->processing.bControlSize; in uvc_ctrl_init_chain()
2530 bmControls = entity->camera.bmControls; in uvc_ctrl_init_chain()
2531 bControlSize = entity->camera.bControlSize; in uvc_ctrl_init_chain()
2533 bmControls = entity->gpio.bmControls; in uvc_ctrl_init_chain()
2534 bControlSize = entity->gpio.bControlSize; in uvc_ctrl_init_chain()
2538 uvc_ctrl_prune_entity(chain->dev, entity); in uvc_ctrl_init_chain()
2545 entity->controls = kcalloc(ncontrols, sizeof(*ctrl), in uvc_ctrl_init_chain()
2547 if (entity->controls == NULL) in uvc_ctrl_init_chain()
2548 return -ENOMEM; in uvc_ctrl_init_chain()
2549 entity->ncontrols = ncontrols; in uvc_ctrl_init_chain()
2552 ctrl = entity->controls; in uvc_ctrl_init_chain()
2557 ctrl->entity = entity; in uvc_ctrl_init_chain()
2558 ctrl->index = i; in uvc_ctrl_init_chain()
2573 INIT_WORK(&dev->async_ctrl.work, uvc_ctrl_status_event_work); in uvc_ctrl_init_device()
2575 list_for_each_entry(chain, &dev->chains, list) { in uvc_ctrl_init_device()
2590 struct uvc_control_mapping *mapping, *nm; in uvc_ctrl_cleanup_mappings() local
2592 list_for_each_entry_safe(mapping, nm, &ctrl->info.mappings, list) { in uvc_ctrl_cleanup_mappings()
2593 list_del(&mapping->list); in uvc_ctrl_cleanup_mappings()
2594 kfree(mapping->menu_info); in uvc_ctrl_cleanup_mappings()
2595 kfree(mapping->name); in uvc_ctrl_cleanup_mappings()
2596 kfree(mapping); in uvc_ctrl_cleanup_mappings()
2606 if (dev->async_ctrl.work.func) in uvc_ctrl_cleanup_device()
2607 cancel_work_sync(&dev->async_ctrl.work); in uvc_ctrl_cleanup_device()
2610 list_for_each_entry(entity, &dev->entities, list) { in uvc_ctrl_cleanup_device()
2611 for (i = 0; i < entity->ncontrols; ++i) { in uvc_ctrl_cleanup_device()
2612 struct uvc_control *ctrl = &entity->controls[i]; in uvc_ctrl_cleanup_device()
2614 if (!ctrl->initialized) in uvc_ctrl_cleanup_device()
2618 kfree(ctrl->uvc_data); in uvc_ctrl_cleanup_device()
2621 kfree(entity->controls); in uvc_ctrl_cleanup_device()