Commit 86f7ef77 authored by Ricardo Ribalda's avatar Ricardo Ribalda Committed by Mauro Carvalho Chehab
Browse files

media: uvcvideo: Add support for per-device control mapping overrides



Some devices do not implement all their controls in a way that complies
with the UVC specification. This is for instance the case for several
devices that do not support the disabled mode for the power line
frequency control. Add a mechanism to allow per-device control mapping
overrides to avoid errors when accessing non-compliant controls.

Signed-off-by: default avatarRicardo Ribalda <ribalda@chromium.org>
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 71087116
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -2444,14 +2444,37 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
	if (!ctrl->initialized)
		return;

	/* Process common mappings first. */
	/*
	 * First check if the device provides a custom mapping for this control,
	 * used to override standard mappings for non-conformant devices. Don't
	 * process standard mappings if a custom mapping is found. This
	 * mechanism doesn't support combining standard and custom mappings for
	 * a single control.
	 */
	if (chain->dev->info->mappings) {
		bool custom = false;
		unsigned int i;

		for (i = 0; (mapping = chain->dev->info->mappings[i]); ++i) {
			if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
			    ctrl->info.selector == mapping->selector) {
				__uvc_ctrl_add_mapping(chain, ctrl, mapping);
				custom = true;
			}
		}

		if (custom)
			return;
	}

	/* Process common mappings next. */
	for (; mapping < mend; ++mapping) {
		if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
		    ctrl->info.selector == mapping->selector)
			__uvc_ctrl_add_mapping(chain, ctrl, mapping);
	}

	/* And then version-specific mappings. */
	/* Finally process version-specific mappings. */
	if (chain->dev->uvc_version < 0x0150) {
		mapping = uvc_ctrl_mappings_uvc11;
		mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings_uvc11);
+1 −0
Original line number Diff line number Diff line
@@ -668,6 +668,7 @@ struct uvc_device_info {
	u32	quirks;
	u32	meta_format;
	u16	uvc_version;
	const struct uvc_control_mapping **mappings;
};

struct uvc_device {