From 9d80a4ce15c265530d8372a3577748123e365ee3 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dsteve@broadcom.com>
Date: Mon, 9 Dec 2013 16:40:24 +0000
Subject: [PATCH 135/174] V4L2: Add flicker avoidance controls

Add support for V4L2_CID_POWER_LINE_FREQUENCY to set flicker
avoidance frequencies.

Signed-off-by: Dave Stevenson <dsteve@broadcom.com>
---
 drivers/media/platform/bcm2835/bcm2835-camera.h  |  2 +-
 drivers/media/platform/bcm2835/controls.c        | 42 ++++++++++++++++++++++++
 drivers/media/platform/bcm2835/mmal-parameters.h |  8 +++++
 3 files changed, 51 insertions(+), 1 deletion(-)

--- 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 19 /* number of v4l controls */
+#define V4L2_CTRL_COUNT 20 /* number of v4l controls */
 
 enum {
 	MMAL_COMPONENT_CAMERA = 0,
--- a/drivers/media/platform/bcm2835/controls.c
+++ b/drivers/media/platform/bcm2835/controls.c
@@ -56,6 +56,13 @@ static const s64 iso_qmenu[] = {
 	0, 100, 200, 400, 800,
 };
 
+static const s64 mains_freq_qmenu[] = {
+	V4L2_CID_POWER_LINE_FREQUENCY_DISABLED,
+	V4L2_CID_POWER_LINE_FREQUENCY_50HZ,
+	V4L2_CID_POWER_LINE_FREQUENCY_60HZ,
+	V4L2_CID_POWER_LINE_FREQUENCY_AUTO
+};
+
 /* Supported video encode modes */
 static const s64 bitrate_mode_qmenu[] = {
 	(s64)V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
@@ -373,6 +380,35 @@ static int ctrl_set_metering_mode(struct
 					     &u32_value, sizeof(u32_value));
 }
 
+static int ctrl_set_flicker_avoidance(struct bm2835_mmal_dev *dev,
+			   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_CID_POWER_LINE_FREQUENCY_DISABLED:
+		u32_value = MMAL_PARAM_FLICKERAVOID_OFF;
+		break;
+	case V4L2_CID_POWER_LINE_FREQUENCY_50HZ:
+		u32_value = MMAL_PARAM_FLICKERAVOID_50HZ;
+		break;
+	case V4L2_CID_POWER_LINE_FREQUENCY_60HZ:
+		u32_value = MMAL_PARAM_FLICKERAVOID_60HZ;
+		break;
+	case V4L2_CID_POWER_LINE_FREQUENCY_AUTO:
+		u32_value = MMAL_PARAM_FLICKERAVOID_AUTO;
+		break;
+	}
+
+	return vchiq_mmal_port_parameter_set(dev->instance, control,
+					     mmal_ctrl->mmal_id,
+					     &u32_value, sizeof(u32_value));
+}
+
 static int ctrl_set_awb_mode(struct bm2835_mmal_dev *dev,
 		      struct v4l2_ctrl *ctrl,
 		      const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
@@ -706,6 +742,12 @@ static const struct bm2835_mmal_v4l2_ctr
 		30, 1, NULL,
 		MMAL_PARAMETER_JPEG_Q_FACTOR, &ctrl_set_image_encode_output
 	},
+	{
+		V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU,
+		0, ARRAY_SIZE(mains_freq_qmenu) - 1,
+		1, 1, NULL,
+		MMAL_PARAMETER_FLICKER_AVOID, &ctrl_set_flicker_avoidance
+	},
 };
 
 int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev)
--- a/drivers/media/platform/bcm2835/mmal-parameters.h
+++ b/drivers/media/platform/bcm2835/mmal-parameters.h
@@ -271,6 +271,14 @@ enum mmal_parameter_imagefx {
 	MMAL_PARAM_IMAGEFX_CARTOON,
 };
 
+enum MMAL_PARAM_FLICKERAVOID_T {
+	MMAL_PARAM_FLICKERAVOID_OFF,
+	MMAL_PARAM_FLICKERAVOID_AUTO,
+	MMAL_PARAM_FLICKERAVOID_50HZ,
+	MMAL_PARAM_FLICKERAVOID_60HZ,
+	MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF
+};
+
 /** Manner of video rate control */
 enum mmal_parameter_rate_control_mode {
 	MMAL_VIDEO_RATECONTROL_DEFAULT,
