diff options
Diffstat (limited to 'target/linux/brcm2708/patches-3.10/0173-V4L2-Initial-pass-at-scene-modes.patch')
-rw-r--r-- | target/linux/brcm2708/patches-3.10/0173-V4L2-Initial-pass-at-scene-modes.patch | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-3.10/0173-V4L2-Initial-pass-at-scene-modes.patch b/target/linux/brcm2708/patches-3.10/0173-V4L2-Initial-pass-at-scene-modes.patch new file mode 100644 index 0000000000..c8c8abf070 --- /dev/null +++ b/target/linux/brcm2708/patches-3.10/0173-V4L2-Initial-pass-at-scene-modes.patch @@ -0,0 +1,360 @@ +From ba09044961948d93db7aa166f2829d46e81e875a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dsteve@broadcom.com> +Date: Fri, 14 Feb 2014 17:12:08 +0000 +Subject: [PATCH 173/174] V4L2: Initial pass at scene modes. + +Only supports exposure mode and metering modes. + +Signed-off-by: Dave Stevenson <dsteve@broadcom.com> +--- + drivers/media/platform/bcm2835/bcm2835-camera.h | 10 +- + drivers/media/platform/bcm2835/controls.c | 225 ++++++++++++++++++++---- + 2 files changed, 199 insertions(+), 36 deletions(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-camera.h ++++ b/drivers/media/platform/bcm2835/bcm2835-camera.h +@@ -15,7 +15,7 @@ + * core driver device + */ + +-#define V4L2_CTRL_COUNT 24 /* number of v4l controls */ ++#define V4L2_CTRL_COUNT 25 /* number of v4l controls */ + + enum { + MMAL_COMPONENT_CAMERA = 0, +@@ -45,11 +45,15 @@ struct bm2835_mmal_dev { + /* controls */ + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl *ctrls[V4L2_CTRL_COUNT]; ++ enum v4l2_scene_mode scene_mode; + struct mmal_colourfx colourfx; + int hflip; + int vflip; +- enum mmal_parameter_exposuremode exposure_mode; +- enum v4l2_exposure_auto_type exposure_mode_v4l2; ++ enum mmal_parameter_exposuremode exposure_mode_user; ++ enum v4l2_exposure_auto_type exposure_mode_v4l2_user; ++ /* active exposure mode may differ if selected via a scene mode */ ++ enum mmal_parameter_exposuremode exposure_mode_active; ++ enum mmal_parameter_exposuremeteringmode metering_mode; + unsigned int manual_shutter_speed; + bool exp_auto_priority; + +--- a/drivers/media/platform/bcm2835/controls.c ++++ b/drivers/media/platform/bcm2835/controls.c +@@ -145,6 +145,25 @@ static const struct v4l2_to_mmal_effects + 1, 1, 0, 0, 0, {0, 0, 0, 0, 0} } + }; + ++struct v4l2_mmal_scene_config { ++ enum v4l2_scene_mode v4l2_scene; ++ enum mmal_parameter_exposuremode exposure_mode; ++ enum mmal_parameter_exposuremeteringmode metering_mode; ++}; ++ ++static const struct v4l2_mmal_scene_config scene_configs[] = { ++ /* V4L2_SCENE_MODE_NONE automatically added */ ++ { ++ V4L2_SCENE_MODE_NIGHT, ++ MMAL_PARAM_EXPOSUREMODE_NIGHT, ++ MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE ++ }, ++ { ++ V4L2_SCENE_MODE_SPORTS, ++ MMAL_PARAM_EXPOSUREMODE_SPORTS, ++ MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE ++ }, ++}; + + /* control handlers*/ + +@@ -296,7 +315,7 @@ static int ctrl_set_exposure(struct bm28 + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) + { +- enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode; ++ enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode_user; + u32 shutter_speed = 0; + struct vchiq_mmal_port *control; + int ret = 0; +@@ -317,31 +336,32 @@ static int ctrl_set_exposure(struct bm28 + case V4L2_EXPOSURE_MANUAL: + exp_mode = MMAL_PARAM_EXPOSUREMODE_OFF; + break; +- +- case V4L2_EXPOSURE_SHUTTER_PRIORITY: +- exp_mode = MMAL_PARAM_EXPOSUREMODE_SPORTS; +- break; +- +- case V4L2_EXPOSURE_APERTURE_PRIORITY: +- exp_mode = MMAL_PARAM_EXPOSUREMODE_NIGHT; +- break; +- + } +- dev->exposure_mode = exp_mode; +- dev->exposure_mode_v4l2 = ctrl->val; ++ dev->exposure_mode_user = exp_mode; ++ dev->exposure_mode_v4l2_user = ctrl->val; + } else if (mmal_ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) { + dev->exp_auto_priority = ctrl->val; + } + +- if (dev->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF) +- shutter_speed = dev->manual_shutter_speed; ++ if (dev->scene_mode == V4L2_SCENE_MODE_NONE) { ++ if (exp_mode == MMAL_PARAM_EXPOSUREMODE_OFF) ++ shutter_speed = dev->manual_shutter_speed; + +- ret = vchiq_mmal_port_parameter_set(dev->instance, control, +- MMAL_PARAMETER_SHUTTER_SPEED, +- &shutter_speed, sizeof(shutter_speed)); +- ret += vchiq_mmal_port_parameter_set(dev->instance, control, +- MMAL_PARAMETER_EXPOSURE_MODE, +- &exp_mode, sizeof(u32)); ++ ret = vchiq_mmal_port_parameter_set(dev->instance, ++ control, ++ MMAL_PARAMETER_SHUTTER_SPEED, ++ &shutter_speed, ++ sizeof(shutter_speed)); ++ ret += vchiq_mmal_port_parameter_set(dev->instance, ++ control, ++ MMAL_PARAMETER_EXPOSURE_MODE, ++ &exp_mode, ++ sizeof(u32)); ++ dev->exposure_mode_active = exp_mode; ++ } ++ /* exposure_dynamic_framerate (V4L2_CID_EXPOSURE_AUTO_PRIORITY) should ++ * always apply irrespective of scene mode. ++ */ + ret += set_framerate_params(dev); + + return ret; +@@ -351,35 +371,38 @@ static int ctrl_set_metering_mode(struct + struct v4l2_ctrl *ctrl, + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) + { +- u32 u32_value; +- struct vchiq_mmal_port *control; +- +- control = &dev->component[MMAL_COMPONENT_CAMERA]->control; +- + switch (ctrl->val) { + case V4L2_EXPOSURE_METERING_AVERAGE: +- u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE; ++ dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE; + break; + + case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED: +- u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT; ++ dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT; + break; + + case V4L2_EXPOSURE_METERING_SPOT: +- u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT; ++ dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT; + break; + + /* todo matrix weighting not added to Linux API till 3.9 + case V4L2_EXPOSURE_METERING_MATRIX: +- u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX; ++ dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX; + break; + */ + + } + +- return vchiq_mmal_port_parameter_set(dev->instance, control, ++ if (dev->scene_mode == V4L2_SCENE_MODE_NONE) { ++ struct vchiq_mmal_port *control; ++ u32 u32_value = dev->metering_mode; ++ ++ control = &dev->component[MMAL_COMPONENT_CAMERA]->control; ++ ++ return vchiq_mmal_port_parameter_set(dev->instance, control, + mmal_ctrl->mmal_id, + &u32_value, sizeof(u32_value)); ++ } else ++ return 0; + } + + static int ctrl_set_flicker_avoidance(struct bm2835_mmal_dev *dev, +@@ -738,6 +761,113 @@ static int ctrl_set_video_encode_profile + return ret; + } + ++static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev, ++ struct v4l2_ctrl *ctrl, ++ const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) ++{ ++ int ret = 0; ++ int shutter_speed; ++ struct vchiq_mmal_port *control; ++ ++ v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "scene mode selected %d, was %d\n", ctrl->val, ++ dev->scene_mode); ++ control = &dev->component[MMAL_COMPONENT_CAMERA]->control; ++ ++ if (ctrl->val == dev->scene_mode) ++ return 0; ++ ++ if (ctrl->val == V4L2_SCENE_MODE_NONE) { ++ /* Restore all user selections */ ++ dev->scene_mode = V4L2_SCENE_MODE_NONE; ++ ++ if (dev->exposure_mode_user == MMAL_PARAM_EXPOSUREMODE_OFF) ++ shutter_speed = dev->manual_shutter_speed; ++ else ++ shutter_speed = 0; ++ ++ v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n", ++ __func__, shutter_speed, dev->exposure_mode_user, ++ dev->metering_mode); ++ ret = vchiq_mmal_port_parameter_set(dev->instance, ++ control, ++ MMAL_PARAMETER_SHUTTER_SPEED, ++ &shutter_speed, ++ sizeof(shutter_speed)); ++ ret += vchiq_mmal_port_parameter_set(dev->instance, ++ control, ++ MMAL_PARAMETER_EXPOSURE_MODE, ++ &dev->exposure_mode_user, ++ sizeof(u32)); ++ dev->exposure_mode_active = dev->exposure_mode_user; ++ ret += vchiq_mmal_port_parameter_set(dev->instance, ++ control, ++ MMAL_PARAMETER_EXP_METERING_MODE, ++ &dev->metering_mode, ++ sizeof(u32)); ++ ret += set_framerate_params(dev); ++ } else { ++ /* Set up scene mode */ ++ int i; ++ const struct v4l2_mmal_scene_config *scene = NULL; ++ int shutter_speed; ++ enum mmal_parameter_exposuremode exposure_mode; ++ enum mmal_parameter_exposuremeteringmode metering_mode; ++ ++ for (i = 0; i < ARRAY_SIZE(scene_configs); i++) { ++ if (scene_configs[i].v4l2_scene == ++ ctrl->val) { ++ scene = &scene_configs[i]; ++ break; ++ } ++ } ++ if (i >= ARRAY_SIZE(scene_configs)) ++ return -EINVAL; ++ ++ /* Set all the values */ ++ dev->scene_mode = ctrl->val; ++ ++ if (scene->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF) ++ shutter_speed = dev->manual_shutter_speed; ++ else ++ shutter_speed = 0; ++ exposure_mode = scene->exposure_mode; ++ metering_mode = scene->metering_mode; ++ ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n", ++ __func__, shutter_speed, exposure_mode, metering_mode); ++ ++ ret = vchiq_mmal_port_parameter_set(dev->instance, control, ++ MMAL_PARAMETER_SHUTTER_SPEED, ++ &shutter_speed, ++ sizeof(shutter_speed)); ++ ret += vchiq_mmal_port_parameter_set(dev->instance, ++ control, ++ MMAL_PARAMETER_EXPOSURE_MODE, ++ &exposure_mode, ++ sizeof(u32)); ++ dev->exposure_mode_active = exposure_mode; ++ ret += vchiq_mmal_port_parameter_set(dev->instance, control, ++ MMAL_PARAMETER_EXPOSURE_MODE, ++ &exposure_mode, ++ sizeof(u32)); ++ ret += vchiq_mmal_port_parameter_set(dev->instance, control, ++ MMAL_PARAMETER_EXP_METERING_MODE, ++ &metering_mode, ++ sizeof(u32)); ++ ret += set_framerate_params(dev); ++ } ++ if (ret) { ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "%s: Setting scene to %d, ret=%d\n", ++ __func__, ctrl->val, ret); ++ ret = -EINVAL; ++ } ++ return 0; ++} ++ + static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl) + { + struct bm2835_mmal_dev *dev = +@@ -973,6 +1103,15 @@ static const struct bm2835_mmal_v4l2_ctr + &ctrl_set_video_encode_profile_level, + false + }, ++ { ++ V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU, ++ -1, /* Min is computed at runtime */ ++ V4L2_SCENE_MODE_TEXT, ++ V4L2_SCENE_MODE_NONE, 1, NULL, ++ MMAL_PARAMETER_PROFILE, ++ &ctrl_set_scene_mode, ++ false ++ }, + }; + + int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev) +@@ -1000,8 +1139,7 @@ int set_framerate_params(struct bm2835_m + struct mmal_parameter_fps_range fps_range; + int ret; + +- if ((dev->exposure_mode_v4l2 == V4L2_EXPOSURE_AUTO || +- dev->exposure_mode_v4l2 == V4L2_EXPOSURE_APERTURE_PRIORITY) && ++ if ((dev->exposure_mode_active != MMAL_PARAM_EXPOSUREMODE_OFF) && + (dev->exp_auto_priority)) { + /* Variable FPS. Define min FPS as 1fps. + * Max as max defined FPS. +@@ -1049,6 +1187,7 @@ int set_framerate_params(struct bm2835_m + return ret; + + } ++ + int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev, + struct v4l2_ctrl_handler *hdl) + { +@@ -1068,10 +1207,30 @@ int bm2835_mmal_init_controls(struct bm2 + break; + + case MMAL_CONTROL_TYPE_STD_MENU: ++ { ++ int mask = ctrl->min; ++ ++ if (ctrl->id == V4L2_CID_SCENE_MODE) { ++ /* Special handling to work out the mask ++ * value based on the scene_configs array ++ * at runtime. Reduces the chance of ++ * mismatches. ++ */ ++ int i; ++ mask = 1<<V4L2_SCENE_MODE_NONE; ++ for (i = 0; ++ i < ARRAY_SIZE(scene_configs); ++ i++) { ++ mask |= 1<<scene_configs[i].v4l2_scene; ++ } ++ mask = ~mask; ++ } ++ + dev->ctrls[c] = v4l2_ctrl_new_std_menu(hdl, + &bm2835_mmal_ctrl_ops, ctrl->id, +- ctrl->max, ctrl->min, ctrl->def); ++ ctrl->max, mask, ctrl->def); + break; ++ } + + case MMAL_CONTROL_TYPE_INT_MENU: + dev->ctrls[c] = v4l2_ctrl_new_int_menu(hdl, |