For the devices we tested with, firmwares have wrong initial ROI configuration. Initialize roi by setting to default value. Signed-off-by: Yunke Cao <yunkec@xxxxxxxxxx> --- drivers/media/usb/uvc/uvc_ctrl.c | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 0abe174231ab..f7aa97aa3772 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -2506,6 +2506,40 @@ static void uvc_ctrl_prune_entity(struct uvc_device *dev, } } +static int uvc_ctrl_init_roi(struct uvc_device *dev, struct uvc_control *ctrl) +{ + int ret; + + ret = uvc_query_ctrl(dev, UVC_GET_DEF, ctrl->entity->id, dev->intfnum, + UVC_CT_REGION_OF_INTEREST_CONTROL, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), + ctrl->info.size); + if (ret) + goto out; + + /* + * Some firmwares have wrong GET_CURRENT configuration. E.g. it's + * below GET_MIN, or have rectangle coordinates mixed up. This + * causes problems sometimes, because we are unable to set + * auto-controls value without first setting ROI rectangle to + * valid configuration. + * + * We expect that default configuration is always correct and + * is within the GET_MIN / GET_MAX boundaries. + * + * Set current ROI configuration to GET_DEF, so that we will + * always have properly configured ROI. + */ + ret = uvc_query_ctrl(dev, UVC_SET_CUR, 1, dev->intfnum, + UVC_CT_REGION_OF_INTEREST_CONTROL, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), + ctrl->info.size); +out: + if (ret) + dev_err(&dev->udev->dev, "Failed to fixup ROI (%d).\n", ret); + return ret; +} + /* * Add control information and hardcoded stock control mappings to the given * device. @@ -2518,6 +2552,7 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain, const struct uvc_control_mapping *mapping = uvc_ctrl_mappings; const struct uvc_control_mapping *mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings); + const u8 camera_entity[16] = UVC_GUID_UVC_CAMERA; /* XU controls initialization requires querying the device for control * information. As some buggy UVC devices will crash when queried @@ -2538,6 +2573,11 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain, * GET_INFO on standard controls. */ uvc_ctrl_get_flags(chain->dev, ctrl, &ctrl->info); + + if (ctrl->info.selector == + UVC_CT_REGION_OF_INTEREST_CONTROL && + uvc_entity_match_guid(ctrl->entity, camera_entity)) + uvc_ctrl_init_roi(chain->dev, ctrl); break; } } -- 2.36.0.550.gb090851708-goog