aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-3.10/0131-V4L2-Fix-EV-values.-Add-manual-shutter-speed-control.patch
blob: 9983c3de507bd49c810e62dc9c989162d0a11941 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
From 6519115a0742befaa2e5864a496398367aab97b0 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dsteve@broadcom.com>
Date: Mon, 9 Dec 2013 10:58:01 +0000
Subject: [PATCH 131/196] V4L2: Fix EV values. Add manual shutter speed control

V4L2 EV values should be in units of 1/1000. Corrected.
Add support for V4L2_CID_EXPOSURE_ABSOLUTE which should
give manual shutter control. Requires manual exposure mode
to be selected first.

Signed-off-by: Dave Stevenson <dsteve@broadcom.com>
---
 drivers/media/platform/bcm2835/bcm2835-camera.h  |  4 +-
 drivers/media/platform/bcm2835/controls.c        | 94 ++++++++++++++++++------
 drivers/media/platform/bcm2835/mmal-parameters.h |  1 +
 3 files changed, 76 insertions(+), 23 deletions(-)

diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.h b/drivers/media/platform/bcm2835/bcm2835-camera.h
index 883eab7..5640492 100644
--- 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 18 /* number of v4l controls */
+#define V4L2_CTRL_COUNT 19 /* number of v4l controls */
 
 enum {
 	MMAL_COMPONENT_CAMERA = 0,
@@ -51,6 +51,8 @@ struct bm2835_mmal_dev {
 	struct mmal_colourfx      colourfx;
 	int                       hflip;
 	int                       vflip;
+	enum mmal_parameter_exposuremode exposure_mode;
+	unsigned int		  manual_shutter_speed;
 
 	/* allocated mmal instance and components */
 	struct vchiq_mmal_instance   *instance;
diff --git a/drivers/media/platform/bcm2835/controls.c b/drivers/media/platform/bcm2835/controls.c
index d1408e5..481d1f6 100644
--- a/drivers/media/platform/bcm2835/controls.c
+++ b/drivers/media/platform/bcm2835/controls.c
@@ -30,11 +30,23 @@
 #include "mmal-parameters.h"
 #include "bcm2835-camera.h"
 
-/* The supported V4L2_CID_AUTO_EXPOSURE_BIAS values are from -24 to +24.
- * These are in 1/6th increments so the effective range is -4.0EV to +4.0EV.
+/* The supported V4L2_CID_AUTO_EXPOSURE_BIAS values are from -4.0 to +4.0.
+ * MMAL values are in 1/6th increments so the MMAL range is -24 to +24.
+ * V4L2 docs say value "is expressed in terms of EV, drivers should interpret
+ * the values as 0.001 EV units, where the value 1000 stands for +1 EV."
+ * V4L2 is limited to a max of 32 values in a menu, so count in 1/3rds from
+ * -4 to +4
  */
 static const s64 ev_bias_qmenu[] = {
-	-24, -21, -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21, 24
+	-4000, -3667, -3333,
+	-3000, -2667, -2333,
+	-2000, -1667, -1333,
+	-1000,  -667,  -333,
+	    0,   333,   667,
+	 1000,  1333,  1667,
+	 2000,  2333,  2667,
+	 3000,  3333,  3667,
+	 4000
 };
 
 /* Supported ISO values
@@ -166,6 +178,22 @@ static int ctrl_set_value(struct bm2835_mmal_dev *dev,
 					     &u32_value, sizeof(u32_value));
 }
 
+static int ctrl_set_value_ev(struct bm2835_mmal_dev *dev,
+		      struct v4l2_ctrl *ctrl,
+		      const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+{
+	s32 s32_value;
+	struct vchiq_mmal_port *control;
+
+	control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
+
+	s32_value = (ctrl->val-12)*2;	/* Convert from index to 1/6ths */
+
+	return vchiq_mmal_port_parameter_set(dev->instance, control,
+					     mmal_ctrl->mmal_id,
+					     &s32_value, sizeof(s32_value));
+}
+
 static int ctrl_set_rotate(struct bm2835_mmal_dev *dev,
 		      struct v4l2_ctrl *ctrl,
 		      const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
@@ -245,34 +273,50 @@ static int ctrl_set_exposure(struct bm2835_mmal_dev *dev,
 		      struct v4l2_ctrl *ctrl,
 		      const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
-	u32 u32_value;
+	enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode;
+	u32 shutter_speed = 0;
 	struct vchiq_mmal_port *control;
+	int ret = 0;
 
 	control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
 
-	switch (ctrl->val) {
-	case V4L2_EXPOSURE_AUTO:
-		u32_value = MMAL_PARAM_EXPOSUREMODE_AUTO;
-		break;
+	if (mmal_ctrl->mmal_id == MMAL_PARAMETER_SHUTTER_SPEED)	{
+		/* V4L2 is in 100usec increments.
+		 * MMAL is 1usec.
+		 */
+		dev->manual_shutter_speed = ctrl->val * 100;
+	} else if (mmal_ctrl->mmal_id == MMAL_PARAMETER_EXPOSURE_MODE) {
+		switch (ctrl->val) {
+		case V4L2_EXPOSURE_AUTO:
+			exp_mode = MMAL_PARAM_EXPOSUREMODE_AUTO;
+			break;
 
-	case V4L2_EXPOSURE_MANUAL:
-		u32_value = MMAL_PARAM_EXPOSUREMODE_OFF;
-		break;
+		case V4L2_EXPOSURE_MANUAL:
+			exp_mode = MMAL_PARAM_EXPOSUREMODE_OFF;
+			break;
 
-	case V4L2_EXPOSURE_SHUTTER_PRIORITY:
-		u32_value = MMAL_PARAM_EXPOSUREMODE_SPORTS;
-		break;
+		case V4L2_EXPOSURE_SHUTTER_PRIORITY:
+			exp_mode = MMAL_PARAM_EXPOSUREMODE_SPORTS;
+			break;
 
-	case V4L2_EXPOSURE_APERTURE_PRIORITY:
-		u32_value = MMAL_PARAM_EXPOSUREMODE_NIGHT;
-		break;
+		case V4L2_EXPOSURE_APERTURE_PRIORITY:
+			exp_mode = MMAL_PARAM_EXPOSUREMODE_NIGHT;
+			break;
 
+		}
+		dev->exposure_mode = exp_mode;
 	}
 
-	/* todo: what about the other ten modes there are MMAL parameters for */
-	return vchiq_mmal_port_parameter_set(dev->instance, control,
-					     mmal_ctrl->mmal_id,
-					     &u32_value, sizeof(u32_value));
+	if (dev->exposure_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));
+	return ret;
 }
 
 static int ctrl_set_metering_mode(struct bm2835_mmal_dev *dev,
@@ -578,10 +622,16 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
 	},
  */
 	{
+		V4L2_CID_EXPOSURE_ABSOLUTE, MMAL_CONTROL_TYPE_STD,
+		/* Units of 100usecs */
+		1, 1*1000*10, 100*10, 1, NULL,
+		MMAL_PARAMETER_SHUTTER_SPEED, &ctrl_set_exposure
+	},
+	{
 		V4L2_CID_AUTO_EXPOSURE_BIAS, MMAL_CONTROL_TYPE_INT_MENU,
 		0, ARRAY_SIZE(ev_bias_qmenu) - 1,
 		(ARRAY_SIZE(ev_bias_qmenu)+1)/2 - 1, 0, ev_bias_qmenu,
-		MMAL_PARAMETER_EXPOSURE_COMP, &ctrl_set_value
+		MMAL_PARAMETER_EXPOSURE_COMP, &ctrl_set_value_ev
 	},
 	{
 		V4L2_CID_EXPOSURE_METERING,
diff --git a/drivers/media/platform/bcm2835/mmal-parameters.h b/drivers/media/platform/bcm2835/mmal-parameters.h
index c611b58..d8aace5 100644
--- a/drivers/media/platform/bcm2835/mmal-parameters.h
+++ b/drivers/media/platform/bcm2835/mmal-parameters.h
@@ -161,6 +161,7 @@ enum mmal_parameter_camera_type {
 	MMAL_PARAMETER_SW_SHARPEN_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */
 	MMAL_PARAMETER_FLASH_REQUIRED, /**< @ref MMAL_PARAMETER_BOOLEAN_T */
 	MMAL_PARAMETER_SW_SATURATION_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */
+	MMAL_PARAMETER_SHUTTER_SPEED              /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
 };
 
 enum mmal_parameter_camera_config_timestamp_mode {
-- 
1.9.1